@vellumai/assistant 0.8.0 → 0.8.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 (692) hide show
  1. package/AGENTS.md +11 -0
  2. package/Dockerfile +5 -4
  3. package/README.md +2 -2
  4. package/docker-entrypoint.sh +16 -0
  5. package/eslint-rules/__tests__/cli-no-daemon-internals.test.ts +420 -0
  6. package/eslint-rules/cli-no-daemon-internals.js +283 -0
  7. package/eslint.config.mjs +12 -0
  8. package/knip.json +2 -1
  9. package/node_modules/@vellumai/skill-host-contracts/src/client.ts +10 -1
  10. package/openapi.yaml +4847 -1698
  11. package/package.json +3 -1
  12. package/scripts/generate-openapi.ts +52 -4
  13. package/scripts/sync-llm-catalog.ts +165 -0
  14. package/scripts/sync-web-search-catalog.ts +107 -0
  15. package/src/__tests__/actor-trust-resolver-address-fallback.test.ts +169 -0
  16. package/src/__tests__/agent-loop-override-profile.test.ts +26 -1
  17. package/src/__tests__/anthropic-provider.test.ts +92 -2
  18. package/src/__tests__/app-control-flow.test.ts +7 -0
  19. package/src/__tests__/assistant-events-sse-shed.test.ts +232 -0
  20. package/src/__tests__/avatar-identity-sync.test.ts +87 -0
  21. package/src/__tests__/background-workers-disk-pressure.test.ts +11 -22
  22. package/src/__tests__/btw-routes.test.ts +1 -0
  23. package/src/__tests__/call-site-routing-provider.test.ts +172 -45
  24. package/src/__tests__/cancel-resolves-conversation-key.test.ts +44 -3
  25. package/src/__tests__/channel-policy.test.ts +12 -0
  26. package/src/__tests__/checker.test.ts +89 -0
  27. package/src/__tests__/cli-memory-v2-reembed-skills.test.ts +35 -7
  28. package/src/__tests__/compact-event-conversation-id-guard.test.ts +33 -5
  29. package/src/__tests__/compaction-strip-metadata-clear.test.ts +26 -1
  30. package/src/__tests__/config-loader-backfill.test.ts +526 -102
  31. package/src/__tests__/config-loader-corrupt.test.ts +68 -0
  32. package/src/__tests__/config-loader-platform-defaults.test.ts +77 -23
  33. package/src/__tests__/config-schema-cmd.test.ts +63 -29
  34. package/src/__tests__/config-schema.test.ts +14 -3
  35. package/src/__tests__/config-set-platform-guard.test.ts +75 -152
  36. package/src/__tests__/config-set-route.test.ts +198 -0
  37. package/src/__tests__/config-watcher.test.ts +6 -0
  38. package/src/__tests__/contacts-tools.test.ts +51 -199
  39. package/src/__tests__/context-search-agent-protocol.test.ts +21 -2
  40. package/src/__tests__/context-search-agent-runner.test.ts +22 -138
  41. package/src/__tests__/context-search-conversations-source.test.ts +42 -16
  42. package/src/__tests__/context-search-fanout.test.ts +20 -157
  43. package/src/__tests__/context-search-memory-v2-source.test.ts +3 -3
  44. package/src/__tests__/context-search-types.test.ts +7 -2
  45. package/src/__tests__/context-window-manager.test.ts +389 -1
  46. package/src/__tests__/conversation-agent-loop-overflow.test.ts +1 -0
  47. package/src/__tests__/conversation-crud-inference-profile.test.ts +100 -0
  48. package/src/__tests__/conversation-error.test.ts +38 -0
  49. package/src/__tests__/conversation-fork-crud.test.ts +241 -1
  50. package/src/__tests__/conversation-inference-profile-route.test.ts +14 -14
  51. package/src/__tests__/conversation-init.benchmark.test.ts +1 -0
  52. package/src/__tests__/conversation-lifecycle.test.ts +124 -0
  53. package/src/__tests__/conversation-process-app-control-preactivation.test.ts +100 -1
  54. package/src/__tests__/conversation-process-callsite.test.ts +21 -1
  55. package/src/__tests__/conversation-runtime-assembly.test.ts +4 -4
  56. package/src/__tests__/conversation-slash-commands.test.ts +194 -2
  57. package/src/__tests__/conversation-surfaces-app-control.test.ts +323 -3
  58. package/src/__tests__/credential-security-invariants.test.ts +5 -6
  59. package/src/__tests__/daemon-credential-client.test.ts +56 -1
  60. package/src/__tests__/db-activation-state-fk-cascade.test.ts +132 -0
  61. package/src/__tests__/db-conversation-inference-profile-migration.test.ts +37 -0
  62. package/src/__tests__/db-memory-graph-event-date-repair.test.ts +43 -20
  63. package/src/__tests__/db-proxy-transaction.test.ts +206 -0
  64. package/src/__tests__/external-plugin-loader.test.ts +458 -0
  65. package/src/__tests__/filing-service.test.ts +23 -3
  66. package/src/__tests__/fixtures/mock-chrome-extension.ts +5 -0
  67. package/src/__tests__/gateway-only-guard.test.ts +0 -1
  68. package/src/__tests__/graph-extraction-event-date.test.ts +34 -0
  69. package/src/__tests__/handlers-skills-memory-v2-reseed.test.ts +0 -8
  70. package/src/__tests__/heartbeat-disk-pressure.test.ts +21 -8
  71. package/src/__tests__/heartbeat-service.test.ts +50 -233
  72. package/src/__tests__/history-repair.test.ts +89 -0
  73. package/src/__tests__/host-app-control-proxy.test.ts +109 -1
  74. package/src/__tests__/host-app-control-routes.test.ts +247 -1
  75. package/src/__tests__/host-browser-proxy.test.ts +416 -20
  76. package/src/__tests__/host-browser-routes.test.ts +325 -33
  77. package/src/__tests__/host-proxy-preactivation.test.ts +211 -0
  78. package/src/__tests__/inference-no-mode-boot-e2e.test.ts +246 -0
  79. package/src/__tests__/inference-profile-reaper.test.ts +154 -0
  80. package/src/__tests__/inference-profile-session-handler.test.ts +398 -0
  81. package/src/__tests__/inference-profile-session-ipc.test.ts +236 -0
  82. package/src/__tests__/inline-skill-load-permissions.test.ts +6 -1
  83. package/src/__tests__/install-skill-routing.test.ts +2 -2
  84. package/src/__tests__/lifecycle-memory-v2-seed.test.ts +15 -0
  85. package/src/__tests__/llm-callsite-catalog.test.ts +20 -1
  86. package/src/__tests__/llm-catalog-parity.test.ts +146 -0
  87. package/src/__tests__/llm-request-log-source-clickhouse.test.ts +188 -0
  88. package/src/__tests__/llm-request-log-source-factory.test.ts +124 -0
  89. package/src/__tests__/llm-resolver.test.ts +46 -0
  90. package/src/__tests__/managed-profile-guard.test.ts +131 -2
  91. package/src/__tests__/mcp-auth-routes.test.ts +1 -0
  92. package/src/__tests__/mcp-cli.test.ts +182 -220
  93. package/src/__tests__/mcp-health-check.test.ts +56 -27
  94. package/src/__tests__/memory-jobs-worker-lanes.test.ts +18 -11
  95. package/src/__tests__/message-complete-display-id.test.ts +175 -0
  96. package/src/__tests__/notification-platform-adapter.test.ts +229 -0
  97. package/src/__tests__/oauth-cli.test.ts +38 -2009
  98. package/src/__tests__/oauth-commands-routes.test.ts +711 -0
  99. package/src/__tests__/oauth-connect-routes.test.ts +174 -11
  100. package/src/__tests__/oauth-providers-routes.test.ts +14 -10
  101. package/src/__tests__/openai-responses-cutover-guard.test.ts +33 -12
  102. package/src/__tests__/openai-responses-provider.test.ts +17 -0
  103. package/src/__tests__/plugin-bootstrap.test.ts +31 -2
  104. package/src/__tests__/plugin-route-contribution.test.ts +31 -3
  105. package/src/__tests__/plugin-tool-contribution.test.ts +31 -3
  106. package/src/__tests__/plugin-types.test.ts +13 -11
  107. package/src/__tests__/process-message-background-slack.test.ts +46 -0
  108. package/src/__tests__/profile-entry-status.test.ts +43 -0
  109. package/src/__tests__/provider-managed-proxy-integration.test.ts +12 -4
  110. package/src/__tests__/provider-registry-ollama.test.ts +12 -4
  111. package/src/__tests__/provider-send-message-override-profile.test.ts +10 -4
  112. package/src/__tests__/relay-server.test.ts +118 -0
  113. package/src/__tests__/retry-thinking-tool-choice.test.ts +15 -0
  114. package/src/__tests__/schedule-retry.test.ts +56 -4
  115. package/src/__tests__/schedule-routes.test.ts +104 -0
  116. package/src/__tests__/scheduler-disk-pressure.test.ts +0 -4
  117. package/src/__tests__/scheduler-recurrence.test.ts +87 -34
  118. package/src/__tests__/scheduler-reuse-conversation.test.ts +161 -5
  119. package/src/__tests__/scheduler-wake.test.ts +0 -63
  120. package/src/__tests__/secret-allowlist.test.ts +1 -0
  121. package/src/__tests__/secret-routes-managed-proxy.test.ts +12 -4
  122. package/src/__tests__/shell-credential-ref.test.ts +95 -3
  123. package/src/__tests__/shell-tool-proxy-mode.test.ts +14 -0
  124. package/src/__tests__/skill-load-feature-flag.test.ts +1 -0
  125. package/src/__tests__/skill-load-tool.test.ts +2 -4
  126. package/src/__tests__/subagent-call-site-routing.test.ts +78 -16
  127. package/src/__tests__/suggestion-routes.test.ts +3 -3
  128. package/src/__tests__/sync-message-contract.test.ts +63 -0
  129. package/src/__tests__/task-scheduler.test.ts +88 -23
  130. package/src/__tests__/update-bulletin-job.test.ts +96 -193
  131. package/src/__tests__/usage-cli.test.ts +11 -73
  132. package/src/__tests__/user-plugin-loader.test.ts +145 -0
  133. package/src/__tests__/vercel-config.test.ts +168 -0
  134. package/src/__tests__/web-search-catalog-parity.test.ts +86 -0
  135. package/src/__tests__/web-search.test.ts +303 -2
  136. package/src/__tests__/workspace-migration-039-drop-legacy-llm-keys.test.ts +1 -21
  137. package/src/__tests__/workspace-migration-057-repair-stale-gemini-model-ids.test.ts +58 -0
  138. package/src/__tests__/workspace-migration-069-seed-onboarding-threads.test.ts +53 -20
  139. package/src/__tests__/workspace-migration-072-seed-reply-suggestion-callsite.test.ts +191 -0
  140. package/src/__tests__/workspace-migration-076-drop-services-inference-mode.test.ts +211 -0
  141. package/src/__tests__/workspace-migration-077-seed-memory-router-callsite.test.ts +174 -0
  142. package/src/__tests__/workspace-migration-079-home-feed-notification-only.test.ts +323 -0
  143. package/src/__tests__/workspace-migration-080-restrict-vercel-api-token-metadata.test.ts +299 -0
  144. package/src/__tests__/workspace-migration-081-backfill-bash-allowed-tools.test.ts +410 -0
  145. package/src/__tests__/workspace-migration-082-backfill-managed-profile-labels.test.ts +268 -0
  146. package/src/__tests__/workspace-migration-unify-llm-callsite-configs.test.ts +3 -3
  147. package/src/__tests__/workspace-release-notes-feature-flag-guard.test.ts +115 -0
  148. package/src/acp/__tests__/helpers/which-stub.ts +4 -2
  149. package/src/acp/resolve-agent.test.ts +25 -0
  150. package/src/acp/resolve-agent.ts +13 -2
  151. package/src/acp/session-manager.ts +14 -0
  152. package/src/approvals/guardian-request-resolvers.ts +32 -87
  153. package/src/calls/relay-server.ts +35 -0
  154. package/src/calls/relay-setup-router.ts +36 -0
  155. package/src/calls/types.ts +1 -0
  156. package/src/calls/voice-session-bridge.ts +23 -4
  157. package/src/channels/config.ts +14 -1
  158. package/src/channels/types.ts +1 -0
  159. package/src/cli/AGENTS.md +164 -4
  160. package/src/cli/__tests__/notifications.test.ts +54 -0
  161. package/src/cli/commands/__tests__/avatar.test.ts +540 -0
  162. package/src/cli/commands/__tests__/backup.test.ts +236 -776
  163. package/src/cli/commands/__tests__/cache.test.ts +1 -1
  164. package/src/cli/commands/__tests__/changelog.test.ts +593 -0
  165. package/src/cli/commands/__tests__/channel-verification-sessions.test.ts +503 -0
  166. package/src/cli/commands/__tests__/conversations-import.test.ts +515 -0
  167. package/src/cli/commands/__tests__/domain-register.test.ts +140 -167
  168. package/src/cli/commands/__tests__/domain-status.test.ts +137 -76
  169. package/src/cli/commands/__tests__/email-attachment.test.ts +314 -337
  170. package/src/cli/commands/__tests__/email-core.test.ts +579 -0
  171. package/src/cli/commands/__tests__/image-generation.test.ts +87 -824
  172. package/src/cli/commands/__tests__/inference-send.test.ts +30 -266
  173. package/src/cli/commands/__tests__/inference-session.test.ts +423 -0
  174. package/src/cli/commands/__tests__/memory-v2.test.ts +81 -110
  175. package/src/cli/commands/__tests__/skills.test.ts +563 -0
  176. package/src/cli/commands/__tests__/status.test.ts +249 -0
  177. package/src/cli/commands/__tests__/stt.test.ts +320 -0
  178. package/src/cli/commands/__tests__/tts-synthesize.test.ts +4 -603
  179. package/src/cli/commands/__tests__/tts.test.ts +321 -0
  180. package/src/cli/commands/__tests__/webhooks.test.ts +86 -511
  181. package/src/cli/commands/attachment.ts +8 -3
  182. package/src/cli/commands/audit.ts +95 -64
  183. package/src/cli/commands/auth.ts +61 -58
  184. package/src/cli/commands/avatar.ts +276 -390
  185. package/src/cli/commands/backup.ts +409 -505
  186. package/src/cli/commands/bash.ts +9 -5
  187. package/src/cli/commands/browser.ts +28 -9
  188. package/src/cli/commands/cache.ts +9 -4
  189. package/src/cli/commands/changelog.ts +414 -0
  190. package/src/cli/commands/channel-verification-sessions.ts +238 -317
  191. package/src/cli/commands/clients.ts +8 -3
  192. package/src/cli/commands/completions.ts +9 -9
  193. package/src/cli/commands/config.ts +102 -72
  194. package/src/cli/commands/contacts.ts +575 -696
  195. package/src/cli/commands/conversations-defer.ts +17 -69
  196. package/src/cli/commands/conversations-import.ts +90 -253
  197. package/src/cli/commands/conversations.ts +346 -436
  198. package/src/cli/commands/credential-execution.ts +9 -6
  199. package/src/cli/commands/credentials.ts +456 -736
  200. package/src/cli/commands/domain.ts +128 -206
  201. package/src/cli/commands/email.ts +606 -794
  202. package/src/cli/commands/gateway.ts +8 -1
  203. package/src/cli/commands/image-generation.ts +157 -205
  204. package/src/cli/commands/inference-providers.ts +352 -0
  205. package/src/cli/commands/inference-session.ts +415 -0
  206. package/src/cli/commands/inference.ts +87 -65
  207. package/src/cli/commands/keys.ts +8 -3
  208. package/src/cli/commands/mcp.ts +103 -287
  209. package/src/cli/commands/memory-v2.ts +162 -516
  210. package/src/cli/commands/notifications.ts +33 -7
  211. package/src/cli/commands/oauth/apps.ts +292 -261
  212. package/src/cli/commands/oauth/connect.ts +176 -297
  213. package/src/cli/commands/oauth/disconnect.ts +16 -215
  214. package/src/cli/commands/oauth/index.ts +49 -45
  215. package/src/cli/commands/oauth/mode.ts +43 -199
  216. package/src/cli/commands/oauth/ping.ts +17 -125
  217. package/src/cli/commands/oauth/providers.ts +732 -921
  218. package/src/cli/commands/oauth/request.ts +60 -350
  219. package/src/cli/commands/oauth/shared.ts +11 -121
  220. package/src/cli/commands/oauth/status.ts +31 -121
  221. package/src/cli/commands/oauth/token.ts +13 -55
  222. package/src/cli/commands/pending.ts +19 -10
  223. package/src/cli/commands/platform/__tests__/callback-routes-list.test.ts +133 -183
  224. package/src/cli/commands/platform/__tests__/connect.test.ts +66 -181
  225. package/src/cli/commands/platform/__tests__/disconnect.test.ts +71 -227
  226. package/src/cli/commands/platform/__tests__/status.test.ts +169 -287
  227. package/src/cli/commands/platform/connect.ts +16 -80
  228. package/src/cli/commands/platform/disconnect.ts +14 -112
  229. package/src/cli/commands/platform/index.ts +177 -246
  230. package/src/cli/commands/routes.ts +153 -336
  231. package/src/cli/commands/sequence.ts +316 -360
  232. package/src/cli/commands/skills.ts +449 -671
  233. package/src/cli/commands/status.ts +58 -37
  234. package/src/cli/commands/stt.ts +94 -262
  235. package/src/cli/commands/task.ts +14 -40
  236. package/src/cli/commands/trust.ts +8 -3
  237. package/src/cli/commands/tts.ts +162 -167
  238. package/src/cli/commands/ui.ts +35 -42
  239. package/src/cli/commands/usage.ts +188 -126
  240. package/src/cli/commands/watchers.ts +8 -3
  241. package/src/cli/commands/webhooks.ts +99 -193
  242. package/src/cli/lib/__tests__/register-command.test.ts +85 -0
  243. package/src/cli/lib/daemon-credential-client.ts +4 -5
  244. package/src/cli/lib/nested-value.ts +44 -0
  245. package/src/cli/lib/open-browser.ts +36 -0
  246. package/src/cli/lib/register-command.ts +19 -0
  247. package/src/cli/lib/time-ago.ts +34 -0
  248. package/src/cli/program.ts +2 -4
  249. package/src/cli/utils/__tests__/conversation-id.test.ts +66 -0
  250. package/src/cli/utils/__tests__/parse-duration.test.ts +49 -0
  251. package/src/cli/utils/conversation-id.ts +30 -0
  252. package/src/cli/utils/parse-duration.ts +41 -0
  253. package/src/config/acp-defaults.test.ts +5 -1
  254. package/src/config/acp-defaults.ts +11 -4
  255. package/src/config/bundled-skills/acp/TOOLS.json +2 -2
  256. package/src/config/bundled-skills/app-control/TOOLS.json +32 -0
  257. package/src/config/bundled-skills/contacts/SKILL.md +12 -45
  258. package/src/config/bundled-skills/contacts/TOOLS.json +0 -57
  259. package/src/config/bundled-skills/messaging/tools/messaging-archive-by-sender.ts +0 -12
  260. package/src/config/bundled-skills/messaging/tools/messaging-send.ts +0 -58
  261. package/src/config/bundled-tool-registry.ts +0 -2
  262. package/src/config/feature-flag-registry.json +16 -0
  263. package/src/config/llm-resolver.ts +16 -1
  264. package/src/config/loader.ts +76 -14
  265. package/src/config/raw-config-utils.ts +2 -30
  266. package/src/config/schema.ts +4 -0
  267. package/src/config/schemas/__tests__/memory-v2.test.ts +49 -0
  268. package/src/config/schemas/call-site-catalog.ts +29 -7
  269. package/src/config/schemas/llm-request-logs.ts +57 -0
  270. package/src/config/schemas/llm.ts +52 -2
  271. package/src/config/schemas/memory-retrospective.ts +48 -0
  272. package/src/config/schemas/memory-v2.ts +32 -1
  273. package/src/config/schemas/memory.ts +4 -0
  274. package/src/config/schemas/services.ts +15 -12
  275. package/src/config/seed-inference-profiles.ts +195 -134
  276. package/src/contacts/contact-store.ts +0 -61
  277. package/src/context/window-manager.ts +191 -5
  278. package/src/daemon/__tests__/conversation-lifecycle-auto-analyze.test.ts +79 -0
  279. package/src/daemon/__tests__/conversation-tool-setup.test.ts +109 -4
  280. package/src/daemon/__tests__/daemon-skill-host.test.ts +10 -4
  281. package/src/daemon/approval-generators.ts +23 -29
  282. package/src/daemon/config-watcher.ts +2 -0
  283. package/src/daemon/conversation-agent-loop-handlers.ts +24 -0
  284. package/src/daemon/conversation-agent-loop.ts +127 -97
  285. package/src/daemon/conversation-error.ts +21 -0
  286. package/src/daemon/conversation-lifecycle.ts +46 -5
  287. package/src/daemon/conversation-process.ts +36 -19
  288. package/src/daemon/conversation-runtime-assembly.ts +14 -5
  289. package/src/daemon/conversation-slash.ts +175 -23
  290. package/src/daemon/conversation-store.ts +17 -10
  291. package/src/daemon/conversation-surfaces.ts +76 -12
  292. package/src/daemon/conversation-tool-setup.ts +24 -14
  293. package/src/daemon/conversation.ts +48 -9
  294. package/src/daemon/external-plugins-bootstrap.ts +18 -8
  295. package/src/daemon/guardian-action-generators.ts +7 -22
  296. package/src/daemon/handlers/config-model.ts +8 -126
  297. package/src/daemon/handlers/config-slack-channel.ts +10 -7
  298. package/src/daemon/handlers/config-vercel.ts +3 -1
  299. package/src/daemon/handlers/skills.ts +84 -5
  300. package/src/daemon/history-repair.ts +33 -6
  301. package/src/daemon/host-app-control-proxy.ts +44 -19
  302. package/src/daemon/host-bash-proxy.ts +85 -158
  303. package/src/daemon/host-browser-proxy.ts +96 -35
  304. package/src/daemon/host-proxy-base.ts +13 -1
  305. package/src/daemon/host-proxy-preactivation.ts +25 -1
  306. package/src/daemon/identity-helpers.ts +19 -0
  307. package/src/daemon/lifecycle.ts +42 -43
  308. package/src/daemon/meet-host-supervisor.ts +15 -15
  309. package/src/daemon/memory-v2-startup.ts +9 -2
  310. package/src/daemon/message-protocol.ts +6 -0
  311. package/src/daemon/message-types/bookmarks.ts +18 -0
  312. package/src/daemon/message-types/conversations.ts +12 -9
  313. package/src/daemon/message-types/messages.ts +9 -1
  314. package/src/daemon/message-types/sync.ts +60 -0
  315. package/src/daemon/pkb-reminder-builder.test.ts +54 -13
  316. package/src/daemon/pkb-reminder-builder.ts +21 -7
  317. package/src/daemon/process-message.ts +56 -23
  318. package/src/daemon/server.ts +23 -18
  319. package/src/daemon/shutdown-handlers.ts +0 -2
  320. package/src/daemon/tool-setup-types.ts +9 -0
  321. package/src/daemon/tool-side-effects.ts +6 -4
  322. package/src/daemon/wake-target-adapter.ts +11 -0
  323. package/src/export/transcript-formatter.ts +61 -2
  324. package/src/filing/filing-service.ts +40 -53
  325. package/src/heartbeat/__tests__/heartbeat-service.test.ts +359 -0
  326. package/src/heartbeat/heartbeat-run-store.ts +2 -1
  327. package/src/heartbeat/heartbeat-service.ts +148 -127
  328. package/src/home/__tests__/feed-types.test.ts +63 -131
  329. package/src/home/__tests__/feed-writer.test.ts +77 -278
  330. package/src/home/__tests__/post-connect-feed.test.ts +9 -12
  331. package/src/home/feed-types.ts +19 -73
  332. package/src/home/feed-writer.ts +25 -156
  333. package/src/home/post-connect-feed.ts +1 -3
  334. package/src/ipc/__tests__/cli-ipc.test.ts +2 -0
  335. package/src/ipc/__tests__/email-ipc.test.ts +506 -0
  336. package/src/ipc/__tests__/exit-helper.test.ts +104 -0
  337. package/src/ipc/__tests__/streaming-client.test.ts +237 -0
  338. package/src/ipc/__tests__/streaming-framing.test.ts +142 -0
  339. package/src/ipc/assistant-server.ts +55 -6
  340. package/src/ipc/cli-client.ts +370 -50
  341. package/src/ipc/routes/db-proxy-transaction.ts +151 -0
  342. package/src/ipc/skill-routes/__tests__/events-ipc.test.ts +60 -0
  343. package/src/ipc/skill-routes/events.ts +30 -3
  344. package/src/live-voice/__tests__/live-voice-session-manager.test.ts +46 -0
  345. package/src/live-voice/__tests__/runtime-websocket-shell.test.ts +1 -0
  346. package/src/live-voice/live-voice-session-manager.ts +11 -4
  347. package/src/live-voice/live-voice-session.ts +14 -6
  348. package/src/memory/__tests__/bookmark-crud.test.ts +258 -0
  349. package/src/memory/__tests__/bookmark-schema.test.ts +181 -0
  350. package/src/memory/__tests__/conversation-types.test.ts +36 -0
  351. package/src/memory/__tests__/find-most-recent-retrospective-for.test.ts +130 -0
  352. package/src/memory/__tests__/memory-retrospective-enqueue.test.ts +177 -0
  353. package/src/memory/__tests__/memory-retrospective-job.test.ts +328 -0
  354. package/src/memory/__tests__/memory-retrospective-startup-cleanup.test.ts +213 -0
  355. package/src/memory/__tests__/memory-retrospective-trigger-check.test.ts +90 -0
  356. package/src/memory/__tests__/memory-v2-activation-log-store.test.ts +69 -0
  357. package/src/memory/__tests__/memory-v2-concept-frequency.test.ts +3 -0
  358. package/src/memory/bookmark-crud.ts +179 -0
  359. package/src/memory/context-search/__tests__/agent-runner-redaction.test.ts +31 -9
  360. package/src/memory/context-search/agent-protocol.ts +5 -1
  361. package/src/memory/context-search/agent-runner.ts +60 -85
  362. package/src/memory/context-search/limits.ts +1 -4
  363. package/src/memory/context-search/search.ts +23 -113
  364. package/src/memory/context-search/sources/conversations.ts +18 -6
  365. package/src/memory/context-search/sources/memory-v2.ts +39 -14
  366. package/src/memory/context-search/sources/memory.ts +7 -0
  367. package/src/memory/context-search/sources/workspace.ts +13 -10
  368. package/src/memory/context-search/types.ts +1 -1
  369. package/src/memory/conversation-bootstrap.ts +11 -0
  370. package/src/memory/conversation-crud.ts +312 -10
  371. package/src/memory/conversation-queries.ts +9 -5
  372. package/src/memory/conversation-title-service.ts +1 -0
  373. package/src/memory/conversation-types.ts +16 -0
  374. package/src/memory/db-init.ts +14 -0
  375. package/src/memory/embedding-backend.ts +2 -1
  376. package/src/memory/embedding-runtime-manager.ts +1 -2
  377. package/src/memory/graph/__tests__/remember-description.test.ts +55 -0
  378. package/src/memory/graph/conversation-graph-memory.ts +76 -5
  379. package/src/memory/graph/extraction.ts +4 -0
  380. package/src/memory/graph/graph-memory-state-store.ts +16 -3
  381. package/src/memory/graph/tool-handlers.ts +17 -7
  382. package/src/memory/graph/tools.ts +44 -5
  383. package/src/memory/indexer.ts +17 -0
  384. package/src/memory/jobs/__tests__/embed-concept-page.test.ts +13 -15
  385. package/src/memory/jobs/embed-concept-page.ts +45 -9
  386. package/src/memory/jobs-store.ts +51 -1
  387. package/src/memory/jobs-worker.ts +52 -3
  388. package/src/memory/llm-request-log-source-clickhouse.ts +317 -0
  389. package/src/memory/llm-request-log-source-local.ts +26 -0
  390. package/src/memory/llm-request-log-source.ts +97 -0
  391. package/src/memory/llm-request-log-store.ts +1 -1
  392. package/src/memory/memory-retrospective-constants.ts +13 -0
  393. package/src/memory/memory-retrospective-enqueue.ts +114 -0
  394. package/src/memory/memory-retrospective-job.ts +351 -0
  395. package/src/memory/memory-retrospective-startup-cleanup.ts +108 -0
  396. package/src/memory/memory-retrospective-state.ts +162 -0
  397. package/src/memory/memory-retrospective-trigger-check.ts +91 -0
  398. package/src/memory/memory-v2-activation-log-store.ts +49 -5
  399. package/src/memory/memory-v2-concept-frequency.ts +4 -0
  400. package/src/memory/message-content.ts +38 -1
  401. package/src/memory/migrations/227-add-conversation-inference-profile.ts +6 -1
  402. package/src/memory/migrations/228-rename-inference-profile-snake-case.ts +20 -7
  403. package/src/memory/migrations/229-delete-private-conversations.test.ts +70 -1
  404. package/src/memory/migrations/229-delete-private-conversations.ts +12 -0
  405. package/src/memory/migrations/231-repair-memory-graph-event-dates.ts +16 -2
  406. package/src/memory/migrations/240-conversation-inference-profile-session.ts +25 -0
  407. package/src/memory/migrations/241-activation-state-fk-cascade.ts +50 -0
  408. package/src/memory/migrations/242-message-bookmarks.ts +38 -0
  409. package/src/memory/migrations/243-provider-connections.ts +68 -0
  410. package/src/memory/migrations/244-provider-connection-status-label.ts +23 -0
  411. package/src/memory/migrations/245-memory-retrospective-state.ts +36 -0
  412. package/src/memory/migrations/246-backfill-provider-connection-label.ts +81 -0
  413. package/src/memory/migrations/__tests__/244-provider-connection-status-label.test.ts +84 -0
  414. package/src/memory/migrations/__tests__/245-memory-retrospective-state.test.ts +125 -0
  415. package/src/memory/migrations/__tests__/246-backfill-provider-connection-label.test.ts +192 -0
  416. package/src/memory/migrations/index.ts +7 -0
  417. package/src/memory/published-pages-store.ts +16 -0
  418. package/src/memory/schema/bookmarks.ts +38 -0
  419. package/src/memory/schema/conversations.ts +2 -0
  420. package/src/memory/schema/index.ts +2 -0
  421. package/src/memory/schema/inference.ts +29 -0
  422. package/src/memory/schema/memory-core.ts +9 -0
  423. package/src/memory/search/semantic.ts +1 -4
  424. package/src/memory/v2/__tests__/__snapshots__/prompts-router.test.ts.snap +27 -0
  425. package/src/memory/v2/__tests__/activation-store.test.ts +5 -5
  426. package/src/memory/v2/__tests__/activation.test.ts +11 -4
  427. package/src/memory/v2/__tests__/backfill-jobs.test.ts +38 -21
  428. package/src/memory/v2/__tests__/consolidation-job.test.ts +123 -135
  429. package/src/memory/v2/__tests__/edge-index.test.ts +1 -1
  430. package/src/memory/v2/__tests__/frontmatter-sweep.test.ts +111 -0
  431. package/src/memory/v2/__tests__/injection.test.ts +628 -10
  432. package/src/memory/v2/__tests__/migration.test.ts +7 -3
  433. package/src/memory/v2/__tests__/page-index.test.ts +277 -0
  434. package/src/memory/v2/__tests__/page-store.test.ts +14 -1
  435. package/src/memory/v2/__tests__/prompts-router.test.ts +257 -0
  436. package/src/memory/v2/__tests__/qdrant.test.ts +72 -0
  437. package/src/memory/v2/__tests__/reranker.test.ts +4 -4
  438. package/src/memory/v2/__tests__/router.test.ts +516 -0
  439. package/src/memory/v2/__tests__/sim.test.ts +45 -1
  440. package/src/memory/v2/__tests__/skill-store.test.ts +58 -3
  441. package/src/memory/v2/__tests__/static-context.test.ts +7 -22
  442. package/src/memory/v2/__tests__/sweep-job.test.ts +95 -0
  443. package/src/memory/v2/activation-store.ts +34 -5
  444. package/src/memory/v2/activation.ts +40 -27
  445. package/src/memory/v2/backfill-jobs.ts +17 -84
  446. package/src/memory/v2/consolidation-job.ts +85 -78
  447. package/src/memory/v2/frontmatter-sweep.ts +91 -0
  448. package/src/memory/v2/injection.ts +440 -109
  449. package/src/memory/v2/migration.ts +117 -20
  450. package/src/memory/v2/page-index.ts +191 -0
  451. package/src/memory/v2/page-store.ts +3 -0
  452. package/src/memory/v2/prompts/consolidation.ts +9 -7
  453. package/src/memory/v2/prompts/router.ts +192 -0
  454. package/src/memory/v2/qdrant.ts +100 -87
  455. package/src/memory/v2/reranker.ts +14 -7
  456. package/src/memory/v2/router.ts +322 -0
  457. package/src/memory/v2/sim.ts +25 -12
  458. package/src/memory/v2/skill-store.ts +118 -29
  459. package/src/memory/v2/static-context.ts +16 -9
  460. package/src/memory/v2/sweep-job.ts +122 -96
  461. package/src/memory/v2/types.ts +10 -6
  462. package/src/memory/validation.ts +13 -0
  463. package/src/notifications/__tests__/emit-signal-home-feed.test.ts +182 -0
  464. package/src/notifications/__tests__/home-feed-side-effect.test.ts +199 -0
  465. package/src/notifications/__tests__/signal-registry.test.ts +17 -0
  466. package/src/notifications/adapters/platform.ts +171 -0
  467. package/src/notifications/conversation-pairing.ts +2 -2
  468. package/src/notifications/copy-composer.ts +15 -0
  469. package/src/notifications/destination-resolver.ts +21 -0
  470. package/src/notifications/emit-signal.ts +28 -1
  471. package/src/notifications/home-feed-side-effect.ts +111 -0
  472. package/src/notifications/signal.ts +5 -0
  473. package/src/permissions/checker.ts +12 -0
  474. package/src/permissions/ipc-risk-types.ts +2 -0
  475. package/src/plugin-api/index.ts +13 -0
  476. package/src/plugin-api/package.json +12 -0
  477. package/src/plugin-api/types.ts +62 -0
  478. package/src/plugins/defaults/injectors.ts +19 -3
  479. package/src/plugins/external-plugin-loader.ts +294 -0
  480. package/src/plugins/types.ts +46 -30
  481. package/src/plugins/user-loader.ts +64 -41
  482. package/src/proactive-artifact/job.test.ts +12 -4
  483. package/src/proactive-artifact/job.ts +4 -0
  484. package/src/proactive-artifact/trigger-state.test.ts +9 -0
  485. package/src/proactive-artifact/trigger-state.ts +4 -0
  486. package/src/prompts/__tests__/system-prompt.test.ts +105 -0
  487. package/src/prompts/system-prompt.ts +22 -1
  488. package/src/prompts/update-bulletin-job.ts +61 -73
  489. package/src/providers/__tests__/dispatch-connection-routing.test.ts +279 -0
  490. package/src/providers/__tests__/inference.test.ts +288 -0
  491. package/src/providers/__tests__/provider-env-vars.test.ts +6 -0
  492. package/src/providers/__tests__/provider-secret-catalog.test.ts +6 -0
  493. package/src/providers/__tests__/retry-callsite.test.ts +14 -32
  494. package/src/providers/__tests__/satellite-connection-routing.test.ts +510 -0
  495. package/src/providers/__tests__/search-provider-catalog.test.ts +80 -0
  496. package/src/providers/anthropic/client.ts +95 -26
  497. package/src/providers/call-site-routing.ts +94 -16
  498. package/src/providers/connection-resolution.ts +163 -0
  499. package/src/providers/inference/__tests__/connections-status-label.test.ts +250 -0
  500. package/src/providers/inference/adapter-factory.ts +173 -0
  501. package/src/providers/inference/auth.ts +112 -0
  502. package/src/providers/inference/backfill.ts +196 -0
  503. package/src/providers/inference/connections.ts +356 -0
  504. package/src/providers/inference/resolve-auth.ts +65 -0
  505. package/src/providers/model-catalog.ts +104 -6
  506. package/src/providers/openai/responses-provider.ts +4 -2
  507. package/src/providers/provider-env-vars.ts +17 -7
  508. package/src/providers/provider-secret-catalog.ts +49 -30
  509. package/src/providers/provider-send-message.ts +41 -20
  510. package/src/providers/registry.ts +143 -159
  511. package/src/providers/retry.ts +18 -10
  512. package/src/providers/search-provider-catalog.ts +121 -0
  513. package/src/runtime/AGENTS.md +18 -5
  514. package/src/runtime/__tests__/background-job-runner.test.ts +357 -0
  515. package/src/runtime/__tests__/pre-first-message-gate.test.ts +82 -0
  516. package/src/runtime/actor-trust-resolver.ts +32 -10
  517. package/src/runtime/agent-wake.ts +35 -6
  518. package/src/runtime/assistant-event-hub.ts +3 -85
  519. package/src/runtime/auth/route-policy.ts +303 -8
  520. package/src/runtime/auth/same-actor.ts +2 -0
  521. package/src/runtime/background-job-runner.ts +339 -0
  522. package/src/runtime/btw-sidechain.ts +1 -0
  523. package/src/runtime/http-router.ts +36 -1
  524. package/src/runtime/http-server.ts +31 -5
  525. package/src/runtime/http-types.ts +2 -0
  526. package/src/runtime/middleware/__tests__/request-logger.test.ts +162 -0
  527. package/src/runtime/middleware/request-logger.ts +62 -1
  528. package/src/runtime/pre-first-message-gate.ts +83 -0
  529. package/src/runtime/routes/__tests__/backup-routes.test.ts +8 -1
  530. package/src/runtime/routes/__tests__/bookmark-routes.test.ts +251 -0
  531. package/src/runtime/routes/__tests__/connection-routes-vs-cli-parity.test.ts +142 -0
  532. package/src/runtime/routes/__tests__/conversation-management-routes.test.ts +315 -0
  533. package/src/runtime/routes/__tests__/conversation-query-routes.test.ts +189 -0
  534. package/src/runtime/routes/__tests__/home-feed-routes.test.ts +15 -136
  535. package/src/runtime/routes/__tests__/inference-provider-connection-routes.test.ts +736 -0
  536. package/src/runtime/routes/__tests__/memory-v2-routes.test.ts +4 -4
  537. package/src/runtime/routes/__tests__/stt-routes.test.ts +5 -1
  538. package/src/runtime/routes/__tests__/surface-action-routes.test.ts +384 -0
  539. package/src/runtime/routes/__tests__/tts-routes.test.ts +6 -2
  540. package/src/runtime/routes/acp-routes.ts +10 -8
  541. package/src/runtime/routes/app-management-routes.ts +228 -3
  542. package/src/runtime/routes/approval-routes.ts +0 -18
  543. package/src/runtime/routes/audit-routes.ts +43 -0
  544. package/src/runtime/routes/auth-routes.ts +72 -0
  545. package/src/runtime/routes/avatar-routes.ts +273 -20
  546. package/src/runtime/routes/backup-routes.ts +406 -2
  547. package/src/runtime/routes/bookmark-routes.ts +154 -0
  548. package/src/runtime/routes/channel-verification-routes.ts +2 -1
  549. package/src/runtime/routes/contact-routes.ts +0 -160
  550. package/src/runtime/routes/conversation-cli-routes.ts +192 -0
  551. package/src/runtime/routes/conversation-management-routes.ts +30 -43
  552. package/src/runtime/routes/conversation-query-routes.ts +334 -86
  553. package/src/runtime/routes/conversation-routes.ts +31 -10
  554. package/src/runtime/routes/conversations-import-routes.ts +229 -0
  555. package/src/runtime/routes/credential-routes.ts +540 -0
  556. package/src/runtime/routes/debug-routes.ts +2 -2
  557. package/src/runtime/routes/document-pdf-renderer.ts +5 -1
  558. package/src/runtime/routes/domain-routes.ts +167 -0
  559. package/src/runtime/routes/email-routes.ts +603 -0
  560. package/src/runtime/routes/errors.ts +2 -2
  561. package/src/runtime/routes/events-routes.ts +192 -0
  562. package/src/runtime/routes/home-feed-routes.ts +6 -78
  563. package/src/runtime/routes/host-app-control-routes.ts +44 -2
  564. package/src/runtime/routes/host-browser-routes.ts +103 -22
  565. package/src/runtime/routes/http-adapter.ts +2 -0
  566. package/src/runtime/routes/identity-routes.ts +5 -0
  567. package/src/runtime/routes/image-generation-routes.ts +99 -0
  568. package/src/runtime/routes/inbound-stages/background-dispatch.test.ts +137 -1
  569. package/src/runtime/routes/inbound-stages/background-dispatch.ts +87 -7
  570. package/src/runtime/routes/inbound-stages/guardian-reply-intercept.test.ts +156 -0
  571. package/src/runtime/routes/inbound-stages/guardian-reply-intercept.ts +22 -4
  572. package/src/runtime/routes/index.ts +36 -0
  573. package/src/runtime/routes/inference-profile-session-handler.ts +312 -0
  574. package/src/runtime/routes/inference-profile-session-reaper.ts +98 -0
  575. package/src/runtime/routes/inference-profile-session-routes.ts +146 -0
  576. package/src/runtime/routes/inference-provider-connection-routes.ts +317 -0
  577. package/src/runtime/routes/inference-send-routes.ts +115 -0
  578. package/src/runtime/routes/integrations/twilio.ts +1 -0
  579. package/src/runtime/routes/mcp-auth-routes.ts +283 -9
  580. package/src/runtime/routes/memory-v2-routes.ts +13 -398
  581. package/src/runtime/routes/notification-routes.ts +2 -0
  582. package/src/runtime/routes/oauth-apps.ts +112 -7
  583. package/src/runtime/routes/oauth-commands-routes.ts +1007 -0
  584. package/src/runtime/routes/oauth-connect-routes.ts +67 -5
  585. package/src/runtime/routes/oauth-providers.ts +298 -8
  586. package/src/runtime/routes/platform-routes.ts +336 -0
  587. package/src/runtime/routes/playground/inject-failures.ts +2 -1
  588. package/src/runtime/routes/playground/reset-circuit.ts +2 -1
  589. package/src/runtime/routes/playground/state.ts +2 -1
  590. package/src/runtime/routes/publish-routes.ts +221 -0
  591. package/src/runtime/routes/schedule-routes.ts +82 -0
  592. package/src/runtime/routes/sequence-routes.ts +291 -0
  593. package/src/runtime/routes/settings-routes.ts +2 -10
  594. package/src/runtime/routes/skills-routes.ts +31 -1
  595. package/src/runtime/routes/stt-routes.ts +240 -3
  596. package/src/runtime/routes/surface-action-routes.ts +43 -7
  597. package/src/runtime/routes/tts-routes.ts +67 -0
  598. package/src/runtime/routes/types.ts +32 -0
  599. package/src/runtime/routes/user-routes-cli.ts +243 -0
  600. package/src/runtime/routes/webhook-routes.ts +165 -0
  601. package/src/runtime/sync/resource-sync-events.ts +25 -0
  602. package/src/runtime/sync/sync-publisher.test.ts +105 -0
  603. package/src/runtime/sync/sync-publisher.ts +21 -0
  604. package/src/schedule/scheduler.ts +200 -123
  605. package/src/security/__tests__/provider-key-env-fallback.test.ts +12 -6
  606. package/src/security/secret-patterns.ts +3 -0
  607. package/src/sequence/engine.ts +38 -40
  608. package/src/subagent/manager.ts +20 -15
  609. package/src/tools/browser/__tests__/browser-execution-acquire.test.ts +206 -0
  610. package/src/tools/browser/browser-execution.ts +15 -4
  611. package/src/tools/browser/cdp-client/__tests__/factory.test.ts +174 -0
  612. package/src/tools/browser/cdp-client/cdp-inspect/__tests__/ws-transport.test.ts +16 -13
  613. package/src/tools/browser/cdp-client/extension-cdp-client.ts +24 -1
  614. package/src/tools/browser/cdp-client/factory.ts +66 -5
  615. package/src/tools/browser/runtime-check.ts +77 -0
  616. package/src/tools/memory/register.test.ts +3 -3
  617. package/src/tools/memory/register.ts +9 -1
  618. package/src/tools/network/__tests__/web-search.test.ts +156 -0
  619. package/src/tools/network/web-search.ts +280 -37
  620. package/src/tools/permission-checker.ts +13 -5
  621. package/src/tools/subagent/spawn.ts +3 -3
  622. package/src/tools/terminal/shell.ts +44 -0
  623. package/src/usage/attribution.ts +3 -2
  624. package/src/util/pricing.ts +86 -160
  625. package/src/watcher/__tests__/engine.test.ts +301 -0
  626. package/src/watcher/constants.ts +7 -0
  627. package/src/watcher/engine.ts +90 -90
  628. package/src/workspace/migrations/046-seed-conversation-starters-callsite.ts +6 -9
  629. package/src/workspace/migrations/054-seed-recall-callsite.ts +10 -1
  630. package/src/workspace/migrations/057-repair-stale-gemini-model-ids.ts +28 -4
  631. package/src/workspace/migrations/069-seed-onboarding-threads.ts +8 -2
  632. package/src/workspace/migrations/072-seed-reply-suggestion-callsite.ts +104 -0
  633. package/src/workspace/migrations/073-repair-recall-callsite-empty-profile.ts +93 -0
  634. package/src/workspace/migrations/074-drop-deprecated-secret-detection-keys.ts +117 -0
  635. package/src/workspace/migrations/075-memory-v2-bm25-b-default-reembed.ts +61 -0
  636. package/src/workspace/migrations/076-drop-services-inference-mode.ts +62 -0
  637. package/src/workspace/migrations/077-seed-memory-router-callsite.ts +89 -0
  638. package/src/workspace/migrations/078-release-notes-tavily-web-search.ts +66 -0
  639. package/src/workspace/migrations/079-home-feed-notification-only.ts +197 -0
  640. package/src/workspace/migrations/080-restrict-vercel-api-token-metadata.ts +182 -0
  641. package/src/workspace/migrations/081-backfill-bash-allowed-tools-for-injection-credentials.ts +160 -0
  642. package/src/workspace/migrations/082-backfill-managed-profile-labels.ts +154 -0
  643. package/src/workspace/migrations/registry.ts +22 -0
  644. package/src/workspace/migrations/runner.ts +13 -2
  645. package/src/workspace/migrations/types.ts +13 -3
  646. package/src/workspace/provider-commit-message-generator.ts +3 -2
  647. package/src/__tests__/context-search-pkb-source.test.ts +0 -498
  648. package/src/__tests__/credentials-cli.test.ts +0 -1225
  649. package/src/__tests__/memory-admin-recall.test.ts +0 -213
  650. package/src/approvals/__tests__/guardian-feed-event.test.ts +0 -303
  651. package/src/cli/commands/__tests__/email-download.test.ts +0 -260
  652. package/src/cli/commands/__tests__/email-list.test.ts +0 -216
  653. package/src/cli/commands/__tests__/email-register.test.ts +0 -186
  654. package/src/cli/commands/__tests__/email-send.test.ts +0 -416
  655. package/src/cli/commands/__tests__/email-status.test.ts +0 -185
  656. package/src/cli/commands/__tests__/email-unregister.test.ts +0 -168
  657. package/src/cli/commands/__tests__/routes.test.ts +0 -562
  658. package/src/cli/commands/__tests__/stt-transcribe.test.ts +0 -454
  659. package/src/cli/commands/autonomy.ts +0 -365
  660. package/src/cli/commands/memory.ts +0 -424
  661. package/src/cli/commands/oauth/__tests__/connect.test.ts +0 -947
  662. package/src/cli/commands/oauth/__tests__/disconnect.test.ts +0 -686
  663. package/src/cli/commands/oauth/__tests__/mode.test.ts +0 -632
  664. package/src/cli/commands/oauth/__tests__/ping.test.ts +0 -631
  665. package/src/cli/commands/oauth/__tests__/providers-delete.test.ts +0 -573
  666. package/src/cli/commands/oauth/__tests__/providers-register.test.ts +0 -330
  667. package/src/cli/commands/oauth/__tests__/providers-update.test.ts +0 -521
  668. package/src/cli/commands/oauth/__tests__/status.test.ts +0 -551
  669. package/src/cli/commands/oauth/__tests__/token.test.ts +0 -420
  670. package/src/cli/lib/daemon-avatar-client.ts +0 -37
  671. package/src/config/bundled-skills/contacts/tools/contact-upsert.ts +0 -87
  672. package/src/config/bundled-skills/messaging/tools/__tests__/messaging-feed-events.test.ts +0 -207
  673. package/src/daemon/__tests__/conversation-feed-event.test.ts +0 -304
  674. package/src/heartbeat/__tests__/heartbeat-feed-event.test.ts +0 -233
  675. package/src/home/__tests__/assistant-feed-authoring.test.ts +0 -156
  676. package/src/home/__tests__/emit-feed-event.test.ts +0 -169
  677. package/src/home/__tests__/feed-population-integration.test.ts +0 -312
  678. package/src/home/__tests__/feed-scheduler.test.ts +0 -222
  679. package/src/home/__tests__/phase5-exit-criteria.test.ts +0 -229
  680. package/src/home/__tests__/platform-gmail-digest.test.ts +0 -222
  681. package/src/home/__tests__/rollup-producer.test.ts +0 -507
  682. package/src/home/assistant-feed-authoring.ts +0 -135
  683. package/src/home/emit-feed-event.ts +0 -169
  684. package/src/home/feed-scheduler.ts +0 -281
  685. package/src/home/platform-gmail-digest.ts +0 -163
  686. package/src/home/rewrite-command-preview.ts +0 -66
  687. package/src/home/rewrite-feed-title.ts +0 -58
  688. package/src/home/rollup-producer.ts +0 -426
  689. package/src/memory/admin.ts +0 -326
  690. package/src/memory/context-search/sources/pkb.ts +0 -476
  691. package/src/memory/graph/compaction.ts +0 -299
  692. /package/src/cli/{commands → lib}/cache-fs.ts +0 -0
