@vellumai/assistant 0.8.4 → 0.8.6

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (802) hide show
  1. package/AGENTS.md +33 -1
  2. package/ARCHITECTURE.md +3 -3
  3. package/bunfig.toml +6 -1
  4. package/docs/browser-use-architecture-phase2.md +1 -1
  5. package/docs/credential-execution-service.md +6 -6
  6. package/docs/plugins.md +4 -3
  7. package/knip.json +2 -1
  8. package/node_modules/@vellumai/skill-host-contracts/src/client.ts +12 -13
  9. package/node_modules/@vellumai/skill-host-contracts/src/skill-host.ts +4 -1
  10. package/node_modules/@vellumai/skill-host-contracts/src/tool-types.ts +16 -14
  11. package/openapi.yaml +2748 -216
  12. package/package.json +1 -1
  13. package/src/__tests__/actor-token-service.test.ts +3 -2
  14. package/src/__tests__/agent-loop-exit-reason.test.ts +102 -9
  15. package/src/__tests__/agent-loop-override-profile.test.ts +2 -1
  16. package/src/__tests__/agent-wake-disk-pressure-callsite.test.ts +1 -0
  17. package/src/__tests__/agent-wake-override-profile.test.ts +1 -0
  18. package/src/__tests__/always-loaded-tools-guard.test.ts +2 -2
  19. package/src/__tests__/annotate-risk-options.test.ts +1 -0
  20. package/src/__tests__/anthropic-provider.test.ts +34 -37
  21. package/src/__tests__/approval-cascade.test.ts +1 -0
  22. package/src/__tests__/approval-routes-http.test.ts +9 -13
  23. package/src/__tests__/assert-not-live-db.ts +79 -0
  24. package/src/__tests__/assistant-event-hub-self-exclusion.test.ts +293 -0
  25. package/src/__tests__/assistant-feature-flags-integration.test.ts +12 -28
  26. package/src/__tests__/audit-log-rotation.test.ts +72 -18
  27. package/src/__tests__/auto-analysis-end-to-end.test.ts +6 -6
  28. package/src/__tests__/background-workers-disk-pressure.test.ts +8 -11
  29. package/src/__tests__/browser-skill-endstate.test.ts +3 -3
  30. package/src/__tests__/btw-routes.test.ts +5 -5
  31. package/src/__tests__/call-controller.test.ts +3 -3
  32. package/src/__tests__/cancel-resolves-conversation-key.test.ts +1 -1
  33. package/src/__tests__/channel-approval-routes.test.ts +3 -2
  34. package/src/__tests__/channel-guardian.test.ts +6 -5
  35. package/src/__tests__/channel-readiness-slack-remote.test.ts +175 -0
  36. package/src/__tests__/channel-reply-delivery.test.ts +35 -0
  37. package/src/__tests__/channel-retry-sweep.test.ts +320 -3
  38. package/src/__tests__/checker.test.ts +18 -27
  39. package/src/__tests__/compaction-events.test.ts +2 -0
  40. package/src/__tests__/compaction-trail-store.test.ts +264 -0
  41. package/src/__tests__/compactor-call-site-logging.test.ts +215 -0
  42. package/src/__tests__/compactor-preserved-tail-count.test.ts +1 -0
  43. package/src/__tests__/computer-use-skill-manifest-regression.test.ts +12 -16
  44. package/src/__tests__/computer-use-tools.test.ts +14 -18
  45. package/src/__tests__/config-loader-backfill.test.ts +13 -28
  46. package/src/__tests__/config-loader-corrupt.test.ts +5 -5
  47. package/src/__tests__/config-loader-platform-defaults.test.ts +93 -26
  48. package/src/__tests__/config-loader-quarantine-bulletin.test.ts +3 -3
  49. package/src/__tests__/config-managed-gemini-defaults.test.ts +3 -4
  50. package/src/__tests__/config-schema.test.ts +10 -10
  51. package/src/__tests__/confirmation-request-guardian-bridge.test.ts +0 -1
  52. package/src/__tests__/connection-model-compat.test.ts +83 -0
  53. package/src/__tests__/contacts-tools.test.ts +3 -2
  54. package/src/__tests__/context-token-estimator.test.ts +22 -0
  55. package/src/__tests__/conversation-abort-tool-results.test.ts +5 -0
  56. package/src/__tests__/conversation-agent-loop-disk-pressure.test.ts +2 -1
  57. package/src/__tests__/conversation-agent-loop-handlers-max-tokens.test.ts +55 -0
  58. package/src/__tests__/conversation-agent-loop-inference-profile.test.ts +2 -1
  59. package/src/__tests__/conversation-agent-loop-overflow.test.ts +231 -2
  60. package/src/__tests__/conversation-agent-loop.test.ts +581 -54
  61. package/src/__tests__/conversation-analysis-routes.test.ts +1 -0
  62. package/src/__tests__/conversation-app-control-instantiation.test.ts +31 -24
  63. package/src/__tests__/conversation-app-control-lifecycle.test.ts +1 -0
  64. package/src/__tests__/conversation-attention-store.test.ts +101 -0
  65. package/src/__tests__/conversation-attention-telegram.test.ts +3 -2
  66. package/src/__tests__/conversation-clear-safety.test.ts +25 -25
  67. package/src/__tests__/conversation-confirmation-signals.test.ts +1 -0
  68. package/src/__tests__/conversation-delete-schedule-cleanup.test.ts +1 -1
  69. package/src/__tests__/conversation-disk-view-integration.test.ts +2 -2
  70. package/src/__tests__/conversation-error.test.ts +61 -0
  71. package/src/__tests__/conversation-fork-crud.test.ts +239 -15
  72. package/src/__tests__/conversation-fork-route.test.ts +3 -2
  73. package/src/__tests__/conversation-history-web-search.test.ts +1 -0
  74. package/src/__tests__/conversation-inference-profile-list.test.ts +3 -2
  75. package/src/__tests__/conversation-inference-profile-route.test.ts +3 -2
  76. package/src/__tests__/conversation-lifecycle.test.ts +53 -11
  77. package/src/__tests__/conversation-list-source.test.ts +3 -2
  78. package/src/__tests__/conversation-load-history-repair.test.ts +2 -1
  79. package/src/__tests__/{conversation-load-cleaned-at.test.ts → conversation-load-history-stripped.test.ts} +14 -13
  80. package/src/__tests__/conversation-pairing.test.ts +53 -0
  81. package/src/__tests__/conversation-process-app-control-preactivation.test.ts +26 -7
  82. package/src/__tests__/conversation-process-callsite.test.ts +1 -0
  83. package/src/__tests__/conversation-provider-retry-repair.test.ts +6 -0
  84. package/src/__tests__/conversation-queue.test.ts +333 -291
  85. package/src/__tests__/conversation-routes-disk-view.test.ts +112 -18
  86. package/src/__tests__/conversation-routes-guardian-reply.test.ts +33 -8
  87. package/src/__tests__/conversation-routes-slash-commands.test.ts +68 -2
  88. package/src/__tests__/conversation-runtime-assembly.test.ts +78 -0
  89. package/src/__tests__/conversation-skill-tools.test.ts +40 -147
  90. package/src/__tests__/conversation-slash-queue.test.ts +84 -32
  91. package/src/__tests__/conversation-slash-unknown.test.ts +5 -0
  92. package/src/__tests__/conversation-speed-override.test.ts +1 -0
  93. package/src/__tests__/conversation-store.test.ts +1 -1
  94. package/src/__tests__/conversation-surfaces-action-delivery.test.ts +46 -0
  95. package/src/__tests__/conversation-surfaces-data-persist.test.ts +1 -0
  96. package/src/__tests__/conversation-surfaces-standalone-payloads.test.ts +6 -3
  97. package/src/__tests__/conversation-surfaces-standalone.test.ts +6 -3
  98. package/src/__tests__/conversation-surfaces-state-update.test.ts +3 -3
  99. package/src/__tests__/conversation-surfaces-table-action.test.ts +7 -17
  100. package/src/__tests__/conversation-sync-tags.test.ts +218 -35
  101. package/src/__tests__/conversation-title-service.test.ts +1 -0
  102. package/src/__tests__/conversation-tool-setup-app-refresh.test.ts +30 -0
  103. package/src/__tests__/conversation-usage.test.ts +1 -0
  104. package/src/__tests__/conversation-workspace-cache-state.test.ts +2 -0
  105. package/src/__tests__/conversation-workspace-injection.test.ts +6 -1
  106. package/src/__tests__/conversation-workspace-tool-tracking.test.ts +6 -1
  107. package/src/__tests__/credential-broker-browser-fill.test.ts +3 -3
  108. package/src/__tests__/credential-broker-server-use.test.ts +5 -5
  109. package/src/__tests__/credential-execution-client.test.ts +72 -1
  110. package/src/__tests__/credential-execution-feature-gates.test.ts +19 -19
  111. package/src/__tests__/credential-execution-tools.test.ts +6 -6
  112. package/src/__tests__/credential-health-service.test.ts +252 -3
  113. package/src/__tests__/credential-security-invariants.test.ts +6 -5
  114. package/src/__tests__/credential-vault-unit.test.ts +21 -21
  115. package/src/__tests__/credential-vault.test.ts +5 -5
  116. package/src/__tests__/cross-provider-web-search.test.ts +56 -2
  117. package/src/__tests__/db-connection-isolation.test.ts +7 -6
  118. package/src/__tests__/db-conversation-fork-lineage-migration.test.ts +8 -10
  119. package/src/__tests__/db-conversation-inference-profile-migration.test.ts +7 -10
  120. package/src/__tests__/db-llm-request-log-provider-migration.test.ts +9 -15
  121. package/src/__tests__/db-test-helpers.ts +58 -0
  122. package/src/__tests__/disk-pressure-guard.test.ts +58 -41
  123. package/src/__tests__/disk-pressure-lifecycle.test.ts +13 -10
  124. package/src/__tests__/disk-pressure-routes.test.ts +0 -33
  125. package/src/__tests__/disk-pressure-tools.test.ts +0 -4
  126. package/src/__tests__/dm-persistence.test.ts +26 -40
  127. package/src/__tests__/document-create-dedupe.test.ts +189 -0
  128. package/src/__tests__/document-find-replace.test.ts +3 -2
  129. package/src/__tests__/document-tool-security.test.ts +81 -2
  130. package/src/__tests__/dynamic-page-surface.test.ts +2 -2
  131. package/src/__tests__/dynamic-skill-workflow-prompt.test.ts +5 -4
  132. package/src/__tests__/email-html-renderer.test.ts +12 -0
  133. package/src/__tests__/encrypted-store-test-helpers.ts +56 -0
  134. package/src/__tests__/encrypted-store.test.ts +11 -9
  135. package/src/__tests__/feature-flag-test-helpers.ts +53 -0
  136. package/src/__tests__/filing-service.test.ts +1 -0
  137. package/src/__tests__/first-greeting.test.ts +62 -12
  138. package/src/__tests__/gateway-flag-listener.test.ts +236 -0
  139. package/src/__tests__/gemini-provider.test.ts +104 -0
  140. package/src/__tests__/guardian-action-sweep.test.ts +3 -2
  141. package/src/__tests__/guardian-dispatch.test.ts +0 -1
  142. package/src/__tests__/guardian-outbound-http.test.ts +10 -7
  143. package/src/__tests__/handlers-skills-memory-v2-reseed.test.ts +48 -3
  144. package/src/__tests__/handlers-user-message-approval-consumption.test.ts +2 -1
  145. package/src/__tests__/heartbeat-disk-pressure.test.ts +5 -0
  146. package/src/__tests__/heartbeat-service.test.ts +5 -0
  147. package/src/__tests__/helpers/mock-logger.ts +26 -0
  148. package/src/__tests__/host-bash-routes.test.ts +1 -0
  149. package/src/__tests__/host-cu-routes-targeted.test.ts +1 -0
  150. package/src/__tests__/host-file-routes-targeted.test.ts +1 -0
  151. package/src/__tests__/host-shell-tool.test.ts +6 -5
  152. package/src/__tests__/host-transfer-routes-targeted.test.ts +1 -0
  153. package/src/__tests__/http-conversation-lineage.test.ts +3 -2
  154. package/src/__tests__/http-user-message-parity.test.ts +29 -7
  155. package/src/__tests__/identity-intro-cache.test.ts +133 -22
  156. package/src/__tests__/inbound-slack-persistence.test.ts +44 -72
  157. package/src/__tests__/inference-profile-reaper.test.ts +3 -2
  158. package/src/__tests__/inference-profile-session-ipc.test.ts +3 -2
  159. package/src/__tests__/init-feature-flag-overrides.test.ts +5 -6
  160. package/src/__tests__/injector-disk-pressure.test.ts +3 -17
  161. package/src/__tests__/inline-skill-load-permissions.test.ts +4 -4
  162. package/src/__tests__/list-messages-hidden-metadata.test.ts +80 -0
  163. package/src/__tests__/list-messages-tool-merge.test.ts +70 -11
  164. package/src/__tests__/llm-context-normalization.test.ts +42 -0
  165. package/src/__tests__/llm-request-log-call-site.test.ts +136 -0
  166. package/src/__tests__/llm-request-log-source-clickhouse.test.ts +26 -0
  167. package/src/__tests__/llm-resolver.test.ts +408 -9
  168. package/src/__tests__/llm-schema.test.ts +1 -1
  169. package/src/__tests__/llm-usage-store.test.ts +66 -0
  170. package/src/__tests__/logger.test.ts +89 -0
  171. package/src/__tests__/manual-token-reconciliation.test.ts +76 -1
  172. package/src/__tests__/mcp-abort-signal.test.ts +16 -2
  173. package/src/__tests__/mcp-client-auth.test.ts +14 -0
  174. package/src/__tests__/media-generate-image.test.ts +31 -0
  175. package/src/__tests__/memory-v2-static-injector.test.ts +7 -7
  176. package/src/__tests__/messaging-send-tool.test.ts +1 -0
  177. package/src/__tests__/migration-import-from-url.test.ts +3 -3
  178. package/src/__tests__/mock-gateway-ipc.ts +18 -2
  179. package/src/__tests__/model-intents.test.ts +4 -6
  180. package/src/__tests__/native-web-search.test.ts +30 -2
  181. package/src/__tests__/notification-deep-link.test.ts +62 -0
  182. package/src/__tests__/notification-guardian-path.test.ts +0 -1
  183. package/src/__tests__/oauth-commands-routes.test.ts +37 -0
  184. package/src/__tests__/oauth-provider-visibility.test.ts +8 -8
  185. package/src/__tests__/oauth-store.test.ts +3 -2
  186. package/src/__tests__/onboarding-template-contract.test.ts +4 -3
  187. package/src/__tests__/openai-provider.test.ts +54 -9
  188. package/src/__tests__/openai-responses-provider.test.ts +176 -14
  189. package/src/__tests__/openrouter-provider-only.test.ts +27 -5
  190. package/src/__tests__/outbound-slack-persistence.test.ts +46 -1
  191. package/src/__tests__/pending-interactions-resolved-event.test.ts +0 -1
  192. package/src/__tests__/persistence-pipeline.test.ts +139 -1
  193. package/src/__tests__/persistence-secret-redaction.test.ts +83 -12
  194. package/src/__tests__/platform-bash-auto-approve.test.ts +2 -2
  195. package/src/__tests__/platform.test.ts +2 -2
  196. package/src/__tests__/plugin-api-tool-definition.test.ts +92 -0
  197. package/src/__tests__/plugin-bootstrap.test.ts +11 -13
  198. package/src/__tests__/plugin-tool-contribution.test.ts +50 -40
  199. package/src/__tests__/plugin-types.test.ts +3 -2
  200. package/src/__tests__/prechat-onboarding-contract.test.ts +131 -98
  201. package/src/__tests__/pricing.test.ts +12 -0
  202. package/src/__tests__/process-message-background-slack.test.ts +21 -16
  203. package/src/__tests__/process-message-display-content.test.ts +19 -22
  204. package/src/__tests__/provider-catalog-visibility.test.ts +9 -9
  205. package/src/__tests__/provider-platform-proxy-integration.test.ts +216 -4
  206. package/src/__tests__/provider-registry-ollama.test.ts +45 -22
  207. package/src/__tests__/prune-jobs-changes-parser.test.ts +61 -0
  208. package/src/__tests__/recording-handler.test.ts +1 -0
  209. package/src/__tests__/regenerate-fire-and-forget-trace.test.ts +1 -0
  210. package/src/__tests__/registry.test.ts +84 -84
  211. package/src/__tests__/relay-server.test.ts +10 -10
  212. package/src/__tests__/require-fresh-approval.test.ts +2 -2
  213. package/src/__tests__/runtime-attachment-metadata.test.ts +3 -2
  214. package/src/__tests__/runtime-events-sse-bilingual.test.ts +154 -0
  215. package/src/__tests__/schedule-store.test.ts +16 -1
  216. package/src/__tests__/scheduler-reuse-conversation.test.ts +48 -3
  217. package/src/__tests__/secret-ingress-http.test.ts +5 -1
  218. package/src/__tests__/secure-keys.test.ts +3 -3
  219. package/src/__tests__/send-endpoint-busy.test.ts +81 -42
  220. package/src/__tests__/server-history-render.test.ts +4 -1
  221. package/src/__tests__/shell-tool-proxy-mode.test.ts +1 -1
  222. package/src/__tests__/skill-feature-flags-integration.test.ts +8 -10
  223. package/src/__tests__/skill-feature-flags.test.ts +16 -18
  224. package/src/__tests__/skill-load-feature-flag.test.ts +5 -5
  225. package/src/__tests__/skill-projection-feature-flag.test.ts +48 -37
  226. package/src/__tests__/skill-projection.benchmark.test.ts +7 -13
  227. package/src/__tests__/skill-tool-factory.test.ts +97 -96
  228. package/src/__tests__/slack-channel-config.test.ts +3 -3
  229. package/src/__tests__/subagent-call-site-routing.test.ts +11 -3
  230. package/src/__tests__/subagent-disposal.test.ts +27 -8
  231. package/src/__tests__/subagent-fork-notifications.test.ts +24 -9
  232. package/src/__tests__/subagent-fork-spawn.test.ts +13 -4
  233. package/src/__tests__/subagent-manager-notify.test.ts +20 -8
  234. package/src/__tests__/subagent-notify-parent.test.ts +6 -5
  235. package/src/__tests__/subagent-spawn-tool-fork.test.ts +58 -0
  236. package/src/__tests__/subagent-tools.test.ts +2 -1
  237. package/src/__tests__/suggestion-routes.test.ts +2 -0
  238. package/src/__tests__/sync-message-contract.test.ts +59 -0
  239. package/src/__tests__/system-prompt.test.ts +183 -131
  240. package/src/__tests__/terminal-tools.test.ts +1 -1
  241. package/src/__tests__/test-preload-verifier.ts +68 -0
  242. package/src/__tests__/test-preload.ts +32 -39
  243. package/src/__tests__/tool-approval-handler.test.ts +1 -5
  244. package/src/__tests__/tool-execute-pipeline.test.ts +2 -2
  245. package/src/__tests__/tool-execution-pipeline.benchmark.test.ts +2 -5
  246. package/src/__tests__/tool-executor-lifecycle-events.test.ts +35 -12
  247. package/src/__tests__/tool-executor.test.ts +64 -72
  248. package/src/__tests__/tool-grant-request-escalation.test.ts +1 -6
  249. package/src/__tests__/tool-preview-lifecycle.test.ts +1 -0
  250. package/src/__tests__/tool-result-metadata-plumbing.test.ts +1 -0
  251. package/src/__tests__/trusted-contact-approval-notifier.test.ts +0 -1
  252. package/src/__tests__/trusted-contact-inline-approval-integration.test.ts +1 -6
  253. package/src/__tests__/trusted-contact-multichannel.test.ts +0 -1
  254. package/src/__tests__/twilio-routes.test.ts +3 -2
  255. package/src/__tests__/ui-file-upload-surface.test.ts +2 -2
  256. package/src/__tests__/usage-routes.test.ts +3 -0
  257. package/src/__tests__/validate-input.test.ts +381 -0
  258. package/src/__tests__/verification-control-plane-policy.test.ts +3 -2
  259. package/src/__tests__/voice-scoped-grant-consumer.test.ts +2 -1
  260. package/src/__tests__/voice-session-bridge.test.ts +37 -28
  261. package/src/__tests__/workspace-git-service.test.ts +6 -5
  262. package/src/__tests__/workspace-migration-089-move-memory-tree-out-of-v3.test.ts +86 -0
  263. package/src/__tests__/workspace-migration-090-memory-router-cost-optimized-profile.test.ts +326 -0
  264. package/src/__tests__/workspace-migration-091-retighten-migration-onboarding-thread.test.ts +166 -0
  265. package/src/acp/__tests__/prepare-agent-env.test.ts +146 -0
  266. package/src/acp/prepare-agent-env.ts +78 -0
  267. package/src/acp/session-manager.ts +6 -7
  268. package/src/agent/loop.ts +88 -0
  269. package/src/api/README.md +127 -0
  270. package/src/api/constants/call-sites.ts +27 -0
  271. package/src/api/events/assistant-outbound-attachment.ts +51 -0
  272. package/src/api/events/assistant-text-delta.ts +32 -0
  273. package/src/api/events/assistant-turn-start.ts +33 -0
  274. package/src/api/events/document-comment-created.ts +48 -0
  275. package/src/api/events/document-comment-deleted.ts +24 -0
  276. package/src/api/events/document-comment-reopened.ts +25 -0
  277. package/src/api/events/document-comment-resolved.ts +27 -0
  278. package/src/api/events/generation-cancelled.ts +24 -0
  279. package/src/api/events/generation-handoff.ts +41 -0
  280. package/src/api/events/message-complete.ts +42 -0
  281. package/src/api/events/open-url.ts +30 -0
  282. package/src/api/events/relationship-state-updated.ts +25 -0
  283. package/src/api/events/tool-use-start.ts +32 -0
  284. package/src/api/index.ts +129 -0
  285. package/src/api/package.json +10 -0
  286. package/src/api/responses/llm-context-response.ts +39 -0
  287. package/src/api/responses/llm-request-log-entry.ts +93 -0
  288. package/src/api/responses/memory-recall-log.ts +65 -0
  289. package/src/api/responses/memory-v2-activation-log.ts +78 -0
  290. package/src/background-wake/background-wake-routes.test.ts +868 -0
  291. package/src/background-wake/platform-client.test.ts +308 -0
  292. package/src/background-wake/platform-client.ts +167 -0
  293. package/src/background-wake/publisher.ts +91 -0
  294. package/src/background-wake/runtime-registry.ts +24 -0
  295. package/src/background-wake/wake-intent-hooks.test.ts +282 -0
  296. package/src/calls/guardian-dispatch.ts +1 -0
  297. package/src/calls/voice-session-bridge.ts +4 -4
  298. package/src/cli/commands/__tests__/browser.test.ts +23 -5
  299. package/src/cli/commands/__tests__/conversations-slack.test.ts +16 -0
  300. package/src/cli/commands/__tests__/domain-register.test.ts +110 -0
  301. package/src/cli/commands/__tests__/domain-status.test.ts +33 -33
  302. package/src/cli/commands/__tests__/inference-send.test.ts +108 -5
  303. package/src/cli/commands/__tests__/memory-v2-compare-render.test.ts +98 -0
  304. package/src/cli/commands/__tests__/memory-v2.test.ts +1 -0
  305. package/src/cli/commands/__tests__/memory-v3-render.test.ts +340 -0
  306. package/src/cli/commands/__tests__/notifications.test.ts +184 -40
  307. package/src/cli/commands/browser.ts +247 -0
  308. package/src/cli/commands/channels/__tests__/channels.test.ts +143 -0
  309. package/src/cli/commands/channels/index.ts +229 -0
  310. package/src/cli/commands/domain.ts +91 -41
  311. package/src/cli/commands/inference.ts +93 -40
  312. package/src/cli/commands/memory-v2-compare-render.ts +115 -0
  313. package/src/cli/commands/memory-v2.ts +176 -1
  314. package/src/cli/commands/memory-v3-render.ts +491 -0
  315. package/src/cli/commands/memory-v3.ts +567 -0
  316. package/src/cli/commands/notifications.ts +365 -55
  317. package/src/cli/lib/open-browser.ts +7 -2
  318. package/src/cli/program.ts +4 -0
  319. package/src/config/assistant-feature-flags.ts +39 -46
  320. package/src/config/bundled-skills/document-editor/SKILL.md +16 -3
  321. package/src/config/bundled-skills/document-editor/TOOLS.json +18 -0
  322. package/src/config/bundled-skills/document-editor/tools/document-open.ts +12 -0
  323. package/src/config/bundled-skills/image-studio/SKILL.md +4 -0
  324. package/src/config/bundled-skills/image-studio/tools/media-generate-image.ts +2 -2
  325. package/src/config/bundled-skills/media-processing/tools/ingest-media.ts +13 -8
  326. package/src/config/bundled-skills/messaging/tools/messaging-analyze-style.ts +10 -3
  327. package/src/config/bundled-skills/phone-calls/references/TRANSCRIPTS.md +16 -14
  328. package/src/config/bundled-skills/playbooks/tools/playbook-create.ts +7 -2
  329. package/src/config/bundled-skills/playbooks/tools/playbook-update.ts +7 -2
  330. package/src/config/bundled-skills/schedule/SKILL.md +1 -1
  331. package/src/config/bundled-skills/schedule/TOOLS.json +2 -2
  332. package/src/config/bundled-skills/settings/tools/open-system-settings.ts +1 -0
  333. package/src/config/bundled-tool-registry.ts +2 -0
  334. package/src/config/call-site-defaults.ts +8 -7
  335. package/src/config/feature-flag-cache.ts +86 -0
  336. package/src/config/feature-flag-registry.json +33 -17
  337. package/src/config/llm-context-resolution.ts +10 -1
  338. package/src/config/llm-resolver.ts +121 -15
  339. package/src/config/loader.ts +4 -5
  340. package/src/config/schemas/__tests__/memory-v2.test.ts +228 -1
  341. package/src/config/schemas/call-site-catalog.ts +21 -7
  342. package/src/config/schemas/heartbeat.ts +1 -1
  343. package/src/config/schemas/llm.ts +102 -2
  344. package/src/config/schemas/memory-v2.ts +272 -0
  345. package/src/config/schemas/memory.ts +2 -1
  346. package/src/config/schemas/services.ts +6 -2
  347. package/src/config/seed-inference-profiles.ts +36 -16
  348. package/src/context/compactor.ts +52 -0
  349. package/src/context/token-estimator.ts +10 -5
  350. package/src/conversations/__tests__/message-consolidation.test.ts +350 -0
  351. package/src/conversations/message-consolidation.ts +404 -0
  352. package/src/credential-execution/executable-discovery.ts +40 -0
  353. package/src/credential-execution/process-manager.ts +6 -2
  354. package/src/credential-health/credential-health-service.ts +125 -40
  355. package/src/daemon/__tests__/conversation-lifecycle-auto-analyze.test.ts +3 -6
  356. package/src/daemon/__tests__/conversation-surfaces-launch.test.ts +13 -15
  357. package/src/daemon/__tests__/conversation-tool-setup-exclude.test.ts +2 -3
  358. package/src/daemon/__tests__/daemon-skill-host.test.ts +2 -0
  359. package/src/daemon/__tests__/meet-manifest-loader.test.ts +25 -12
  360. package/src/daemon/__tests__/native-web-search-metadata.test.ts +1 -0
  361. package/src/daemon/__tests__/switch-inference-profile-tool.test.ts +107 -0
  362. package/src/daemon/__tests__/web-search-status-text.test.ts +1 -0
  363. package/src/daemon/conversation-agent-loop-handlers.ts +390 -80
  364. package/src/daemon/conversation-agent-loop.ts +244 -90
  365. package/src/daemon/conversation-error.ts +64 -6
  366. package/src/daemon/conversation-lifecycle.ts +27 -22
  367. package/src/daemon/conversation-messaging.ts +84 -43
  368. package/src/daemon/conversation-process.ts +74 -37
  369. package/src/daemon/conversation-runtime-assembly.ts +38 -17
  370. package/src/daemon/conversation-skill-tools.ts +14 -30
  371. package/src/daemon/conversation-surfaces.ts +69 -34
  372. package/src/daemon/conversation-tool-setup.ts +77 -32
  373. package/src/daemon/conversation-usage.ts +2 -0
  374. package/src/daemon/conversation.ts +40 -75
  375. package/src/daemon/daemon-control.ts +1 -1
  376. package/src/daemon/daemon-skill-host.ts +9 -2
  377. package/src/daemon/disk-pressure-guard.ts +39 -29
  378. package/src/daemon/first-greeting.ts +31 -13
  379. package/src/daemon/handlers/config-model.test.ts +1 -0
  380. package/src/daemon/handlers/conversations.ts +11 -3
  381. package/src/daemon/handlers/shared.ts +6 -1
  382. package/src/daemon/host-browser-proxy.ts +5 -5
  383. package/src/daemon/host-cu-proxy.ts +4 -4
  384. package/src/daemon/host-file-proxy.ts +4 -4
  385. package/src/daemon/host-proxy-base.ts +4 -4
  386. package/src/daemon/host-transfer-proxy.ts +10 -10
  387. package/src/daemon/lifecycle.ts +29 -26
  388. package/src/daemon/mcp-reload-service.ts +1 -1
  389. package/src/daemon/meet-manifest-loader.ts +11 -24
  390. package/src/daemon/message-types/conversations.ts +22 -27
  391. package/src/daemon/message-types/document-comments.ts +8 -44
  392. package/src/daemon/message-types/home.ts +2 -14
  393. package/src/daemon/message-types/integrations.ts +2 -7
  394. package/src/daemon/message-types/messages.ts +25 -48
  395. package/src/daemon/message-types/subagents.ts +6 -0
  396. package/src/daemon/message-types/sync.ts +14 -0
  397. package/src/daemon/process-message.ts +9 -9
  398. package/src/daemon/providers-setup.ts +1 -1
  399. package/src/daemon/server.ts +16 -0
  400. package/src/daemon/shutdown-handlers.ts +24 -5
  401. package/src/daemon/switch-inference-profile-tool.ts +62 -0
  402. package/src/daemon/tool-setup-types.ts +7 -0
  403. package/src/daemon/wake-target-adapter.ts +10 -0
  404. package/src/documents/document-store.ts +38 -0
  405. package/src/export/__tests__/transcript-formatter.test.ts +1 -0
  406. package/src/heartbeat/__tests__/heartbeat-service.test.ts +30 -1
  407. package/src/heartbeat/heartbeat-service.ts +63 -0
  408. package/src/home/__tests__/feed-writer.test.ts +161 -0
  409. package/src/home/__tests__/post-connect-feed.test.ts +1 -0
  410. package/src/home/__tests__/suggested-prompts.test.ts +55 -59
  411. package/src/home/feed-writer.ts +146 -7
  412. package/src/home/home-greeting.ts +0 -9
  413. package/src/home/suggested-prompts.ts +27 -154
  414. package/src/ipc/__tests__/cli-ipc.test.ts +1 -0
  415. package/src/ipc/gateway-client.test.ts +4 -1
  416. package/src/ipc/gateway-flag-listener.ts +123 -0
  417. package/src/ipc/skill-routes/__tests__/memory.test.ts +1 -0
  418. package/src/ipc/skill-routes/__tests__/registries.test.ts +36 -7
  419. package/src/ipc/skill-routes/memory.ts +4 -3
  420. package/src/ipc/skill-routes/registries.ts +35 -40
  421. package/src/memory/__tests__/db-async-query.test.ts +165 -0
  422. package/src/memory/__tests__/db-maintenance.test.ts +115 -0
  423. package/src/memory/__tests__/jobs-store-enqueue-gate.test.ts +242 -0
  424. package/src/memory/__tests__/jobs-store-job-classes.test.ts +28 -1
  425. package/src/memory/__tests__/jobs-worker-v2-schedule.test.ts +26 -5
  426. package/src/memory/__tests__/memory-retrospective-enqueue.test.ts +1 -0
  427. package/src/memory/__tests__/memory-retrospective-job.test.ts +8 -0
  428. package/src/memory/__tests__/memory-retrospective-startup-cleanup.test.ts +1 -0
  429. package/src/memory/__tests__/memory-v2-activation-log-store.test.ts +31 -0
  430. package/src/memory/auto-analysis-enqueue.ts +5 -1
  431. package/src/memory/conversation-attention-store.ts +17 -3
  432. package/src/memory/conversation-crud.ts +423 -182
  433. package/src/memory/conversation-starters-cadence.ts +3 -1
  434. package/src/memory/conversation-title-service.ts +19 -3
  435. package/src/memory/db-async-query.ts +214 -0
  436. package/src/memory/db-connection.ts +29 -19
  437. package/src/memory/db-init.ts +14 -0
  438. package/src/memory/db-maintenance.ts +30 -21
  439. package/src/memory/db-singleton.ts +77 -0
  440. package/src/memory/delivery-channels.ts +82 -0
  441. package/src/memory/graph/__tests__/conversation-graph-memory-v2-routing.test.ts +2 -4
  442. package/src/memory/graph/bootstrap.ts +8 -1
  443. package/src/memory/graph/capability-seed.ts +7 -3
  444. package/src/memory/graph/conversation-graph-memory.ts +100 -17
  445. package/src/memory/graph/extraction.ts +1 -5
  446. package/src/memory/graph/graph-search.ts +7 -1
  447. package/src/memory/graph/retriever.test.ts +3 -3
  448. package/src/memory/indexer.ts +28 -18
  449. package/src/memory/job-handlers/cleanup.ts +76 -18
  450. package/src/memory/job-handlers/conversation-starters.ts +1 -4
  451. package/src/memory/job-handlers/embedding.test.ts +3 -2
  452. package/src/memory/jobs/__tests__/embed-concept-page.test.ts +5 -2
  453. package/src/memory/jobs/embed-pkb-file.ts +6 -1
  454. package/src/memory/jobs-store.ts +14 -0
  455. package/src/memory/jobs-worker.ts +66 -22
  456. package/src/memory/llm-request-log-source-clickhouse.ts +122 -2
  457. package/src/memory/llm-request-log-source-local.ts +31 -0
  458. package/src/memory/llm-request-log-source.ts +40 -2
  459. package/src/memory/llm-request-log-store.ts +228 -1
  460. package/src/memory/llm-usage-store.ts +24 -0
  461. package/src/memory/memory-retrospective-enqueue.ts +8 -1
  462. package/src/memory/memory-retrospective-job.ts +5 -0
  463. package/src/memory/memory-v2-activation-log-store.ts +110 -7
  464. package/src/memory/migrations/260-rename-cleaned-at.ts +44 -0
  465. package/src/memory/migrations/261-llm-usage-add-raw-usage.ts +36 -0
  466. package/src/memory/migrations/262-memory-v3-coactivation.ts +57 -0
  467. package/src/memory/migrations/263-memory-v3-auto-edges.ts +50 -0
  468. package/src/memory/migrations/264-llm-request-log-call-site.ts +29 -0
  469. package/src/memory/migrations/265-drop-provider-connection-status.ts +26 -0
  470. package/src/memory/migrations/266-messages-client-message-id.ts +43 -0
  471. package/src/memory/migrations/index.ts +19 -0
  472. package/src/memory/migrations/registry.ts +33 -0
  473. package/src/memory/schema/conversations.ts +10 -2
  474. package/src/memory/schema/inference.ts +0 -1
  475. package/src/memory/schema/infrastructure.ts +21 -0
  476. package/src/memory/tool-usage-store.ts +36 -8
  477. package/src/memory/v2/__tests__/backfill-jobs.test.ts +5 -2
  478. package/src/memory/v2/__tests__/consolidation-job.test.ts +1 -0
  479. package/src/memory/v2/__tests__/harness-compare.test.ts +186 -0
  480. package/src/memory/v2/__tests__/harness-metrics.test.ts +83 -0
  481. package/src/memory/v2/__tests__/harness-oracle.test.ts +257 -0
  482. package/src/memory/v2/__tests__/harness-replay-input.test.ts +230 -0
  483. package/src/memory/v2/__tests__/harness-runner.test.ts +135 -0
  484. package/src/memory/v2/__tests__/injection.test.ts +127 -98
  485. package/src/memory/v2/__tests__/qdrant.test.ts +36 -0
  486. package/src/memory/v2/__tests__/router.test.ts +171 -3
  487. package/src/memory/v2/__tests__/sweep-job.test.ts +6 -3
  488. package/src/memory/v2/harness/compare.ts +57 -0
  489. package/src/memory/v2/harness/metrics.ts +128 -0
  490. package/src/memory/v2/harness/oracle.ts +145 -0
  491. package/src/memory/v2/harness/replay-input.ts +240 -0
  492. package/src/memory/v2/harness/retriever.ts +74 -0
  493. package/src/memory/v2/harness/router-retriever.ts +43 -0
  494. package/src/memory/v2/harness/runner.ts +112 -0
  495. package/src/memory/v2/harness/trace.ts +64 -0
  496. package/src/memory/v2/injection.ts +21 -15
  497. package/src/memory/v2/prompts/router.ts +26 -1
  498. package/src/memory/v2/qdrant.ts +14 -2
  499. package/src/memory/v2/router.ts +171 -18
  500. package/src/memory/v3/__tests__/coactivation-store.test.ts +422 -0
  501. package/src/memory/v3/__tests__/consolidation-job.test.ts +466 -0
  502. package/src/memory/v3/__tests__/coretrieval-seed.test.ts +270 -0
  503. package/src/memory/v3/__tests__/edge-learning-job.test.ts +324 -0
  504. package/src/memory/v3/__tests__/edges.test.ts +706 -0
  505. package/src/memory/v3/__tests__/filter.test.ts +560 -0
  506. package/src/memory/v3/__tests__/gate.test.ts +637 -0
  507. package/src/memory/v3/__tests__/index-composition.test.ts +291 -0
  508. package/src/memory/v3/__tests__/loop.test.ts +775 -0
  509. package/src/memory/v3/__tests__/retriever.test.ts +226 -0
  510. package/src/memory/v3/__tests__/scouts.test.ts +489 -0
  511. package/src/memory/v3/__tests__/shadow-diff.test.ts +225 -0
  512. package/src/memory/v3/__tests__/shadow-middleware.test.ts +398 -0
  513. package/src/memory/v3/__tests__/system-prompts.test.ts +154 -0
  514. package/src/memory/v3/__tests__/traversal.test.ts +508 -0
  515. package/src/memory/v3/__tests__/tree-index.test.ts +280 -0
  516. package/src/memory/v3/__tests__/tree-store.test.ts +529 -0
  517. package/src/memory/v3/__tests__/tree-walk.test.ts +784 -0
  518. package/src/memory/v3/__tests__/validate.test.ts +277 -0
  519. package/src/memory/v3/auto-edges.ts +223 -0
  520. package/src/memory/v3/coactivation-store.ts +124 -0
  521. package/src/memory/v3/consolidation-job.ts +323 -0
  522. package/src/memory/v3/coretrieval-seed.ts +240 -0
  523. package/src/memory/v3/edge-learning-job.ts +160 -0
  524. package/src/memory/v3/edges.ts +286 -0
  525. package/src/memory/v3/filter.ts +286 -0
  526. package/src/memory/v3/gate.ts +349 -0
  527. package/src/memory/v3/index-composition.ts +126 -0
  528. package/src/memory/v3/llm-capture.ts +46 -0
  529. package/src/memory/v3/loop.ts +430 -0
  530. package/src/memory/v3/maintenance.ts +144 -0
  531. package/src/memory/v3/prompt-context.ts +33 -0
  532. package/src/memory/v3/prompts/consolidation.ts +458 -0
  533. package/src/memory/v3/prompts/system-prompts.ts +196 -0
  534. package/src/memory/v3/retriever.ts +33 -0
  535. package/src/memory/v3/scouts.ts +431 -0
  536. package/src/memory/v3/shadow-diff.ts +287 -0
  537. package/src/memory/v3/shadow-middleware.ts +347 -0
  538. package/src/memory/v3/traversal.ts +211 -0
  539. package/src/memory/v3/tree-index.ts +237 -0
  540. package/src/memory/v3/tree-store.ts +394 -0
  541. package/src/memory/v3/tree-walk.ts +356 -0
  542. package/src/memory/v3/types.ts +65 -0
  543. package/src/memory/v3/validate.ts +323 -0
  544. package/src/notifications/__tests__/emit-signal-home-feed.test.ts +1 -0
  545. package/src/notifications/__tests__/home-feed-side-effect.test.ts +1 -0
  546. package/src/notifications/adapters/macos.ts +18 -1
  547. package/src/notifications/adapters/platform.ts +1 -1
  548. package/src/notifications/adapters/slack.ts +45 -11
  549. package/src/notifications/broadcaster.ts +114 -63
  550. package/src/notifications/conversation-pairing.ts +23 -3
  551. package/src/notifications/decision-engine.ts +1 -4
  552. package/src/notifications/decisions-store.ts +32 -1
  553. package/src/notifications/deliveries-store.ts +45 -0
  554. package/src/notifications/edit-notification.ts +201 -0
  555. package/src/notifications/emit-signal.ts +40 -50
  556. package/src/notifications/signal.ts +10 -0
  557. package/src/notifications/types.ts +37 -0
  558. package/src/oauth/byo-connection.test.ts +67 -3
  559. package/src/oauth/byo-connection.ts +32 -5
  560. package/src/oauth/connect-orchestrator.ts +9 -0
  561. package/src/oauth/connection-resolver.test.ts +76 -0
  562. package/src/oauth/connection-resolver.ts +49 -10
  563. package/src/oauth/manual-token-connection.ts +51 -3
  564. package/src/oauth/seed-providers.ts +3 -0
  565. package/src/permissions/approval-policy.test.ts +19 -5
  566. package/src/permissions/approval-policy.ts +14 -3
  567. package/src/permissions/checker.ts +21 -8
  568. package/src/permissions/prompter.ts +3 -3
  569. package/src/permissions/question-prompter.ts +5 -2
  570. package/src/permissions/secret-prompter.ts +2 -2
  571. package/src/platform/client.test.ts +24 -1
  572. package/src/platform/client.ts +8 -0
  573. package/src/platform/feature-gate.ts +15 -0
  574. package/src/plugin-api/index.ts +4 -0
  575. package/src/plugin-api/types.ts +7 -33
  576. package/src/plugins/defaults/index.ts +6 -0
  577. package/src/plugins/defaults/injectors.ts +20 -19
  578. package/src/plugins/defaults/persistence.ts +25 -6
  579. package/src/plugins/external-plugin-loader.ts +5 -68
  580. package/src/plugins/types.ts +68 -29
  581. package/src/proactive-artifact/aux-message-injector.ts +17 -4
  582. package/src/proactive-artifact/job.test.ts +1 -0
  583. package/src/prompts/__tests__/system-prompt.test.ts +4 -4
  584. package/src/prompts/__tests__/task-progress-hint-section.test.ts +3 -9
  585. package/src/prompts/persona-resolver.ts +36 -21
  586. package/src/prompts/sections.ts +39 -7
  587. package/src/prompts/system-prompt.ts +84 -221
  588. package/src/prompts/template-detection.ts +10 -4
  589. package/src/prompts/templates/BOOTSTRAP.md +9 -13
  590. package/src/prompts/templates/IDENTITY.md +0 -2
  591. package/src/prompts/templates/system-sections.ts +230 -8
  592. package/src/providers/__tests__/connection-model-compat.test.ts +233 -0
  593. package/src/providers/__tests__/registry-native-web-search.test.ts +122 -0
  594. package/src/providers/__tests__/retry-callsite.test.ts +85 -5
  595. package/src/providers/anthropic/client.ts +32 -66
  596. package/src/providers/call-site-routing.ts +42 -6
  597. package/src/providers/connection-model-compat.ts +61 -0
  598. package/src/providers/connection-resolution.ts +47 -14
  599. package/src/providers/fireworks/client.ts +1 -0
  600. package/src/providers/gemini/client.ts +70 -6
  601. package/src/providers/inference/__tests__/adapter-factory-openai-compatible.test.ts +0 -2
  602. package/src/providers/inference/__tests__/base-url-security.test.ts +2 -3
  603. package/src/providers/inference/__tests__/{connections-status-label.test.ts → connections-label.test.ts} +12 -111
  604. package/src/providers/inference/adapter-factory.ts +3 -0
  605. package/src/providers/inference/auth.ts +0 -8
  606. package/src/providers/inference/connections.ts +3 -66
  607. package/src/providers/inference/resolve-auth.ts +2 -3
  608. package/src/providers/minimax/client.ts +106 -0
  609. package/src/providers/model-catalog.ts +78 -1
  610. package/src/providers/model-intents.ts +4 -4
  611. package/src/providers/openai/__tests__/api-error-detail.test.ts +120 -0
  612. package/src/providers/openai/__tests__/chat-completions-provider-reasoning.test.ts +157 -5
  613. package/src/providers/openai/chat-completions-provider.ts +116 -15
  614. package/src/providers/openai/codex-models.ts +20 -0
  615. package/src/providers/openai/responses-provider.ts +87 -30
  616. package/src/providers/openrouter/client.ts +13 -8
  617. package/src/providers/provider-send-message.ts +20 -5
  618. package/src/providers/registry.ts +48 -8
  619. package/src/providers/retry.ts +50 -7
  620. package/src/providers/search-provider-catalog.ts +17 -9
  621. package/src/providers/thinking-config.ts +26 -1
  622. package/src/providers/types.ts +9 -0
  623. package/src/providers/usage-tracking.ts +2 -0
  624. package/src/runtime/AGENTS.md +2 -2
  625. package/src/runtime/__tests__/agent-wake.test.ts +1 -0
  626. package/src/runtime/__tests__/background-job-runner.test.ts +1 -0
  627. package/src/runtime/access-request-helper.ts +1 -0
  628. package/src/runtime/agent-wake.ts +1 -0
  629. package/src/runtime/assistant-event-hub.ts +76 -6
  630. package/src/runtime/auth/route-policy.ts +46 -0
  631. package/src/runtime/btw-sidechain.ts +0 -6
  632. package/src/runtime/channel-readiness-service.ts +68 -0
  633. package/src/runtime/channel-reply-delivery.ts +23 -0
  634. package/src/runtime/channel-retry-sweep.ts +47 -14
  635. package/src/runtime/confirmation-request-guardian-bridge.ts +1 -1
  636. package/src/runtime/http-types.ts +0 -2
  637. package/src/runtime/migrations/vbundle-builder.ts +12 -4
  638. package/src/runtime/pending-interactions.ts +0 -1
  639. package/src/runtime/routes/__tests__/bookmark-routes.test.ts +1 -0
  640. package/src/runtime/routes/__tests__/conversation-compaction-routes.test.ts +406 -0
  641. package/src/runtime/routes/__tests__/conversation-query-routes.test.ts +204 -0
  642. package/src/runtime/routes/__tests__/heartbeat-routes.test.ts +1 -1
  643. package/src/runtime/routes/__tests__/home-feed-routes.test.ts +209 -1
  644. package/src/runtime/routes/__tests__/inference-provider-connection-routes.test.ts +13 -50
  645. package/src/runtime/routes/__tests__/memory-v2-simulate-route.test.ts +76 -9
  646. package/src/runtime/routes/__tests__/memory-v3-simulate-params.test.ts +35 -0
  647. package/src/runtime/routes/__tests__/plugins-routes.test.ts +512 -0
  648. package/src/runtime/routes/__tests__/slack-channel-routes.test.ts +3 -2
  649. package/src/runtime/routes/__tests__/surface-content-routes.test.ts +294 -0
  650. package/src/runtime/routes/__tests__/task-routes.test.ts +48 -3
  651. package/src/runtime/routes/acp-routes-list.test.ts +3 -0
  652. package/src/runtime/routes/acp-routes.test.ts +255 -6
  653. package/src/runtime/routes/acp-routes.ts +8 -1
  654. package/src/runtime/routes/app-management-routes.ts +111 -4
  655. package/src/runtime/routes/avatar-routes.ts +10 -10
  656. package/src/runtime/routes/background-wake-routes.ts +356 -0
  657. package/src/runtime/routes/browser-tabs-routes.ts +200 -0
  658. package/src/runtime/routes/btw-routes.ts +4 -10
  659. package/src/runtime/routes/conversation-analysis-routes.ts +6 -0
  660. package/src/runtime/routes/conversation-cli-routes.ts +1 -1
  661. package/src/runtime/routes/conversation-compaction-routes.ts +263 -0
  662. package/src/runtime/routes/conversation-list-routes.ts +159 -4
  663. package/src/runtime/routes/conversation-management-routes.ts +108 -26
  664. package/src/runtime/routes/conversation-query-routes.ts +200 -44
  665. package/src/runtime/routes/conversation-routes.ts +409 -521
  666. package/src/runtime/routes/conversation-starter-routes.ts +6 -3
  667. package/src/runtime/routes/conversations-import-routes.ts +19 -6
  668. package/src/runtime/routes/disk-pressure-routes.ts +1 -1
  669. package/src/runtime/routes/documents-routes.ts +10 -1
  670. package/src/runtime/routes/domain-routes.ts +60 -10
  671. package/src/runtime/routes/email-routes.ts +5 -2
  672. package/src/runtime/routes/events-routes.ts +54 -10
  673. package/src/runtime/routes/group-routes.ts +35 -8
  674. package/src/runtime/routes/home-feed-routes.ts +129 -0
  675. package/src/runtime/routes/host-browser-routes.ts +10 -2
  676. package/src/runtime/routes/host-cu-routes.ts +2 -2
  677. package/src/runtime/routes/identity-intro-cache.ts +61 -16
  678. package/src/runtime/routes/identity-routes.ts +30 -9
  679. package/src/runtime/routes/inbound-stages/acl-enforcement.ts +96 -3
  680. package/src/runtime/routes/inbound-stages/background-dispatch.test.ts +530 -6
  681. package/src/runtime/routes/inbound-stages/background-dispatch.ts +57 -8
  682. package/src/runtime/routes/index.ts +10 -0
  683. package/src/runtime/routes/inference-profile-session-handler.ts +22 -12
  684. package/src/runtime/routes/inference-profile-session-routes.ts +7 -1
  685. package/src/runtime/routes/inference-provider-connection-routes.ts +5 -26
  686. package/src/runtime/routes/integrations/vercel.ts +15 -0
  687. package/src/runtime/routes/llm-call-sites-routes.ts +32 -5
  688. package/src/runtime/routes/llm-context-normalization.ts +7 -2
  689. package/src/runtime/routes/memory-item-routes.ts +8 -3
  690. package/src/runtime/routes/memory-v2-routes.ts +215 -5
  691. package/src/runtime/routes/memory-v3-routes.ts +474 -0
  692. package/src/runtime/routes/migration-routes.ts +32 -28
  693. package/src/runtime/routes/notification-routes.ts +63 -1
  694. package/src/runtime/routes/oauth-commands-routes.ts +6 -1
  695. package/src/runtime/routes/plugins-routes.ts +337 -0
  696. package/src/runtime/routes/rename-conversation-routes.ts +6 -2
  697. package/src/runtime/routes/secret-routes.ts +25 -5
  698. package/src/runtime/routes/settings-routes.ts +12 -11
  699. package/src/runtime/routes/slack-channel-routes.ts +5 -4
  700. package/src/runtime/routes/surface-action-routes.ts +1 -38
  701. package/src/runtime/routes/surface-content-routes.ts +12 -5
  702. package/src/runtime/routes/surface-conversation-resolver.ts +65 -0
  703. package/src/runtime/routes/wipe-conversation-routes.ts +3 -0
  704. package/src/runtime/routes/workspace-routes.ts +25 -10
  705. package/src/runtime/services/__tests__/analyze-conversation.test.ts +2 -0
  706. package/src/runtime/slack-dm-text-delivery.ts +177 -0
  707. package/src/runtime/sync/resource-sync-events.ts +106 -38
  708. package/src/runtime/sync/sync-publisher.test.ts +49 -0
  709. package/src/runtime/sync/sync-publisher.ts +2 -1
  710. package/src/runtime/tool-grant-request-helper.ts +1 -0
  711. package/src/runtime/verification-outbound-actions.ts +73 -1
  712. package/src/schedule/schedule-store.ts +8 -1
  713. package/src/schedule/scheduler.ts +111 -15
  714. package/src/security/__tests__/provider-key-env-fallback.test.ts +3 -3
  715. package/src/security/encrypted-store.ts +7 -16
  716. package/src/security/store-path-override.ts +61 -0
  717. package/src/signals/user-message.ts +5 -8
  718. package/src/skills/validate-input.ts +177 -0
  719. package/src/subagent/manager.ts +13 -13
  720. package/src/subagent/types.ts +6 -0
  721. package/src/tasks/tool-sanitizer.ts +2 -2
  722. package/src/telemetry/types.ts +12 -0
  723. package/src/telemetry/usage-telemetry-reporter.test.ts +48 -0
  724. package/src/telemetry/usage-telemetry-reporter.ts +1 -0
  725. package/src/tools/acp/spawn.test.ts +119 -0
  726. package/src/tools/acp/spawn.ts +15 -2
  727. package/src/tools/apps/definitions.ts +36 -28
  728. package/src/tools/ask-question/ask-question-tool.test.ts +3 -3
  729. package/src/tools/ask-question/ask-question-tool.ts +38 -45
  730. package/src/tools/browser/__tests__/browser-execution-acquire.test.ts +2 -8
  731. package/src/tools/browser/__tests__/pinned-tabs.test.ts +70 -0
  732. package/src/tools/browser/browser-execution.ts +16 -3
  733. package/src/tools/browser/cdp-client/__tests__/browser-tabs-factory.test.ts +402 -0
  734. package/src/tools/browser/cdp-client/__tests__/types.test.ts +3 -0
  735. package/src/tools/browser/cdp-client/cdp-inspect-client.ts +12 -0
  736. package/src/tools/browser/cdp-client/extension-cdp-client.ts +27 -1
  737. package/src/tools/browser/cdp-client/factory.ts +100 -17
  738. package/src/tools/browser/cdp-client/local-cdp-client.ts +12 -0
  739. package/src/tools/browser/cdp-client/types.ts +65 -0
  740. package/src/tools/browser/pinned-tabs.ts +96 -40
  741. package/src/tools/computer-use/definitions.ts +282 -336
  742. package/src/tools/credential-execution/make-authenticated-request.ts +3 -9
  743. package/src/tools/credential-execution/manage-secure-command-tool.ts +3 -9
  744. package/src/tools/credential-execution/run-authenticated-command.ts +3 -9
  745. package/src/tools/credentials/vault.ts +3 -9
  746. package/src/tools/document/document-tool.ts +189 -7
  747. package/src/tools/execution-target.ts +18 -23
  748. package/src/tools/executor.ts +24 -56
  749. package/src/tools/filesystem/edit.ts +3 -9
  750. package/src/tools/filesystem/list.ts +3 -9
  751. package/src/tools/filesystem/read.ts +3 -9
  752. package/src/tools/filesystem/write.ts +3 -9
  753. package/src/tools/host-filesystem/edit.test.ts +1 -0
  754. package/src/tools/host-filesystem/edit.ts +3 -9
  755. package/src/tools/host-filesystem/read.test.ts +1 -0
  756. package/src/tools/host-filesystem/read.ts +3 -9
  757. package/src/tools/host-filesystem/transfer.test.ts +31 -6
  758. package/src/tools/host-filesystem/transfer.ts +3 -9
  759. package/src/tools/host-filesystem/write.test.ts +1 -0
  760. package/src/tools/host-filesystem/write.ts +3 -9
  761. package/src/tools/host-terminal/host-shell.ts +3 -9
  762. package/src/tools/mcp/mcp-tool-factory.ts +1 -10
  763. package/src/tools/memory/register.test.ts +1 -1
  764. package/src/tools/memory/register.ts +4 -9
  765. package/src/tools/network/__tests__/managed-search-proxy.test.ts +282 -0
  766. package/src/tools/network/__tests__/web-search.test.ts +211 -3
  767. package/src/tools/network/managed-search-proxy.ts +183 -0
  768. package/src/tools/network/web-fetch.ts +3 -9
  769. package/src/tools/network/web-search.ts +224 -76
  770. package/src/tools/policy-context.ts +3 -1
  771. package/src/tools/registry.ts +150 -123
  772. package/src/tools/schedule/create.ts +1 -1
  773. package/src/tools/schema-transforms.ts +1 -1
  774. package/src/tools/skills/execute.ts +3 -9
  775. package/src/tools/skills/load.ts +3 -9
  776. package/src/tools/skills/skill-tool-factory.ts +18 -44
  777. package/src/tools/subagent/notify-parent.ts +3 -9
  778. package/src/tools/subagent/spawn.ts +3 -0
  779. package/src/tools/system/request-permission.ts +3 -9
  780. package/src/tools/terminal/shell.ts +3 -9
  781. package/src/tools/tool-approval-handler.ts +10 -4
  782. package/src/tools/tool-defaults.ts +94 -0
  783. package/src/tools/tool-name-aliases.ts +72 -14
  784. package/src/tools/types.ts +32 -101
  785. package/src/tools/ui-surface/definitions.ts +104 -108
  786. package/src/types/onboarding-context.ts +6 -0
  787. package/src/usage/attribution.ts +32 -1
  788. package/src/usage/pricing.ts +23 -0
  789. package/src/usage/types.ts +12 -0
  790. package/src/util/browser.ts +7 -2
  791. package/src/util/logger.ts +16 -7
  792. package/src/util/platform.ts +7 -2
  793. package/src/util/sqlite3-runtime.ts +65 -0
  794. package/src/workspace/migrations/086-revert-stale-gemini-mis-rewrites.ts +1 -0
  795. package/src/workspace/migrations/089-move-memory-tree-out-of-v3.ts +86 -0
  796. package/src/workspace/migrations/090-memory-router-cost-optimized-profile.ts +109 -0
  797. package/src/workspace/migrations/091-retighten-migration-onboarding-thread.ts +41 -0
  798. package/src/workspace/migrations/registry.ts +6 -0
  799. package/src/__tests__/compaction-strip-metadata-clear.test.ts +0 -206
  800. package/src/__tests__/message-complete-display-id.test.ts +0 -175
  801. package/src/daemon/query-complexity-router.ts +0 -75
  802. package/src/prompts/cache-boundary.ts +0 -8
