@vellumai/assistant 0.12.0 → 0.12.1-dev.202609141913.5e16607

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 (441) hide show
  1. package/AGENTS.md +5 -1
  2. package/ARCHITECTURE.md +11 -12
  3. package/docs/architecture/turn-actor.md +15 -8
  4. package/docs/guardian-request-flow.md +16 -0
  5. package/openapi.yaml +292 -50
  6. package/package.json +1 -1
  7. package/scripts/smoke-desktop-window-theme.ts +186 -0
  8. package/src/__tests__/always-loaded-tools-guard.test.ts +18 -10
  9. package/src/__tests__/app-compiler.test.ts +6 -0
  10. package/src/__tests__/app-control-tool-schemas.test.ts +5 -2
  11. package/src/__tests__/app-dir-path-guard.test.ts +1 -3
  12. package/src/__tests__/computer-use-skill-proxy-bridge.test.ts +5 -2
  13. package/src/__tests__/computer-use-tools.test.ts +17 -5
  14. package/src/__tests__/config-schema-cmd.test.ts +2 -2
  15. package/src/__tests__/config-schema.test.ts +28 -29
  16. package/src/__tests__/config-watcher.test.ts +23 -8
  17. package/src/__tests__/connection-model-compat.test.ts +2 -2
  18. package/src/__tests__/conversation-key-store-disk-view.test.ts +1 -1
  19. package/src/__tests__/conversation-pairing.test.ts +26 -0
  20. package/src/__tests__/conversation-process-app-control-preactivation.test.ts +4 -10
  21. package/src/__tests__/conversation-queue.test.ts +48 -207
  22. package/src/__tests__/conversation-retry-discard.test.ts +54 -1
  23. package/src/__tests__/conversation-skill-tools.test.ts +27 -0
  24. package/src/__tests__/conversation-surfaces-app-control.test.ts +8 -3
  25. package/src/__tests__/conversation-surfaces-task-progress.test.ts +67 -0
  26. package/src/__tests__/conversation-title-service.test.ts +14 -10
  27. package/src/__tests__/conversation-tool-setup-app-refresh.test.ts +3 -5
  28. package/src/__tests__/conversation-tool-setup-attribution.test.ts +51 -0
  29. package/src/__tests__/credential-record-retire.test.ts +171 -1
  30. package/src/__tests__/credential-routes.test.ts +212 -3
  31. package/src/__tests__/credential-security-invariants.test.ts +4 -2
  32. package/src/__tests__/cu-unified-flow.test.ts +8 -2
  33. package/src/__tests__/document-sync-tags.test.ts +25 -0
  34. package/src/__tests__/drain-kick-guard.test.ts +0 -2
  35. package/src/__tests__/drain-requeue-on-contention.test.ts +0 -6
  36. package/src/__tests__/evict-conversations-for-reload.test.ts +1 -1
  37. package/src/__tests__/git-porcelain.test.ts +47 -0
  38. package/src/__tests__/helpers/set-workspace-mcp.ts +11 -0
  39. package/src/__tests__/host-bash-proxy.test.ts +26 -45
  40. package/src/__tests__/host-browser-proxy.test.ts +6 -17
  41. package/src/__tests__/host-file-proxy-targeted.test.ts +23 -0
  42. package/src/__tests__/host-file-proxy.test.ts +11 -23
  43. package/src/__tests__/host-transfer-proxy-targeted.test.ts +30 -9
  44. package/src/__tests__/llm-catalog-parity.test.ts +25 -0
  45. package/src/__tests__/mcp-auth-routes.test.ts +6 -9
  46. package/src/__tests__/mcp-config-secret-boundary.test.ts +78 -136
  47. package/src/__tests__/mcp-health-check.test.ts +8 -11
  48. package/src/__tests__/mcp-list-plugin-servers.test.ts +8 -10
  49. package/src/__tests__/message-deleted-hook-dispatch.test.ts +119 -0
  50. package/src/__tests__/messages-after-tiebreaker.test.ts +91 -0
  51. package/src/__tests__/messages-read-boundary-guard.test.ts +1 -1
  52. package/src/__tests__/messaging-send-tool.test.ts +355 -548
  53. package/src/__tests__/model-intents.test.ts +3 -0
  54. package/src/__tests__/notification-vellum-adapter.test.ts +85 -2
  55. package/src/__tests__/outlook-messaging-provider.test.ts +6 -6
  56. package/src/__tests__/platform-callback-registration.test.ts +8 -16
  57. package/src/__tests__/platform-client-verify-credential.test.ts +2 -0
  58. package/src/__tests__/plugin-import-boundary-guard.test.ts +13 -0
  59. package/src/__tests__/resolve-app.test.ts +135 -0
  60. package/src/__tests__/script-proxy-certs.test.ts +35 -0
  61. package/src/__tests__/service-account-token.test.ts +247 -0
  62. package/src/__tests__/skill-feature-flags-integration.test.ts +1 -1
  63. package/src/__tests__/skill-feature-flags.test.ts +2 -2
  64. package/src/__tests__/source-fingerprint.test.ts +184 -0
  65. package/src/__tests__/subagent-tool-gate-mode.test.ts +19 -3
  66. package/src/__tests__/subagent-tools.test.ts +3 -2
  67. package/src/__tests__/telephony-tts-guard.test.ts +38 -3
  68. package/src/__tests__/vellum-self-knowledge-inline-command.test.ts +4 -0
  69. package/src/__tests__/watch-retro-tool-availability.test.ts +8 -17
  70. package/src/__tests__/workspace-git-service.test.ts +26 -0
  71. package/src/__tests__/workspace-migration-154-repair-retired-codex-gpt-5-4-model-ids.test.ts +336 -0
  72. package/src/acp/__tests__/agent-process.test.ts +258 -4
  73. package/src/acp/__tests__/auth-required.test.ts +96 -0
  74. package/src/acp/__tests__/client-handler.test.ts +90 -2
  75. package/src/acp/__tests__/helpers/acp-model-option.ts +51 -0
  76. package/src/acp/__tests__/session-manager-persistence.test.ts +5 -1
  77. package/src/acp/__tests__/session-manager-resume.test.ts +270 -6
  78. package/src/acp/__tests__/session-manager-usage.test.ts +4 -2
  79. package/src/acp/__tests__/session-manager.test.ts +895 -4
  80. package/src/acp/agent-process.test.ts +4 -1
  81. package/src/acp/agent-process.ts +94 -9
  82. package/src/acp/auth-required.ts +50 -1
  83. package/src/acp/auto-install.test.ts +9 -7
  84. package/src/acp/client-handler.ts +16 -3
  85. package/src/acp/model-config.test.ts +166 -0
  86. package/src/acp/model-config.ts +138 -0
  87. package/src/acp/resolve-agent.test.ts +220 -6
  88. package/src/acp/resolve-agent.ts +88 -23
  89. package/src/acp/session-manager.test.ts +196 -3
  90. package/src/acp/session-manager.ts +441 -18
  91. package/src/acp/types.ts +50 -5
  92. package/src/api/events/acp-session-model-update.test.ts +88 -0
  93. package/src/api/events/acp-session-model-update.ts +46 -0
  94. package/src/api/events/app-files-changed.ts +4 -3
  95. package/src/api/events/notification-intent.ts +2 -0
  96. package/src/api/index.ts +6 -0
  97. package/src/apps/app-store.ts +1 -1
  98. package/src/apps/resolve-app.ts +81 -0
  99. package/src/apps/source-fingerprint.ts +266 -0
  100. package/src/bundler/app-compiler.ts +15 -0
  101. package/src/calls/__tests__/barge-in-guard.test.ts +81 -0
  102. package/src/{__tests__ → calls/__tests__}/call-controller.test.ts +503 -82
  103. package/src/{__tests__ → calls/__tests__}/media-stream-audio-transcode.test.ts +1 -1
  104. package/src/{__tests__ → calls/__tests__}/media-stream-output.test.ts +37 -8
  105. package/src/{__tests__ → calls/__tests__}/media-stream-parser.test.ts +1 -1
  106. package/src/{__tests__ → calls/__tests__}/media-stream-server-integration.test.ts +150 -57
  107. package/src/{__tests__ → calls/__tests__}/media-stream-stt-session.test.ts +5 -5
  108. package/src/{__tests__ → calls/__tests__}/media-turn-detector.test.ts +1 -1
  109. package/src/{live-voice → calls}/__tests__/progress-narration.test.ts +4 -4
  110. package/src/{live-voice → calls}/__tests__/progress-phrases.test.ts +1 -1
  111. package/src/calls/__tests__/voice-control-protocol.test.ts +58 -25
  112. package/src/calls/__tests__/voice-leg-coordinator.test.ts +229 -0
  113. package/src/calls/__tests__/voice-progress-cadence.test.ts +274 -0
  114. package/src/{__tests__/voice-session-bridge.test.ts → calls/__tests__/voice-session-bridge-turn-flow.test.ts} +20 -12
  115. package/src/calls/__tests__/voice-session-bridge.test.ts +37 -1
  116. package/src/calls/__tests__/voice-triage-escalate.test.ts +105 -0
  117. package/src/calls/barge-in-guard.ts +118 -0
  118. package/src/calls/call-constants.ts +24 -4
  119. package/src/calls/call-controller.ts +499 -199
  120. package/src/calls/call-transport.ts +16 -0
  121. package/src/calls/media-stream-output.ts +32 -0
  122. package/src/calls/media-stream-server.ts +82 -30
  123. package/src/calls/media-stream-stt-session.ts +15 -0
  124. package/src/{live-voice → calls}/progress-narration.ts +2 -2
  125. package/src/calls/resolve-call-tts-provider.ts +33 -2
  126. package/src/calls/tts-call-strategy.ts +9 -5
  127. package/src/calls/types.ts +2 -0
  128. package/src/calls/voice-control-protocol.ts +53 -21
  129. package/src/calls/voice-leg-coordinator.ts +189 -0
  130. package/src/calls/voice-progress-cadence.ts +423 -0
  131. package/src/calls/voice-session-bridge.ts +59 -46
  132. package/src/calls/voice-triage-escalate.ts +175 -56
  133. package/src/cli/commands/__tests__/apps.test.ts +245 -0
  134. package/src/cli/commands/__tests__/bash.test.ts +53 -0
  135. package/src/cli/commands/__tests__/roadmap.help.test.ts +19 -0
  136. package/src/cli/commands/apps.help.ts +67 -13
  137. package/src/cli/commands/apps.ts +183 -0
  138. package/src/cli/commands/bash.help.ts +8 -13
  139. package/src/cli/commands/bash.ts +7 -25
  140. package/src/cli/commands/channels/__tests__/send.test.ts +218 -0
  141. package/src/cli/commands/channels/index.help.ts +70 -2
  142. package/src/cli/commands/channels/index.ts +16 -3
  143. package/src/cli/commands/channels/send.ts +128 -0
  144. package/src/cli/commands/credentials.help.ts +6 -2
  145. package/src/cli/commands/credentials.ts +2 -2
  146. package/src/cli/commands/mcp.help.ts +8 -8
  147. package/src/cli/commands/mcp.ts +1 -1
  148. package/src/cli/commands/roadmap.help.ts +5 -1
  149. package/src/cli/commands/roadmap.ts +1 -1
  150. package/src/cli/lib/bundled-marketplace.json +103 -90
  151. package/src/config/__tests__/default-profile-catalog.test.ts +22 -0
  152. package/src/config/__tests__/memory-retrospective-schema.test.ts +15 -1
  153. package/src/config/__tests__/platform-identity.test.ts +255 -0
  154. package/src/config/__tests__/platform-rehydration.test.ts +99 -9
  155. package/src/config/acp-agent-write.ts +43 -0
  156. package/src/config/acp-defaults.test.ts +13 -3
  157. package/src/config/acp-defaults.ts +23 -6
  158. package/src/config/acp-schema.test.ts +81 -0
  159. package/src/config/acp-schema.ts +30 -2
  160. package/src/config/bundled-skills/acp/SKILL.md +22 -14
  161. package/src/config/bundled-skills/acp/TOOLS.json +5 -1
  162. package/src/config/bundled-skills/app-builder/SKILL.md +12 -9
  163. package/src/config/bundled-skills/app-builder/references/CUSTOM_ROUTES.md +1 -1
  164. package/src/config/bundled-skills/messaging/SKILL.md +3 -3
  165. package/src/config/bundled-skills/messaging/TOOLS.json +3 -3
  166. package/src/config/bundled-skills/messaging/tools/messaging-send.ts +67 -139
  167. package/src/config/bundled-skills/phone-calls/references/TRANSCRIPTS.md +1 -1
  168. package/src/config/bundled-skills/schedule/SKILL.md +3 -4
  169. package/src/config/bundled-skills/screen-annotation/SKILL.md +8 -1
  170. package/src/config/bundled-skills/screen-annotation/tools/screen-annotation.test.ts +4 -1
  171. package/src/config/bundled-skills/skill-management/TOOLS.json +2 -2
  172. package/src/config/default-profile-catalog.ts +1 -1
  173. package/src/config/env.ts +2 -2
  174. package/src/config/feature-flag-registry.json +24 -12
  175. package/src/config/loader.ts +1 -0
  176. package/src/config/memory-v3-gate.test.ts +31 -0
  177. package/src/config/memory-v3-gate.ts +20 -16
  178. package/src/config/platform-identity.ts +201 -0
  179. package/src/config/platform-rehydration.ts +11 -27
  180. package/src/config/schema.ts +2 -2
  181. package/src/config/schemas/__tests__/live-voice.test.ts +8 -158
  182. package/src/config/schemas/__tests__/voice.test.ts +148 -0
  183. package/src/config/schemas/calls.ts +1 -28
  184. package/src/config/schemas/live-voice.ts +1 -173
  185. package/src/config/schemas/mcp.ts +1 -1
  186. package/src/config/schemas/memory-retrospective.ts +10 -0
  187. package/src/config/schemas/services.ts +8 -0
  188. package/src/config/schemas/skills.ts +0 -14
  189. package/src/config/schemas/voice.ts +150 -0
  190. package/src/credential-execution/process-manager.test.ts +18 -19
  191. package/src/daemon/__tests__/conversation-tool-setup.test.ts +66 -121
  192. package/src/daemon/__tests__/plugin-mcp-reconcile.test.ts +4 -1
  193. package/src/daemon/__tests__/skill-memory-refresh-mtime.test.ts +133 -0
  194. package/src/daemon/app-change-notify.ts +45 -0
  195. package/src/daemon/config-watcher.ts +13 -194
  196. package/src/daemon/conversation-process.ts +35 -64
  197. package/src/daemon/conversation-skill-tools.ts +13 -31
  198. package/src/daemon/conversation-store.ts +1 -1
  199. package/src/daemon/conversation-surfaces.ts +10 -8
  200. package/src/daemon/conversation-tool-setup.ts +37 -43
  201. package/src/daemon/conversation.ts +0 -3
  202. package/src/daemon/host-bash-proxy.ts +8 -12
  203. package/src/daemon/host-browser-proxy.ts +15 -1
  204. package/src/daemon/host-file-proxy.ts +8 -10
  205. package/src/daemon/host-transfer-proxy.ts +14 -18
  206. package/src/daemon/lifecycle.ts +0 -5
  207. package/src/daemon/mcp-reload-service.ts +5 -5
  208. package/src/daemon/message-types/sync.ts +1 -0
  209. package/src/daemon/orphan-reaper.ts +1 -1
  210. package/src/daemon/providers-setup.ts +1 -1
  211. package/src/daemon/shutdown-handlers.ts +1 -9
  212. package/src/daemon/skill-memory-refresh.ts +64 -0
  213. package/src/daemon/tool-side-effects.ts +7 -18
  214. package/src/desktop/__tests__/fake-desktop.ts +119 -0
  215. package/src/desktop/desktop-chrome-policy.test.ts +71 -0
  216. package/src/desktop/desktop-chrome-policy.ts +42 -0
  217. package/src/desktop/desktop-dependencies.test.ts +102 -0
  218. package/src/desktop/desktop-dependencies.ts +306 -0
  219. package/src/desktop/desktop-feature.test.ts +18 -0
  220. package/src/desktop/desktop-feature.ts +19 -0
  221. package/src/desktop/desktop-panel-config.test.ts +135 -0
  222. package/src/desktop/desktop-panel-config.ts +149 -0
  223. package/src/desktop/desktop-session-manager.test.ts +627 -0
  224. package/src/desktop/desktop-session-manager.ts +814 -0
  225. package/src/desktop/desktop-stream-bridge.test.ts +395 -0
  226. package/src/desktop/desktop-stream-bridge.ts +214 -0
  227. package/src/desktop/desktop-wallpaper.test.ts +191 -0
  228. package/src/desktop/desktop-wallpaper.ts +113 -0
  229. package/src/desktop/desktop-window-theme.ts +170 -0
  230. package/src/home/__tests__/feed-writer.test.ts +22 -0
  231. package/src/home/feed-writer.ts +11 -2
  232. package/src/hooks/types.ts +33 -0
  233. package/src/i18n/AGENTS.md +22 -0
  234. package/src/i18n/__tests__/i18n.test.ts +108 -0
  235. package/src/i18n/index.ts +16 -0
  236. package/src/i18n/locales.ts +93 -0
  237. package/src/i18n/messages.ts +61 -0
  238. package/src/i18n/title.ts +25 -0
  239. package/src/inbound/platform-callback-registration.ts +4 -5
  240. package/src/live-voice/__tests__/live-voice-metrics.test.ts +0 -3
  241. package/src/live-voice/__tests__/live-voice-progress.test.ts +15 -15
  242. package/src/live-voice/__tests__/live-voice-vad.test.ts +2 -2
  243. package/src/live-voice/__tests__/runtime-websocket-shell.test.ts +13 -69
  244. package/src/live-voice/live-voice-session.ts +213 -693
  245. package/src/live-voice/protocol.ts +0 -2
  246. package/src/mcp/__tests__/effective-config.test.ts +2 -2
  247. package/src/mcp/__tests__/workspace-mcp-config.test.ts +135 -0
  248. package/src/mcp/effective-config.ts +3 -3
  249. package/src/mcp/mcp-header-store.ts +29 -45
  250. package/src/mcp/spec-schema.ts +111 -0
  251. package/src/mcp/startup.ts +8 -4
  252. package/src/mcp/workspace-mcp-config.ts +188 -0
  253. package/src/messaging/provider.ts +10 -3
  254. package/src/messaging/providers/__tests__/proactive-address.test.ts +95 -0
  255. package/src/messaging/providers/callback-routing.ts +18 -0
  256. package/src/messaging/providers/channel-transport.ts +56 -0
  257. package/src/messaging/providers/discord/transport.ts +17 -0
  258. package/src/messaging/providers/slack/__tests__/adapter-token-routing.test.ts +6 -17
  259. package/src/messaging/providers/slack/adapter.ts +7 -44
  260. package/src/messaging/providers/slack/transport.ts +16 -0
  261. package/src/messaging/providers/telegram-bot/adapter.ts +1 -48
  262. package/src/messaging/providers/telegram-bot/client.ts +0 -26
  263. package/src/messaging/providers/telegram-bot/transport.ts +20 -0
  264. package/src/messaging/providers/whatsapp/adapter.ts +1 -48
  265. package/src/messaging/providers/whatsapp/transport.ts +18 -0
  266. package/src/monitoring/__tests__/workspace-git-heartbeat.test.ts +8 -0
  267. package/src/notifications/__tests__/assistant-reply-producer.test.ts +55 -0
  268. package/src/notifications/__tests__/guardian-feed-projection.test.ts +158 -2
  269. package/src/notifications/__tests__/home-feed-side-effect.test.ts +153 -3
  270. package/src/notifications/__tests__/schedule-result-producer.test.ts +99 -3
  271. package/src/notifications/adapters/macos.ts +3 -0
  272. package/src/notifications/assistant-reply-producer.ts +8 -3
  273. package/src/notifications/conversation-pairing.ts +36 -16
  274. package/src/notifications/delivered-post-record.ts +11 -1
  275. package/src/notifications/guardian-feed-projection.ts +125 -5
  276. package/src/notifications/home-feed-side-effect.ts +55 -7
  277. package/src/notifications/schedule-result-producer.ts +66 -22
  278. package/src/oauth/__tests__/seed-providers-managed.test.ts +54 -0
  279. package/src/oauth/byo-connection.test.ts +45 -0
  280. package/src/oauth/byo-connection.ts +36 -6
  281. package/src/oauth/connection-resolver.test.ts +73 -0
  282. package/src/oauth/connection-resolver.ts +95 -2
  283. package/src/oauth/seed-providers.ts +165 -0
  284. package/src/outbound-proxy/certs.ts +3 -5
  285. package/src/permissions/checker.test.ts +11 -6
  286. package/src/persistence/compaction-log-store-clickhouse.ts +3 -3
  287. package/src/persistence/conversation-crud.ts +71 -63
  288. package/src/persistence/conversation-lineage.ts +12 -4
  289. package/src/persistence/conversation-title-placeholders.ts +23 -0
  290. package/src/persistence/conversation-title-service.ts +9 -26
  291. package/src/persistence/llm-request-log-sink-clickhouse.ts +3 -3
  292. package/src/persistence/llm-request-log-source-clickhouse.ts +3 -3
  293. package/src/persistence/message-cursor.ts +78 -0
  294. package/src/persistence/message-reads.ts +30 -0
  295. package/src/persistence/migrations/157-invite-contact-id.ts +18 -6
  296. package/src/persistence/migrations/__tests__/157-invite-contact-id.test.ts +149 -0
  297. package/src/persistence/schema/memory-core.ts +5 -0
  298. package/src/platform/client.test.ts +4 -2
  299. package/src/platform/client.ts +2 -10
  300. package/src/plugin-api/constants.ts +2 -0
  301. package/src/plugin-api/index.ts +1 -0
  302. package/src/plugin-api/types.ts +2 -0
  303. package/src/plugins/defaults/index.ts +2 -0
  304. package/src/plugins/defaults/memory/__tests__/memory-retrospective-accounting.test.ts +46 -0
  305. package/src/plugins/defaults/memory/__tests__/memory-retrospective-cursor-backfill.test.ts +118 -0
  306. package/src/plugins/defaults/memory/__tests__/memory-retrospective-cursor-preserve.test.ts +83 -0
  307. package/src/plugins/defaults/memory/__tests__/memory-retrospective-enqueue.test.ts +9 -5
  308. package/src/plugins/defaults/memory/__tests__/memory-retrospective-job.test.ts +20 -10
  309. package/src/plugins/defaults/memory/__tests__/memory-retrospective-state.test.ts +219 -0
  310. package/src/plugins/defaults/memory/__tests__/memory-retrospective-sweep.test.ts +31 -0
  311. package/src/plugins/defaults/memory/__tests__/memory-retrospective-trigger-check.test.ts +63 -0
  312. package/src/plugins/defaults/memory/__tests__/shutdown-hook.test.ts +4 -0
  313. package/src/plugins/defaults/memory/graph/capability-seed.ts +4 -6
  314. package/src/plugins/defaults/memory/hooks/init.ts +10 -0
  315. package/src/plugins/defaults/memory/hooks/message-deleted.ts +21 -0
  316. package/src/plugins/defaults/memory/hooks/shutdown.ts +2 -0
  317. package/src/plugins/defaults/memory/jobs-worker.ts +13 -0
  318. package/src/plugins/defaults/memory/memory-retrospective-accounting.ts +34 -60
  319. package/src/plugins/defaults/memory/memory-retrospective-cursor-backfill.ts +126 -0
  320. package/src/plugins/defaults/memory/memory-retrospective-cursor-preserve.ts +79 -0
  321. package/src/plugins/defaults/memory/memory-retrospective-cursor.ts +28 -0
  322. package/src/plugins/defaults/memory/memory-retrospective-enqueue.ts +3 -5
  323. package/src/plugins/defaults/memory/memory-retrospective-job.ts +12 -3
  324. package/src/plugins/defaults/memory/memory-retrospective-state.ts +312 -71
  325. package/src/plugins/defaults/memory/memory-retrospective-sweep.ts +2 -1
  326. package/src/plugins/defaults/memory/memory-retrospective-trigger-check.ts +5 -3
  327. package/src/plugins/defaults/memory/skill-md-mtime-poll.ts +9 -0
  328. package/src/plugins/defaults/memory/startup.ts +6 -1
  329. package/src/plugins/defaults/memory/substrate/__tests__/skill-content.test.ts +7 -9
  330. package/src/plugins/defaults/memory/substrate/skill-content.ts +2 -2
  331. package/src/plugins/defaults/memory/v3/__tests__/pool-select.test.ts +89 -0
  332. package/src/plugins/defaults/memory/worker.ts +6 -0
  333. package/src/plugins/mcp-servers.ts +15 -75
  334. package/src/providers/__tests__/connection-model-compat.test.ts +3 -3
  335. package/src/providers/gemini/client.ts +9 -23
  336. package/src/providers/gemini-thought-signature.test.ts +63 -0
  337. package/src/providers/gemini-thought-signature.ts +44 -0
  338. package/src/providers/inference/auth.ts +2 -3
  339. package/src/providers/inference/connection-availability.ts +27 -8
  340. package/src/providers/inference/resolve-auth.ts +22 -4
  341. package/src/providers/inference/service-account-token.ts +248 -0
  342. package/src/providers/model-catalog.ts +34 -0
  343. package/src/providers/model-intents.ts +10 -5
  344. package/src/providers/openai/__tests__/chat-completions-provider-reasoning.test.ts +146 -18
  345. package/src/providers/openai/__tests__/chat-completions-provider-thought-signature.test.ts +613 -0
  346. package/src/providers/openai/__tests__/google-thought-signature.test.ts +235 -0
  347. package/src/providers/openai/__tests__/tool-choice-mapping.test.ts +83 -1
  348. package/src/providers/openai/chat-completions-provider.ts +192 -78
  349. package/src/providers/openai/codex-models.ts +0 -4
  350. package/src/providers/openai/google-thought-signature.ts +320 -0
  351. package/src/runtime/AGENTS.md +2 -0
  352. package/src/runtime/__tests__/channel-send.test.ts +443 -0
  353. package/src/runtime/__tests__/desktop-stream-upgrade.test.ts +89 -0
  354. package/src/runtime/__tests__/live-voice-upgrade.test.ts +58 -0
  355. package/src/runtime/__tests__/runtime-ws-test-utils.ts +72 -0
  356. package/src/runtime/__tests__/watch-stream-upgrade.test.ts +59 -0
  357. package/src/runtime/auth/same-actor.ts +38 -3
  358. package/src/runtime/channel-send.ts +316 -0
  359. package/src/runtime/http-server.ts +160 -151
  360. package/src/runtime/routes/__tests__/acp-routes.test.ts +159 -4
  361. package/src/runtime/routes/__tests__/apps-refresh-route.test.ts +205 -0
  362. package/src/runtime/routes/__tests__/channel-send-routes.test.ts +127 -0
  363. package/src/runtime/routes/__tests__/conversation-query-routes.test.ts +108 -1
  364. package/src/runtime/routes/__tests__/default-provider-routes.test.ts +2 -2
  365. package/src/runtime/routes/__tests__/dictation-cleanup-guard.test.ts +107 -0
  366. package/src/runtime/routes/__tests__/mcp-add-default-risk.test.ts +16 -12
  367. package/src/runtime/routes/acp-routes.test.ts +15 -0
  368. package/src/runtime/routes/acp-routes.ts +72 -9
  369. package/src/runtime/routes/app-management-routes.ts +73 -0
  370. package/src/runtime/routes/app-routes.ts +1 -1
  371. package/src/runtime/routes/channel-send-routes.ts +85 -0
  372. package/src/runtime/routes/conversation-list-routes.ts +14 -3
  373. package/src/runtime/routes/conversation-query-routes.ts +40 -0
  374. package/src/runtime/routes/credential-routes.ts +19 -10
  375. package/src/runtime/routes/desktop-setup-routes.test.ts +74 -0
  376. package/src/runtime/routes/desktop-setup-routes.ts +35 -0
  377. package/src/runtime/routes/diagnostics-routes.ts +55 -3
  378. package/src/runtime/routes/index.ts +4 -2
  379. package/src/runtime/routes/log-export-routes.ts +2 -0
  380. package/src/runtime/routes/mcp-auth-routes.ts +39 -47
  381. package/src/runtime/routes/migration-routes.ts +6 -20
  382. package/src/runtime/routes/platform-routes.ts +18 -15
  383. package/src/runtime/services/__tests__/conversation-serializer.test.ts +28 -0
  384. package/src/runtime/services/conversation-serializer.ts +16 -3
  385. package/src/runtime/sync/resource-sync-events.ts +2 -1
  386. package/src/schedule/worker.ts +1 -1
  387. package/src/security/__tests__/ces-http-record-backend.test.ts +137 -0
  388. package/src/security/ces-http-record-backend.ts +120 -0
  389. package/src/security/ces-rpc-record-backend.ts +7 -0
  390. package/src/skills/__tests__/workspace-skill-md-signature.test.ts +60 -0
  391. package/src/skills/workspace-skill-md-signature.ts +50 -0
  392. package/src/subagent/consult-context.ts +12 -25
  393. package/src/tools/acp/list-agents.test.ts +3 -1
  394. package/src/tools/acp/spawn.test.ts +146 -11
  395. package/src/tools/acp/spawn.ts +21 -3
  396. package/src/tools/acp/status.test.ts +94 -0
  397. package/src/tools/acp/status.ts +40 -3
  398. package/src/tools/app-control/skill-proxy-bridge.ts +2 -1
  399. package/src/tools/capability-offer.test.ts +22 -2
  400. package/src/tools/capability-offer.ts +16 -1
  401. package/src/tools/computer-use/definitions.ts +4 -2
  402. package/src/tools/computer-use/skill-proxy-bridge.ts +2 -1
  403. package/src/tools/credentials/metadata-store.ts +100 -0
  404. package/src/tools/host-filesystem/edit.test.ts +2 -1
  405. package/src/tools/host-filesystem/edit.ts +2 -2
  406. package/src/tools/host-filesystem/read.test.ts +2 -1
  407. package/src/tools/host-filesystem/read.ts +2 -2
  408. package/src/tools/host-filesystem/transfer.test.ts +2 -1
  409. package/src/tools/host-filesystem/transfer.ts +2 -2
  410. package/src/tools/host-filesystem/write.test.ts +2 -1
  411. package/src/tools/host-filesystem/write.ts +2 -2
  412. package/src/tools/host-terminal/host-shell.test.ts +16 -0
  413. package/src/tools/host-terminal/host-shell.ts +4 -20
  414. package/src/tools/policy-context.ts +6 -7
  415. package/src/tools/subagent/spawn.ts +5 -8
  416. package/src/tools/terminal/__tests__/safe-env.test.ts +6 -6
  417. package/src/tools/terminal/__tests__/sanitized-bash.test.ts +57 -0
  418. package/src/tools/terminal/safe-env.ts +23 -3
  419. package/src/tools/terminal/sanitized-bash.ts +105 -0
  420. package/src/tools/watch/watch-retro-report.ts +0 -8
  421. package/src/util/__tests__/language-subtag.test.ts +23 -1
  422. package/src/util/ca-bundle.ts +13 -0
  423. package/src/util/language-subtag.ts +16 -0
  424. package/src/util/platform.ts +8 -0
  425. package/src/workspace/git-porcelain.ts +66 -0
  426. package/src/workspace/git-service.ts +5 -54
  427. package/src/workspace/migrations/154-repair-retired-codex-gpt-5-4-model-ids.ts +258 -0
  428. package/src/workspace/migrations/155-move-front-model-config-to-voice.ts +78 -0
  429. package/src/workspace/migrations/156-extract-workspace-mcp-json.ts +214 -0
  430. package/src/workspace/migrations/__tests__/155-move-front-model-config-to-voice.test.ts +102 -0
  431. package/src/workspace/migrations/__tests__/156-extract-workspace-mcp-json.test.ts +199 -0
  432. package/src/workspace/migrations/registry.ts +6 -0
  433. package/src/__tests__/app-source-watcher.test.ts +0 -218
  434. package/src/__tests__/config-watcher-skill-reseed.test.ts +0 -359
  435. package/src/__tests__/speaker-identification.test.ts +0 -56
  436. package/src/calls/speaker-identification.ts +0 -233
  437. package/src/daemon/app-source-watcher.ts +0 -218
  438. package/src/messaging/providers/whatsapp/client.ts +0 -29
  439. package/src/runtime/routes/debug-bash-routes.ts +0 -173
  440. package/src/util/fs-watcher-error.ts +0 -36
  441. /package/src/{live-voice → calls}/progress-phrases.ts +0 -0
