@vellumai/assistant 0.8.4 → 0.8.6

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 (802) hide show
  1. package/AGENTS.md +33 -1
  2. package/ARCHITECTURE.md +3 -3
  3. package/bunfig.toml +6 -1
  4. package/docs/browser-use-architecture-phase2.md +1 -1
  5. package/docs/credential-execution-service.md +6 -6
  6. package/docs/plugins.md +4 -3
  7. package/knip.json +2 -1
  8. package/node_modules/@vellumai/skill-host-contracts/src/client.ts +12 -13
  9. package/node_modules/@vellumai/skill-host-contracts/src/skill-host.ts +4 -1
  10. package/node_modules/@vellumai/skill-host-contracts/src/tool-types.ts +16 -14
  11. package/openapi.yaml +2748 -216
  12. package/package.json +1 -1
  13. package/src/__tests__/actor-token-service.test.ts +3 -2
  14. package/src/__tests__/agent-loop-exit-reason.test.ts +102 -9
  15. package/src/__tests__/agent-loop-override-profile.test.ts +2 -1
  16. package/src/__tests__/agent-wake-disk-pressure-callsite.test.ts +1 -0
  17. package/src/__tests__/agent-wake-override-profile.test.ts +1 -0
  18. package/src/__tests__/always-loaded-tools-guard.test.ts +2 -2
  19. package/src/__tests__/annotate-risk-options.test.ts +1 -0
  20. package/src/__tests__/anthropic-provider.test.ts +34 -37
  21. package/src/__tests__/approval-cascade.test.ts +1 -0
  22. package/src/__tests__/approval-routes-http.test.ts +9 -13
  23. package/src/__tests__/assert-not-live-db.ts +79 -0
  24. package/src/__tests__/assistant-event-hub-self-exclusion.test.ts +293 -0
  25. package/src/__tests__/assistant-feature-flags-integration.test.ts +12 -28
  26. package/src/__tests__/audit-log-rotation.test.ts +72 -18
  27. package/src/__tests__/auto-analysis-end-to-end.test.ts +6 -6
  28. package/src/__tests__/background-workers-disk-pressure.test.ts +8 -11
  29. package/src/__tests__/browser-skill-endstate.test.ts +3 -3
  30. package/src/__tests__/btw-routes.test.ts +5 -5
  31. package/src/__tests__/call-controller.test.ts +3 -3
  32. package/src/__tests__/cancel-resolves-conversation-key.test.ts +1 -1
  33. package/src/__tests__/channel-approval-routes.test.ts +3 -2
  34. package/src/__tests__/channel-guardian.test.ts +6 -5
  35. package/src/__tests__/channel-readiness-slack-remote.test.ts +175 -0
  36. package/src/__tests__/channel-reply-delivery.test.ts +35 -0
  37. package/src/__tests__/channel-retry-sweep.test.ts +320 -3
  38. package/src/__tests__/checker.test.ts +18 -27
  39. package/src/__tests__/compaction-events.test.ts +2 -0
  40. package/src/__tests__/compaction-trail-store.test.ts +264 -0
  41. package/src/__tests__/compactor-call-site-logging.test.ts +215 -0
  42. package/src/__tests__/compactor-preserved-tail-count.test.ts +1 -0
  43. package/src/__tests__/computer-use-skill-manifest-regression.test.ts +12 -16
  44. package/src/__tests__/computer-use-tools.test.ts +14 -18
  45. package/src/__tests__/config-loader-backfill.test.ts +13 -28
  46. package/src/__tests__/config-loader-corrupt.test.ts +5 -5
  47. package/src/__tests__/config-loader-platform-defaults.test.ts +93 -26
  48. package/src/__tests__/config-loader-quarantine-bulletin.test.ts +3 -3
  49. package/src/__tests__/config-managed-gemini-defaults.test.ts +3 -4
  50. package/src/__tests__/config-schema.test.ts +10 -10
  51. package/src/__tests__/confirmation-request-guardian-bridge.test.ts +0 -1
  52. package/src/__tests__/connection-model-compat.test.ts +83 -0
  53. package/src/__tests__/contacts-tools.test.ts +3 -2
  54. package/src/__tests__/context-token-estimator.test.ts +22 -0
  55. package/src/__tests__/conversation-abort-tool-results.test.ts +5 -0
  56. package/src/__tests__/conversation-agent-loop-disk-pressure.test.ts +2 -1
  57. package/src/__tests__/conversation-agent-loop-handlers-max-tokens.test.ts +55 -0
  58. package/src/__tests__/conversation-agent-loop-inference-profile.test.ts +2 -1
  59. package/src/__tests__/conversation-agent-loop-overflow.test.ts +231 -2
  60. package/src/__tests__/conversation-agent-loop.test.ts +581 -54
  61. package/src/__tests__/conversation-analysis-routes.test.ts +1 -0
  62. package/src/__tests__/conversation-app-control-instantiation.test.ts +31 -24
  63. package/src/__tests__/conversation-app-control-lifecycle.test.ts +1 -0
  64. package/src/__tests__/conversation-attention-store.test.ts +101 -0
  65. package/src/__tests__/conversation-attention-telegram.test.ts +3 -2
  66. package/src/__tests__/conversation-clear-safety.test.ts +25 -25
  67. package/src/__tests__/conversation-confirmation-signals.test.ts +1 -0
  68. package/src/__tests__/conversation-delete-schedule-cleanup.test.ts +1 -1
  69. package/src/__tests__/conversation-disk-view-integration.test.ts +2 -2
  70. package/src/__tests__/conversation-error.test.ts +61 -0
  71. package/src/__tests__/conversation-fork-crud.test.ts +239 -15
  72. package/src/__tests__/conversation-fork-route.test.ts +3 -2
  73. package/src/__tests__/conversation-history-web-search.test.ts +1 -0
  74. package/src/__tests__/conversation-inference-profile-list.test.ts +3 -2
  75. package/src/__tests__/conversation-inference-profile-route.test.ts +3 -2
  76. package/src/__tests__/conversation-lifecycle.test.ts +53 -11
  77. package/src/__tests__/conversation-list-source.test.ts +3 -2
  78. package/src/__tests__/conversation-load-history-repair.test.ts +2 -1
  79. package/src/__tests__/{conversation-load-cleaned-at.test.ts → conversation-load-history-stripped.test.ts} +14 -13
  80. package/src/__tests__/conversation-pairing.test.ts +53 -0
  81. package/src/__tests__/conversation-process-app-control-preactivation.test.ts +26 -7
  82. package/src/__tests__/conversation-process-callsite.test.ts +1 -0
  83. package/src/__tests__/conversation-provider-retry-repair.test.ts +6 -0
  84. package/src/__tests__/conversation-queue.test.ts +333 -291
  85. package/src/__tests__/conversation-routes-disk-view.test.ts +112 -18
  86. package/src/__tests__/conversation-routes-guardian-reply.test.ts +33 -8
  87. package/src/__tests__/conversation-routes-slash-commands.test.ts +68 -2
  88. package/src/__tests__/conversation-runtime-assembly.test.ts +78 -0
  89. package/src/__tests__/conversation-skill-tools.test.ts +40 -147
  90. package/src/__tests__/conversation-slash-queue.test.ts +84 -32
  91. package/src/__tests__/conversation-slash-unknown.test.ts +5 -0
  92. package/src/__tests__/conversation-speed-override.test.ts +1 -0
  93. package/src/__tests__/conversation-store.test.ts +1 -1
  94. package/src/__tests__/conversation-surfaces-action-delivery.test.ts +46 -0
  95. package/src/__tests__/conversation-surfaces-data-persist.test.ts +1 -0
  96. package/src/__tests__/conversation-surfaces-standalone-payloads.test.ts +6 -3
  97. package/src/__tests__/conversation-surfaces-standalone.test.ts +6 -3
  98. package/src/__tests__/conversation-surfaces-state-update.test.ts +3 -3
  99. package/src/__tests__/conversation-surfaces-table-action.test.ts +7 -17
  100. package/src/__tests__/conversation-sync-tags.test.ts +218 -35
  101. package/src/__tests__/conversation-title-service.test.ts +1 -0
  102. package/src/__tests__/conversation-tool-setup-app-refresh.test.ts +30 -0
  103. package/src/__tests__/conversation-usage.test.ts +1 -0
  104. package/src/__tests__/conversation-workspace-cache-state.test.ts +2 -0
  105. package/src/__tests__/conversation-workspace-injection.test.ts +6 -1
  106. package/src/__tests__/conversation-workspace-tool-tracking.test.ts +6 -1
  107. package/src/__tests__/credential-broker-browser-fill.test.ts +3 -3
  108. package/src/__tests__/credential-broker-server-use.test.ts +5 -5
  109. package/src/__tests__/credential-execution-client.test.ts +72 -1
  110. package/src/__tests__/credential-execution-feature-gates.test.ts +19 -19
  111. package/src/__tests__/credential-execution-tools.test.ts +6 -6
  112. package/src/__tests__/credential-health-service.test.ts +252 -3
  113. package/src/__tests__/credential-security-invariants.test.ts +6 -5
  114. package/src/__tests__/credential-vault-unit.test.ts +21 -21
  115. package/src/__tests__/credential-vault.test.ts +5 -5
  116. package/src/__tests__/cross-provider-web-search.test.ts +56 -2
  117. package/src/__tests__/db-connection-isolation.test.ts +7 -6
  118. package/src/__tests__/db-conversation-fork-lineage-migration.test.ts +8 -10
  119. package/src/__tests__/db-conversation-inference-profile-migration.test.ts +7 -10
  120. package/src/__tests__/db-llm-request-log-provider-migration.test.ts +9 -15
  121. package/src/__tests__/db-test-helpers.ts +58 -0
  122. package/src/__tests__/disk-pressure-guard.test.ts +58 -41
  123. package/src/__tests__/disk-pressure-lifecycle.test.ts +13 -10
  124. package/src/__tests__/disk-pressure-routes.test.ts +0 -33
  125. package/src/__tests__/disk-pressure-tools.test.ts +0 -4
  126. package/src/__tests__/dm-persistence.test.ts +26 -40
  127. package/src/__tests__/document-create-dedupe.test.ts +189 -0
  128. package/src/__tests__/document-find-replace.test.ts +3 -2
  129. package/src/__tests__/document-tool-security.test.ts +81 -2
  130. package/src/__tests__/dynamic-page-surface.test.ts +2 -2
  131. package/src/__tests__/dynamic-skill-workflow-prompt.test.ts +5 -4
  132. package/src/__tests__/email-html-renderer.test.ts +12 -0
  133. package/src/__tests__/encrypted-store-test-helpers.ts +56 -0
  134. package/src/__tests__/encrypted-store.test.ts +11 -9
  135. package/src/__tests__/feature-flag-test-helpers.ts +53 -0
  136. package/src/__tests__/filing-service.test.ts +1 -0
  137. package/src/__tests__/first-greeting.test.ts +62 -12
  138. package/src/__tests__/gateway-flag-listener.test.ts +236 -0
  139. package/src/__tests__/gemini-provider.test.ts +104 -0
  140. package/src/__tests__/guardian-action-sweep.test.ts +3 -2
  141. package/src/__tests__/guardian-dispatch.test.ts +0 -1
  142. package/src/__tests__/guardian-outbound-http.test.ts +10 -7
  143. package/src/__tests__/handlers-skills-memory-v2-reseed.test.ts +48 -3
  144. package/src/__tests__/handlers-user-message-approval-consumption.test.ts +2 -1
  145. package/src/__tests__/heartbeat-disk-pressure.test.ts +5 -0
  146. package/src/__tests__/heartbeat-service.test.ts +5 -0
  147. package/src/__tests__/helpers/mock-logger.ts +26 -0
  148. package/src/__tests__/host-bash-routes.test.ts +1 -0
  149. package/src/__tests__/host-cu-routes-targeted.test.ts +1 -0
  150. package/src/__tests__/host-file-routes-targeted.test.ts +1 -0
  151. package/src/__tests__/host-shell-tool.test.ts +6 -5
  152. package/src/__tests__/host-transfer-routes-targeted.test.ts +1 -0
  153. package/src/__tests__/http-conversation-lineage.test.ts +3 -2
  154. package/src/__tests__/http-user-message-parity.test.ts +29 -7
  155. package/src/__tests__/identity-intro-cache.test.ts +133 -22
  156. package/src/__tests__/inbound-slack-persistence.test.ts +44 -72
  157. package/src/__tests__/inference-profile-reaper.test.ts +3 -2
  158. package/src/__tests__/inference-profile-session-ipc.test.ts +3 -2
  159. package/src/__tests__/init-feature-flag-overrides.test.ts +5 -6
  160. package/src/__tests__/injector-disk-pressure.test.ts +3 -17
  161. package/src/__tests__/inline-skill-load-permissions.test.ts +4 -4
  162. package/src/__tests__/list-messages-hidden-metadata.test.ts +80 -0
  163. package/src/__tests__/list-messages-tool-merge.test.ts +70 -11
  164. package/src/__tests__/llm-context-normalization.test.ts +42 -0
  165. package/src/__tests__/llm-request-log-call-site.test.ts +136 -0
  166. package/src/__tests__/llm-request-log-source-clickhouse.test.ts +26 -0
  167. package/src/__tests__/llm-resolver.test.ts +408 -9
  168. package/src/__tests__/llm-schema.test.ts +1 -1
  169. package/src/__tests__/llm-usage-store.test.ts +66 -0
  170. package/src/__tests__/logger.test.ts +89 -0
  171. package/src/__tests__/manual-token-reconciliation.test.ts +76 -1
  172. package/src/__tests__/mcp-abort-signal.test.ts +16 -2
  173. package/src/__tests__/mcp-client-auth.test.ts +14 -0
  174. package/src/__tests__/media-generate-image.test.ts +31 -0
  175. package/src/__tests__/memory-v2-static-injector.test.ts +7 -7
  176. package/src/__tests__/messaging-send-tool.test.ts +1 -0
  177. package/src/__tests__/migration-import-from-url.test.ts +3 -3
  178. package/src/__tests__/mock-gateway-ipc.ts +18 -2
  179. package/src/__tests__/model-intents.test.ts +4 -6
  180. package/src/__tests__/native-web-search.test.ts +30 -2
  181. package/src/__tests__/notification-deep-link.test.ts +62 -0
  182. package/src/__tests__/notification-guardian-path.test.ts +0 -1
  183. package/src/__tests__/oauth-commands-routes.test.ts +37 -0
  184. package/src/__tests__/oauth-provider-visibility.test.ts +8 -8
  185. package/src/__tests__/oauth-store.test.ts +3 -2
  186. package/src/__tests__/onboarding-template-contract.test.ts +4 -3
  187. package/src/__tests__/openai-provider.test.ts +54 -9
  188. package/src/__tests__/openai-responses-provider.test.ts +176 -14
  189. package/src/__tests__/openrouter-provider-only.test.ts +27 -5
  190. package/src/__tests__/outbound-slack-persistence.test.ts +46 -1
  191. package/src/__tests__/pending-interactions-resolved-event.test.ts +0 -1
  192. package/src/__tests__/persistence-pipeline.test.ts +139 -1
  193. package/src/__tests__/persistence-secret-redaction.test.ts +83 -12
  194. package/src/__tests__/platform-bash-auto-approve.test.ts +2 -2
  195. package/src/__tests__/platform.test.ts +2 -2
  196. package/src/__tests__/plugin-api-tool-definition.test.ts +92 -0
  197. package/src/__tests__/plugin-bootstrap.test.ts +11 -13
  198. package/src/__tests__/plugin-tool-contribution.test.ts +50 -40
  199. package/src/__tests__/plugin-types.test.ts +3 -2
  200. package/src/__tests__/prechat-onboarding-contract.test.ts +131 -98
  201. package/src/__tests__/pricing.test.ts +12 -0
  202. package/src/__tests__/process-message-background-slack.test.ts +21 -16
  203. package/src/__tests__/process-message-display-content.test.ts +19 -22
  204. package/src/__tests__/provider-catalog-visibility.test.ts +9 -9
  205. package/src/__tests__/provider-platform-proxy-integration.test.ts +216 -4
  206. package/src/__tests__/provider-registry-ollama.test.ts +45 -22
  207. package/src/__tests__/prune-jobs-changes-parser.test.ts +61 -0
  208. package/src/__tests__/recording-handler.test.ts +1 -0
  209. package/src/__tests__/regenerate-fire-and-forget-trace.test.ts +1 -0
  210. package/src/__tests__/registry.test.ts +84 -84
  211. package/src/__tests__/relay-server.test.ts +10 -10
  212. package/src/__tests__/require-fresh-approval.test.ts +2 -2
  213. package/src/__tests__/runtime-attachment-metadata.test.ts +3 -2
  214. package/src/__tests__/runtime-events-sse-bilingual.test.ts +154 -0
  215. package/src/__tests__/schedule-store.test.ts +16 -1
  216. package/src/__tests__/scheduler-reuse-conversation.test.ts +48 -3
  217. package/src/__tests__/secret-ingress-http.test.ts +5 -1
  218. package/src/__tests__/secure-keys.test.ts +3 -3
  219. package/src/__tests__/send-endpoint-busy.test.ts +81 -42
  220. package/src/__tests__/server-history-render.test.ts +4 -1
  221. package/src/__tests__/shell-tool-proxy-mode.test.ts +1 -1
  222. package/src/__tests__/skill-feature-flags-integration.test.ts +8 -10
  223. package/src/__tests__/skill-feature-flags.test.ts +16 -18
  224. package/src/__tests__/skill-load-feature-flag.test.ts +5 -5
  225. package/src/__tests__/skill-projection-feature-flag.test.ts +48 -37
  226. package/src/__tests__/skill-projection.benchmark.test.ts +7 -13
  227. package/src/__tests__/skill-tool-factory.test.ts +97 -96
  228. package/src/__tests__/slack-channel-config.test.ts +3 -3
  229. package/src/__tests__/subagent-call-site-routing.test.ts +11 -3
  230. package/src/__tests__/subagent-disposal.test.ts +27 -8
  231. package/src/__tests__/subagent-fork-notifications.test.ts +24 -9
  232. package/src/__tests__/subagent-fork-spawn.test.ts +13 -4
  233. package/src/__tests__/subagent-manager-notify.test.ts +20 -8
  234. package/src/__tests__/subagent-notify-parent.test.ts +6 -5
  235. package/src/__tests__/subagent-spawn-tool-fork.test.ts +58 -0
  236. package/src/__tests__/subagent-tools.test.ts +2 -1
  237. package/src/__tests__/suggestion-routes.test.ts +2 -0
  238. package/src/__tests__/sync-message-contract.test.ts +59 -0
  239. package/src/__tests__/system-prompt.test.ts +183 -131
  240. package/src/__tests__/terminal-tools.test.ts +1 -1
  241. package/src/__tests__/test-preload-verifier.ts +68 -0
  242. package/src/__tests__/test-preload.ts +32 -39
  243. package/src/__tests__/tool-approval-handler.test.ts +1 -5
  244. package/src/__tests__/tool-execute-pipeline.test.ts +2 -2
  245. package/src/__tests__/tool-execution-pipeline.benchmark.test.ts +2 -5
  246. package/src/__tests__/tool-executor-lifecycle-events.test.ts +35 -12
  247. package/src/__tests__/tool-executor.test.ts +64 -72
  248. package/src/__tests__/tool-grant-request-escalation.test.ts +1 -6
  249. package/src/__tests__/tool-preview-lifecycle.test.ts +1 -0
  250. package/src/__tests__/tool-result-metadata-plumbing.test.ts +1 -0
  251. package/src/__tests__/trusted-contact-approval-notifier.test.ts +0 -1
  252. package/src/__tests__/trusted-contact-inline-approval-integration.test.ts +1 -6
  253. package/src/__tests__/trusted-contact-multichannel.test.ts +0 -1
  254. package/src/__tests__/twilio-routes.test.ts +3 -2
  255. package/src/__tests__/ui-file-upload-surface.test.ts +2 -2
  256. package/src/__tests__/usage-routes.test.ts +3 -0
  257. package/src/__tests__/validate-input.test.ts +381 -0
  258. package/src/__tests__/verification-control-plane-policy.test.ts +3 -2
  259. package/src/__tests__/voice-scoped-grant-consumer.test.ts +2 -1
  260. package/src/__tests__/voice-session-bridge.test.ts +37 -28
  261. package/src/__tests__/workspace-git-service.test.ts +6 -5
  262. package/src/__tests__/workspace-migration-089-move-memory-tree-out-of-v3.test.ts +86 -0
  263. package/src/__tests__/workspace-migration-090-memory-router-cost-optimized-profile.test.ts +326 -0
  264. package/src/__tests__/workspace-migration-091-retighten-migration-onboarding-thread.test.ts +166 -0
  265. package/src/acp/__tests__/prepare-agent-env.test.ts +146 -0
  266. package/src/acp/prepare-agent-env.ts +78 -0
  267. package/src/acp/session-manager.ts +6 -7
  268. package/src/agent/loop.ts +88 -0
  269. package/src/api/README.md +127 -0
  270. package/src/api/constants/call-sites.ts +27 -0
  271. package/src/api/events/assistant-outbound-attachment.ts +51 -0
  272. package/src/api/events/assistant-text-delta.ts +32 -0
  273. package/src/api/events/assistant-turn-start.ts +33 -0
  274. package/src/api/events/document-comment-created.ts +48 -0
  275. package/src/api/events/document-comment-deleted.ts +24 -0
  276. package/src/api/events/document-comment-reopened.ts +25 -0
  277. package/src/api/events/document-comment-resolved.ts +27 -0
  278. package/src/api/events/generation-cancelled.ts +24 -0
  279. package/src/api/events/generation-handoff.ts +41 -0
  280. package/src/api/events/message-complete.ts +42 -0
  281. package/src/api/events/open-url.ts +30 -0
  282. package/src/api/events/relationship-state-updated.ts +25 -0
  283. package/src/api/events/tool-use-start.ts +32 -0
  284. package/src/api/index.ts +129 -0
  285. package/src/api/package.json +10 -0
  286. package/src/api/responses/llm-context-response.ts +39 -0
  287. package/src/api/responses/llm-request-log-entry.ts +93 -0
  288. package/src/api/responses/memory-recall-log.ts +65 -0
  289. package/src/api/responses/memory-v2-activation-log.ts +78 -0
  290. package/src/background-wake/background-wake-routes.test.ts +868 -0
  291. package/src/background-wake/platform-client.test.ts +308 -0
  292. package/src/background-wake/platform-client.ts +167 -0
  293. package/src/background-wake/publisher.ts +91 -0
  294. package/src/background-wake/runtime-registry.ts +24 -0
  295. package/src/background-wake/wake-intent-hooks.test.ts +282 -0
  296. package/src/calls/guardian-dispatch.ts +1 -0
  297. package/src/calls/voice-session-bridge.ts +4 -4
  298. package/src/cli/commands/__tests__/browser.test.ts +23 -5
  299. package/src/cli/commands/__tests__/conversations-slack.test.ts +16 -0
  300. package/src/cli/commands/__tests__/domain-register.test.ts +110 -0
  301. package/src/cli/commands/__tests__/domain-status.test.ts +33 -33
  302. package/src/cli/commands/__tests__/inference-send.test.ts +108 -5
  303. package/src/cli/commands/__tests__/memory-v2-compare-render.test.ts +98 -0
  304. package/src/cli/commands/__tests__/memory-v2.test.ts +1 -0
  305. package/src/cli/commands/__tests__/memory-v3-render.test.ts +340 -0
  306. package/src/cli/commands/__tests__/notifications.test.ts +184 -40
  307. package/src/cli/commands/browser.ts +247 -0
  308. package/src/cli/commands/channels/__tests__/channels.test.ts +143 -0
  309. package/src/cli/commands/channels/index.ts +229 -0
  310. package/src/cli/commands/domain.ts +91 -41
  311. package/src/cli/commands/inference.ts +93 -40
  312. package/src/cli/commands/memory-v2-compare-render.ts +115 -0
  313. package/src/cli/commands/memory-v2.ts +176 -1
  314. package/src/cli/commands/memory-v3-render.ts +491 -0
  315. package/src/cli/commands/memory-v3.ts +567 -0
  316. package/src/cli/commands/notifications.ts +365 -55
  317. package/src/cli/lib/open-browser.ts +7 -2
  318. package/src/cli/program.ts +4 -0
  319. package/src/config/assistant-feature-flags.ts +39 -46
  320. package/src/config/bundled-skills/document-editor/SKILL.md +16 -3
  321. package/src/config/bundled-skills/document-editor/TOOLS.json +18 -0
  322. package/src/config/bundled-skills/document-editor/tools/document-open.ts +12 -0
  323. package/src/config/bundled-skills/image-studio/SKILL.md +4 -0
  324. package/src/config/bundled-skills/image-studio/tools/media-generate-image.ts +2 -2
  325. package/src/config/bundled-skills/media-processing/tools/ingest-media.ts +13 -8
  326. package/src/config/bundled-skills/messaging/tools/messaging-analyze-style.ts +10 -3
  327. package/src/config/bundled-skills/phone-calls/references/TRANSCRIPTS.md +16 -14
  328. package/src/config/bundled-skills/playbooks/tools/playbook-create.ts +7 -2
  329. package/src/config/bundled-skills/playbooks/tools/playbook-update.ts +7 -2
  330. package/src/config/bundled-skills/schedule/SKILL.md +1 -1
  331. package/src/config/bundled-skills/schedule/TOOLS.json +2 -2
  332. package/src/config/bundled-skills/settings/tools/open-system-settings.ts +1 -0
  333. package/src/config/bundled-tool-registry.ts +2 -0
  334. package/src/config/call-site-defaults.ts +8 -7
  335. package/src/config/feature-flag-cache.ts +86 -0
  336. package/src/config/feature-flag-registry.json +33 -17
  337. package/src/config/llm-context-resolution.ts +10 -1
  338. package/src/config/llm-resolver.ts +121 -15
  339. package/src/config/loader.ts +4 -5
  340. package/src/config/schemas/__tests__/memory-v2.test.ts +228 -1
  341. package/src/config/schemas/call-site-catalog.ts +21 -7
  342. package/src/config/schemas/heartbeat.ts +1 -1
  343. package/src/config/schemas/llm.ts +102 -2
  344. package/src/config/schemas/memory-v2.ts +272 -0
  345. package/src/config/schemas/memory.ts +2 -1
  346. package/src/config/schemas/services.ts +6 -2
  347. package/src/config/seed-inference-profiles.ts +36 -16
  348. package/src/context/compactor.ts +52 -0
  349. package/src/context/token-estimator.ts +10 -5
  350. package/src/conversations/__tests__/message-consolidation.test.ts +350 -0
  351. package/src/conversations/message-consolidation.ts +404 -0
  352. package/src/credential-execution/executable-discovery.ts +40 -0
  353. package/src/credential-execution/process-manager.ts +6 -2
  354. package/src/credential-health/credential-health-service.ts +125 -40
  355. package/src/daemon/__tests__/conversation-lifecycle-auto-analyze.test.ts +3 -6
  356. package/src/daemon/__tests__/conversation-surfaces-launch.test.ts +13 -15
  357. package/src/daemon/__tests__/conversation-tool-setup-exclude.test.ts +2 -3
  358. package/src/daemon/__tests__/daemon-skill-host.test.ts +2 -0
  359. package/src/daemon/__tests__/meet-manifest-loader.test.ts +25 -12
  360. package/src/daemon/__tests__/native-web-search-metadata.test.ts +1 -0
  361. package/src/daemon/__tests__/switch-inference-profile-tool.test.ts +107 -0
  362. package/src/daemon/__tests__/web-search-status-text.test.ts +1 -0
  363. package/src/daemon/conversation-agent-loop-handlers.ts +390 -80
  364. package/src/daemon/conversation-agent-loop.ts +244 -90
  365. package/src/daemon/conversation-error.ts +64 -6
  366. package/src/daemon/conversation-lifecycle.ts +27 -22
  367. package/src/daemon/conversation-messaging.ts +84 -43
  368. package/src/daemon/conversation-process.ts +74 -37
  369. package/src/daemon/conversation-runtime-assembly.ts +38 -17
  370. package/src/daemon/conversation-skill-tools.ts +14 -30
  371. package/src/daemon/conversation-surfaces.ts +69 -34
  372. package/src/daemon/conversation-tool-setup.ts +77 -32
  373. package/src/daemon/conversation-usage.ts +2 -0
  374. package/src/daemon/conversation.ts +40 -75
  375. package/src/daemon/daemon-control.ts +1 -1
  376. package/src/daemon/daemon-skill-host.ts +9 -2
  377. package/src/daemon/disk-pressure-guard.ts +39 -29
  378. package/src/daemon/first-greeting.ts +31 -13
  379. package/src/daemon/handlers/config-model.test.ts +1 -0
  380. package/src/daemon/handlers/conversations.ts +11 -3
  381. package/src/daemon/handlers/shared.ts +6 -1
  382. package/src/daemon/host-browser-proxy.ts +5 -5
  383. package/src/daemon/host-cu-proxy.ts +4 -4
  384. package/src/daemon/host-file-proxy.ts +4 -4
  385. package/src/daemon/host-proxy-base.ts +4 -4
  386. package/src/daemon/host-transfer-proxy.ts +10 -10
  387. package/src/daemon/lifecycle.ts +29 -26
  388. package/src/daemon/mcp-reload-service.ts +1 -1
  389. package/src/daemon/meet-manifest-loader.ts +11 -24
  390. package/src/daemon/message-types/conversations.ts +22 -27
  391. package/src/daemon/message-types/document-comments.ts +8 -44
  392. package/src/daemon/message-types/home.ts +2 -14
  393. package/src/daemon/message-types/integrations.ts +2 -7
  394. package/src/daemon/message-types/messages.ts +25 -48
  395. package/src/daemon/message-types/subagents.ts +6 -0
  396. package/src/daemon/message-types/sync.ts +14 -0
  397. package/src/daemon/process-message.ts +9 -9
  398. package/src/daemon/providers-setup.ts +1 -1
  399. package/src/daemon/server.ts +16 -0
  400. package/src/daemon/shutdown-handlers.ts +24 -5
  401. package/src/daemon/switch-inference-profile-tool.ts +62 -0
  402. package/src/daemon/tool-setup-types.ts +7 -0
  403. package/src/daemon/wake-target-adapter.ts +10 -0
  404. package/src/documents/document-store.ts +38 -0
  405. package/src/export/__tests__/transcript-formatter.test.ts +1 -0
  406. package/src/heartbeat/__tests__/heartbeat-service.test.ts +30 -1
  407. package/src/heartbeat/heartbeat-service.ts +63 -0
  408. package/src/home/__tests__/feed-writer.test.ts +161 -0
  409. package/src/home/__tests__/post-connect-feed.test.ts +1 -0
  410. package/src/home/__tests__/suggested-prompts.test.ts +55 -59
  411. package/src/home/feed-writer.ts +146 -7
  412. package/src/home/home-greeting.ts +0 -9
  413. package/src/home/suggested-prompts.ts +27 -154
  414. package/src/ipc/__tests__/cli-ipc.test.ts +1 -0
  415. package/src/ipc/gateway-client.test.ts +4 -1
  416. package/src/ipc/gateway-flag-listener.ts +123 -0
  417. package/src/ipc/skill-routes/__tests__/memory.test.ts +1 -0
  418. package/src/ipc/skill-routes/__tests__/registries.test.ts +36 -7
  419. package/src/ipc/skill-routes/memory.ts +4 -3
  420. package/src/ipc/skill-routes/registries.ts +35 -40
  421. package/src/memory/__tests__/db-async-query.test.ts +165 -0
  422. package/src/memory/__tests__/db-maintenance.test.ts +115 -0
  423. package/src/memory/__tests__/jobs-store-enqueue-gate.test.ts +242 -0
  424. package/src/memory/__tests__/jobs-store-job-classes.test.ts +28 -1
  425. package/src/memory/__tests__/jobs-worker-v2-schedule.test.ts +26 -5
  426. package/src/memory/__tests__/memory-retrospective-enqueue.test.ts +1 -0
  427. package/src/memory/__tests__/memory-retrospective-job.test.ts +8 -0
  428. package/src/memory/__tests__/memory-retrospective-startup-cleanup.test.ts +1 -0
  429. package/src/memory/__tests__/memory-v2-activation-log-store.test.ts +31 -0
  430. package/src/memory/auto-analysis-enqueue.ts +5 -1
  431. package/src/memory/conversation-attention-store.ts +17 -3
  432. package/src/memory/conversation-crud.ts +423 -182
  433. package/src/memory/conversation-starters-cadence.ts +3 -1
  434. package/src/memory/conversation-title-service.ts +19 -3
  435. package/src/memory/db-async-query.ts +214 -0
  436. package/src/memory/db-connection.ts +29 -19
  437. package/src/memory/db-init.ts +14 -0
  438. package/src/memory/db-maintenance.ts +30 -21
  439. package/src/memory/db-singleton.ts +77 -0
  440. package/src/memory/delivery-channels.ts +82 -0
  441. package/src/memory/graph/__tests__/conversation-graph-memory-v2-routing.test.ts +2 -4
  442. package/src/memory/graph/bootstrap.ts +8 -1
  443. package/src/memory/graph/capability-seed.ts +7 -3
  444. package/src/memory/graph/conversation-graph-memory.ts +100 -17
  445. package/src/memory/graph/extraction.ts +1 -5
  446. package/src/memory/graph/graph-search.ts +7 -1
  447. package/src/memory/graph/retriever.test.ts +3 -3
  448. package/src/memory/indexer.ts +28 -18
  449. package/src/memory/job-handlers/cleanup.ts +76 -18
  450. package/src/memory/job-handlers/conversation-starters.ts +1 -4
  451. package/src/memory/job-handlers/embedding.test.ts +3 -2
  452. package/src/memory/jobs/__tests__/embed-concept-page.test.ts +5 -2
  453. package/src/memory/jobs/embed-pkb-file.ts +6 -1
  454. package/src/memory/jobs-store.ts +14 -0
  455. package/src/memory/jobs-worker.ts +66 -22
  456. package/src/memory/llm-request-log-source-clickhouse.ts +122 -2
  457. package/src/memory/llm-request-log-source-local.ts +31 -0
  458. package/src/memory/llm-request-log-source.ts +40 -2
  459. package/src/memory/llm-request-log-store.ts +228 -1
  460. package/src/memory/llm-usage-store.ts +24 -0
  461. package/src/memory/memory-retrospective-enqueue.ts +8 -1
  462. package/src/memory/memory-retrospective-job.ts +5 -0
  463. package/src/memory/memory-v2-activation-log-store.ts +110 -7
  464. package/src/memory/migrations/260-rename-cleaned-at.ts +44 -0
  465. package/src/memory/migrations/261-llm-usage-add-raw-usage.ts +36 -0
  466. package/src/memory/migrations/262-memory-v3-coactivation.ts +57 -0
  467. package/src/memory/migrations/263-memory-v3-auto-edges.ts +50 -0
  468. package/src/memory/migrations/264-llm-request-log-call-site.ts +29 -0
  469. package/src/memory/migrations/265-drop-provider-connection-status.ts +26 -0
  470. package/src/memory/migrations/266-messages-client-message-id.ts +43 -0
  471. package/src/memory/migrations/index.ts +19 -0
  472. package/src/memory/migrations/registry.ts +33 -0
  473. package/src/memory/schema/conversations.ts +10 -2
  474. package/src/memory/schema/inference.ts +0 -1
  475. package/src/memory/schema/infrastructure.ts +21 -0
  476. package/src/memory/tool-usage-store.ts +36 -8
  477. package/src/memory/v2/__tests__/backfill-jobs.test.ts +5 -2
  478. package/src/memory/v2/__tests__/consolidation-job.test.ts +1 -0
  479. package/src/memory/v2/__tests__/harness-compare.test.ts +186 -0
  480. package/src/memory/v2/__tests__/harness-metrics.test.ts +83 -0
  481. package/src/memory/v2/__tests__/harness-oracle.test.ts +257 -0
  482. package/src/memory/v2/__tests__/harness-replay-input.test.ts +230 -0
  483. package/src/memory/v2/__tests__/harness-runner.test.ts +135 -0
  484. package/src/memory/v2/__tests__/injection.test.ts +127 -98
  485. package/src/memory/v2/__tests__/qdrant.test.ts +36 -0
  486. package/src/memory/v2/__tests__/router.test.ts +171 -3
  487. package/src/memory/v2/__tests__/sweep-job.test.ts +6 -3
  488. package/src/memory/v2/harness/compare.ts +57 -0
  489. package/src/memory/v2/harness/metrics.ts +128 -0
  490. package/src/memory/v2/harness/oracle.ts +145 -0
  491. package/src/memory/v2/harness/replay-input.ts +240 -0
  492. package/src/memory/v2/harness/retriever.ts +74 -0
  493. package/src/memory/v2/harness/router-retriever.ts +43 -0
  494. package/src/memory/v2/harness/runner.ts +112 -0
  495. package/src/memory/v2/harness/trace.ts +64 -0
  496. package/src/memory/v2/injection.ts +21 -15
  497. package/src/memory/v2/prompts/router.ts +26 -1
  498. package/src/memory/v2/qdrant.ts +14 -2
  499. package/src/memory/v2/router.ts +171 -18
  500. package/src/memory/v3/__tests__/coactivation-store.test.ts +422 -0
  501. package/src/memory/v3/__tests__/consolidation-job.test.ts +466 -0
  502. package/src/memory/v3/__tests__/coretrieval-seed.test.ts +270 -0
  503. package/src/memory/v3/__tests__/edge-learning-job.test.ts +324 -0
  504. package/src/memory/v3/__tests__/edges.test.ts +706 -0
  505. package/src/memory/v3/__tests__/filter.test.ts +560 -0
  506. package/src/memory/v3/__tests__/gate.test.ts +637 -0
  507. package/src/memory/v3/__tests__/index-composition.test.ts +291 -0
  508. package/src/memory/v3/__tests__/loop.test.ts +775 -0
  509. package/src/memory/v3/__tests__/retriever.test.ts +226 -0
  510. package/src/memory/v3/__tests__/scouts.test.ts +489 -0
  511. package/src/memory/v3/__tests__/shadow-diff.test.ts +225 -0
  512. package/src/memory/v3/__tests__/shadow-middleware.test.ts +398 -0
  513. package/src/memory/v3/__tests__/system-prompts.test.ts +154 -0
  514. package/src/memory/v3/__tests__/traversal.test.ts +508 -0
  515. package/src/memory/v3/__tests__/tree-index.test.ts +280 -0
  516. package/src/memory/v3/__tests__/tree-store.test.ts +529 -0
  517. package/src/memory/v3/__tests__/tree-walk.test.ts +784 -0
  518. package/src/memory/v3/__tests__/validate.test.ts +277 -0
  519. package/src/memory/v3/auto-edges.ts +223 -0
  520. package/src/memory/v3/coactivation-store.ts +124 -0
  521. package/src/memory/v3/consolidation-job.ts +323 -0
  522. package/src/memory/v3/coretrieval-seed.ts +240 -0
  523. package/src/memory/v3/edge-learning-job.ts +160 -0
  524. package/src/memory/v3/edges.ts +286 -0
  525. package/src/memory/v3/filter.ts +286 -0
  526. package/src/memory/v3/gate.ts +349 -0
  527. package/src/memory/v3/index-composition.ts +126 -0
  528. package/src/memory/v3/llm-capture.ts +46 -0
  529. package/src/memory/v3/loop.ts +430 -0
  530. package/src/memory/v3/maintenance.ts +144 -0
  531. package/src/memory/v3/prompt-context.ts +33 -0
  532. package/src/memory/v3/prompts/consolidation.ts +458 -0
  533. package/src/memory/v3/prompts/system-prompts.ts +196 -0
  534. package/src/memory/v3/retriever.ts +33 -0
  535. package/src/memory/v3/scouts.ts +431 -0
  536. package/src/memory/v3/shadow-diff.ts +287 -0
  537. package/src/memory/v3/shadow-middleware.ts +347 -0
  538. package/src/memory/v3/traversal.ts +211 -0
  539. package/src/memory/v3/tree-index.ts +237 -0
  540. package/src/memory/v3/tree-store.ts +394 -0
  541. package/src/memory/v3/tree-walk.ts +356 -0
  542. package/src/memory/v3/types.ts +65 -0
  543. package/src/memory/v3/validate.ts +323 -0
  544. package/src/notifications/__tests__/emit-signal-home-feed.test.ts +1 -0
  545. package/src/notifications/__tests__/home-feed-side-effect.test.ts +1 -0
  546. package/src/notifications/adapters/macos.ts +18 -1
  547. package/src/notifications/adapters/platform.ts +1 -1
  548. package/src/notifications/adapters/slack.ts +45 -11
  549. package/src/notifications/broadcaster.ts +114 -63
  550. package/src/notifications/conversation-pairing.ts +23 -3
  551. package/src/notifications/decision-engine.ts +1 -4
  552. package/src/notifications/decisions-store.ts +32 -1
  553. package/src/notifications/deliveries-store.ts +45 -0
  554. package/src/notifications/edit-notification.ts +201 -0
  555. package/src/notifications/emit-signal.ts +40 -50
  556. package/src/notifications/signal.ts +10 -0
  557. package/src/notifications/types.ts +37 -0
  558. package/src/oauth/byo-connection.test.ts +67 -3
  559. package/src/oauth/byo-connection.ts +32 -5
  560. package/src/oauth/connect-orchestrator.ts +9 -0
  561. package/src/oauth/connection-resolver.test.ts +76 -0
  562. package/src/oauth/connection-resolver.ts +49 -10
  563. package/src/oauth/manual-token-connection.ts +51 -3
  564. package/src/oauth/seed-providers.ts +3 -0
  565. package/src/permissions/approval-policy.test.ts +19 -5
  566. package/src/permissions/approval-policy.ts +14 -3
  567. package/src/permissions/checker.ts +21 -8
  568. package/src/permissions/prompter.ts +3 -3
  569. package/src/permissions/question-prompter.ts +5 -2
  570. package/src/permissions/secret-prompter.ts +2 -2
  571. package/src/platform/client.test.ts +24 -1
  572. package/src/platform/client.ts +8 -0
  573. package/src/platform/feature-gate.ts +15 -0
  574. package/src/plugin-api/index.ts +4 -0
  575. package/src/plugin-api/types.ts +7 -33
  576. package/src/plugins/defaults/index.ts +6 -0
  577. package/src/plugins/defaults/injectors.ts +20 -19
  578. package/src/plugins/defaults/persistence.ts +25 -6
  579. package/src/plugins/external-plugin-loader.ts +5 -68
  580. package/src/plugins/types.ts +68 -29
  581. package/src/proactive-artifact/aux-message-injector.ts +17 -4
  582. package/src/proactive-artifact/job.test.ts +1 -0
  583. package/src/prompts/__tests__/system-prompt.test.ts +4 -4
  584. package/src/prompts/__tests__/task-progress-hint-section.test.ts +3 -9
  585. package/src/prompts/persona-resolver.ts +36 -21
  586. package/src/prompts/sections.ts +39 -7
  587. package/src/prompts/system-prompt.ts +84 -221
  588. package/src/prompts/template-detection.ts +10 -4
  589. package/src/prompts/templates/BOOTSTRAP.md +9 -13
  590. package/src/prompts/templates/IDENTITY.md +0 -2
  591. package/src/prompts/templates/system-sections.ts +230 -8
  592. package/src/providers/__tests__/connection-model-compat.test.ts +233 -0
  593. package/src/providers/__tests__/registry-native-web-search.test.ts +122 -0
  594. package/src/providers/__tests__/retry-callsite.test.ts +85 -5
  595. package/src/providers/anthropic/client.ts +32 -66
  596. package/src/providers/call-site-routing.ts +42 -6
  597. package/src/providers/connection-model-compat.ts +61 -0
  598. package/src/providers/connection-resolution.ts +47 -14
  599. package/src/providers/fireworks/client.ts +1 -0
  600. package/src/providers/gemini/client.ts +70 -6
  601. package/src/providers/inference/__tests__/adapter-factory-openai-compatible.test.ts +0 -2
  602. package/src/providers/inference/__tests__/base-url-security.test.ts +2 -3
  603. package/src/providers/inference/__tests__/{connections-status-label.test.ts → connections-label.test.ts} +12 -111
  604. package/src/providers/inference/adapter-factory.ts +3 -0
  605. package/src/providers/inference/auth.ts +0 -8
  606. package/src/providers/inference/connections.ts +3 -66
  607. package/src/providers/inference/resolve-auth.ts +2 -3
  608. package/src/providers/minimax/client.ts +106 -0
  609. package/src/providers/model-catalog.ts +78 -1
  610. package/src/providers/model-intents.ts +4 -4
  611. package/src/providers/openai/__tests__/api-error-detail.test.ts +120 -0
  612. package/src/providers/openai/__tests__/chat-completions-provider-reasoning.test.ts +157 -5
  613. package/src/providers/openai/chat-completions-provider.ts +116 -15
  614. package/src/providers/openai/codex-models.ts +20 -0
  615. package/src/providers/openai/responses-provider.ts +87 -30
  616. package/src/providers/openrouter/client.ts +13 -8
  617. package/src/providers/provider-send-message.ts +20 -5
  618. package/src/providers/registry.ts +48 -8
  619. package/src/providers/retry.ts +50 -7
  620. package/src/providers/search-provider-catalog.ts +17 -9
  621. package/src/providers/thinking-config.ts +26 -1
  622. package/src/providers/types.ts +9 -0
  623. package/src/providers/usage-tracking.ts +2 -0
  624. package/src/runtime/AGENTS.md +2 -2
  625. package/src/runtime/__tests__/agent-wake.test.ts +1 -0
  626. package/src/runtime/__tests__/background-job-runner.test.ts +1 -0
  627. package/src/runtime/access-request-helper.ts +1 -0
  628. package/src/runtime/agent-wake.ts +1 -0
  629. package/src/runtime/assistant-event-hub.ts +76 -6
  630. package/src/runtime/auth/route-policy.ts +46 -0
  631. package/src/runtime/btw-sidechain.ts +0 -6
  632. package/src/runtime/channel-readiness-service.ts +68 -0
  633. package/src/runtime/channel-reply-delivery.ts +23 -0
  634. package/src/runtime/channel-retry-sweep.ts +47 -14
  635. package/src/runtime/confirmation-request-guardian-bridge.ts +1 -1
  636. package/src/runtime/http-types.ts +0 -2
  637. package/src/runtime/migrations/vbundle-builder.ts +12 -4
  638. package/src/runtime/pending-interactions.ts +0 -1
  639. package/src/runtime/routes/__tests__/bookmark-routes.test.ts +1 -0
  640. package/src/runtime/routes/__tests__/conversation-compaction-routes.test.ts +406 -0
  641. package/src/runtime/routes/__tests__/conversation-query-routes.test.ts +204 -0
  642. package/src/runtime/routes/__tests__/heartbeat-routes.test.ts +1 -1
  643. package/src/runtime/routes/__tests__/home-feed-routes.test.ts +209 -1
  644. package/src/runtime/routes/__tests__/inference-provider-connection-routes.test.ts +13 -50
  645. package/src/runtime/routes/__tests__/memory-v2-simulate-route.test.ts +76 -9
  646. package/src/runtime/routes/__tests__/memory-v3-simulate-params.test.ts +35 -0
  647. package/src/runtime/routes/__tests__/plugins-routes.test.ts +512 -0
  648. package/src/runtime/routes/__tests__/slack-channel-routes.test.ts +3 -2
  649. package/src/runtime/routes/__tests__/surface-content-routes.test.ts +294 -0
  650. package/src/runtime/routes/__tests__/task-routes.test.ts +48 -3
  651. package/src/runtime/routes/acp-routes-list.test.ts +3 -0
  652. package/src/runtime/routes/acp-routes.test.ts +255 -6
  653. package/src/runtime/routes/acp-routes.ts +8 -1
  654. package/src/runtime/routes/app-management-routes.ts +111 -4
  655. package/src/runtime/routes/avatar-routes.ts +10 -10
  656. package/src/runtime/routes/background-wake-routes.ts +356 -0
  657. package/src/runtime/routes/browser-tabs-routes.ts +200 -0
  658. package/src/runtime/routes/btw-routes.ts +4 -10
  659. package/src/runtime/routes/conversation-analysis-routes.ts +6 -0
  660. package/src/runtime/routes/conversation-cli-routes.ts +1 -1
  661. package/src/runtime/routes/conversation-compaction-routes.ts +263 -0
  662. package/src/runtime/routes/conversation-list-routes.ts +159 -4
  663. package/src/runtime/routes/conversation-management-routes.ts +108 -26
  664. package/src/runtime/routes/conversation-query-routes.ts +200 -44
  665. package/src/runtime/routes/conversation-routes.ts +409 -521
  666. package/src/runtime/routes/conversation-starter-routes.ts +6 -3
  667. package/src/runtime/routes/conversations-import-routes.ts +19 -6
  668. package/src/runtime/routes/disk-pressure-routes.ts +1 -1
  669. package/src/runtime/routes/documents-routes.ts +10 -1
  670. package/src/runtime/routes/domain-routes.ts +60 -10
  671. package/src/runtime/routes/email-routes.ts +5 -2
  672. package/src/runtime/routes/events-routes.ts +54 -10
  673. package/src/runtime/routes/group-routes.ts +35 -8
  674. package/src/runtime/routes/home-feed-routes.ts +129 -0
  675. package/src/runtime/routes/host-browser-routes.ts +10 -2
  676. package/src/runtime/routes/host-cu-routes.ts +2 -2
  677. package/src/runtime/routes/identity-intro-cache.ts +61 -16
  678. package/src/runtime/routes/identity-routes.ts +30 -9
  679. package/src/runtime/routes/inbound-stages/acl-enforcement.ts +96 -3
  680. package/src/runtime/routes/inbound-stages/background-dispatch.test.ts +530 -6
  681. package/src/runtime/routes/inbound-stages/background-dispatch.ts +57 -8
  682. package/src/runtime/routes/index.ts +10 -0
  683. package/src/runtime/routes/inference-profile-session-handler.ts +22 -12
  684. package/src/runtime/routes/inference-profile-session-routes.ts +7 -1
  685. package/src/runtime/routes/inference-provider-connection-routes.ts +5 -26
  686. package/src/runtime/routes/integrations/vercel.ts +15 -0
  687. package/src/runtime/routes/llm-call-sites-routes.ts +32 -5
  688. package/src/runtime/routes/llm-context-normalization.ts +7 -2
  689. package/src/runtime/routes/memory-item-routes.ts +8 -3
  690. package/src/runtime/routes/memory-v2-routes.ts +215 -5
  691. package/src/runtime/routes/memory-v3-routes.ts +474 -0
  692. package/src/runtime/routes/migration-routes.ts +32 -28
  693. package/src/runtime/routes/notification-routes.ts +63 -1
  694. package/src/runtime/routes/oauth-commands-routes.ts +6 -1
  695. package/src/runtime/routes/plugins-routes.ts +337 -0
  696. package/src/runtime/routes/rename-conversation-routes.ts +6 -2
  697. package/src/runtime/routes/secret-routes.ts +25 -5
  698. package/src/runtime/routes/settings-routes.ts +12 -11
  699. package/src/runtime/routes/slack-channel-routes.ts +5 -4
  700. package/src/runtime/routes/surface-action-routes.ts +1 -38
  701. package/src/runtime/routes/surface-content-routes.ts +12 -5
  702. package/src/runtime/routes/surface-conversation-resolver.ts +65 -0
  703. package/src/runtime/routes/wipe-conversation-routes.ts +3 -0
  704. package/src/runtime/routes/workspace-routes.ts +25 -10
  705. package/src/runtime/services/__tests__/analyze-conversation.test.ts +2 -0
  706. package/src/runtime/slack-dm-text-delivery.ts +177 -0
  707. package/src/runtime/sync/resource-sync-events.ts +106 -38
  708. package/src/runtime/sync/sync-publisher.test.ts +49 -0
  709. package/src/runtime/sync/sync-publisher.ts +2 -1
  710. package/src/runtime/tool-grant-request-helper.ts +1 -0
  711. package/src/runtime/verification-outbound-actions.ts +73 -1
  712. package/src/schedule/schedule-store.ts +8 -1
  713. package/src/schedule/scheduler.ts +111 -15
  714. package/src/security/__tests__/provider-key-env-fallback.test.ts +3 -3
  715. package/src/security/encrypted-store.ts +7 -16
  716. package/src/security/store-path-override.ts +61 -0
  717. package/src/signals/user-message.ts +5 -8
  718. package/src/skills/validate-input.ts +177 -0
  719. package/src/subagent/manager.ts +13 -13
  720. package/src/subagent/types.ts +6 -0
  721. package/src/tasks/tool-sanitizer.ts +2 -2
  722. package/src/telemetry/types.ts +12 -0
  723. package/src/telemetry/usage-telemetry-reporter.test.ts +48 -0
  724. package/src/telemetry/usage-telemetry-reporter.ts +1 -0
  725. package/src/tools/acp/spawn.test.ts +119 -0
  726. package/src/tools/acp/spawn.ts +15 -2
  727. package/src/tools/apps/definitions.ts +36 -28
  728. package/src/tools/ask-question/ask-question-tool.test.ts +3 -3
  729. package/src/tools/ask-question/ask-question-tool.ts +38 -45
  730. package/src/tools/browser/__tests__/browser-execution-acquire.test.ts +2 -8
  731. package/src/tools/browser/__tests__/pinned-tabs.test.ts +70 -0
  732. package/src/tools/browser/browser-execution.ts +16 -3
  733. package/src/tools/browser/cdp-client/__tests__/browser-tabs-factory.test.ts +402 -0
  734. package/src/tools/browser/cdp-client/__tests__/types.test.ts +3 -0
  735. package/src/tools/browser/cdp-client/cdp-inspect-client.ts +12 -0
  736. package/src/tools/browser/cdp-client/extension-cdp-client.ts +27 -1
  737. package/src/tools/browser/cdp-client/factory.ts +100 -17
  738. package/src/tools/browser/cdp-client/local-cdp-client.ts +12 -0
  739. package/src/tools/browser/cdp-client/types.ts +65 -0
  740. package/src/tools/browser/pinned-tabs.ts +96 -40
  741. package/src/tools/computer-use/definitions.ts +282 -336
  742. package/src/tools/credential-execution/make-authenticated-request.ts +3 -9
  743. package/src/tools/credential-execution/manage-secure-command-tool.ts +3 -9
  744. package/src/tools/credential-execution/run-authenticated-command.ts +3 -9
  745. package/src/tools/credentials/vault.ts +3 -9
  746. package/src/tools/document/document-tool.ts +189 -7
  747. package/src/tools/execution-target.ts +18 -23
  748. package/src/tools/executor.ts +24 -56
  749. package/src/tools/filesystem/edit.ts +3 -9
  750. package/src/tools/filesystem/list.ts +3 -9
  751. package/src/tools/filesystem/read.ts +3 -9
  752. package/src/tools/filesystem/write.ts +3 -9
  753. package/src/tools/host-filesystem/edit.test.ts +1 -0
  754. package/src/tools/host-filesystem/edit.ts +3 -9
  755. package/src/tools/host-filesystem/read.test.ts +1 -0
  756. package/src/tools/host-filesystem/read.ts +3 -9
  757. package/src/tools/host-filesystem/transfer.test.ts +31 -6
  758. package/src/tools/host-filesystem/transfer.ts +3 -9
  759. package/src/tools/host-filesystem/write.test.ts +1 -0
  760. package/src/tools/host-filesystem/write.ts +3 -9
  761. package/src/tools/host-terminal/host-shell.ts +3 -9
  762. package/src/tools/mcp/mcp-tool-factory.ts +1 -10
  763. package/src/tools/memory/register.test.ts +1 -1
  764. package/src/tools/memory/register.ts +4 -9
  765. package/src/tools/network/__tests__/managed-search-proxy.test.ts +282 -0
  766. package/src/tools/network/__tests__/web-search.test.ts +211 -3
  767. package/src/tools/network/managed-search-proxy.ts +183 -0
  768. package/src/tools/network/web-fetch.ts +3 -9
  769. package/src/tools/network/web-search.ts +224 -76
  770. package/src/tools/policy-context.ts +3 -1
  771. package/src/tools/registry.ts +150 -123
  772. package/src/tools/schedule/create.ts +1 -1
  773. package/src/tools/schema-transforms.ts +1 -1
  774. package/src/tools/skills/execute.ts +3 -9
  775. package/src/tools/skills/load.ts +3 -9
  776. package/src/tools/skills/skill-tool-factory.ts +18 -44
  777. package/src/tools/subagent/notify-parent.ts +3 -9
  778. package/src/tools/subagent/spawn.ts +3 -0
  779. package/src/tools/system/request-permission.ts +3 -9
  780. package/src/tools/terminal/shell.ts +3 -9
  781. package/src/tools/tool-approval-handler.ts +10 -4
  782. package/src/tools/tool-defaults.ts +94 -0
  783. package/src/tools/tool-name-aliases.ts +72 -14
  784. package/src/tools/types.ts +32 -101
  785. package/src/tools/ui-surface/definitions.ts +104 -108
  786. package/src/types/onboarding-context.ts +6 -0
  787. package/src/usage/attribution.ts +32 -1
  788. package/src/usage/pricing.ts +23 -0
  789. package/src/usage/types.ts +12 -0
  790. package/src/util/browser.ts +7 -2
  791. package/src/util/logger.ts +16 -7
  792. package/src/util/platform.ts +7 -2
  793. package/src/util/sqlite3-runtime.ts +65 -0
  794. package/src/workspace/migrations/086-revert-stale-gemini-mis-rewrites.ts +1 -0
  795. package/src/workspace/migrations/089-move-memory-tree-out-of-v3.ts +86 -0
  796. package/src/workspace/migrations/090-memory-router-cost-optimized-profile.ts +109 -0
  797. package/src/workspace/migrations/091-retighten-migration-onboarding-thread.ts +41 -0
  798. package/src/workspace/migrations/registry.ts +6 -0
  799. package/src/__tests__/compaction-strip-metadata-clear.test.ts +0 -206
  800. package/src/__tests__/message-complete-display-id.test.ts +0 -175
  801. package/src/daemon/query-complexity-router.ts +0 -75
  802. package/src/prompts/cache-boundary.ts +0 -8