@@ -14,9 +14,12 @@ import { ROUTES as APP_ROUTES } from "./app-routes.js";
14
14
  import { ROUTES as APPROVAL_ROUTES } from "./approval-routes.js";
15
15
  import { ROUTES as ATTACHMENT_ROUTES } from "./attachment-routes.js";
16
16
  import { ROUTES as AUDIO_ROUTES } from "./audio-routes.js";
17
+ import { ROUTES as AUDIT_ROUTES } from "./audit-routes.js";
18
+ import { ROUTES as AUTH_ROUTES } from "./auth-routes.js";
17
19
  import { ROUTES as AVATAR_ROUTES } from "./avatar-routes.js";
18
20
  import { ROUTES as BACKGROUND_TOOL_ROUTES } from "./background-tool-routes.js";
19
21
  import { ROUTES as BACKUP_ROUTES } from "./backup-routes.js";
22
+ import { ROUTES as BOOKMARK_ROUTES } from "./bookmark-routes.js";
20
23
  import { ROUTES as BRAIN_GRAPH_ROUTES } from "./brain-graph-routes.js";
21
24
  import { ROUTES as BROWSER_ROUTES } from "./browser-routes.js";
22
25
  import { ROUTES as BTW_ROUTES } from "./btw-routes.js";
@@ -31,18 +34,23 @@ import { CONTACT_PROMPT_ROUTES } from "./contact-prompt-routes.js";
31
34
  import { ROUTES as CONTACT_ROUTES } from "./contact-routes.js";