@@ -0,0 +1,126 @@
1
+ // ---------------------------------------------------------------------------
2
+ // Memory retrospective: cursor timestamp backfill.
3
+ // ---------------------------------------------------------------------------
4
+ //
5
+ // State rows written before `last_processed_created_at` existed carry an
6
+ // id-only cursor, which stops bounding reads the moment its row is deleted
7
+ // (see `memory-retrospective-state.ts`). This pass copies `createdAt` from
8
+ // each such row's message while the message still exists. Rows whose message
9
+ // is already gone stay NULL: nothing remains to recover, and they are counted
10
+ // so the stall is visible in the log. Runs detached at daemon init (ahead of
11
+ // any client regenerating a reply) and again at memory-worker startup;
12
+ // idempotent, keyset-paginated by conversation id, and yielding between pages.
13
+
14
+ import { and, asc, eq, gt, isNull, ne } from "drizzle-orm";
15
+
16
+ import { messageCreatedAtByIds } from "../../../persistence/message-reads.js";
17
+ import { memoryRetrospectiveState } from "../../../persistence/schema/index.js";
18
+ import { withSqliteRetry } from "./host-utils.js";
19
+ import { getLogger } from "./logging.js";
20
+ import { memoryDbOrNull } from "./memory-db.js";
21
+ import { ensureRetrospectiveCursorColumn } from "./memory-retrospective-state.js";
22
+
23
+ const log = getLogger("memory-retrospective-cursor-backfill");
24
+
25
+ const DEFAULT_PAGE_SIZE = 500;
26
+
27
+ export interface CursorBackfillResult {
28
+ /** Rows with a cursor id but no timestamp. */
29
+ scanned: number;
30
+ /** Rows whose message still exists and received its `createdAt`. */
31
+ backfilled: number;
32
+ /** Rows whose cursor message no longer exists; left NULL. */
33
+ unrecoverable: number;
34
+ }
35
+
36
+ /**
37
+ * Fill `last_processed_created_at` on every state row that has a cursor id
38
+ * but no timestamp. Best-effort: a missing memory connection or column is a
39
+ * no-op, and a row the job rewrites mid-pass is skipped by the update's
40
+ * `IS NULL` guard rather than stomped. Pages by conversation id so a large
41
+ * backlog never materializes at once or holds the event loop.
42
+ */
43
+ export async function backfillRetrospectiveCursorTimestamps(opts?: {
44
+ pageSize?: number;
45
+ }): Promise<CursorBackfillResult> {
46
+ const pageSize = opts?.pageSize ?? DEFAULT_PAGE_SIZE;
47
+ const result: CursorBackfillResult = {
48
+ scanned: 0,
49
+ backfilled: 0,
50
+ unrecoverable: 0,
51
+ };
52
+ const context = "backfillRetrospectiveCursorTimestamps";
53
+ const mdb = memoryDbOrNull(context);
54
+ if (!mdb || !ensureRetrospectiveCursorColumn(context)) {
55
+ return result;
56
+ }
57
+
58
+ let afterConversationId = "";
59
+ for (;;) {
60
+ const page = mdb
61
+ .select({
62
+ conversationId: memoryRetrospectiveState.conversationId,
63
+ messageId: memoryRetrospectiveState.lastProcessedMessageId,
64
+ })
65
+ .from(memoryRetrospectiveState)
66
+ .where(
67
+ and(
68
+ isNull(memoryRetrospectiveState.lastProcessedCreatedAt),
69
+ ne(memoryRetrospectiveState.lastProcessedMessageId, ""),
70
+ gt(memoryRetrospectiveState.conversationId, afterConversationId),
71
+ ),
72
+ )
73
+ .orderBy(asc(memoryRetrospectiveState.conversationId))
74
+ .limit(pageSize)
75
+ .all();
76
+ if (page.length === 0) {
77
+ break;
78
+ }
79
+ afterConversationId = page[page.length - 1]!.conversationId;
80
+ result.scanned += page.length;
81
+
82
+ const createdAtById = messageCreatedAtByIds(
83
+ page.map((row) => row.messageId),
84
+ );
85
+ const recoverable = page.flatMap((row) => {
86
+ const createdAt = createdAtById.get(row.messageId);
87
+ return createdAt === undefined ? [] : [{ ...row, createdAt }];
88
+ });
89
+ result.unrecoverable += page.length - recoverable.length;
90
+
91
+ if (recoverable.length > 0) {
92
+ await withSqliteRetry(
93
+ () => {
94
+ mdb.transaction((tx) => {
95
+ for (const row of recoverable) {
96
+ tx.update(memoryRetrospectiveState)
97
+ .set({ lastProcessedCreatedAt: row.createdAt })
98
+ .where(
99
+ and(
100
+ eq(
101
+ memoryRetrospectiveState.conversationId,
102
+ row.conversationId,
103
+ ),
104
+ eq(
105
+ memoryRetrospectiveState.lastProcessedMessageId,
106
+ row.messageId,
107
+ ),
108
+ isNull(memoryRetrospectiveState.lastProcessedCreatedAt),
109
+ ),
110
+ )
111
+ .run();
112
+ }
113
+ });
114
+ },
115
+ { op: context, context: { afterConversationId } },
116
+ );
117
+ result.backfilled += recoverable.length;
118
+ }
119
+ await Bun.sleep(0);
120
+ }
121
+
122
+ if (result.backfilled > 0 || result.unrecoverable > 0) {
123
+ log.info(result, "Retrospective cursor timestamps backfilled");
124
+ }
125
+ return result;
126
+ }
@@ -0,0 +1,79 @@
1
+ // ---------------------------------------------------------------------------
2
+ // Memory retrospective: keep the cursor's timestamp when its row is deleted.
3
+ // ---------------------------------------------------------------------------
4
+ //
5
+ // The cursor normally sits on the latest assistant reply, and the retry route
6
+ // deletes exactly that row when the user regenerates it. A cursor written
7
+ // before the timestamp column existed carries only the id, so once the row is
8
+ // gone nothing can place it. The `message-deleted` hook delivers each deleted
9
+ // row's `(createdAt, id)` here: when the conversation's cursor is among the
10
+ // rows and has no timestamp yet, the row's `createdAt` is recorded. The
11
+ // timestamps travel in the call, so the write does not need the rows to
12
+ // still exist.
13
+
14
+ import { and, eq, isNull } from "drizzle-orm";
15
+
16
+ import { memoryRetrospectiveState } from "../../../persistence/schema/index.js";
17
+ import { withSqliteRetry } from "./host-utils.js";
18
+ import { getLogger } from "./logging.js";
19
+ import { memoryDbOrNull } from "./memory-db.js";
20
+ import { ensureRetrospectiveCursorColumn } from "./memory-retrospective-state.js";
21
+
22
+ const log = getLogger("memory-retrospective-cursor-preserve");
23
+
24
+ /**
25
+ * Record `createdAt` on the conversation's retrospective cursor when it points
26
+ * at one of `rows` and has no timestamp yet. Best-effort: an unavailable
27
+ * memory connection or column is a no-op, and a cursor the job has moved
28
+ * since the caller read it is skipped by the `IS NULL` guard.
29
+ */
30
+ export async function preserveRetrospectiveCursorTimestamps(
31
+ conversationId: string,
32
+ rows: ReadonlyArray<{ id: string; createdAt: number }>,
33
+ ): Promise<void> {
34
+ if (rows.length === 0) {
35
+ return;
36
+ }
37
+ const context = "preserveRetrospectiveCursorTimestamps";
38
+ try {
39
+ const mdb = memoryDbOrNull(context);
40
+ if (!mdb || !ensureRetrospectiveCursorColumn(context)) {
41
+ return;
42
+ }
43
+ const state = mdb
44
+ .select({
45
+ messageId: memoryRetrospectiveState.lastProcessedMessageId,
46
+ createdAt: memoryRetrospectiveState.lastProcessedCreatedAt,
47
+ })
48
+ .from(memoryRetrospectiveState)
49
+ .where(eq(memoryRetrospectiveState.conversationId, conversationId))
50
+ .get();
51
+ if (!state || state.createdAt !== null) {
52
+ return;
53
+ }
54
+ const row = rows.find((candidate) => candidate.id === state.messageId);
55
+ if (!row) {
56
+ return;
57
+ }
58
+ await withSqliteRetry(
59
+ () =>
60
+ mdb
61
+ .update(memoryRetrospectiveState)
62
+ .set({ lastProcessedCreatedAt: row.createdAt })
63
+ .where(
64
+ and(
65
+ eq(memoryRetrospectiveState.conversationId, conversationId),
66
+ eq(memoryRetrospectiveState.lastProcessedMessageId, row.id),
67
+ isNull(memoryRetrospectiveState.lastProcessedCreatedAt),
68
+ ),
69
+ )
70
+ .run(),
71
+ { op: context, context: { conversationId } },
72
+ );
73
+ } catch (err) {
74
+ log.warn(
75
+ { err, conversationId },
76
+ "could not preserve the retrospective cursor timestamp before its row was deleted",
77
+ );
78
+ }
79
+ }
@@ -0,0 +1,28 @@
1
+ // ---------------------------------------------------------------------------
2
+ // Memory retrospective: the cursor a state row hands to the messages-after
3
+ // reads.
4
+ // ---------------------------------------------------------------------------
5
+
6
+ import type { MessageCursor } from "../../../persistence/message-cursor.js";
7
+
8
+ /**
9
+ * The `(createdAt, id)` cursor a retrospective state row carries, or null
10
+ * when nothing has been processed yet (no row, or the `""` sentinel left by
11
+ * failure-only attempts). The timestamp lets the reads keep their bound after
12
+ * the cursor's row is deleted, which is what a regenerated reply does to the
13
+ * latest assistant message the cursor usually sits on.
14
+ */
15
+ export function retrospectiveCursor(
16
+ state: {
17
+ lastProcessedMessageId: string;
18
+ lastProcessedCreatedAt?: number | null;
19
+ } | null,
20
+ ): MessageCursor | null {
21
+ if (!state || state.lastProcessedMessageId === "") {
22
+ return null;
23
+ }
24
+ return {
25
+ id: state.lastProcessedMessageId,
26
+ createdAt: state.lastProcessedCreatedAt ?? null,
27
+ };
28
+ }
@@ -47,6 +47,7 @@ import { resolveCapabilities } from "../../../runtime/capabilities.js";
47
47
  import { getLogger } from "./logging.js";