@@ -1,6 +1,22 @@
1
- import { and, desc, eq, gte, inArray, isNull, lte, sql } from "drizzle-orm";
1
+ import {
2
+ and,
3
+ asc,
4
+ desc,
5
+ eq,
6
+ gt,
7
+ gte,
8
+ inArray,
9
+ isNull,
10
+ lt,
11
+ lte,
12
+ ne,
13
+ or,
14
+ sql,
15
+ } from "drizzle-orm";
2
16
  import { v4 as uuid } from "uuid";
3
17
 
18
+ import { CALL_SITE_SYNTHETIC_AGENT_ERROR_MESSAGE } from "../api/constants/call-sites.js";
19
+ import type { LLMCallSite } from "../config/schemas/llm.js";
4
20
  import { AssistantError, ProviderError } from "../util/errors.js";
5
21
  import {
6
22
  getAssistantMessageIdsInTurn,
@@ -26,6 +42,12 @@ export type LogRow = {
26
42
  * `AgentLoopExitReason` in `agent/loop.ts`.
27
43
  */
28
44
  agentLoopExitReason: string | null;
45
+ /**
46
+ * Logical call site that produced this row — `mainAgent`,
47
+ * `compactionAgent`, etc. NULL on pre-migration-264 rows (no backfill).
48
+ * In practice values come from `LLMCallSite` (`config/schemas/llm.ts`).
49
+ */
50
+ callSite: string | null;
29
51
  };
30
52
 
31
53
  /**
@@ -73,6 +95,7 @@ export function recordRequestLog(
73
95
  responsePayload: string,
74
96
  messageId?: string,
75
97
  provider?: string,
98
+ callSite?: LLMCallSite,
76
99
  ): string {
77
100
  const db = getDb();
78
101
  const id = uuid();
@@ -88,6 +111,84 @@ export function recordRequestLog(
88
111
  // Stamped later via setAgentLoopExitReasonOnLatestLog, once the
89
112
  // agent loop body actually exits. Intermediate rows stay NULL.
90
113
  agentLoopExitReason: null,
114
+ // Logical call site (`mainAgent`, `compactionAgent`, …). NULL when
115
+ // a caller hasn't been updated yet — preserves backward compat
116
+ // while we plumb call sites through one site at a time.
117
+ callSite: callSite ?? null,
118
+ })
119
+ .run();
120
+ return id;
121
+ }
122
+
123
+ /**
124
+ * Insert a synthetic `llm_request_logs` row for an agent-loop error
125
+ * message that has no LLM call backing it but should appear in the
126
+ * inspector rail. Today the only caller is the
127
+ * `budget_yield_unrecovered` persistence path
128
+ * (`conversation-agent-loop.ts`); the helper is named generically so
129
+ * the next out-of-funds / provider-error / etc. path can route through
130
+ * the same primitive.
131
+ *
132
+ * The caller persists the user-visible assistant message separately
133
+ * via the `persistence` pipeline; this helper only writes the synthetic
134
+ * call row. `messageId` should be the id of the just-persisted notice
135
+ * so `getRequestLogsByMessageId` surfaces both together.
136
+ *
137
+ * Payload semantics mirror real LLM-call rows:
138
+ * - `requestPayload`: the best-known LLM request body the loop was
139
+ * about to send when it yielded — typically the prepared messages
140
+ * snapshot and any input-token budget context. Stored as JSON so
141
+ * the Raw tab renders it consistently with real calls.
142
+ * - `responsePayload`: the synthetic notice text the user saw plus
143
+ * the exit reason. This is the "response" from the user's point of
144
+ * view — what came back from a call that never actually happened.
145
+ *
146
+ * Stamps `agent_loop_exit_reason` directly so the row already carries
147
+ * the reason at insert time — the post-loop
148
+ * `setAgentLoopExitReasonOnLatestLog` query then skips it (its IS NULL
149
+ * guard) and stamps the prior real LLM call instead, preserving the
150
+ * existing "latest LLM call carries the exit reason" invariant that
151
+ * other consumers depend on.
152
+ */
153
+ export function recordSyntheticAgentErrorMessageLog(args: {
154
+ conversationId: string;
155
+ messageId: string;
156
+ exitReason: string;
157
+ /** User-visible notice text — goes into `response_payload`. */
158
+ noticeText: string;
159
+ /**
160
+ * Best-known LLM request state at the moment the loop gave up.
161
+ * `null` when no prepared request was available (rare — generally
162
+ * we know at least the conversation history we were about to send).
163
+ */
164
+ preparedRequest: unknown | null;
165
+ createdAt: number;
166
+ }): string {
167
+ const db = getDb();
168
+ const id = uuid();
169
+ const requestPayload = JSON.stringify({
170
+ syntheticAgentErrorMessage: {
171
+ exitReason: args.exitReason,
172
+ preparedRequest: args.preparedRequest,
173
+ },
174
+ });
175
+ const responsePayload = JSON.stringify({
176
+ syntheticAgentErrorMessage: {
177
+ exitReason: args.exitReason,
178
+ noticeText: args.noticeText,
179
+ },
180
+ });
181
+ db.insert(llmRequestLogs)
182
+ .values({
183
+ id,
184
+ conversationId: args.conversationId,
185
+ messageId: args.messageId,
186
+ provider: null,
187
+ requestPayload,
188
+ responsePayload,
189
+ createdAt: args.createdAt,
190
+ agentLoopExitReason: args.exitReason,
191
+ callSite: CALL_SITE_SYNTHETIC_AGENT_ERROR_MESSAGE,
91
192
  })
92
193
  .run();
93
194
  return id;
@@ -182,6 +283,7 @@ function selectLogsByMessageIds(messageIds: string[]): LogRow[] {
182
283
  responsePayload: llmRequestLogs.responsePayload,
183
284
  createdAt: llmRequestLogs.createdAt,
184
285
  agentLoopExitReason: llmRequestLogs.agentLoopExitReason,
286
+ callSite: llmRequestLogs.callSite,
185
287
  })
186
288
  .from(llmRequestLogs)
187
289
  .where(inArray(llmRequestLogs.messageId, messageIds))
@@ -189,6 +291,34 @@ function selectLogsByMessageIds(messageIds: string[]): LogRow[] {
189
291
  .all();
190
292
  }
191
293
 
294
+ /**
295
+ * Query every LLM request log recorded for a conversation, ordered by
296
+ * creation time. Conversation-scoped inspector views intentionally do
297
+ * not apply turn recovery: the `conversation_id` column already includes
298
+ * linked, unlinked, and orphaned rows for the full conversation.
299
+ */
300
+ export function getRequestLogsByConversationId(
301
+ conversationId: string,
302
+ ): LogRow[] {
303
+ const db = getDb();
304
+ return db
305
+ .select({
306
+ id: llmRequestLogs.id,
307
+ conversationId: llmRequestLogs.conversationId,
308
+ messageId: llmRequestLogs.messageId,
309
+ provider: llmRequestLogs.provider,
310
+ requestPayload: llmRequestLogs.requestPayload,
311
+ responsePayload: llmRequestLogs.responsePayload,
312
+ createdAt: llmRequestLogs.createdAt,
313
+ agentLoopExitReason: llmRequestLogs.agentLoopExitReason,
314
+ callSite: llmRequestLogs.callSite,
315
+ })
316
+ .from(llmRequestLogs)
317
+ .where(eq(llmRequestLogs.conversationId, conversationId))
318
+ .orderBy(asc(llmRequestLogs.createdAt), asc(llmRequestLogs.id))
319
+ .all();
320
+ }
321
+
192
322
  /**
193
323
  * Find orphaned logs — logs whose `message_id` references a message that no
194
324
  * longer exists in the DB. These are left behind when intermediate assistant
@@ -214,6 +344,7 @@ function selectOrphanedLogsInRange(
214
344
  responsePayload: llmRequestLogs.responsePayload,
215
345
  createdAt: llmRequestLogs.createdAt,
216
346
  agentLoopExitReason: llmRequestLogs.agentLoopExitReason,
347
+ callSite: llmRequestLogs.callSite,
217
348
  })
218
349
  .from(llmRequestLogs)
219
350
  .leftJoin(messages, eq(llmRequestLogs.messageId, messages.id))
@@ -255,6 +386,7 @@ function selectUnlinkedLogsInRange(
255
386
  responsePayload: llmRequestLogs.responsePayload,
256
387
  createdAt: llmRequestLogs.createdAt,
257
388
  agentLoopExitReason: llmRequestLogs.agentLoopExitReason,
389
+ callSite: llmRequestLogs.callSite,
258
390
  })
259
391
  .from(llmRequestLogs)
260
392
  .where(
@@ -269,6 +401,100 @@ function selectUnlinkedLogsInRange(
269
401
  .all();
270
402
  }
271
403
 
404
+ /**
405
+ * Fetch every `compactionAgent` log row in the conversation whose
406
+ * `createdAt` falls in the **open window** `(afterCreatedAt, beforeCreatedAt)`,
407
+ * ordered chronologically.
408
+ *
409
+ * Drives the Inspector's Compaction tab. The caller resolves both
410
+ * bounds:
411
+ * - `beforeCreatedAt` = the selected LLM call's `createdAt` (ceiling).
412
+ * - `afterCreatedAt` = the previous non-`compactionAgent` call's
413
+ * `createdAt` (floor), or `null` when the selected call is the first
414
+ * real call in the conversation.
415
+ *
416
+ * Both bounds are **strict**: the selected call itself never appears in
417
+ * its own trail (`<` ceiling), and compactions that fed an earlier real
418
+ * call's context don't bleed into this call's window (`>` floor). When
419
+ * `afterCreatedAt` is `null` the floor is dropped entirely — every
420
+ * preceding compaction is in scope, which is the right behavior for the
421
+ * very first real call in the conversation.
422
+ *
423
+ * NULL `callSite` rows (pre-migration-264) are excluded by the explicit
424
+ * `callSite = 'compactionAgent'` predicate without a separate IS NOT
425
+ * NULL clause.
426
+ */
427
+ export function getCompactionLogsBetween(
428
+ conversationId: string,
429
+ afterCreatedAt: number | null,
430
+ beforeCreatedAt: number,
431
+ ): LogRow[] {
432
+ const db = getDb();
433
+ const predicates = [
434
+ eq(llmRequestLogs.conversationId, conversationId),
435
+ eq(llmRequestLogs.callSite, "compactionAgent"),
436
+ lt(llmRequestLogs.createdAt, beforeCreatedAt),
437
+ ];
438
+ if (afterCreatedAt !== null) {
439
+ predicates.push(gt(llmRequestLogs.createdAt, afterCreatedAt));
440
+ }
441
+ return db
442
+ .select({
443
+ id: llmRequestLogs.id,
444
+ conversationId: llmRequestLogs.conversationId,
445
+ messageId: llmRequestLogs.messageId,
446
+ provider: llmRequestLogs.provider,
447
+ requestPayload: llmRequestLogs.requestPayload,
448
+ responsePayload: llmRequestLogs.responsePayload,
449
+ createdAt: llmRequestLogs.createdAt,
450
+ agentLoopExitReason: llmRequestLogs.agentLoopExitReason,
451
+ callSite: llmRequestLogs.callSite,
452
+ })
453
+ .from(llmRequestLogs)
454
+ .where(and(...predicates))
455
+ .orderBy(asc(llmRequestLogs.createdAt), asc(llmRequestLogs.id))
456
+ .all();
457
+ }
458
+
459
+ /**
460
+ * Find the `createdAt` of the most recent non-`compactionAgent` LLM
461
+ * call in the conversation strictly before `beforeCreatedAt`, or `null`
462
+ * when no such call exists (i.e. the cutoff is the first real call).
463
+ *
464
+ * Pairs with `getCompactionLogsBetween` to bound the compaction trail
465
+ * to the window between the prior real call and the selected call.
466
+ *
467
+ * "Non-compactionAgent" means `callSite IS NULL OR callSite !=
468
+ * 'compactionAgent'`. NULL rows are pre-migration-264 (no backfill) and
469
+ * are treated as real agent calls — they were `mainAgent` in practice.
470
+ * The OR-with-IS NULL is required because SQL's three-valued logic
471
+ * makes `callSite != 'compactionAgent'` return UNKNOWN (not TRUE) for
472
+ * NULL rows, which would otherwise filter them out.
473
+ */
474
+ export function getPreviousNonCompactionCallCreatedAt(
475
+ conversationId: string,
476
+ beforeCreatedAt: number,
477
+ ): number | null {
478
+ const db = getDb();
479
+ const row = db
480
+ .select({ createdAt: llmRequestLogs.createdAt })
481
+ .from(llmRequestLogs)
482
+ .where(
483
+ and(
484
+ eq(llmRequestLogs.conversationId, conversationId),
485
+ lt(llmRequestLogs.createdAt, beforeCreatedAt),
486
+ or(
487
+ isNull(llmRequestLogs.callSite),
488
+ ne(llmRequestLogs.callSite, "compactionAgent"),
489
+ ),
490
+ ),
491
+ )
492
+ .orderBy(desc(llmRequestLogs.createdAt), desc(llmRequestLogs.id))
493
+ .limit(1)
494
+ .get();
495
+ return row?.createdAt ?? null;
496
+ }
497
+
272
498
  export function getRequestLogById(logId: string): LogRow | null {
273
499
  const db = getDb();
274
500
  return (
@@ -282,6 +508,7 @@ export function getRequestLogById(logId: string): LogRow | null {
282
508
  responsePayload: llmRequestLogs.responsePayload,
283
509
  createdAt: llmRequestLogs.createdAt,
284
510
  agentLoopExitReason: llmRequestLogs.agentLoopExitReason,
511
+ callSite: llmRequestLogs.callSite,
285
512
  })
286
513
  .from(llmRequestLogs)
287
514
  .where(eq(llmRequestLogs.id, logId))
@@ -57,6 +57,7 @@ export function recordUsageEvent(
57
57
  outputTokens: event.outputTokens,
58
58
  cacheCreationInputTokens: event.cacheCreationInputTokens,
59
59
  cacheReadInputTokens: event.cacheReadInputTokens,
60
+ rawUsage: event.rawUsage === null ? null : JSON.stringify(event.rawUsage),
60
61
  estimatedCostUsd: event.estimatedCostUsd,
61
62
  pricingStatus: event.pricingStatus,
62
63
  llmCallCount: event.llmCallCount ?? 1,
@@ -87,6 +88,7 @@ function rowToUsageEvent(row: {
87
88
  outputTokens: number;
88
89
  cacheCreationInputTokens: number | null;
89
90
  cacheReadInputTokens: number | null;
91
+ rawUsage: string | null;
90
92
  estimatedCostUsd: number | null;
91
93
  pricingStatus: string;
92
94
  }): UsageEvent {
@@ -107,11 +109,32 @@ function rowToUsageEvent(row: {
107
109
  outputTokens: row.outputTokens,
108
110
  cacheCreationInputTokens: row.cacheCreationInputTokens,
109
111
  cacheReadInputTokens: row.cacheReadInputTokens,
112
+ rawUsage: parseRawUsage(row.rawUsage),
110
113
  estimatedCostUsd: row.estimatedCostUsd,
111
114
  pricingStatus: row.pricingStatus as "priced" | "unpriced",
112
115
  };
113
116
  }
114
117
 
118
+ /**
119
+ * Parse the JSON-serialized provider usage payload stored in `raw_usage`.
120
+ * Returns `null` for missing or malformed values; malformed JSON is logged
121
+ * and discarded rather than failing the read, because callers (admin
122
+ * dashboards, telemetry forwarders) treat `raw_usage` as opaque diagnostic
123
+ * data and shouldn't be blocked by a single corrupt row.
124
+ */
125
+ function parseRawUsage(value: string | null): Record<string, unknown> | null {
126
+ if (value === null) return null;
127
+ try {
128
+ const parsed = JSON.parse(value);
129
+ if (parsed && typeof parsed === "object" && !Array.isArray(parsed)) {
130
+ return parsed as Record<string, unknown>;
131
+ }
132
+ return null;
133
+ } catch {
134
+ return null;
135
+ }
136
+ }
137
+
115
138
  export function listUsageEvents(options?: { limit?: number }): UsageEvent[] {
116
139
  const db = getDb();
117
140
  const rows = db
@@ -187,6 +210,7 @@ export function queryUnreportedUsageEvents(
187
210
  outputTokens: llmUsageEvents.outputTokens,
188
211
  cacheCreationInputTokens: llmUsageEvents.cacheCreationInputTokens,
189
212
  cacheReadInputTokens: llmUsageEvents.cacheReadInputTokens,
213
+ rawUsage: llmUsageEvents.rawUsage,
190
214
  estimatedCostUsd: llmUsageEvents.estimatedCostUsd,
191
215
  pricingStatus: llmUsageEvents.pricingStatus,
192
216
  conversationType: conversations.conversationType,
@@ -19,7 +19,10 @@ import {
19
19
  } from "../runtime/actor-trust-resolver.js";
20
20
  import { getLogger } from "../util/logger.js";
21
21
  import { getConversationSource } from "./conversation-crud.js";
22
- import { upsertMemoryRetrospectiveJob } from "./jobs-store.js";
22
+ import {
23
+ isMemoryEnabled,
24
+ upsertMemoryRetrospectiveJob,
25
+ } from "./jobs-store.js";
23
26
  import { MEMORY_RETROSPECTIVE_SOURCES } from "./memory-retrospective-constants.js";
24
27
 
25
28
  const log = getLogger("memory-retrospective-enqueue");
@@ -38,6 +41,10 @@ export function enqueueMemoryRetrospectiveIfEnabled(args: {
38
41
  }): void {
39
42
  const { conversationId, trigger } = args;
40
43
 
44
+ if (!isMemoryEnabled()) {
45
+ return;
46
+ }
47
+
41
48
  if (isMemoryRetrospectiveConversation(conversationId)) {
42
49
  log.debug(
43
50
  { conversationId, trigger },
@@ -208,6 +208,11 @@ async function runLegacyRetrospective(
208
208
  source: MEMORY_RETROSPECTIVE_SOURCE,
209
209
  trustContext: INTERNAL_GUARDIAN_TRUST_CONTEXT,
210
210
  callSite: "memoryRetrospective",
211
+ // The background conversation's title already reads "Memory
212
+ // Retrospective", and `hint` is the full retrospective prompt — surfacing
213
+ // it verbatim as a "Conversation Woke" card body is noisy internal
214
+ // scaffolding for the user. Suppress it, matching the fork-based path.
215
+ suppressWakeSurface: true,
211
216
  });
212
217
  wakeSucceeded = result.invoked;
213
218
  failureReason = result.reason;
@@ -1,8 +1,9 @@
1
- import { and, desc, eq, inArray, isNull } from "drizzle-orm";
1
+ import { and, desc, eq, gte, inArray, isNull, lte, ne } from "drizzle-orm";
2
2
  import { v4 as uuid } from "uuid";
3
3
 
4
4
  import { getDb } from "./db-connection.js";
5
5
  import { memoryV2ActivationLogs } from "./schema.js";
6
+ import type { ShadowDiffLogRow } from "./v3/shadow-diff.js";
6
7
 
7
8
  export interface MemoryV2ConceptRowRecord {
8
9
  slug: string;
@@ -94,6 +95,14 @@ export interface MemoryV2ConceptRowRecord {
94
95
  | "not_injected"
95
96
  | "page_missing"
96
97
  | "corrupt";
98
+ /**
99
+ * v3 shadow only: the retrieval lane that surfaced this slug
100
+ * (`hot` | `sparse` | `dense` | `tree` | `edge`). Lets a shadow run be
101
+ * analyzed by provenance — which lane each v3 pick came from. Undefined on
102
+ * `router`/`per-turn`/etc. v2 rows; stored in the JSON concept blob, so older
103
+ * rows decode with `undefined`.
104
+ */
105
+ lane?: string;
97
106
  }
98
107
 
99
108
  export interface MemoryV2ConfigSnapshot {
@@ -115,11 +124,15 @@ export interface RecordMemoryV2ActivationLogParams {
115
124
  * `per-turn` for normal append injections, `errored` when `injectMemoryV2Block`
116
125
  * threw before completing — telemetry is still written so silent failures
117
126
  * are observable in the database, with whatever `concepts` rows had been
118
- * built so far (possibly empty). `router` indicates the Sonnet
119
- * router selected the per-turn page set; router-mode rows carry zeroed
120
- * activation values and `source: "router"` on every concept row.
127
+ * built so far (possibly empty). `router` indicates the LLM router selected
128
+ * the per-turn page set; router-mode rows carry zeroed activation values and
129
+ * `source: "router"` on every concept row. `v3_shadow` is written by the
130
+ * live-shadow v3 retrieval middleware: it records v3's selection set for
131
+ * comparison without affecting injected context. The harness oracle filters
132
+ * `mode='router'`, so `v3_shadow` rows never pollute it; the inspector can
133
+ * still surface them.
121
134
  */
122
- mode: "context-load" | "per-turn" | "errored" | "router";
135
+ mode: "context-load" | "per-turn" | "errored" | "router" | "v3_shadow";
123
136
  concepts: MemoryV2ConceptRowRecord[];
124
137
  config: MemoryV2ConfigSnapshot;
125
138
  }
@@ -153,12 +166,16 @@ export function backfillMemoryV2ActivationMessageId(
153
166
  messageId: string,
154
167
  ): void {
155
168
  const db = getDb();
169
+ // `v3_shadow` rows are detached telemetry written outside the live turn with
170
+ // a null messageId; they are not tied to any specific message. Excluding them
171
+ // keeps their messageId null instead of stamping them with a later turn's id.
156
172
  db.update(memoryV2ActivationLogs)
157
173
  .set({ messageId })
158
174
  .where(
159
175
  and(
160
176
  eq(memoryV2ActivationLogs.conversationId, conversationId),
161
177
  isNull(memoryV2ActivationLogs.messageId),
178
+ ne(memoryV2ActivationLogs.mode, "v3_shadow"),
162
179
  ),
163
180
  )
164
181
  .run();
@@ -167,7 +184,7 @@ export function backfillMemoryV2ActivationMessageId(
167
184
  export interface MemoryV2ActivationLog {
168
185
  conversationId: string;
169
186
  turn: number;
170
- mode: "context-load" | "per-turn" | "errored" | "router";
187
+ mode: "context-load" | "per-turn" | "errored" | "router" | "v3_shadow";
171
188
  concepts: MemoryV2ConceptRowRecord[];
172
189
  config: MemoryV2ConfigSnapshot;
173
190
  }
@@ -188,8 +205,94 @@ export function getMemoryV2ActivationLogByMessageIds(
188
205
  return {
189
206
  conversationId: row.conversationId,
190
207
  turn: row.turn,
191
- mode: row.mode as "context-load" | "per-turn" | "errored" | "router",
208
+ mode: row.mode as
209
+ | "context-load"
210
+ | "per-turn"
211
+ | "errored"
212
+ | "router"
213
+ | "v3_shadow",
192
214
  concepts: JSON.parse(row.conceptsJson) as MemoryV2ConceptRowRecord[],
193
215
  config: JSON.parse(row.configJson) as MemoryV2ConfigSnapshot,
194
216
  };
195
217
  }
218
+
219
+ function parseConcepts(conceptsJson: string): MemoryV2ConceptRowRecord[] {
220
+ try {
221
+ const parsed = JSON.parse(conceptsJson);
222
+ return Array.isArray(parsed) ? (parsed as MemoryV2ConceptRowRecord[]) : [];
223
+ } catch {
224
+ return [];
225
+ }
226
+ }
227
+
228
+ /**
229
+ * Read the activation-log rows the v3 shadow-diff needs: every `v3_shadow` row
230
+ * (optionally newer than `sinceMs`), plus the `router` rows that could pair
231
+ * with them. The router read is bounded to the shadow rows' conversations and
232
+ * their time span (padded by `paddingMs`) so a shadow-diff over a few turns
233
+ * never scans the entire multi-GB log table. Returns `{ shadow, router }` for
234
+ * {@link computeShadowDiff} to pair and diff.
235
+ */
236
+ export function readActivationLogsForShadowDiff(opts: {
237
+ sinceMs: number | null;
238
+ paddingMs: number;
239
+ }): { shadow: ShadowDiffLogRow[]; router: ShadowDiffLogRow[] } {
240
+ const db = getDb();
241
+
242
+ const shadow = db
243
+ .select({
244
+ conversationId: memoryV2ActivationLogs.conversationId,
245
+ createdAt: memoryV2ActivationLogs.createdAt,
246
+ conceptsJson: memoryV2ActivationLogs.conceptsJson,
247
+ })
248
+ .from(memoryV2ActivationLogs)
249
+ .where(
250
+ opts.sinceMs !== null
251
+ ? and(
252
+ eq(memoryV2ActivationLogs.mode, "v3_shadow"),
253
+ gte(memoryV2ActivationLogs.createdAt, opts.sinceMs),
254
+ )
255
+ : eq(memoryV2ActivationLogs.mode, "v3_shadow"),
256
+ )
257
+ .orderBy(memoryV2ActivationLogs.createdAt)
258
+ .all()
259
+ .map((row) => ({
260
+ conversationId: row.conversationId,
261
+ createdAt: row.createdAt,
262
+ concepts: parseConcepts(row.conceptsJson),
263
+ }));
264
+
265
+ if (shadow.length === 0) return { shadow: [], router: [] };
266
+
267
+ const convIds = [...new Set(shadow.map((s) => s.conversationId))];
268
+ let tMin = Number.POSITIVE_INFINITY;
269
+ let tMax = Number.NEGATIVE_INFINITY;
270
+ for (const s of shadow) {
271
+ if (s.createdAt < tMin) tMin = s.createdAt;
272
+ if (s.createdAt > tMax) tMax = s.createdAt;
273
+ }
274
+
275
+ const router = db
276
+ .select({
277
+ conversationId: memoryV2ActivationLogs.conversationId,
278
+ createdAt: memoryV2ActivationLogs.createdAt,
279
+ conceptsJson: memoryV2ActivationLogs.conceptsJson,
280
+ })
281
+ .from(memoryV2ActivationLogs)
282
+ .where(
283
+ and(
284
+ eq(memoryV2ActivationLogs.mode, "router"),
285
+ inArray(memoryV2ActivationLogs.conversationId, convIds),
286
+ gte(memoryV2ActivationLogs.createdAt, tMin - opts.paddingMs),
287
+ lte(memoryV2ActivationLogs.createdAt, tMax + opts.paddingMs),
288
+ ),
289
+ )
290
+ .all()
291
+ .map((row) => ({
292
+ conversationId: row.conversationId,
293
+ createdAt: row.createdAt,
294
+ concepts: parseConcepts(row.conceptsJson),
295
+ }));
296
+
297
+ return { shadow, router };
298
+ }
@@ -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_rename_cleaned_at_v1";
6
+
7
+ const OLD_COLUMN = "cleaned_at";
8
+ const NEW_COLUMN = "history_stripped_at";
9
+
10
+ /**
11
+ * Rename `conversations.cleaned_at` → `conversations.history_stripped_at`.
12
+ *
13
+ * The marker now records any injection-strip event (`/clean` or compaction),
14
+ * not just `/clean`. Renaming reflects the broader semantics; compaction
15
+ * sets it alongside its summary state instead of destructively wiping
16
+ * message metadata.
17
+ */
18
+ export function migrateRenameCleanedAt(database: DrizzleDb): void {
19
+ withCrashRecovery(database, CHECKPOINT_KEY, () => {
20
+ if (tableHasColumn(database, "conversations", NEW_COLUMN)) {
21
+ return;
22
+ }
23
+ if (!tableHasColumn(database, "conversations", OLD_COLUMN)) {
24
+ // 259 didn't run (fresh install on a newer schema where 259's column
25
+ // was added under the new name) — nothing to rename.
26
+ return;
27
+ }
28
+ database.run(
29
+ `ALTER TABLE conversations RENAME COLUMN ${OLD_COLUMN} TO ${NEW_COLUMN}`,
30
+ );
31
+ });
32
+ }
33
+
34
+ export function downRenameCleanedAt(database: DrizzleDb): void {
35
+ if (!tableHasColumn(database, "conversations", NEW_COLUMN)) {
36
+ return;
37
+ }
38
+ if (tableHasColumn(database, "conversations", OLD_COLUMN)) {
39
+ return;
40
+ }
41
+ database.run(
42
+ `ALTER TABLE conversations RENAME COLUMN ${NEW_COLUMN} TO ${OLD_COLUMN}`,
43
+ );
44
+ }
@@ -0,0 +1,36 @@
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_llm_usage_add_raw_usage_v1";
6
+
7
+ const TABLE = "llm_usage_events";
8
+ const COLUMN = "raw_usage";
9
+
10
+ /**
11
+ * Add a `raw_usage` TEXT column to `llm_usage_events` for storing the
12
+ * provider's untouched `usage` block as JSON.
13
+ *
14
+ * The Anthropic API surfaces a TTL breakdown of cache writes
15
+ * (`usage.cache_creation.ephemeral_5m_input_tokens`,
16
+ * `usage.cache_creation.ephemeral_1h_input_tokens`); OpenAI surfaces
17
+ * nested `prompt_tokens_details` and `completion_tokens_details`; both
18
+ * are kept as opaque JSON so admin charts and downstream consumers can
19
+ * extract provider-specific detail without requiring a new column every
20
+ * time a provider adds a usage field. `NULL` for rows persisted before
21
+ * this migration ran and for providers that did not return a usage
22
+ * payload.
23
+ */
24
+ export function migrateLlmUsageAddRawUsage(database: DrizzleDb): void {
25
+ withCrashRecovery(database, CHECKPOINT_KEY, () => {
26
+ if (!tableHasColumn(database, TABLE, COLUMN)) {
27
+ database.run(`ALTER TABLE ${TABLE} ADD COLUMN ${COLUMN} TEXT`);
28
+ }
29
+ });
30
+ }
31
+
32
+ export function downLlmUsageAddRawUsage(database: DrizzleDb): void {
33
+ if (tableHasColumn(database, TABLE, COLUMN)) {
34
+ database.run(`ALTER TABLE ${TABLE} DROP COLUMN ${COLUMN}`);
35
+ }
36
+ }
@@ -0,0 +1,57 @@
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_v3_coactivation_v1";
6
+
7
+ /**
8
+ * Create the memory_v3_coactivation table — an append-only log of
9
+ * pass-1 → pass-N co-activation pairs observed during a v3 retrieval loop.
10
+ *
11
+ * Each row records that a page (`target_slug`) first surfaced on a later
12
+ * descent pass was co-selected alongside a page (`source_slug`) that surfaced
13
+ * on pass 1, with `pass_gap` = passOf(target) − passOf(source). This is the
14
+ * raw gradient signal that edge-learning later reconciles into curated-graph
15
+ * edge weights: a source that repeatedly precedes a target across turns is a
16
+ * candidate association. `used` is the usefulness flag (0 here — the loop
17
+ * cannot know whether the target was actually load-bearing for the turn; a
18
+ * later edge-learning pass reconciles it).
19
+ *
20
+ * The table just accumulates raw events; the edge-learning formula or the
21
+ * decay/weighting can change later without losing signal.
22
+ *
23
+ * Indexes:
24
+ * - `(source_slug, target_slug)` for per-pair aggregation (the hot path for
25
+ * edge-learning reads).
26
+ * - `(created_at)` for time-range pruning later.
27
+ */
28
+ export function migrateMemoryV3Coactivation(database: DrizzleDb): void {
29
+ withCrashRecovery(database, CHECKPOINT_KEY, () => {
30
+ const raw = getSqliteFrom(database);
31
+ raw.exec(/*sql*/ `
32
+ CREATE TABLE IF NOT EXISTS memory_v3_coactivation (
33
+ id INTEGER PRIMARY KEY,
34
+ conversation_id TEXT NOT NULL,
35
+ turn INTEGER NOT NULL,
36
+ source_slug TEXT NOT NULL,
37
+ target_slug TEXT NOT NULL,
38
+ pass_gap INTEGER NOT NULL,
39
+ used INTEGER NOT NULL,
40
+ created_at INTEGER NOT NULL
41
+ )
42
+ `);
43
+ raw.exec(/*sql*/ `
44
+ CREATE INDEX IF NOT EXISTS idx_memory_v3_coactivation_pair
45
+ ON memory_v3_coactivation (source_slug, target_slug)
46
+ `);
47
+ raw.exec(/*sql*/ `
48
+ CREATE INDEX IF NOT EXISTS idx_memory_v3_coactivation_time
49
+ ON memory_v3_coactivation (created_at)
50
+ `);
51
+ });
52
+ }
53
+
54
+ export function downMemoryV3Coactivation(database: DrizzleDb): void {
55
+ const raw = getSqliteFrom(database);
56
+ raw.exec(/*sql*/ `DROP TABLE IF EXISTS memory_v3_coactivation`);
57
+ }