32
35
  import { ROUTES as CONVERSATION_ANALYSIS_ROUTES } from "./conversation-analysis-routes.js";
33
36
  import { ROUTES as CONVERSATION_ATTENTION_ROUTES } from "./conversation-attention-routes.js";
37
+ import { ROUTES as CONVERSATION_CLI_ROUTES } from "./conversation-cli-routes.js";
34
38
  import { ROUTES as CONVERSATION_LIST_ROUTES } from "./conversation-list-routes.js";
35
39
  import { ROUTES as CONVERSATION_MANAGEMENT_ROUTES } from "./conversation-management-routes.js";
36
40
  import { ROUTES as CONVERSATION_QUERY_ROUTES } from "./conversation-query-routes.js";
37
41
  import { ROUTES as CONVERSATION_MESSAGE_ROUTES } from "./conversation-routes.js";
38
42
  import { ROUTES as CONVERSATION_STARTER_ROUTES } from "./conversation-starter-routes.js";
43
+ import { ROUTES as CONVERSATIONS_IMPORT_ROUTES } from "./conversations-import-routes.js";
39
44
  import { ROUTES as CREDENTIAL_PROMPT_ROUTES } from "./credential-prompt-routes.js";
45
+ import { ROUTES as CREDENTIAL_ROUTES } from "./credential-routes.js";
40
46
  import { ROUTES as DEBUG_BASH_ROUTES } from "./debug-bash-routes.js";