48
48
  import { hasQualifyingUserMessageAfter } from "./memory-retrospective-accounting.js";
49
49
  import { isMemoryRetrospectiveSource } from "./memory-retrospective-constants.js";
50
+ import { retrospectiveCursor } from "./memory-retrospective-cursor.js";
50
51
  import { getRetrospectiveState } from "./memory-retrospective-state.js";
51
52
 
52
53
  const log = getLogger("memory-retrospective-enqueue");
@@ -139,7 +140,7 @@ function isRetrospectiveEnabled(): boolean {
139
140
  /**
140
141
  * The `memory.retrospective.requireUserActivity` gate: pass when the config
141
142
  * is off or the unprocessed tail (everything after the conversation's
142
- * `lastProcessedMessageId`) contains at least one user message carrying
143
+ * retrospective cursor) contains at least one user message carrying
143
144
  * non-tool_result content. A gate that cannot be evaluated (config or DB
144
145
  * unavailable) passes — an unevaluable gate must not silence retrospectives.
145
146
  */
@@ -153,10 +154,7 @@ function passesUserActivityGate(
153
154
  }
154
155
  const state = getRetrospectiveState(conversationId);
155
156
  if (
156
- hasQualifyingUserMessageAfter(
157
- conversationId,
158
- state?.lastProcessedMessageId ?? null,
159
- )
157
+ hasQualifyingUserMessageAfter(conversationId, retrospectiveCursor(state))
160
158
  ) {
161
159
  return true;
162
160
  }
@@ -58,7 +58,7 @@ import {
58
58
  parseClientOs,
59
59
  parseInterfaceId,
60
60
  } from "../../../channels/types.js";
61
- import { isV3TierActive } from "../../../config/memory-v3-gate.js";
61
+ import { isSkillImprovementActive } from "../../../config/memory-v3-gate.js";
62
62
  import type { AssistantConfig } from "../../../config/types.js";
63
63
  import { warmGuardianBindings } from "../../../contacts/guardian-delivery-reader.js";
64
64
  import { extractTurnContextTimestamp } from "../../../context/compactor.js";
@@ -95,6 +95,7 @@ import {
95
95
  MEMORY_RETROSPECTIVE_SOURCE,
96
96
  SKILL_MANAGEMENT_SKILL_ID,
97
97
  } from "./memory-retrospective-constants.js";
98
+ import { retrospectiveCursor } from "./memory-retrospective-cursor.js";
98
99
  import { loadRetrospectiveRunMessages } from "./memory-retrospective-fork-boundary.js";
99
100
  import { buildForkInstruction } from "./memory-retrospective-prompt.js";
100
101
  import {
@@ -357,7 +358,7 @@ export async function runForkBasedRetrospective(
357
358
  // `memory-retrospective-accounting.ts`.
358
359
  const newMessages = getRetrospectiveMessagesAfter(
359
360
  sourceConversationId,
360
- lastProcessedMessageId,
361
+ retrospectiveCursor(state),
361
362
  );
362
363
 
363
364
  if (newMessages.length === 0) {
@@ -448,7 +449,7 @@ export async function runForkBasedRetrospective(
448
449
  }
449
450
  const forkId = forkConversationRow.id;
450
451
 
451
- const procToSkillsActive = isV3TierActive(config);
452
+ const procToSkillsActive = isSkillImprovementActive(config);
452
453
  const instruction = buildForkInstruction({
453
454
  windowStartTimestamp,
454
455
  windowAnchorKind: turnContextTimestamp ? "turn_context" : "created_at",
@@ -650,6 +651,7 @@ export async function runForkBasedRetrospective(
650
651
  sourceConversationId,
651
652
  retrospectiveConversationId: forkId,
652
653
  cutoffMessageId,
654
+ cutoffCreatedAt: cutoffMessage.createdAt,
653
655
  newMessageCount: newMessages.length,
654
656
  prior,
655
657
  priorRemembers,
@@ -947,6 +949,11 @@ async function finalizeSuccessfulRetrospective(args: {
947
949
  sourceConversationId: string;
948
950
  retrospectiveConversationId: string;
949
951
  cutoffMessageId: string;
952
+ /**
953
+ * `createdAt` of the cutoff row, persisted beside its id so the cursor
954
+ * keeps bounding reads after the row is deleted.
955
+ */
956
+ cutoffCreatedAt: number;
950
957
  newMessageCount: number;
951
958
  prior: PriorRetrospective | null;
952
959
  priorRemembers: string[];
@@ -966,6 +973,7 @@ async function finalizeSuccessfulRetrospective(args: {
966
973
  sourceConversationId,
967
974
  retrospectiveConversationId,
968
975
  cutoffMessageId,
976
+ cutoffCreatedAt,
969
977
  newMessageCount,
970
978
  prior,
971
979
  priorRemembers,
@@ -977,6 +985,7 @@ async function finalizeSuccessfulRetrospective(args: {
977
985
  await upsertRetrospectiveState({
978
986
  conversationId: sourceConversationId,
979
987
  lastProcessedMessageId: cutoffMessageId,
988
+ lastProcessedCreatedAt: cutoffCreatedAt,
980
989
  lastRunAt: Date.now(),
981
990
  rememberedLog: appendToRememberedLog(priorRemembers, runRemembers),
982
991
  });