@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
@@ -0,0 +1,117 @@
1
+ import {
2
+ appendFileSync,
3
+ existsSync,
4
+ readFileSync,
5
+ writeFileSync,
6
+ } from "node:fs";
7
+ import { join } from "node:path";
8
+
9
+ import { getLogger } from "../../util/logger.js";
10
+ import type { WorkspaceMigration } from "./types.js";
11
+
12
+ const log = getLogger(
13
+ "workspace-migration-074-drop-deprecated-secret-detection-keys",
14
+ );
15
+
16
+ const MIGRATION_ID = "074-drop-deprecated-secret-detection-keys";
17
+ const NOTICE_MARKER = `<!-- release-note-id:${MIGRATION_ID} -->`;
18
+
19
+ function buildNotice(previousAction: string): string {
20
+ return `${NOTICE_MARKER}
21
+ ## Heads-up: tool-output secret scanning was retired
22
+
23
+ Your previous \`secretDetection.action\` setting was \`"${previousAction}"\`,
24
+ which used to gate or redact tool output containing high-entropy strings or
25
+ matches against custom regex patterns. That post-execution scanning layer has
26
+ been removed because it was false-positive prone and prevented the assistant
27
+ from acting on values it had legitimately fetched.
28
+
29
+ Prefix-based ingress detection on user messages is still active
30
+ (\`secretDetection.enabled\` / \`secretDetection.blockIngress\`), and the
31
+ \`secretDetection.entropyThreshold\` and \`secretDetection.customPatterns\`
32
+ fields have been removed from your config. If you relied on the old behavior,
33
+ please reach out so we can find a better solution for your use case.
34
+ `;
35
+ }
36
+
37
+ export const dropDeprecatedSecretDetectionKeysMigration: WorkspaceMigration = {
38
+ id: MIGRATION_ID,
39
+ description:
40
+ "Strip removed secretDetection.action / entropyThreshold / customPatterns keys; notify users who had a non-default action policy",
41
+
42
+ run(workspaceDir: string): void {
43
+ const configPath = join(workspaceDir, "config.json");
44
+ if (!existsSync(configPath)) return;
45
+
46
+ let config: Record<string, unknown>;
47
+ try {
48
+ const raw = JSON.parse(readFileSync(configPath, "utf-8"));
49
+ if (!raw || typeof raw !== "object" || Array.isArray(raw)) return;
50
+ config = raw as Record<string, unknown>;
51
+ } catch {
52
+ return;
53
+ }
54
+
55
+ const secretDetection = readObject(config.secretDetection);
56
+ if (secretDetection === null) return;
57
+
58
+ const previousAction =
59
+ typeof secretDetection.action === "string"
60
+ ? secretDetection.action
61
+ : null;
62
+
63
+ let mutated = false;
64
+ for (const key of ["action", "entropyThreshold", "customPatterns"]) {
65
+ if (key in secretDetection) {
66
+ delete secretDetection[key];
67
+ mutated = true;
68
+ }
69
+ }
70
+
71
+ if (mutated) {
72
+ writeFileSync(configPath, JSON.stringify(config, null, 2) + "\n");
73
+ }
74
+
75
+ if (previousAction === "block" || previousAction === "prompt") {
76
+ appendNotice(workspaceDir, previousAction);
77
+ }
78
+ },
79
+
80
+ down(_workspaceDir: string): void {
81
+ // Forward-only: restoring the deleted keys would re-introduce schema
82
+ // warnings without changing runtime behavior — the post-execution scanner
83
+ // they used to drive no longer exists.
84
+ },
85
+ };
86
+
87
+ function appendNotice(workspaceDir: string, previousAction: string): void {
88
+ const updatesPath = join(workspaceDir, "UPDATES.md");
89
+ const notice = buildNotice(previousAction);
90
+
91
+ try {
92
+ if (existsSync(updatesPath)) {
93
+ const existing = readFileSync(updatesPath, "utf-8");
94
+ if (existing.includes(NOTICE_MARKER)) return;
95
+ const prefix = existing.endsWith("\n") ? "\n" : "\n\n";
96
+ appendFileSync(updatesPath, `${prefix}${notice}`, "utf-8");
97
+ } else {
98
+ writeFileSync(updatesPath, notice, "utf-8");
99
+ }
100
+ log.info(
101
+ { path: updatesPath, previousAction },
102
+ "Appended secret-detection retirement notice",
103
+ );
104
+ } catch (err) {
105
+ log.warn(
106
+ { err, path: updatesPath, previousAction },
107
+ "Failed to append secret-detection retirement notice to UPDATES.md",
108
+ );
109
+ }
110
+ }
111
+
112
+ function readObject(value: unknown): Record<string, unknown> | null {
113
+ if (value === null || typeof value !== "object" || Array.isArray(value)) {
114
+ return null;
115
+ }
116
+ return value as Record<string, unknown>;
117
+ }
@@ -0,0 +1,61 @@
1
+ import { randomUUID } from "node:crypto";
2
+ import { existsSync } from "node:fs";
3
+ import { join } from "node:path";
4
+ import { Database } from "bun:sqlite";
5
+
6
+ import type { WorkspaceMigration } from "./types.js";
7
+
8
+ /**
9
+ * Enqueue a one-shot `memory_v2_reembed` job so existing concept pages pick
10
+ * up the new `memory.v2.bm25_b` default (0.4, lowered from 0.75 in PR
11
+ * #29345). `embed_concept_page` bakes `bm25_b` into the stored sparse
12
+ * vectors at write time, so without this nudge workspaces that never pinned
13
+ * the field would silently mix old and new length normalization until a
14
+ * manual reembed.
15
+ */
16
+ export const memoryV2Bm25BDefaultReembedMigration: WorkspaceMigration = {
17
+ id: "075-memory-v2-bm25-b-default-reembed",
18
+ description:
19
+ "Enqueue memory_v2_reembed so existing concept pages pick up the new bm25_b=0.4 default",
20
+
21
+ run(workspaceDir: string): void {
22
+ const dbPath = join(workspaceDir, "data", "db", "assistant.db");
23
+ if (!existsSync(dbPath)) return; // Fresh install — pages will embed at the new default.
24
+
25
+ let db: Database;
26
+ try {
27
+ db = new Database(dbPath);
28
+ } catch {
29
+ return;
30
+ }
31
+
32
+ try {
33
+ const tableRow = db
34
+ .query(
35
+ `SELECT name FROM sqlite_master WHERE type='table' AND name='memory_jobs'`,
36
+ )
37
+ .get();
38
+ if (!tableRow) return;
39
+
40
+ const existing = db
41
+ .query(
42
+ `SELECT id FROM memory_jobs WHERE type='memory_v2_reembed' AND status IN ('pending','running') LIMIT 1`,
43
+ )
44
+ .get();
45
+ if (existing) return;
46
+
47
+ const now = Date.now();
48
+ db.query(
49
+ `INSERT INTO memory_jobs
50
+ (id, type, payload, status, attempts, deferrals, run_after, last_error, created_at, updated_at)
51
+ VALUES (?, 'memory_v2_reembed', '{}', 'pending', 0, 0, ?, NULL, ?, ?)`,
52
+ ).run(randomUUID(), now, now, now);
53
+ } finally {
54
+ db.close();
55
+ }
56
+ },
57
+
58
+ down(_workspaceDir: string): void {
59
+ // Forward-only: the reembed is a one-shot data refresh.
60
+ },
61
+ };
@@ -0,0 +1,62 @@
1
+ import { existsSync, readFileSync, writeFileSync } from "node:fs";
2
+ import { join } from "node:path";
3
+
4
+ import type { WorkspaceMigration } from "./types.js";
5
+
6
+ /**
7
+ * Strip the now-removed `services.inference.mode` field from existing
8
+ * `config.json` files. The field governed the global `managed` vs `your-own`
9
+ * routing toggle that was superseded by the `provider_connections` table. Auth
10
+ * routing is now per-profile via the `provider_connection` reference; there is
11
+ * no longer a schema-level field to store here.
12
+ *
13
+ * If `services.inference` becomes an empty object after stripping, it is left
14
+ * as `{}` — the schema still expects the key to be present (other code walks
15
+ * `config.services.inference`).
16
+ *
17
+ * Idempotent: re-running when `mode` is already absent is a no-op.
18
+ */
19
+ export const dropServicesInferenceModeMigration: WorkspaceMigration = {
20
+ id: "076-drop-services-inference-mode",
21
+ description:
22
+ "Strip services.inference.mode from config.json (mode field removed from schema)",
23
+ run(workspaceDir: string): void {
24
+ const configPath = join(workspaceDir, "config.json");
25
+ if (!existsSync(configPath)) return;
26
+
27
+ let config: Record<string, unknown>;
28
+ try {
29
+ const raw = JSON.parse(readFileSync(configPath, "utf-8"));
30
+ if (!raw || typeof raw !== "object" || Array.isArray(raw)) return;
31
+ config = raw as Record<string, unknown>;
32
+ } catch {
33
+ return;
34
+ }
35
+
36
+ const services = config.services;
37
+ if (
38
+ services === null ||
39
+ typeof services !== "object" ||
40
+ Array.isArray(services)
41
+ )
42
+ return;
43
+
44
+ const inference = (services as Record<string, unknown>).inference;
45
+ if (
46
+ inference === null ||
47
+ typeof inference !== "object" ||
48
+ Array.isArray(inference)
49
+ )
50
+ return;
51
+
52
+ const inferenceObj = inference as Record<string, unknown>;
53
+ if (!("mode" in inferenceObj)) return;
54
+
55
+ delete inferenceObj.mode;
56
+ writeFileSync(configPath, JSON.stringify(config, null, 2) + "\n");
57
+ },
58
+ down(_workspaceDir: string): void {
59
+ // Forward-only: re-adding mode would reintroduce a field the schema no
60
+ // longer recognizes.
61
+ },
62
+ };
@@ -0,0 +1,89 @@
1
+ import { existsSync, readFileSync, writeFileSync } from "node:fs";
2
+ import { join } from "node:path";
3
+
4
+ import type { WorkspaceMigration } from "./types.js";
5
+
6
+ /**
7
+ * Seed `callSites.memoryRouter = { model: "claude-sonnet-4-6",
8
+ * contextWindow: { maxInputTokens: 1000000 } }` so the per-turn memory
9
+ * router runs on Sonnet 4.6 with the 1M context window by default.
10
+ *
11
+ * The router builds a numbered page index in the system prompt; a 1M
12
+ * context window keeps every concept page reachable even on large
13
+ * workspaces, and Sonnet 4.6 is the cheapest 1M-context Anthropic
14
+ * model that handles the routing task well. Without this seed the
15
+ * call site would inherit the workspace default model, which may
16
+ * cap context at 200k and silently truncate the index for large
17
+ * workspaces.
18
+ *
19
+ * Mirrors {@link seedMainAgentOpusCallsiteMigration} (050):
20
+ *
21
+ * 1. Existing workspace (config.json present): merge the seed into
22
+ * `llm.callSites` without overwriting a user-defined override.
23
+ * 2. Fresh install (config.json absent): write a minimal starter
24
+ * config carrying just the seed; `loadConfig()` applies schema
25
+ * defaults to the in-memory config after migrations run.
26
+ *
27
+ * Skipped when:
28
+ * - `VELLUM_DEFAULT_WORKSPACE_CONFIG_PATH` is set (platform overlay wins),
29
+ * - the user already has `llm.callSites.memoryRouter` (any override stays),
30
+ * - the resolved provider is non-Anthropic (those workspaces pick their
31
+ * own equivalent — we don't know which OpenAI/Gemini/Ollama model the
32
+ * operator wants for the routing role).
33
+ */
34
+ export const seedMemoryRouterCallsiteMigration: WorkspaceMigration = {
35
+ id: "077-seed-memory-router-callsite",
36
+ description:
37
+ "Seed callSites.memoryRouter to claude-sonnet-4-6 + 1M context for Anthropic",
38
+ run(workspaceDir: string): void {
39
+ if (process.env.VELLUM_DEFAULT_WORKSPACE_CONFIG_PATH) return;
40
+
41
+ const configPath = join(workspaceDir, "config.json");
42
+ const configExisted = existsSync(configPath);
43
+
44
+ let config: Record<string, unknown> = {};
45
+ if (configExisted) {
46
+ try {
47
+ const raw = JSON.parse(readFileSync(configPath, "utf-8"));
48
+ if (!raw || typeof raw !== "object" || Array.isArray(raw)) return;
49
+ config = raw as Record<string, unknown>;
50
+ } catch {
51
+ return;
52
+ }
53
+ }
54
+
55
+ const llm = readObject(config.llm) ?? {};
56
+ const defaultBlock = readObject(llm.default);
57
+
58
+ const explicitProvider = readString(defaultBlock?.provider);
59
+ if (explicitProvider !== undefined && explicitProvider !== "anthropic") {
60
+ return;
61
+ }
62
+
63
+ const callSites = readObject(llm.callSites) ?? {};
64
+ if (readObject(callSites.memoryRouter) !== null) return;
65
+
66
+ callSites.memoryRouter = {
67
+ model: "claude-sonnet-4-6",
68
+ contextWindow: { maxInputTokens: 1_000_000 },
69
+ };
70
+ llm.callSites = callSites;
71
+ config.llm = llm;
72
+ writeFileSync(configPath, JSON.stringify(config, null, 2) + "\n");
73
+ },
74
+ down(_workspaceDir: string): void {
75
+ // Forward-only: removing the seed would downgrade the router to the
76
+ // workspace default model on every re-run, defeating the goal.
77
+ },
78
+ };
79
+
80
+ function readObject(value: unknown): Record<string, unknown> | null {
81
+ if (value === null || typeof value !== "object" || Array.isArray(value)) {
82
+ return null;
83
+ }
84
+ return value as Record<string, unknown>;
85
+ }
86
+
87
+ function readString(value: unknown): string | undefined {
88
+ return typeof value === "string" && value.length > 0 ? value : undefined;
89
+ }
@@ -0,0 +1,66 @@
1
+ import {
2
+ appendFileSync,
3
+ existsSync,
4
+ readFileSync,
5
+ writeFileSync,
6
+ } from "node:fs";
7
+ import { join } from "node:path";
8
+
9
+ import { getLogger } from "../../util/logger.js";
10
+ import type { WorkspaceMigration } from "./types.js";
11
+
12
+ const log = getLogger(
13
+ "workspace-migration-078-release-notes-tavily-web-search",
14
+ );
15
+
16
+ const MIGRATION_ID = "078-release-notes-tavily-web-search";
17
+ const MARKER = `<!-- release-note-id:${MIGRATION_ID} -->`;
18
+
19
+ const RELEASE_NOTE = `${MARKER}
20
+ ## Tavily web search
21
+
22
+ Tavily is now available as a web search provider. Add your Tavily API key in
23
+ Settings → Models & Services, or run \`assistant keys set tavily <key>\`, then
24
+ select Tavily for Web Search.
25
+ `;
26
+
27
+ export const releaseNotesTavilyWebSearchMigration: WorkspaceMigration = {
28
+ id: MIGRATION_ID,
29
+ description: "Append release notes for Tavily web search to UPDATES.md",
30
+
31
+ run(workspaceDir: string): void {
32
+ const updatesPath = join(workspaceDir, "UPDATES.md");
33
+
34
+ try {
35
+ if (existsSync(updatesPath)) {
36
+ const existing = readFileSync(updatesPath, "utf-8");
37
+ if (existing.includes(MARKER)) {
38
+ return;
39
+ }
40
+ const needsLeadingNewline = !existing.endsWith("\n\n");
41
+ const prefix = existing.endsWith("\n") ? "\n" : "\n\n";
42
+ appendFileSync(
43
+ updatesPath,
44
+ needsLeadingNewline ? `${prefix}${RELEASE_NOTE}` : RELEASE_NOTE,
45
+ "utf-8",
46
+ );
47
+ } else {
48
+ writeFileSync(updatesPath, RELEASE_NOTE, "utf-8");
49
+ }
50
+ log.info(
51
+ { path: updatesPath },
52
+ "Appended Tavily web search release note",
53
+ );
54
+ } catch (err) {
55
+ log.warn(
56
+ { err, path: updatesPath },
57
+ "Failed to append Tavily web search release note to UPDATES.md",
58
+ );
59
+ }
60
+ },
61
+
62
+ down(_workspaceDir: string): void {
63
+ // Forward-only: UPDATES.md is a user-facing bulletin the assistant
64
+ // processes and deletes on its own.
65
+ },
66
+ };
@@ -0,0 +1,197 @@
1
+ /**
2
+ * Workspace migration `076-home-feed-notification-only`.
3
+ *
4
+ * Rewrites `<workspace>/data/home-feed.json` from the legacy v1 schema
5
+ * (mixed `nudge | digest | action | thread` types with `source`,
6
+ * `author`, `minTimeAway` fields) into the collapsed v2 schema (single
7
+ * `notification` type, no source/author/minTimeAway).
8
+ *
9
+ * Behaviour:
10
+ * - Missing file → no-op.
11
+ * - Malformed JSON → log and no-op (daemon startup must never block;
12
+ * the writer's `readHomeFeed()` already treats unreadable files as
13
+ * empty so the next append cycle naturally rewrites a clean file).
14
+ * - Already v2 → no-op (idempotent).
15
+ * - v1 (or any non-v2 shape with an `items` array): drop entries
16
+ * whose `type !== "action"` (legacy nudge/digest/thread items have
17
+ * no v2 analogue and weren't surfaced as live notifications anyway,
18
+ * per PR 15 of the home-notif-feed-revamp plan); for kept entries
19
+ * drop `source` / `author` / `minTimeAway` and rewrite `type` to
20
+ * `"notification"`. Persist as `{ version: 2, items, updatedAt }`.
21
+ *
22
+ * Idempotent: running the migration a second time on a v2 file is a
23
+ * no-op. The runner's checkpoint also skips re-runs, but this in-file
24
+ * guard keeps the migration safe even if the checkpoint is wiped.
25
+ *
26
+ * `down()` is a no-op — the legacy v1 fields (`source`, `author`,
27
+ * `minTimeAway`, the four item types) were dropped during the
28
+ * forward migration and cannot be recovered. Rolling back to v1 from
29
+ * v2 would also leave the writer producing a shape the older code
30
+ * cannot parse, so a real rollback would require reverting the writer
31
+ * code in lockstep.
32
+ */
33
+
34
+ import { existsSync, readFileSync, writeFileSync } from "node:fs";
35
+ import { join } from "node:path";
36
+
37
+ import { getLogger } from "../../util/logger.js";
38
+ import type { WorkspaceMigration } from "./types.js";
39
+
40
+ const log = getLogger("workspace-migration-076-home-feed-notification-only");
41
+
42
+ const HOME_FEED_RELATIVE_PATH = join("data", "home-feed.json");
43
+
44
+ /** v2 file format. Mirrors `HomeFeedFile` in `home/feed-types.ts`. */
45
+ interface V2HomeFeedFile {
46
+ version: 2;
47
+ items: V2FeedItem[];
48
+ updatedAt: string;
49
+ }
50
+
51
+ /**
52
+ * v2 item shape. Inlined rather than imported from `home/feed-types.ts`
53
+ * so the migration stays self-contained — per AGENTS.md migrations
54
+ * should minimise cross-module coupling so they remain stable as code
55
+ * around them evolves.
56
+ */
57
+ interface V2FeedItem {
58
+ id: string;
59
+ type: "notification";
60
+ priority: number;
61
+ title: string;
62
+ summary: string;
63
+ timestamp: string;
64
+ status: string;
65
+ expiresAt?: string;
66
+ actions?: unknown[];
67
+ urgency?: string;
68
+ conversationId?: string;
69
+ detailPanel?: unknown;
70
+ createdAt: string;
71
+ }
72
+
73
+ export const homeFeedNotificationOnlyMigration: WorkspaceMigration = {
74
+ id: "home-feed-notification-only-v2",
75
+ description:
76
+ "Rewrite home-feed.json into v2 schema (single 'notification' type)",
77
+
78
+ run(workspaceDir: string): void {
79
+ const path = join(workspaceDir, HOME_FEED_RELATIVE_PATH);
80
+ if (!existsSync(path)) {
81
+ return;
82
+ }
83
+
84
+ let raw: unknown;
85
+ try {
86
+ raw = JSON.parse(readFileSync(path, "utf-8"));
87
+ } catch (err) {
88
+ // Daemon startup must never block on a parse failure here. The
89
+ // writer's read path also treats malformed files as empty, so
90
+ // skipping the migration just means the next append cycle will
91
+ // overwrite the file with a fresh v2 snapshot.
92
+ log.warn(
93
+ { err, path },
94
+ "Failed to parse home-feed.json; skipping migration",
95
+ );
96
+ return;
97
+ }
98
+
99
+ if (!isPlainObject(raw)) {
100
+ log.warn({ path }, "home-feed.json is not an object; skipping migration");
101
+ return;
102
+ }
103
+
104
+ if (raw.version === 2) {
105
+ // Already migrated.
106
+ return;
107
+ }
108
+
109
+ const rawItems = Array.isArray(raw.items) ? raw.items : [];
110
+ const items: V2FeedItem[] = [];
111
+ for (const entry of rawItems) {
112
+ const migrated = migrateItem(entry);
113
+ if (migrated) items.push(migrated);
114
+ }
115
+
116
+ const next: V2HomeFeedFile = {
117
+ version: 2,
118
+ items,
119
+ updatedAt: new Date().toISOString(),
120
+ };
121
+
122
+ try {
123
+ writeFileSync(path, JSON.stringify(next, null, 2), "utf-8");
124
+ log.info(
125
+ { path, items: items.length },
126
+ "Rewrote home-feed.json to v2 schema",
127
+ );
128
+ } catch (err) {
129
+ log.warn(
130
+ { err, path },
131
+ "Failed to write migrated home-feed.json; leaving prior file in place",
132
+ );
133
+ }
134
+ },
135
+
136
+ down(_workspaceDir: string): void {
137
+ // Lossy migration — legacy fields (source/author/minTimeAway and
138
+ // nudge/digest/thread items) cannot be reconstructed. The writer
139
+ // code itself only emits v2 now, so rolling back would also leave
140
+ // the file in a shape the v1 reader could not parse without
141
+ // reverting feed-writer.ts in lockstep.
142
+ },
143
+ };
144
+
145
+ /**
146
+ * Convert a single legacy item into a v2 item, or return `null` to
147
+ * drop it. Only `type === "action"` items survive — legacy
148
+ * nudge/digest/thread entries have no v2 analogue and were not
149
+ * surfaced as live notifications by PR 4's wiring (only assistant-
150
+ * authored `action` items reached the live feed via
151
+ * `home-feed-side-effect.ts`).
152
+ */
153
+ function migrateItem(entry: unknown): V2FeedItem | null {
154
+ if (!isPlainObject(entry)) return null;
155
+ if (entry.type !== "action") return null;
156
+
157
+ // Required fields — fail-soft on missing critical strings rather
158
+ // than throwing, so a single bad legacy entry does not lose the
159
+ // rest of the items.
160
+ if (
161
+ typeof entry.id !== "string" ||
162
+ typeof entry.title !== "string" ||
163
+ typeof entry.summary !== "string" ||
164
+ typeof entry.timestamp !== "string" ||
165
+ typeof entry.createdAt !== "string"
166
+ ) {
167
+ return null;
168
+ }
169
+ const priority =
170
+ typeof entry.priority === "number" && Number.isInteger(entry.priority)
171
+ ? entry.priority
172
+ : 50;
173
+ const status = typeof entry.status === "string" ? entry.status : "new";
174
+
175
+ const out: V2FeedItem = {
176
+ id: entry.id,
177
+ type: "notification",
178
+ priority,
179
+ title: entry.title,
180
+ summary: entry.summary,
181
+ timestamp: entry.timestamp,
182
+ status,
183
+ createdAt: entry.createdAt,
184
+ };
185
+ if (typeof entry.expiresAt === "string") out.expiresAt = entry.expiresAt;
186
+ if (Array.isArray(entry.actions)) out.actions = entry.actions;
187
+ if (typeof entry.urgency === "string") out.urgency = entry.urgency;
188
+ if (typeof entry.conversationId === "string") {
189
+ out.conversationId = entry.conversationId;
190
+ }
191
+ if (isPlainObject(entry.detailPanel)) out.detailPanel = entry.detailPanel;
192
+ return out;
193
+ }
194
+
195
+ function isPlainObject(value: unknown): value is Record<string, unknown> {
196
+ return typeof value === "object" && value !== null && !Array.isArray(value);
197
+ }