41
47
  import { ROUTES as DEBUG_ROUTES } from "./debug-routes.js";
42
48
  import { ROUTES as DEFER_ROUTES } from "./defer-routes.js";
43
49
  import { ROUTES as DIAGNOSTICS_ROUTES } from "./diagnostics-routes.js";
44
50
  import { ROUTES as DISK_PRESSURE_ROUTES } from "./disk-pressure-routes.js";
45
51
  import { ROUTES as DOCUMENT_ROUTES } from "./documents-routes.js";
52
+ import { ROUTES as DOMAIN_ROUTES } from "./domain-routes.js";
53
+ import { ROUTES as EMAIL_ROUTES } from "./email-routes.js";
46
54
  import { ROUTES as EVENTS_ROUTES } from "./events-routes.js";
47
55
  import { ROUTES as FILING_ROUTES } from "./filing-routes.js";
48
56
  import { ROUTES as GATEWAY_LOG_ROUTES } from "./gateway-log-routes.js";
@@ -59,6 +67,10 @@ import { ROUTES as HOST_CU_ROUTES } from "./host-cu-routes.js";
59
67
  import { ROUTES as HOST_FILE_ROUTES } from "./host-file-routes.js";
60
68
  import { ROUTES as HOST_TRANSFER_ROUTES } from "./host-transfer-routes.js";