@@ -1,22 +1,12 @@
1
- import { describe, expect, mock, test } from "bun:test";
1
+ import { afterEach, describe, expect, mock, test } from "bun:test";
2
2
 
3
3
  // ─── Mocks ─────────────────────────────────────────────────────────────
4
4
 
5
- let mockConnectedProviders = new Set<string>();
6
-
7
- mock.module("../../oauth/oauth-store.js", () => ({
8
- listProviders: () => [
9
- { provider: "google" },
10
- { provider: "slack" },
11
- { provider: "notion" },
12
- { provider: "linear" },
13
- { provider: "github" },
14
- ],
15
- }));
5
+ const mockIntegrationSummary = "Gmail ✓ | Slack ✓ | Twilio ✗ | Telegram ✗";
6
+ let mockSidechainText = "";
16
7
 
17
8
  mock.module("../../schedule/integration-status.js", () => ({
18
- isOAuthProviderConnected: async (provider: string) =>
19
- mockConnectedProviders.has(provider),
9
+ formatIntegrationSummary: async () => mockIntegrationSummary,
20
10
  }));
21
11
 
22
12
  mock.module("../../util/logger.js", () => ({
@@ -31,7 +21,7 @@ mock.module("../../config/loader.js", () => ({
31
21
  }));
32
22
 
33
23
  mock.module("../../config/llm-resolver.js", () => ({
34
- resolveCallSiteConfig: () => ({ provider: "mock" }),
24
+ resolveCallSiteConfig: () => ({ provider: "mock", maxTokens: 256 }),
35
25
  }));
36
26
 
37
27
  mock.module("../../providers/provider-send-message.js", () => ({
@@ -51,70 +41,76 @@ mock.module("../../prompts/system-prompt.js", () => ({
51
41
  }));
52
42
 
53
43
  mock.module("../../runtime/btw-sidechain.js", () => ({
54
- runBtwSidechain: async () => ({ text: "" }),
44
+ runBtwSidechain: async () => ({ text: mockSidechainText }),
55
45
  }));
56
46
 
57
- const { getSuggestedPrompts } = await import("../suggested-prompts.js");
47
+ mock.module("../../runtime/assistant-event.js", () => ({
48
+ buildAssistantEvent: (e: unknown) => e,
49
+ }));
50
+
51
+ mock.module("../../runtime/assistant-event-hub.js", () => ({
52
+ assistantEventHub: { publish: async () => {} },
53
+ }));
54
+
55
+ const {
56
+ getSuggestedPrompts,
57
+ refreshAssistantSuggestedPrompts,
58
+ invalidateAssistantSuggestedPromptsCache,
59
+ } = await import("../suggested-prompts.js");
58
60
 
59
61
  // ─── Tests ─────────────────────────────────────────────────────────────
60
62
 
61
63
  describe("getSuggestedPrompts", () => {
62
- test("shows 'Connect X' prompts when providers are disconnected", async () => {
63
- mockConnectedProviders = new Set();
64
+ afterEach(() => {
65
+ invalidateAssistantSuggestedPromptsCache();
66
+ mockSidechainText = "";
67
+ });
64
68
 
69
+ test("returns empty array before cache is populated", async () => {
65
70
  const prompts = await getSuggestedPrompts();
66
- const ids = prompts.map((p) => p.id);
67
-
68
- expect(ids).toContain("connect-google");
69
- expect(ids).toContain("connect-slack");
70
- expect(prompts.find((p) => p.id === "connect-google")!.label).toBe(
71
- "Connect Gmail",
72
- );
71
+ expect(prompts).toEqual([]);
73
72
  });
74
73
 
75
- test("shows email management prompts when Google is connected", async () => {
76
- mockConnectedProviders = new Set(["google"]);
74
+ test("returns LLM-generated prompts after refresh", async () => {
75
+ mockSidechainText = JSON.stringify([
76
+ { label: "Triage my inbox", prompt: "Help me triage my inbox" },
77
+ { label: "Check meetings", prompt: "What meetings do I have today?" },
78
+ ]);
77
79
 
80
+ await refreshAssistantSuggestedPrompts();
78
81
  const prompts = await getSuggestedPrompts();
79
- const ids = prompts.map((p) => p.id);
80
-
81
- // Should NOT show "Connect Gmail"
82
- expect(ids).not.toContain("connect-google");
83
-
84
- // Should show management prompts
85
- expect(ids).toContain("manage-google-triage-my-inbox");
86
- expect(ids).toContain("manage-google-summarize-today's-emails");
87
-
88
- const triage = prompts.find(
89
- (p) => p.id === "manage-google-triage-my-inbox",
90
- );
91
- expect(triage).toBeDefined();
92
- expect(triage!.label).toBe("Triage my inbox");
93
- expect(triage!.icon).toBe("mail");
94
- expect(triage!.source).toBe("deterministic");
82
+
83
+ expect(prompts).toHaveLength(2);
84
+ expect(prompts[0]!.label).toBe("Triage my inbox");
85
+ expect(prompts[0]!.source).toBe("assistant");
86
+ expect(prompts[1]!.label).toBe("Check meetings");
95
87
  });
96
88
 
97
- test("still shows Connect prompts for disconnected providers alongside management prompts", async () => {
98
- mockConnectedProviders = new Set(["google"]);
89
+ test("invalidation clears the cache", async () => {
90
+ mockSidechainText = JSON.stringify([
91
+ { label: "Do stuff", prompt: "Do stuff for me" },
92
+ ]);
99
93
 
100
- const prompts = await getSuggestedPrompts();
101
- const ids = prompts.map((p) => p.id);
94
+ await refreshAssistantSuggestedPrompts();
95
+ expect(await getSuggestedPrompts()).toHaveLength(1);
102
96
 
103
- // Gmail management prompts
104
- expect(ids).toContain("manage-google-triage-my-inbox");
105
- // Slack still disconnected
106
- expect(ids).toContain("connect-slack");
97
+ invalidateAssistantSuggestedPromptsCache();
98
+ expect(await getSuggestedPrompts()).toEqual([]);
107
99
  });
108
100
 
109
- test("providers without connectedPrompts show nothing when connected", async () => {
110
- mockConnectedProviders = new Set(["slack"]);
101
+ test("handles empty LLM response gracefully", async () => {
102
+ mockSidechainText = "";
111
103
 
104
+ await refreshAssistantSuggestedPrompts();
112
105
  const prompts = await getSuggestedPrompts();
113
- const ids = prompts.map((p) => p.id);
106
+ expect(prompts).toEqual([]);
107
+ });
108
+
109
+ test("handles malformed LLM response gracefully", async () => {
110
+ mockSidechainText = "not valid json at all";
114
111
 
115
- // No connect prompt since connected
116
- expect(ids).not.toContain("connect-slack");
117
- // No management prompts since Slack doesn't define any
118
- expect(ids.filter((id) => id.startsWith("manage-slack"))).toHaveLength(0);
112
+ await refreshAssistantSuggestedPrompts();
113
+ const prompts = await getSuggestedPrompts();
114
+ expect(prompts).toEqual([]);
119
115
  });
120
116
  });
@@ -44,6 +44,7 @@ import { getDataDir } from "../util/platform.js";
44
44
  import {
45
45
  type FeedItem,
46
46
  type FeedItemStatus,
47
+ type FeedItemUrgency,
47
48
  type HomeFeedFile,
48
49
  parseFeedFile,
49
50
  } from "./feed-types.js";
@@ -155,6 +156,72 @@ export async function patchFeedItemStatus(
155
156
  return resultPromise;
156
157
  }
157
158
 
159
+ /**
160
+ * Patch the user-editable copy fields on a single feed item by id.
161
+ *
162
+ * Returns the updated `FeedItem`, or `null` if no item with the given
163
+ * id exists. Used by the `assistant notifications edit` flow. Patches
164
+ * are applied inside the same coalescing queue as appends and status
165
+ * patches so overlapping writes don't race.
166
+ *
167
+ * Only fields explicitly present on `patch` are touched. Pass an empty
168
+ * object and the call is a no-op that returns the existing item (or
169
+ * `null` if the id isn't on disk).
170
+ */
171
+ export interface FeedItemContentPatch {
172
+ title?: string;
173
+ summary?: string;
174
+ urgency?: FeedItemUrgency;
175
+ status?: FeedItemStatus;
176
+ }
177
+
178
+ export async function patchFeedItemContent(
179
+ id: string,
180
+ patch: FeedItemContentPatch,
181
+ ): Promise<FeedItem | null> {
182
+ let resolveResult!: (value: FeedItem | null) => void;
183
+ const resultPromise = new Promise<FeedItem | null>((resolve) => {
184
+ resolveResult = resolve;
185
+ });
186
+ pendingContentPatches.push({ id, patch, resolve: resolveResult });
187
+ void scheduleWrite();
188
+ return resultPromise;
189
+ }
190
+
191
+ /**
192
+ * Remove the `conversationId` field from all feed items that reference
193
+ * the given conversation. Returns the number of items modified.
194
+ *
195
+ * This is the daemon-side cleanup path invoked when a conversation is
196
+ * deleted — it prevents "Go to Thread" buttons from linking to a
197
+ * conversation that no longer exists. Goes through the same coalescing
198
+ * queue as appends and patches so there are no file-I/O races.
199
+ */
200
+ export async function stripConversationIds(
201
+ conversationId: string,
202
+ ): Promise<number> {
203
+ let resolveResult!: (count: number) => void;
204
+ const resultPromise = new Promise<number>((resolve) => {
205
+ resolveResult = resolve;
206
+ });
207
+ pendingStrips.push({ conversationId, resolve: resolveResult });
208
+ void scheduleWrite();
209
+ return resultPromise;
210
+ }
211
+
212
+ /**
213
+ * Remove the `conversationId` field from ALL feed items that have one.
214
+ * Returns the number of items modified.
215
+ *
216
+ * Used by the clear-all-conversations flow to bulk-invalidate every
217
+ * "Go to Thread" link at once. Uses the same coalescing queue with a
218
+ * `"*"` sentinel that the strip loop in `runWrite` treats as "match
219
+ * all items with a conversationId".
220
+ */
221
+ export async function clearAllConversationIds(): Promise<number> {
222
+ return stripConversationIds("*");
223
+ }
224
+
158
225
  // ─── Internal: coalescing queue ────────────────────────────────────────
159
226
 
160
227
  /**
@@ -168,6 +235,15 @@ const pendingPatches: Array<{
168
235
  status: FeedItemStatus;
169
236
  resolve: (value: FeedItem | null) => void;
170
237
  }> = [];
238
+ const pendingContentPatches: Array<{
239
+ id: string;
240
+ patch: FeedItemContentPatch;
241
+ resolve: (value: FeedItem | null) => void;
242
+ }> = [];
243
+ const pendingStrips: Array<{
244
+ conversationId: string;
245
+ resolve: (count: number) => void;
246
+ }> = [];
171
247
 
172
248
  let writeInFlight: Promise<void> | null = null;
173
249
  let writeDirty = false;
@@ -206,6 +282,11 @@ function scheduleWrite(): Promise<void> {
206
282
  async function runWrite(): Promise<void> {
207
283
  const appendsToApply = pendingAppends.splice(0, pendingAppends.length);
208
284
  const patchesToApply = pendingPatches.splice(0, pendingPatches.length);
285
+ const contentPatchesToApply = pendingContentPatches.splice(
286
+ 0,
287
+ pendingContentPatches.length,
288
+ );
289
+ const stripsToApply = pendingStrips.splice(0, pendingStrips.length);
209
290
 
210
291
  const current = readHomeFeed();
211
292
  let items = current.items.slice();
@@ -233,6 +314,57 @@ async function runWrite(): Promise<void> {
233
314
  patchResults.push({ resolve: patch.resolve, value: updated });
234
315
  }
235
316
 
317
+ const contentPatchResults: Array<{
318
+ resolve: (v: FeedItem | null) => void;
319
+ value: FeedItem | null;
320
+ }> = [];
321
+ for (const { id, patch, resolve } of contentPatchesToApply) {
322
+ const idx = items.findIndex((i) => i.id === id);
323
+ if (idx === -1) {
324
+ contentPatchResults.push({ resolve, value: null });
325
+ continue;
326
+ }
327
+ const existing = items[idx]!;
328
+ const updated: FeedItem = { ...existing };
329
+ if (patch.title !== undefined) {
330
+ const trimmed = patch.title.trim();
331
+ if (trimmed.length === 0) {
332
+ delete updated.title;
333
+ } else {
334
+ updated.title = trimmed;
335
+ }
336
+ }
337
+ if (patch.summary !== undefined) {
338
+ updated.summary = patch.summary;
339
+ }
340
+ if (patch.urgency !== undefined) {
341
+ updated.urgency = patch.urgency;
342
+ }
343
+ if (patch.status !== undefined) {
344
+ updated.status = patch.status;
345
+ }
346
+ items[idx] = updated;
347
+ contentPatchResults.push({ resolve, value: updated });
348
+ }
349
+
350
+ // Strip conversationId from matching items.
351
+ const stripResults: Array<{
352
+ resolve: (count: number) => void;
353
+ count: number;
354
+ }> = [];
355
+ for (const strip of stripsToApply) {
356
+ let count = 0;
357
+ for (let i = 0; i < items.length; i++) {
358
+ const matchAll = strip.conversationId === "*";
359
+ const matchOne = items[i]!.conversationId === strip.conversationId;
360
+ if (matchAll ? items[i]!.conversationId != null : matchOne) {
361
+ items[i] = { ...items[i]!, conversationId: undefined };
362
+ count++;
363
+ }
364
+ }
365
+ stripResults.push({ resolve: strip.resolve, count });
366
+ }
367
+
236
368
  items.sort(compareFeedItems);
237
369
 
238
370
  const updatedAt = new Date().toISOString();
@@ -258,17 +390,24 @@ async function runWrite(): Promise<void> {
258
390
  publishHomeFeedUpdated(updatedAt, newItemCount);
259
391
  }
260
392
 
261
- // Resolve pending patch promises AFTER we've emitted the SSE event
262
- // so callers awaiting `patchFeedItemStatus` observe a fully
263
- // consistent world: the on-disk file, the SSE event, and the
264
- // returned `FeedItem` all reflect the same write.
393
+ // Resolve pending patch and strip promises AFTER we've emitted the
394
+ // SSE event so callers awaiting `patchFeedItemStatus` or
395
+ // `stripConversationIds` observe a fully consistent world: the
396
+ // on-disk file, the SSE event, and the returned value all reflect
397
+ // the same write.
265
398
  //
266
- // If the write failed, resolve all patch promises with `null` the
267
- // state was not persisted, and callers (e.g. HTTP route handlers)
268
- // must not report success when the underlying write failed.
399
+ // If the write failed, resolve patch promises with `null` and strip
400
+ // promises with `0` — the state was not persisted, and callers must
401
+ // not report success when the underlying write failed.
269
402
  for (const { resolve, value } of patchResults) {
270
403
  resolve(wrote ? value : null);
271
404
  }
405
+ for (const { resolve, value } of contentPatchResults) {
406
+ resolve(wrote ? value : null);
407
+ }
408
+ for (const { resolve, count } of stripResults) {
409
+ resolve(wrote ? count : 0);
410
+ }
272
411
  }
273
412
 
274
413
  /**
@@ -13,7 +13,6 @@
13
13
 
14
14
  import { resolveCallSiteConfig } from "../config/llm-resolver.js";
15
15
  import { getConfig } from "../config/loader.js";
16
- import { resolvePersonaContext } from "../prompts/persona-resolver.js";
17
16
  import { buildSystemPrompt } from "../prompts/system-prompt.js";
18
17
  import { getConfiguredProvider } from "../providers/provider-send-message.js";
19
18
  import { runBtwSidechain } from "../runtime/btw-sidechain.js";
@@ -56,17 +55,9 @@ export async function refreshPersonalizedGreeting(): Promise<void> {
56
55
  return;
57
56
  }
58
57
 
59
- const { userPersona, userSlug, channelPersona } = resolvePersonaContext(
60
- undefined,
61
- undefined,
62
- );
63
-
64
58
  const systemPrompt = buildSystemPrompt({
65
59
  excludeBootstrap: true,
66
60
  excludeCustomPrefix: true,
67
- userPersona,
68
- channelPersona,
69
- userSlug,
70
61
  });
71
62
 
72
63
  const result = await runBtwSidechain({
@@ -2,88 +2,25 @@
2
2
  * Suggested prompt producer for the Home feed.
3
3
  *
4
4
  * Returns an array of `SuggestedPrompt` items shown at the top of the
5
- * Home page as conversation starters (e.g. "Connect Gmail", "Add Slack").
6
- *
7
- * Two sources of prompts:
8
- * - **Deterministic** derived from missing OAuth connections.
9
- * Computed inline (read-only, safe for GET).
10
- * - **Assistant-generated** — contextual suggestions from the LLM
11
- * based on what's relevant to the user. Read from an in-memory
12
- * cache in the GET path; generation runs in the background via
13
- * `refreshAssistantSuggestedPrompts`.
5
+ * Home page as conversation starters. All prompts are generated by the
6
+ * assistant based on the user's connected services and context —
7
+ * read from an in-memory cache in the GET path; generation runs in
8
+ * the background via `refreshAssistantSuggestedPrompts`.
14
9
  */
15
10
 
16
11
  import { resolveCallSiteConfig } from "../config/llm-resolver.js";
17
12
  import { getConfig } from "../config/loader.js";
18
- import { listProviders } from "../oauth/oauth-store.js";
19
- import { resolvePersonaContext } from "../prompts/persona-resolver.js";
20
13
  import { buildSystemPrompt } from "../prompts/system-prompt.js";
21
14
  import { getConfiguredProvider } from "../providers/provider-send-message.js";
22
15
  import { buildAssistantEvent } from "../runtime/assistant-event.js";
23
16
  import { assistantEventHub } from "../runtime/assistant-event-hub.js";
24
17
  import { runBtwSidechain } from "../runtime/btw-sidechain.js";
25
- import { isOAuthProviderConnected } from "../schedule/integration-status.js";
18
+ import { formatIntegrationSummary } from "../schedule/integration-status.js";
26
19
  import { getLogger } from "../util/logger.js";
27
20
  import type { SuggestedPrompt } from "./feed-types.js";
28
21
 
29
22
  const log = getLogger("suggested-prompts");
30
23
 
31
- /**
32
- * Map of provider keys to their suggested-prompt metadata. Only providers
33
- * listed here produce deterministic "Connect X" prompts when disconnected.
34
- * The icon values are VIcon case names rendered by the macOS client.
35
- */
36
- interface PromptEntry {
37
- label: string;
38
- prompt: string;
39
- icon: string;
40
- }
41
-
42
- const CONNECT_PROMPT_META: Record<
43
- string,
44
- PromptEntry & { connectedPrompts?: PromptEntry[] }
45
- > = {
46
- google: {
47
- label: "Connect Gmail",
48
- prompt: "Help me connect my Gmail account",
49
- icon: "mail",
50
- connectedPrompts: [
51
- {
52
- label: "Triage my inbox",
53
- prompt:
54
- "Help me triage my inbox — summarize what's unread and flag anything that needs a reply",
55
- icon: "mail",
56
- },
57
- {
58
- label: "Summarize today's emails",
59
- prompt:
60
- "Summarize the emails I received today and highlight anything important",
61
- icon: "mail",
62
- },
63
- ],
64
- },
65
- slack: {
66
- label: "Connect Slack",
67
- prompt: "Help me connect my Slack workspace",
68
- icon: "hash",
69
- },
70
- notion: {
71
- label: "Connect Notion",
72
- prompt: "Help me connect my Notion workspace",
73
- icon: "fileText",
74
- },
75
- linear: {
76
- label: "Connect Linear",
77
- prompt: "Help me connect my Linear workspace",
78
- icon: "clipboardList",
79
- },
80
- github: {
81
- label: "Connect GitHub",
82
- prompt: "Help me connect my GitHub account",
83
- icon: "terminal",
84
- },
85
- };
86
-
87
24
  const LLM_SUGGESTIONS_TIMEOUT_MS = 5_000;
88
25
  const LLM_CACHE_TTL_MS = 30 * 60 * 1000; // 30 minutes
89
26
 
@@ -95,37 +32,23 @@ let cachedLLMPrompts: SuggestedPrompt[] = [];
95
32
  let cachedLLMPromptsAt = 0;
96
33
 
97
34
  /**
98
- * Produce suggested prompts from both deterministic and cached LLM sources.
99
- * Deterministic prompts always come first; cached LLM-generated prompts are
100
- * appended when available. No LLM calls happen in this path — safe for GET.
35
+ * Return cached assistant-generated prompts. No LLM calls happen in
36
+ * this path safe for GET. Returns an empty array until the first
37
+ * background refresh populates the cache.
101
38
  */
102
39
  export async function getSuggestedPrompts(): Promise<SuggestedPrompt[]> {
103
- const prompts: SuggestedPrompt[] = [];
104
-
105
- let deterministicPrompts: SuggestedPrompt[] = [];
106
- try {
107
- deterministicPrompts = await getDeterministicPrompts();
108
- prompts.push(...deterministicPrompts);
109
- } catch (err) {
110
- log.warn({ err }, "Failed to compute deterministic suggested prompts");
111
- }
112
-
113
40
  if (Date.now() - cachedLLMPromptsAt < LLM_CACHE_TTL_MS) {
114
- prompts.push(...cachedLLMPrompts);
41
+ return [...cachedLLMPrompts];
115
42
  }
116
-
117
- return prompts;
43
+ return [];
118
44
  }
119
45
 
120
46
  /**
121
- * Drops the in-memory LLM suggestion cache so the next call to
122
- * `getSuggestedPrompts()` returns only the fresh deterministic list (and
123
- * a follow-up background refresh repopulates the LLM half).
47
+ * Drops the in-memory suggestion cache so the next background refresh
48
+ * regenerates prompts with current integration state.
124
49
  *
125
- * Called from OAuth connect/disconnect paths so a freshly-connected
126
- * provider stops surfacing as a "Connect X" pill within one reload — the
127
- * 30-minute TTL would otherwise pin a stale suggestion until the next
128
- * periodic refresh.
50
+ * Called from OAuth connect/disconnect paths so suggestions reflect the
51
+ * new state within one reload instead of waiting for the 30-minute TTL.
129
52
  */
130
53
  export function invalidateAssistantSuggestedPromptsCache(): void {
131
54
  cachedLLMPrompts = [];
@@ -157,8 +80,7 @@ export async function refreshAssistantSuggestedPrompts(): Promise<void> {
157
80
  }
158
81
 
159
82
  try {
160
- const deterministicPrompts = await getDeterministicPrompts();
161
- const llmPrompts = await generateAssistantPrompts(deterministicPrompts);
83
+ const llmPrompts = await generateAssistantPrompts();
162
84
  cachedLLMPrompts = llmPrompts;
163
85
  cachedLLMPromptsAt = Date.now();
164
86
  } catch (err) {
@@ -166,49 +88,6 @@ export async function refreshAssistantSuggestedPrompts(): Promise<void> {
166
88
  }
167
89
  }
168
90
 
169
- /**
170
- * Check which well-known OAuth providers are not connected and return
171
- * a "Connect X" prompt for each. For connected providers that have
172
- * `connectedPrompts`, return those instead so users discover ongoing
173
- * management capabilities.
174
- */
175
- async function getDeterministicPrompts(): Promise<SuggestedPrompt[]> {
176
- const providers = listProviders();
177
- const prompts: SuggestedPrompt[] = [];
178
-
179
- for (const provider of providers) {
180
- const meta = CONNECT_PROMPT_META[provider.provider];
181
- if (!meta) continue;
182
-
183
- const connected = await isOAuthProviderConnected(provider.provider);
184
-
185
- if (!connected) {
186
- prompts.push({
187
- id: `connect-${provider.provider}`,
188
- label: meta.label,
189
- icon: meta.icon,
190
- prompt: meta.prompt,
191
- source: "deterministic",
192
- });
193
- continue;
194
- }
195
-
196
- if (meta.connectedPrompts) {
197
- for (const cp of meta.connectedPrompts) {
198
- prompts.push({
199
- id: `manage-${provider.provider}-${cp.label.toLowerCase().replace(/\s+/g, "-")}`,
200
- label: cp.label,
201
- icon: cp.icon,
202
- prompt: cp.prompt,
203
- source: "deterministic",
204
- });
205
- }
206
- }
207
- }
208
-
209
- return prompts;
210
- }
211
-
212
91
  // ---------------------------------------------------------------------------
213
92
  // LLM-generated suggestions
214
93
  // ---------------------------------------------------------------------------
@@ -221,11 +100,9 @@ interface LLMSuggestion {
221
100
  /**
222
101
  * Ask the LLM to generate contextual conversation-starter suggestions
223
102
  * based on the assistant's persona and the user's connected services.
224
- * Returns an empty array on failure so deterministic prompts still show.
103
+ * Returns an empty array on failure.
225
104
  */
226
- async function generateAssistantPrompts(
227
- deterministicPrompts: SuggestedPrompt[],
228
- ): Promise<SuggestedPrompt[]> {
105
+ async function generateAssistantPrompts(): Promise<SuggestedPrompt[]> {
229
106
  const config = getConfig();
230
107
  const resolved = resolveCallSiteConfig("homeSuggestedPrompts", config.llm);
231
108
 
@@ -234,30 +111,26 @@ async function generateAssistantPrompts(
234
111
  return [];
235
112
  }
236
113
 
237
- const { userPersona, userSlug, channelPersona } = resolvePersonaContext(
238
- undefined,
239
- undefined,
240
- );
241
-
242
114
  const systemPrompt = buildSystemPrompt({
243
115
  excludeBootstrap: true,
244
116
  excludeCustomPrefix: true,
245
- userPersona,
246
- channelPersona,
247
- userSlug,
248
117
  });
249
118
 
250
- const existingLabels = deterministicPrompts.map((p) => p.label).join(", ");
251
- const contextNote = existingLabels
252
- ? `The user already has these suggestions: ${existingLabels}. Do NOT duplicate them.`
253
- : "";
119
+ let integrationContext = "";
120
+ try {
121
+ integrationContext = `\nConnected integrations: ${await formatIntegrationSummary()}`;
122
+ } catch {
123
+ // Best-effort — continue without integration info
124
+ }
254
125
 
255
126
  const result = await runBtwSidechain({
256
127
  content:
257
128
  "Suggest 2-3 short, actionable conversation starters for the home page. " +
258
129
  "Each should be something specific and helpful you can do for the user right now. " +
259
- `${contextNote} ` +
260
- 'Return ONLY a JSON array of objects with "label" (max 5 words) and "prompt" (the full message to send). ' +
130
+ "Focus on things the user's connected services enable — don't suggest connecting services they already have. " +
131
+ "You may suggest connecting a service only if it's not yet connected and would be genuinely useful." +
132
+ integrationContext +
133
+ ' Return ONLY a JSON array of objects with "label" (max 5 words) and "prompt" (the full message to send). ' +
261
134
  "No markdown fences, no explanation.",
262
135
  provider,
263
136
  systemPrompt,
@@ -37,6 +37,7 @@ mock.module("../../runtime/agent-wake.js", () => ({
37
37
 
38
38
  mock.module("../../memory/conversation-crud.js", () => ({
39
39
  getConversation: (id: string) => ({ id, createdAt: Date.now() }),
40
+ reserveMessage: mock(async () => ({ id: "msg-reserve" })),
40
41
  }));
41
42
 
42
43
  // ---------------------------------------------------------------------------
@@ -108,7 +108,10 @@ describe("ipcGetFeatureFlags", () => {
108
108
  });
109
109
 
110
110
  test("returns empty record when IPC returns undefined", async () => {
111
- // No mock configured ipcCall returns undefined
111
+ // Explicitly suppress the mock's default `get_feature_flags` sentinel
112
+ // (which exists to short-circuit `initFeatureFlagOverrides()`'s retry
113
+ // loop) so this test exercises the underlying-undefined path.
114
+ mockGatewayIpc(null, { results: { get_feature_flags: undefined } });
112
115
  const flags = await ipcGetFeatureFlags();
113
116
  expect(flags).toEqual({});
114
117
  });