61
69
  import { ROUTES as IDENTITY_ROUTES } from "./identity-routes.js";
70
+ import { ROUTES as IMAGE_GENERATION_ROUTES } from "./image-generation-routes.js";
71
+ import { ROUTES as INFERENCE_PROFILE_SESSION_ROUTES } from "./inference-profile-session-routes.js";
72
+ import { ROUTES as INFERENCE_PROVIDER_CONNECTION_ROUTES } from "./inference-provider-connection-routes.js";
73
+ import { ROUTES as INFERENCE_SEND_ROUTES } from "./inference-send-routes.js";
62
74
  import { ROUTES as SLACK_CHANNEL_ROUTES } from "./integrations/slack/channel.js";
63
75
  import { ROUTES as SLACK_SHARE_ROUTES } from "./integrations/slack/share.js";
64
76
  import { ROUTES as TELEGRAM_ROUTES } from "./integrations/telegram.js";
@@ -76,15 +88,19 @@ import { ROUTES as MIGRATION_ROLLBACK_ROUTES } from "./migration-rollback-routes
76
88
  import { ROUTES as MIGRATION_ROUTES } from "./migration-routes.js";
77
89
  import { ROUTES as NOTIFICATION_ROUTES } from "./notification-routes.js";
78
90
  import { ROUTES as OAUTH_APPS_ROUTES } from "./oauth-apps.js";
91
+ import { ROUTES as OAUTH_COMMANDS_ROUTES } from "./oauth-commands-routes.js";
79
92
  import { ROUTES as OAUTH_CONNECT_ROUTES } from "./oauth-connect-routes.js";
80
93
  import { ROUTES as OAUTH_PROVIDERS_ROUTES } from "./oauth-providers.js";
94
+ import { ROUTES as PLATFORM_ROUTES } from "./platform-routes.js";
81
95
  import { ROUTES as PLAYGROUND_ROUTES } from "./playground/index.js";
82
96
  import { ROUTES as PROFILER_ROUTES } from "./profiler-routes.js";
83
97
  import { ROUTES as PS_ROUTES } from "./ps-routes.js";
98
+ import { ROUTES as PUBLISH_ROUTES } from "./publish-routes.js";
84
99
  import { ROUTES as RECORDING_ROUTES } from "./recording-routes.js";
85
100
  import { ROUTES as RENAME_CONVERSATION_ROUTES } from "./rename-conversation-routes.js";
86
101
  import { ROUTES as SCHEDULE_ROUTES } from "./schedule-routes.js";
87
102
  import { ROUTES as SECRET_ROUTES } from "./secret-routes.js";
103
+ import { ROUTES as SEQUENCE_ROUTES } from "./sequence-routes.js";
88
104
  import { ROUTES as SETTINGS_ROUTES } from "./settings-routes.js";
89
105
  import { ROUTES as SKILL_ROUTES } from "./skills-routes.js";
90
106
  import { ROUTES as STT_ROUTES } from "./stt-routes.js";
@@ -102,8 +118,10 @@ import { ROUTES as UI_REQUEST_ROUTES } from "./ui-request-routes.js";
102
118
  import { ROUTES as UPGRADE_BROADCAST_ROUTES } from "./upgrade-broadcast-routes.js";
103
119
  import { ROUTES as USAGE_ROUTES } from "./usage-routes.js";
104
120
  import { ROUTES as USER_ROUTES } from "./user-routes.js";
121
+ import { ROUTES as USER_ROUTES_CLI } from "./user-routes-cli.js";
105
122
  import { ROUTES as WAKE_CONVERSATION_ROUTES } from "./wake-conversation-routes.js";
106
123
  import { ROUTES as WATCHER_ROUTES } from "./watcher-routes.js";
124
+ import { ROUTES as WEBHOOK_ROUTES } from "./webhook-routes.js";
107
125
  import { ROUTES as WIPE_CONVERSATION_ROUTES } from "./wipe-conversation-routes.js";
108
126
  import { ROUTES as WORK_ITEM_ROUTES } from "./work-items-routes.js";
109
127
  import { ROUTES as WORKSPACE_COMMIT_ROUTES } from "./workspace-commit-routes.js";
@@ -116,9 +134,12 @@ export const ROUTES: RouteDefinition[] = [
116
134
  ...APP_ROUTES,
117
135
  ...APPROVAL_ROUTES,
118
136
  ...AUDIO_ROUTES,
137
+ ...AUDIT_ROUTES,
138
+ ...AUTH_ROUTES,
119
139
  ...AVATAR_ROUTES,
120
140
  ...BACKGROUND_TOOL_ROUTES,
121
141
  ...BACKUP_ROUTES,
142
+ ...BOOKMARK_ROUTES,
122
143
  ...CACHE_ROUTES,
123
144
  ...CALL_ROUTES,
124
145
  ...CHANNEL_ROUTES,
@@ -132,11 +153,14 @@ export const ROUTES: RouteDefinition[] = [
132
153
  ...CONTACT_ROUTES,
133
154
  ...CONVERSATION_ANALYSIS_ROUTES,
134
155
  ...CONVERSATION_ATTENTION_ROUTES,
156
+ ...CONVERSATION_CLI_ROUTES,
135
157
  ...CONVERSATION_LIST_ROUTES,
136
158
  ...CONVERSATION_MANAGEMENT_ROUTES,
159
+ ...CONVERSATIONS_IMPORT_ROUTES,
137
160
  ...CONVERSATION_MESSAGE_ROUTES,
138
161
  ...CONSOLIDATION_ROUTES,
139
162
  ...CREDENTIAL_PROMPT_ROUTES,
163
+ ...CREDENTIAL_ROUTES,
140
164
  ...DEFER_ROUTES,
141
165
  ...CONVERSATION_QUERY_ROUTES,
142
166
  ...CONVERSATION_STARTER_ROUTES,
@@ -144,7 +168,9 @@ export const ROUTES: RouteDefinition[] = [
144
168
  ...DEBUG_ROUTES,
145
169
  ...DIAGNOSTICS_ROUTES,
146
170
  ...DISK_PRESSURE_ROUTES,
171
+ ...DOMAIN_ROUTES,
147
172
  ...DOCUMENT_ROUTES,
173
+ ...EMAIL_ROUTES,
148
174
  ...EVENTS_ROUTES,
149
175
  ...FILING_ROUTES,
150
176
  ...GATEWAY_LOG_ROUTES,
@@ -154,6 +180,7 @@ export const ROUTES: RouteDefinition[] = [
154
180
  ...HEARTBEAT_ROUTES,
155
181
  ...HOME_FEED_ROUTES,
156
182
  ...HOME_STATE_ROUTES,
183
+ ...IMAGE_GENERATION_ROUTES,
157
184
  ...HOST_APP_CONTROL_ROUTES,
158
185
  ...HOST_BASH_ROUTES,
159
186
  ...HOST_BROWSER_ROUTES,
@@ -161,6 +188,9 @@ export const ROUTES: RouteDefinition[] = [
161
188
  ...HOST_FILE_ROUTES,
162
189
  ...HOST_TRANSFER_ROUTES,
163
190
  ...IDENTITY_ROUTES,
191
+ ...INFERENCE_PROFILE_SESSION_ROUTES,
192
+ ...INFERENCE_PROVIDER_CONNECTION_ROUTES,
193
+ ...INFERENCE_SEND_ROUTES,
164
194
  ...INTERFACE_ROUTES,
165
195
  ...INTERNAL_OAUTH_ROUTES,
166
196
  ...MCP_AUTH_ROUTES,
@@ -174,10 +204,13 @@ export const ROUTES: RouteDefinition[] = [
174
204
  ...MIGRATION_ROUTES,
175
205
  ...NOTIFICATION_ROUTES,
176
206
  ...OAUTH_APPS_ROUTES,
207
+ ...OAUTH_COMMANDS_ROUTES,
177
208
  ...OAUTH_PROVIDERS_ROUTES,
209
+ ...PLATFORM_ROUTES,
178
210
  ...PLAYGROUND_ROUTES,
179
211
  ...PROFILER_ROUTES,
180
212
  ...PS_ROUTES,
213
+ ...PUBLISH_ROUTES,
181
214
  ...RECORDING_ROUTES,
182
215
  ...RENAME_CONVERSATION_ROUTES,
183
216
  ...SCHEDULE_ROUTES,
@@ -204,10 +237,13 @@ export const ROUTES: RouteDefinition[] = [
204
237
  ...VERCEL_ROUTES,
205
238
  ...WORK_ITEM_ROUTES,
206
239
  ...WATCHER_ROUTES,
240
+ ...WEBHOOK_ROUTES,
207
241
  ...WIPE_CONVERSATION_ROUTES,
208
242
  ...WORKSPACE_COMMIT_ROUTES,
209
243
  ...WAKE_CONVERSATION_ROUTES,
210
244
  ...WORKSPACE_ROUTES,
245
+ ...SEQUENCE_ROUTES,
246
+ ...USER_ROUTES_CLI,
211
247
 
212
248
  // User-defined routes under /x/* — MUST be last so built-in routes
213
249
  // always take priority over the catch-all pattern.
@@ -0,0 +1,312 @@
1
+ /**
2
+ * Shared business-logic handler for inference-profile session open/close/list.
3
+ *
4
+ * This module is the single source of truth for:
5
+ * - setInferenceProfileSession — open (or replace) a session-backed profile
6
+ * - closeInferenceProfileSession — close the active session
7
+ * - listInferenceProfileSessionsWithRemaining — list active sessions with
8
+ * remaining TTL
9
+ *
10
+ * Route handlers in `inference-profile-session-routes.ts` (PR 4) and the IPC
11
+ * route equivalents delegate to these functions rather than duplicating the
12
+ * logic.
13
+ */
14
+
15
+ import { randomUUID } from "node:crypto";
16
+
17
+ import { loadConfig } from "../../config/loader.js";
18
+ import {
19
+ getConversation,
20
+ listActiveInferenceProfileSessions,
21
+ setConversationInferenceProfileSession,
22
+ } from "../../memory/conversation-crud.js";
23
+ import { resolveConversationId } from "../../memory/conversation-key-store.js";
24
+ import { getLogger } from "../../util/logger.js";
25
+ import { buildAssistantEvent } from "../assistant-event.js";
26
+ import { assistantEventHub } from "../assistant-event-hub.js";
27
+ import { BadRequestError, NotFoundError } from "./errors.js";
28
+
29
+ const log = getLogger("inference-profile-session-handler");
30
+
31
+ // ---------------------------------------------------------------------------
32
+ // Types
33
+ // ---------------------------------------------------------------------------
34
+
35
+ export interface InferenceProfileSessionResult {
36
+ conversationId: string;
37
+ profile: string | null;
38
+ sessionId: string | null;
39
+ expiresAt: number | null;
40
+ ttlSeconds: number | null | undefined;
41
+ replaced: {
42
+ profile: string | null;
43
+ sessionId: string | null;
44
+ expiresAt: number | null;
45
+ } | null;
46
+ }
47
+
48
+ // ---------------------------------------------------------------------------
49
+ // setInferenceProfileSession
50
+ // ---------------------------------------------------------------------------
51
+
52
+ /**
53
+ * Open (or replace) a session-backed inference-profile override for a
54
+ * conversation.
55
+ *
56
+ * - `profile === null`: clears any existing override (session or non-session).
57
+ * - `profile` is a string: validates it against `llm.profiles`, then applies
58
+ * it. TTL handling:
59
+ * - `ttlSeconds` is a positive number → clamp to
60
+ * `[1, llm.profileSession.maxTtlSeconds]`, mint a sessionId, compute
61
+ * expiresAt.
62
+ * - `ttlSeconds === null` → apply profile without a session (sticky, no
63
+ * expiry). sessionId and expiresAt are both null.
64
+ * - `ttlSeconds === undefined` → same as null — sticky, no expiry.
65
+ *
66
+ * Returns `replaced` with the prior active session's details when one existed,
67
+ * or `null` when no active session was replaced.
68
+ */
69
+ export async function setInferenceProfileSession({
70
+ conversationId,
71
+ profile,
72
+ ttlSeconds,
73
+ sessionId: callerSessionId,
74
+ }: {
75
+ conversationId: string;
76
+ profile: string | null;
77
+ ttlSeconds?: number | null;
78
+ sessionId?: string;
79
+ }): Promise<InferenceProfileSessionResult> {
80
+ const resolvedId = resolveConversationId(conversationId) ?? conversationId;
81
+ const conversation = getConversation(resolvedId);
82
+ if (!conversation) {
83
+ throw new NotFoundError(`Conversation ${conversationId} not found`);
84
+ }
85
+
86
+ // Capture the prior active session (if any) so we can report it as
87
+ // `replaced` in the response.
88
+ let replaced: InferenceProfileSessionResult["replaced"] = null;
89
+ if (
90
+ conversation.inferenceProfileSessionId != null &&
91
+ (conversation.inferenceProfileExpiresAt == null ||
92
+ conversation.inferenceProfileExpiresAt > Date.now())
93
+ ) {
94
+ replaced = {
95
+ profile: conversation.inferenceProfile,
96
+ sessionId: conversation.inferenceProfileSessionId,
97
+ expiresAt: conversation.inferenceProfileExpiresAt,
98
+ };
99
+ }
100
+
101
+ // --- Clear path ---
102
+ if (profile === null) {
103
+ // Idempotency: skip the write and event when the row is already fully
104
+ // cleared (no profile, no session, no expiry). This keeps `updatedAt`
105
+ // stable and avoids emitting duplicate `conversation_inference_profile_updated`
106
+ // events for retried/repeated clears, matching the behavior of
107
+ // `closeInferenceProfileSession` when there is no active session.
108
+ if (
109
+ conversation.inferenceProfile == null &&
110
+ conversation.inferenceProfileSessionId == null &&
111
+ conversation.inferenceProfileExpiresAt == null
112
+ ) {
113
+ return {
114
+ conversationId: resolvedId,
115
+ profile: null,
116
+ sessionId: null,
117
+ expiresAt: null,
118
+ ttlSeconds: null,
119
+ replaced: null,
120
+ };
121
+ }
122
+ setConversationInferenceProfileSession(resolvedId, null, null, null);
123
+ await assistantEventHub
124
+ .publish(
125
+ buildAssistantEvent(
126
+ {
127
+ type: "conversation_inference_profile_updated",
128
+ conversationId: resolvedId,
129
+ profile: null,
130
+ sessionId: null,
131
+ expiresAt: null,
132
+ },
133
+ resolvedId,
134
+ ),
135
+ )
136
+ .catch((err) => {
137
+ log.warn(
138
+ { err, conversationId: resolvedId },
139
+ "Failed to publish conversation_inference_profile_updated event",
140
+ );
141
+ });
142
+ return {
143
+ conversationId: resolvedId,
144
+ profile: null,
145
+ sessionId: null,
146
+ expiresAt: null,
147
+ ttlSeconds: null,
148
+ replaced,
149
+ };
150
+ }
151
+
152
+ // --- Validate profile ---
153
+ const profiles = loadConfig().llm?.profiles ?? {};
154
+ if (!Object.prototype.hasOwnProperty.call(profiles, profile)) {
155
+ throw new BadRequestError(
156
+ `Profile "${profile}" is not defined in llm.profiles`,
157
+ );
158
+ }
159
+
160
+ // --- Compute session fields based on ttlSeconds ---
161
+ let newSessionId: string | null;
162
+ let newExpiresAt: number | null;
163
+ let clamped: number | null | undefined;
164
+
165
+ if (typeof ttlSeconds === "number") {
166
+ const maxTtl = loadConfig().llm?.profileSession?.maxTtlSeconds ?? 43200;
167
+ clamped = Math.min(Math.max(1, ttlSeconds), maxTtl);
168
+ newExpiresAt = Date.now() + clamped * 1000;
169
+ newSessionId = callerSessionId ?? randomUUID();
170
+ } else if (ttlSeconds === null) {
171
+ newExpiresAt = null;
172
+ newSessionId = null;
173
+ clamped = null;
174
+ } else {
175
+ // undefined
176
+ newExpiresAt = null;
177
+ newSessionId = null;
178
+ clamped = undefined;
179
+ }
180
+
181
+ // Skip write and event when nothing has changed.
182
+ if (
183
+ conversation.inferenceProfile === profile &&
184
+ conversation.inferenceProfileSessionId === (newSessionId ?? null) &&
185
+ conversation.inferenceProfileExpiresAt === (newExpiresAt ?? null)
186
+ ) {
187
+ return {
188
+ conversationId: resolvedId,
189
+ profile,
190
+ sessionId: newSessionId ?? null,
191
+ expiresAt: newExpiresAt ?? null,
192
+ ttlSeconds: clamped,
193
+ replaced,
194
+ };
195
+ }
196
+
197
+ setConversationInferenceProfileSession(
198
+ resolvedId,
199
+ profile,
200
+ newSessionId ?? null,
201
+ newExpiresAt ?? null,
202
+ );
203
+
204
+ await assistantEventHub
205
+ .publish(
206
+ buildAssistantEvent(
207
+ {
208
+ type: "conversation_inference_profile_updated",
209
+ conversationId: resolvedId,
210
+ profile,
211
+ sessionId: newSessionId ?? null,
212
+ expiresAt: newExpiresAt ?? null,
213
+ },
214
+ resolvedId,
215
+ ),
216
+ )
217
+ .catch((err) => {
218
+ log.warn(
219
+ { err, conversationId: resolvedId },
220
+ "Failed to publish conversation_inference_profile_updated event",
221
+ );
222
+ });
223
+
224
+ return {
225
+ conversationId: resolvedId,
226
+ profile,
227
+ sessionId: newSessionId ?? null,
228
+ expiresAt: newExpiresAt ?? null,
229
+ ttlSeconds: clamped,
230
+ replaced,
231
+ };
232
+ }
233
+
234
+ // ---------------------------------------------------------------------------
235
+ // closeInferenceProfileSession
236
+ // ---------------------------------------------------------------------------
237
+
238
+ /**
239
+ * Close the active session-backed inference-profile override for a
240
+ * conversation.
241
+ *
242
+ * Only closes session-backed overrides (rows with a non-null
243
+ * `inferenceProfileSessionId`). Sticky overrides set by the composer picker
244
+ * (profile present, no sessionId) are left untouched — close is not the right
245
+ * verb for those and callers should use the PUT endpoint to clear them.
246
+ *
247
+ * Returns `noop: true` when there was no active session to close.
248
+ */
249
+ export async function closeInferenceProfileSession(
250
+ conversationId: string,
251
+ ): Promise<{
252
+ conversationId: string;
253
+ closed: { profile: string | null; sessionId: string | null } | null;
254
+ noop: boolean;
255
+ }> {
256
+ const resolvedId = resolveConversationId(conversationId) ?? conversationId;
257
+ const conversation = getConversation(resolvedId);
258
+ if (!conversation) {
259
+ throw new NotFoundError(`Conversation ${conversationId} not found`);
260
+ }
261
+
262
+ const hasActiveSession =
263
+ conversation.inferenceProfileSessionId != null &&
264
+ (conversation.inferenceProfileExpiresAt == null ||
265
+ conversation.inferenceProfileExpiresAt > Date.now());
266
+
267
+ if (!hasActiveSession) {
268
+ return { conversationId: resolvedId, closed: null, noop: true };
269
+ }
270
+
271
+ const result = await setInferenceProfileSession({
272
+ conversationId: resolvedId,
273
+ profile: null,
274
+ });
275
+ return {
276
+ conversationId: result.conversationId,
277
+ closed:
278
+ result.replaced !== null
279
+ ? {
280
+ profile: result.replaced.profile,
281
+ sessionId: result.replaced.sessionId,
282
+ }
283
+ : null,
284
+ noop: result.replaced === null,
285
+ };
286
+ }
287
+
288
+ // ---------------------------------------------------------------------------
289
+ // listInferenceProfileSessionsWithRemaining
290
+ // ---------------------------------------------------------------------------
291
+
292
+ /**
293
+ * List all active (non-expired) session-backed inference-profile overrides,
294
+ * augmented with `remainingSeconds` relative to `Date.now()`.
295
+ *
296
+ * Pass `conversationId` to narrow to a single conversation.
297
+ */
298
+ export function listInferenceProfileSessionsWithRemaining(
299
+ conversationId?: string,
300
+ ): Array<{
301
+ conversationId: string;
302
+ conversationTitle: string | null;
303
+ profile: string;
304
+ sessionId: string;
305
+ expiresAt: number;
306
+ remainingSeconds: number;
307
+ }> {
308
+ return listActiveInferenceProfileSessions(conversationId).map((row) => ({
309
+ ...row,
310
+ remainingSeconds: Math.max(0, Math.floor((row.expiresAt - Date.now()) / 1000)),
311
+ }));
312
+ }
@@ -0,0 +1,98 @@
1
+ /**
2
+ * Inference profile session reaper.
3
+ *
4
+ * Periodically scans the `conversations` table for rows whose
5
+ * session-backed inference profile has expired (`inference_profile_expires_at`
6
+ * is in the past) and clears them. For each cleared session a
7
+ * `conversation_inference_profile_updated` event is published so connected
8
+ * clients receive an immediate update without polling.
9
+ *
10
+ * The reaper runs every 30 seconds and is started alongside the other
11
+ * background sweeps in `http-server.ts`.
12
+ */
13
+
14
+ import { clearExpiredInferenceProfiles } from "../../memory/conversation-crud.js";
15
+ import { getLogger } from "../../util/logger.js";
16
+ import { buildAssistantEvent } from "../assistant-event.js";
17
+ import { assistantEventHub } from "../assistant-event-hub.js";
18
+
19
+ const log = getLogger("inference-profile-session-reaper");
20
+
21
+ /** Interval at which the reaper runs (30 seconds). */
22
+ const REAPER_INTERVAL_MS = 30_000;
23
+
24
+ /** Timer handle for the reaper so it can be stopped in tests and shutdown. */
25
+ let reaperTimer: ReturnType<typeof setInterval> | null = null;
26
+
27
+ /** Guard against overlapping reaper runs. */
28
+ let reaperInProgress = false;
29
+
30
+ /**
31
+ * Tick the inference profile session reaper once.
32
+ *
33
+ * Clears all conversations whose session-backed inference profile has expired
34
+ * and emits a `conversation_inference_profile_updated` event for each one.
35
+ * Exported for direct use in tests.
36
+ */
37
+ export function tickInferenceProfileReaper(): void {
38
+ const now = Date.now();
39
+ const cleared = clearExpiredInferenceProfiles(now);
40
+ for (const { conversationId } of cleared) {
41
+ assistantEventHub
42
+ .publish(
43
+ buildAssistantEvent(
44
+ {
45
+ type: "conversation_inference_profile_updated",
46
+ conversationId,
47
+ profile: null,
48
+ sessionId: null,
49
+ expiresAt: null,
50
+ },
51
+ conversationId,
52
+ ),
53
+ )
54
+ .catch((err) => {
55
+ log.warn(
56
+ { err, conversationId },
57
+ "Failed to publish inference profile expiry event",
58
+ );
59
+ });
60
+ }
61
+ if (cleared.length > 0) {
62
+ log.info(
63
+ { count: cleared.length },
64
+ "Inference profile session reaper: cleared expired sessions",
65
+ );
66
+ }
67
+ }
68
+
69
+ /**
70
+ * Start the periodic inference profile session reaper. Idempotent — calling
71
+ * it multiple times reuses the same timer.
72
+ */
73
+ export function startInferenceProfileSessionReaper(): void {
74
+ if (reaperTimer) return;
75
+ reaperTimer = setInterval(() => {
76
+ if (reaperInProgress) return;
77
+ reaperInProgress = true;
78
+ try {
79
+ tickInferenceProfileReaper();
80
+ } catch (err) {
81
+ log.error({ err }, "Inference profile session reaper failed");
82
+ } finally {
83
+ reaperInProgress = false;
84
+ }
85
+ }, REAPER_INTERVAL_MS);
86
+ }
87
+
88
+ /**
89
+ * Stop the periodic inference profile session reaper. Used in tests and
90
+ * shutdown.
91
+ */
92
+ export function stopInferenceProfileSessionReaper(): void {
93
+ if (reaperTimer) {
94
+ clearInterval(reaperTimer);
95
+ reaperTimer = null;
96
+ }
97
+ reaperInProgress = false;
98
+ }