@vellumai/assistant 0.12.1-dev.202609141913.5e16607 → 0.12.1-staging.2

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 (439) hide show
  1. package/AGENTS.md +0 -4
  2. package/ARCHITECTURE.md +12 -11
  3. package/docs/architecture/turn-actor.md +8 -15
  4. package/docs/guardian-request-flow.md +0 -16
  5. package/openapi.yaml +49 -291
  6. package/package.json +1 -1
  7. package/src/__tests__/always-loaded-tools-guard.test.ts +10 -18
  8. package/src/__tests__/app-compiler.test.ts +0 -6
  9. package/src/__tests__/app-control-tool-schemas.test.ts +2 -5
  10. package/src/__tests__/app-dir-path-guard.test.ts +3 -1
  11. package/src/__tests__/app-source-watcher.test.ts +218 -0
  12. package/src/{calls/__tests__ → __tests__}/call-controller.test.ts +82 -503
  13. package/src/__tests__/computer-use-skill-proxy-bridge.test.ts +2 -5
  14. package/src/__tests__/computer-use-tools.test.ts +5 -17
  15. package/src/__tests__/config-schema-cmd.test.ts +2 -2
  16. package/src/__tests__/config-schema.test.ts +29 -28
  17. package/src/__tests__/config-watcher-skill-reseed.test.ts +359 -0
  18. package/src/__tests__/config-watcher.test.ts +8 -23
  19. package/src/__tests__/connection-model-compat.test.ts +2 -2
  20. package/src/__tests__/conversation-key-store-disk-view.test.ts +1 -1
  21. package/src/__tests__/conversation-pairing.test.ts +0 -26
  22. package/src/__tests__/conversation-process-app-control-preactivation.test.ts +10 -4
  23. package/src/__tests__/conversation-queue.test.ts +207 -48
  24. package/src/__tests__/conversation-retry-discard.test.ts +1 -54
  25. package/src/__tests__/conversation-skill-tools.test.ts +0 -27
  26. package/src/__tests__/conversation-surfaces-app-control.test.ts +3 -8
  27. package/src/__tests__/conversation-surfaces-task-progress.test.ts +0 -67
  28. package/src/__tests__/conversation-title-service.test.ts +10 -14
  29. package/src/__tests__/conversation-tool-setup-app-refresh.test.ts +5 -3
  30. package/src/__tests__/conversation-tool-setup-attribution.test.ts +0 -51
  31. package/src/__tests__/credential-record-retire.test.ts +1 -171
  32. package/src/__tests__/credential-routes.test.ts +3 -212
  33. package/src/__tests__/credential-security-invariants.test.ts +2 -4
  34. package/src/__tests__/cu-unified-flow.test.ts +2 -8
  35. package/src/__tests__/document-sync-tags.test.ts +0 -25
  36. package/src/__tests__/drain-kick-guard.test.ts +2 -0
  37. package/src/__tests__/drain-requeue-on-contention.test.ts +6 -0
  38. package/src/__tests__/evict-conversations-for-reload.test.ts +1 -1
  39. package/src/__tests__/host-bash-proxy.test.ts +45 -26
  40. package/src/__tests__/host-browser-proxy.test.ts +17 -6
  41. package/src/__tests__/host-file-proxy-targeted.test.ts +0 -23
  42. package/src/__tests__/host-file-proxy.test.ts +23 -11
  43. package/src/__tests__/host-transfer-proxy-targeted.test.ts +9 -30
  44. package/src/__tests__/llm-catalog-parity.test.ts +0 -25
  45. package/src/__tests__/mcp-auth-routes.test.ts +9 -6
  46. package/src/__tests__/mcp-config-secret-boundary.test.ts +136 -78
  47. package/src/__tests__/mcp-health-check.test.ts +11 -8
  48. package/src/__tests__/mcp-list-plugin-servers.test.ts +10 -8
  49. package/src/{calls/__tests__ → __tests__}/media-stream-audio-transcode.test.ts +1 -1
  50. package/src/{calls/__tests__ → __tests__}/media-stream-output.test.ts +8 -37
  51. package/src/{calls/__tests__ → __tests__}/media-stream-parser.test.ts +1 -1
  52. package/src/{calls/__tests__ → __tests__}/media-stream-server-integration.test.ts +57 -150
  53. package/src/{calls/__tests__ → __tests__}/media-stream-stt-session.test.ts +5 -5
  54. package/src/{calls/__tests__ → __tests__}/media-turn-detector.test.ts +1 -1
  55. package/src/__tests__/messages-after-tiebreaker.test.ts +0 -91
  56. package/src/__tests__/messages-read-boundary-guard.test.ts +1 -1
  57. package/src/__tests__/messaging-send-tool.test.ts +548 -355
  58. package/src/__tests__/model-intents.test.ts +0 -3
  59. package/src/__tests__/notification-vellum-adapter.test.ts +2 -85
  60. package/src/__tests__/outlook-messaging-provider.test.ts +6 -6
  61. package/src/__tests__/platform-callback-registration.test.ts +16 -8
  62. package/src/__tests__/platform-client-verify-credential.test.ts +0 -2
  63. package/src/__tests__/plugin-import-boundary-guard.test.ts +0 -13
  64. package/src/__tests__/script-proxy-certs.test.ts +0 -35
  65. package/src/__tests__/skill-feature-flags-integration.test.ts +1 -1
  66. package/src/__tests__/skill-feature-flags.test.ts +2 -2
  67. package/src/__tests__/speaker-identification.test.ts +56 -0
  68. package/src/__tests__/subagent-tool-gate-mode.test.ts +3 -19
  69. package/src/__tests__/subagent-tools.test.ts +2 -3
  70. package/src/__tests__/telephony-tts-guard.test.ts +3 -38
  71. package/src/__tests__/vellum-self-knowledge-inline-command.test.ts +0 -4
  72. package/src/{calls/__tests__/voice-session-bridge-turn-flow.test.ts → __tests__/voice-session-bridge.test.ts} +12 -20
  73. package/src/__tests__/watch-retro-tool-availability.test.ts +17 -8
  74. package/src/__tests__/workspace-git-service.test.ts +0 -26
  75. package/src/acp/__tests__/agent-process.test.ts +4 -258
  76. package/src/acp/__tests__/auth-required.test.ts +0 -96
  77. package/src/acp/__tests__/client-handler.test.ts +2 -90
  78. package/src/acp/__tests__/session-manager-persistence.test.ts +1 -5
  79. package/src/acp/__tests__/session-manager-resume.test.ts +6 -270
  80. package/src/acp/__tests__/session-manager-usage.test.ts +2 -4
  81. package/src/acp/__tests__/session-manager.test.ts +4 -895
  82. package/src/acp/agent-process.test.ts +1 -4
  83. package/src/acp/agent-process.ts +9 -94
  84. package/src/acp/auth-required.ts +1 -50
  85. package/src/acp/auto-install.test.ts +7 -9
  86. package/src/acp/client-handler.ts +3 -16
  87. package/src/acp/resolve-agent.test.ts +6 -220
  88. package/src/acp/resolve-agent.ts +23 -88
  89. package/src/acp/session-manager.test.ts +3 -196
  90. package/src/acp/session-manager.ts +18 -441
  91. package/src/acp/types.ts +5 -50
  92. package/src/api/events/app-files-changed.ts +3 -4
  93. package/src/api/events/notification-intent.ts +0 -2
  94. package/src/api/index.ts +0 -6
  95. package/src/apps/app-store.ts +1 -1
  96. package/src/bundler/app-compiler.ts +0 -15
  97. package/src/calls/__tests__/voice-control-protocol.test.ts +25 -58
  98. package/src/calls/__tests__/voice-session-bridge.test.ts +1 -37
  99. package/src/calls/__tests__/voice-triage-escalate.test.ts +0 -105
  100. package/src/calls/call-constants.ts +4 -24
  101. package/src/calls/call-controller.ts +199 -499
  102. package/src/calls/call-transport.ts +0 -16
  103. package/src/calls/media-stream-output.ts +0 -32
  104. package/src/calls/media-stream-server.ts +30 -82
  105. package/src/calls/media-stream-stt-session.ts +0 -15
  106. package/src/calls/resolve-call-tts-provider.ts +2 -33
  107. package/src/calls/speaker-identification.ts +233 -0
  108. package/src/calls/tts-call-strategy.ts +5 -9
  109. package/src/calls/types.ts +0 -2
  110. package/src/calls/voice-control-protocol.ts +21 -53
  111. package/src/calls/voice-session-bridge.ts +46 -59
  112. package/src/calls/voice-triage-escalate.ts +56 -175
  113. package/src/cli/commands/apps.help.ts +13 -67
  114. package/src/cli/commands/apps.ts +0 -183
  115. package/src/cli/commands/bash.help.ts +13 -8
  116. package/src/cli/commands/bash.ts +25 -7
  117. package/src/cli/commands/channels/index.help.ts +2 -70
  118. package/src/cli/commands/channels/index.ts +3 -16
  119. package/src/cli/commands/credentials.help.ts +2 -6
  120. package/src/cli/commands/credentials.ts +2 -2
  121. package/src/cli/commands/mcp.help.ts +8 -8
  122. package/src/cli/commands/mcp.ts +1 -1
  123. package/src/cli/commands/roadmap.help.ts +1 -5
  124. package/src/cli/commands/roadmap.ts +1 -1
  125. package/src/cli/lib/bundled-marketplace.json +90 -103
  126. package/src/config/__tests__/default-profile-catalog.test.ts +0 -22
  127. package/src/config/__tests__/memory-retrospective-schema.test.ts +1 -15
  128. package/src/config/__tests__/platform-rehydration.test.ts +9 -99
  129. package/src/config/acp-defaults.test.ts +3 -13
  130. package/src/config/acp-defaults.ts +6 -23
  131. package/src/config/acp-schema.ts +2 -30
  132. package/src/config/bundled-skills/acp/SKILL.md +14 -22
  133. package/src/config/bundled-skills/acp/TOOLS.json +1 -5
  134. package/src/config/bundled-skills/app-builder/SKILL.md +9 -12
  135. package/src/config/bundled-skills/app-builder/references/CUSTOM_ROUTES.md +1 -1
  136. package/src/config/bundled-skills/messaging/SKILL.md +3 -3
  137. package/src/config/bundled-skills/messaging/TOOLS.json +3 -3
  138. package/src/config/bundled-skills/messaging/tools/messaging-send.ts +139 -67
  139. package/src/config/bundled-skills/phone-calls/references/TRANSCRIPTS.md +1 -1
  140. package/src/config/bundled-skills/schedule/SKILL.md +4 -3
  141. package/src/config/bundled-skills/screen-annotation/SKILL.md +1 -8
  142. package/src/config/bundled-skills/screen-annotation/tools/screen-annotation.test.ts +1 -4
  143. package/src/config/bundled-skills/skill-management/TOOLS.json +2 -2
  144. package/src/config/default-profile-catalog.ts +1 -1
  145. package/src/config/env.ts +2 -2
  146. package/src/config/feature-flag-registry.json +12 -24
  147. package/src/config/loader.ts +0 -1
  148. package/src/config/memory-v3-gate.test.ts +0 -31
  149. package/src/config/memory-v3-gate.ts +16 -20
  150. package/src/config/platform-rehydration.ts +27 -11
  151. package/src/config/schema.ts +2 -2
  152. package/src/config/schemas/__tests__/live-voice.test.ts +158 -8
  153. package/src/config/schemas/calls.ts +28 -1
  154. package/src/config/schemas/live-voice.ts +173 -1
  155. package/src/config/schemas/mcp.ts +1 -1
  156. package/src/config/schemas/memory-retrospective.ts +0 -10
  157. package/src/config/schemas/services.ts +0 -8
  158. package/src/config/schemas/skills.ts +14 -0
  159. package/src/credential-execution/process-manager.test.ts +19 -18
  160. package/src/daemon/__tests__/conversation-tool-setup.test.ts +121 -66
  161. package/src/daemon/__tests__/plugin-mcp-reconcile.test.ts +1 -4
  162. package/src/daemon/app-source-watcher.ts +218 -0
  163. package/src/daemon/config-watcher.ts +194 -13
  164. package/src/daemon/conversation-process.ts +64 -35
  165. package/src/daemon/conversation-skill-tools.ts +31 -13
  166. package/src/daemon/conversation-store.ts +1 -1
  167. package/src/daemon/conversation-surfaces.ts +8 -10
  168. package/src/daemon/conversation-tool-setup.ts +43 -37
  169. package/src/daemon/conversation.ts +3 -0
  170. package/src/daemon/host-bash-proxy.ts +12 -8
  171. package/src/daemon/host-browser-proxy.ts +1 -15
  172. package/src/daemon/host-file-proxy.ts +10 -8
  173. package/src/daemon/host-transfer-proxy.ts +18 -14
  174. package/src/daemon/lifecycle.ts +5 -0
  175. package/src/daemon/mcp-reload-service.ts +5 -5
  176. package/src/daemon/message-types/sync.ts +0 -1
  177. package/src/daemon/orphan-reaper.ts +1 -1
  178. package/src/daemon/providers-setup.ts +1 -1
  179. package/src/daemon/shutdown-handlers.ts +9 -1
  180. package/src/daemon/skill-memory-refresh.ts +0 -64
  181. package/src/daemon/tool-side-effects.ts +18 -7
  182. package/src/home/__tests__/feed-writer.test.ts +0 -22
  183. package/src/home/feed-writer.ts +2 -11
  184. package/src/hooks/types.ts +0 -33
  185. package/src/inbound/platform-callback-registration.ts +5 -4
  186. package/src/live-voice/__tests__/live-voice-metrics.test.ts +3 -0
  187. package/src/live-voice/__tests__/live-voice-progress.test.ts +15 -15
  188. package/src/live-voice/__tests__/live-voice-vad.test.ts +2 -2
  189. package/src/{calls → live-voice}/__tests__/progress-narration.test.ts +4 -4
  190. package/src/{calls → live-voice}/__tests__/progress-phrases.test.ts +1 -1
  191. package/src/live-voice/__tests__/runtime-websocket-shell.test.ts +69 -13
  192. package/src/live-voice/live-voice-session.ts +693 -213
  193. package/src/{calls → live-voice}/progress-narration.ts +2 -2
  194. package/src/live-voice/protocol.ts +2 -0
  195. package/src/mcp/__tests__/effective-config.test.ts +2 -2
  196. package/src/mcp/effective-config.ts +3 -3
  197. package/src/mcp/mcp-header-store.ts +45 -29
  198. package/src/mcp/startup.ts +4 -8
  199. package/src/messaging/provider.ts +3 -10
  200. package/src/messaging/providers/callback-routing.ts +0 -18
  201. package/src/messaging/providers/channel-transport.ts +0 -56
  202. package/src/messaging/providers/discord/transport.ts +0 -17
  203. package/src/messaging/providers/slack/__tests__/adapter-token-routing.test.ts +17 -6
  204. package/src/messaging/providers/slack/adapter.ts +44 -7
  205. package/src/messaging/providers/slack/transport.ts +0 -16
  206. package/src/messaging/providers/telegram-bot/adapter.ts +48 -1
  207. package/src/messaging/providers/telegram-bot/client.ts +26 -0
  208. package/src/messaging/providers/telegram-bot/transport.ts +0 -20
  209. package/src/messaging/providers/whatsapp/adapter.ts +48 -1
  210. package/src/messaging/providers/whatsapp/client.ts +29 -0
  211. package/src/messaging/providers/whatsapp/transport.ts +0 -18
  212. package/src/monitoring/__tests__/workspace-git-heartbeat.test.ts +0 -8
  213. package/src/notifications/__tests__/assistant-reply-producer.test.ts +0 -55
  214. package/src/notifications/__tests__/guardian-feed-projection.test.ts +2 -158
  215. package/src/notifications/__tests__/home-feed-side-effect.test.ts +3 -153
  216. package/src/notifications/__tests__/schedule-result-producer.test.ts +3 -99
  217. package/src/notifications/adapters/macos.ts +0 -3
  218. package/src/notifications/assistant-reply-producer.ts +3 -8
  219. package/src/notifications/conversation-pairing.ts +16 -36
  220. package/src/notifications/delivered-post-record.ts +1 -11
  221. package/src/notifications/guardian-feed-projection.ts +5 -125
  222. package/src/notifications/home-feed-side-effect.ts +7 -55
  223. package/src/notifications/schedule-result-producer.ts +22 -66
  224. package/src/oauth/__tests__/seed-providers-managed.test.ts +0 -54
  225. package/src/oauth/byo-connection.test.ts +0 -45
  226. package/src/oauth/byo-connection.ts +6 -36
  227. package/src/oauth/connection-resolver.test.ts +0 -73
  228. package/src/oauth/connection-resolver.ts +2 -95
  229. package/src/oauth/seed-providers.ts +0 -165
  230. package/src/outbound-proxy/certs.ts +5 -3
  231. package/src/permissions/checker.test.ts +6 -11
  232. package/src/persistence/compaction-log-store-clickhouse.ts +3 -3
  233. package/src/persistence/conversation-crud.ts +63 -71
  234. package/src/persistence/conversation-lineage.ts +4 -12
  235. package/src/persistence/conversation-title-service.ts +26 -9
  236. package/src/persistence/llm-request-log-sink-clickhouse.ts +3 -3
  237. package/src/persistence/llm-request-log-source-clickhouse.ts +3 -3
  238. package/src/persistence/message-reads.ts +0 -30
  239. package/src/persistence/migrations/157-invite-contact-id.ts +6 -18
  240. package/src/persistence/schema/memory-core.ts +0 -5
  241. package/src/platform/client.test.ts +2 -4
  242. package/src/platform/client.ts +10 -2
  243. package/src/plugin-api/constants.ts +0 -2
  244. package/src/plugin-api/index.ts +0 -1
  245. package/src/plugin-api/types.ts +0 -2
  246. package/src/plugins/defaults/index.ts +0 -2
  247. package/src/plugins/defaults/memory/__tests__/memory-retrospective-accounting.test.ts +0 -46
  248. package/src/plugins/defaults/memory/__tests__/memory-retrospective-enqueue.test.ts +5 -9
  249. package/src/plugins/defaults/memory/__tests__/memory-retrospective-job.test.ts +10 -20
  250. package/src/plugins/defaults/memory/__tests__/memory-retrospective-state.test.ts +0 -219
  251. package/src/plugins/defaults/memory/__tests__/memory-retrospective-sweep.test.ts +0 -31
  252. package/src/plugins/defaults/memory/__tests__/memory-retrospective-trigger-check.test.ts +0 -63
  253. package/src/plugins/defaults/memory/__tests__/shutdown-hook.test.ts +0 -4
  254. package/src/plugins/defaults/memory/graph/capability-seed.ts +6 -4
  255. package/src/plugins/defaults/memory/hooks/init.ts +0 -10
  256. package/src/plugins/defaults/memory/hooks/shutdown.ts +0 -2
  257. package/src/plugins/defaults/memory/jobs-worker.ts +0 -13
  258. package/src/plugins/defaults/memory/memory-retrospective-accounting.ts +60 -34
  259. package/src/plugins/defaults/memory/memory-retrospective-enqueue.ts +5 -3
  260. package/src/plugins/defaults/memory/memory-retrospective-job.ts +3 -12
  261. package/src/plugins/defaults/memory/memory-retrospective-state.ts +71 -312
  262. package/src/plugins/defaults/memory/memory-retrospective-sweep.ts +1 -2
  263. package/src/plugins/defaults/memory/memory-retrospective-trigger-check.ts +3 -5
  264. package/src/plugins/defaults/memory/startup.ts +1 -6
  265. package/src/plugins/defaults/memory/substrate/__tests__/skill-content.test.ts +9 -7
  266. package/src/plugins/defaults/memory/substrate/skill-content.ts +2 -2
  267. package/src/plugins/defaults/memory/v3/__tests__/pool-select.test.ts +0 -89
  268. package/src/plugins/defaults/memory/worker.ts +0 -6
  269. package/src/plugins/mcp-servers.ts +75 -15
  270. package/src/providers/__tests__/connection-model-compat.test.ts +3 -3
  271. package/src/providers/gemini/client.ts +23 -9
  272. package/src/providers/inference/auth.ts +3 -2
  273. package/src/providers/inference/connection-availability.ts +8 -27
  274. package/src/providers/inference/resolve-auth.ts +4 -22
  275. package/src/providers/model-catalog.ts +0 -34
  276. package/src/providers/model-intents.ts +5 -10
  277. package/src/providers/openai/__tests__/chat-completions-provider-reasoning.test.ts +18 -146
  278. package/src/providers/openai/__tests__/tool-choice-mapping.test.ts +1 -83
  279. package/src/providers/openai/chat-completions-provider.ts +78 -192
  280. package/src/providers/openai/codex-models.ts +4 -0
  281. package/src/runtime/AGENTS.md +0 -2
  282. package/src/runtime/auth/same-actor.ts +3 -38
  283. package/src/runtime/http-server.ts +151 -160
  284. package/src/runtime/routes/__tests__/acp-routes.test.ts +4 -159
  285. package/src/runtime/routes/__tests__/conversation-query-routes.test.ts +1 -108
  286. package/src/runtime/routes/__tests__/default-provider-routes.test.ts +2 -2
  287. package/src/runtime/routes/__tests__/mcp-add-default-risk.test.ts +12 -16
  288. package/src/runtime/routes/acp-routes.test.ts +0 -15
  289. package/src/runtime/routes/acp-routes.ts +9 -72
  290. package/src/runtime/routes/app-management-routes.ts +0 -73
  291. package/src/runtime/routes/app-routes.ts +1 -1
  292. package/src/runtime/routes/conversation-list-routes.ts +3 -14
  293. package/src/runtime/routes/conversation-query-routes.ts +0 -40
  294. package/src/runtime/routes/credential-routes.ts +10 -19
  295. package/src/runtime/routes/debug-bash-routes.ts +173 -0
  296. package/src/runtime/routes/diagnostics-routes.ts +3 -55
  297. package/src/runtime/routes/index.ts +2 -4
  298. package/src/runtime/routes/log-export-routes.ts +0 -2
  299. package/src/runtime/routes/mcp-auth-routes.ts +47 -39
  300. package/src/runtime/routes/migration-routes.ts +20 -6
  301. package/src/runtime/routes/platform-routes.ts +15 -18
  302. package/src/runtime/services/__tests__/conversation-serializer.test.ts +0 -28
  303. package/src/runtime/services/conversation-serializer.ts +3 -16
  304. package/src/runtime/sync/resource-sync-events.ts +1 -2
  305. package/src/schedule/worker.ts +1 -1
  306. package/src/security/ces-rpc-record-backend.ts +0 -7
  307. package/src/subagent/consult-context.ts +25 -12
  308. package/src/tools/acp/list-agents.test.ts +1 -3
  309. package/src/tools/acp/spawn.test.ts +11 -146
  310. package/src/tools/acp/spawn.ts +3 -21
  311. package/src/tools/acp/status.ts +3 -40
  312. package/src/tools/app-control/skill-proxy-bridge.ts +1 -2
  313. package/src/tools/capability-offer.test.ts +2 -22
  314. package/src/tools/capability-offer.ts +1 -16
  315. package/src/tools/computer-use/definitions.ts +2 -4
  316. package/src/tools/computer-use/skill-proxy-bridge.ts +1 -2
  317. package/src/tools/credentials/metadata-store.ts +0 -100
  318. package/src/tools/host-filesystem/edit.test.ts +1 -2
  319. package/src/tools/host-filesystem/edit.ts +2 -2
  320. package/src/tools/host-filesystem/read.test.ts +1 -2
  321. package/src/tools/host-filesystem/read.ts +2 -2
  322. package/src/tools/host-filesystem/transfer.test.ts +1 -2
  323. package/src/tools/host-filesystem/transfer.ts +2 -2
  324. package/src/tools/host-filesystem/write.test.ts +1 -2
  325. package/src/tools/host-filesystem/write.ts +2 -2
  326. package/src/tools/host-terminal/host-shell.test.ts +0 -16
  327. package/src/tools/host-terminal/host-shell.ts +20 -4
  328. package/src/tools/policy-context.ts +7 -6
  329. package/src/tools/subagent/spawn.ts +8 -5
  330. package/src/tools/watch/watch-retro-report.ts +8 -0
  331. package/src/util/__tests__/language-subtag.test.ts +1 -23
  332. package/src/util/fs-watcher-error.ts +36 -0
  333. package/src/util/language-subtag.ts +0 -16
  334. package/src/util/platform.ts +0 -8
  335. package/src/workspace/git-service.ts +54 -5
  336. package/src/workspace/migrations/registry.ts +0 -6
  337. package/scripts/smoke-desktop-window-theme.ts +0 -186
  338. package/src/__tests__/git-porcelain.test.ts +0 -47
  339. package/src/__tests__/helpers/set-workspace-mcp.ts +0 -11
  340. package/src/__tests__/message-deleted-hook-dispatch.test.ts +0 -119
  341. package/src/__tests__/resolve-app.test.ts +0 -135
  342. package/src/__tests__/service-account-token.test.ts +0 -247
  343. package/src/__tests__/source-fingerprint.test.ts +0 -184
  344. package/src/__tests__/workspace-migration-154-repair-retired-codex-gpt-5-4-model-ids.test.ts +0 -336
  345. package/src/acp/__tests__/helpers/acp-model-option.ts +0 -51
  346. package/src/acp/model-config.test.ts +0 -166
  347. package/src/acp/model-config.ts +0 -138
  348. package/src/api/events/acp-session-model-update.test.ts +0 -88
  349. package/src/api/events/acp-session-model-update.ts +0 -46
  350. package/src/apps/resolve-app.ts +0 -81
  351. package/src/apps/source-fingerprint.ts +0 -266
  352. package/src/calls/__tests__/barge-in-guard.test.ts +0 -81
  353. package/src/calls/__tests__/voice-leg-coordinator.test.ts +0 -229
  354. package/src/calls/__tests__/voice-progress-cadence.test.ts +0 -274
  355. package/src/calls/barge-in-guard.ts +0 -118
  356. package/src/calls/voice-leg-coordinator.ts +0 -189
  357. package/src/calls/voice-progress-cadence.ts +0 -423
  358. package/src/cli/commands/__tests__/apps.test.ts +0 -245
  359. package/src/cli/commands/__tests__/bash.test.ts +0 -53
  360. package/src/cli/commands/__tests__/roadmap.help.test.ts +0 -19
  361. package/src/cli/commands/channels/__tests__/send.test.ts +0 -218
  362. package/src/cli/commands/channels/send.ts +0 -128
  363. package/src/config/__tests__/platform-identity.test.ts +0 -255
  364. package/src/config/acp-agent-write.ts +0 -43
  365. package/src/config/acp-schema.test.ts +0 -81
  366. package/src/config/platform-identity.ts +0 -201
  367. package/src/config/schemas/__tests__/voice.test.ts +0 -148
  368. package/src/config/schemas/voice.ts +0 -150
  369. package/src/daemon/__tests__/skill-memory-refresh-mtime.test.ts +0 -133
  370. package/src/daemon/app-change-notify.ts +0 -45
  371. package/src/desktop/__tests__/fake-desktop.ts +0 -119
  372. package/src/desktop/desktop-chrome-policy.test.ts +0 -71
  373. package/src/desktop/desktop-chrome-policy.ts +0 -42
  374. package/src/desktop/desktop-dependencies.test.ts +0 -102
  375. package/src/desktop/desktop-dependencies.ts +0 -306
  376. package/src/desktop/desktop-feature.test.ts +0 -18
  377. package/src/desktop/desktop-feature.ts +0 -19
  378. package/src/desktop/desktop-panel-config.test.ts +0 -135
  379. package/src/desktop/desktop-panel-config.ts +0 -149
  380. package/src/desktop/desktop-session-manager.test.ts +0 -627
  381. package/src/desktop/desktop-session-manager.ts +0 -814
  382. package/src/desktop/desktop-stream-bridge.test.ts +0 -395
  383. package/src/desktop/desktop-stream-bridge.ts +0 -214
  384. package/src/desktop/desktop-wallpaper.test.ts +0 -191
  385. package/src/desktop/desktop-wallpaper.ts +0 -113
  386. package/src/desktop/desktop-window-theme.ts +0 -170
  387. package/src/i18n/AGENTS.md +0 -22
  388. package/src/i18n/__tests__/i18n.test.ts +0 -108
  389. package/src/i18n/index.ts +0 -16
  390. package/src/i18n/locales.ts +0 -93
  391. package/src/i18n/messages.ts +0 -61
  392. package/src/i18n/title.ts +0 -25
  393. package/src/mcp/__tests__/workspace-mcp-config.test.ts +0 -135
  394. package/src/mcp/spec-schema.ts +0 -111
  395. package/src/mcp/workspace-mcp-config.ts +0 -188
  396. package/src/messaging/providers/__tests__/proactive-address.test.ts +0 -95
  397. package/src/persistence/conversation-title-placeholders.ts +0 -23
  398. package/src/persistence/message-cursor.ts +0 -78
  399. package/src/persistence/migrations/__tests__/157-invite-contact-id.test.ts +0 -149
  400. package/src/plugins/defaults/memory/__tests__/memory-retrospective-cursor-backfill.test.ts +0 -118
  401. package/src/plugins/defaults/memory/__tests__/memory-retrospective-cursor-preserve.test.ts +0 -83
  402. package/src/plugins/defaults/memory/hooks/message-deleted.ts +0 -21
  403. package/src/plugins/defaults/memory/memory-retrospective-cursor-backfill.ts +0 -126
  404. package/src/plugins/defaults/memory/memory-retrospective-cursor-preserve.ts +0 -79
  405. package/src/plugins/defaults/memory/memory-retrospective-cursor.ts +0 -28
  406. package/src/plugins/defaults/memory/skill-md-mtime-poll.ts +0 -9
  407. package/src/providers/gemini-thought-signature.test.ts +0 -63
  408. package/src/providers/gemini-thought-signature.ts +0 -44
  409. package/src/providers/inference/service-account-token.ts +0 -248
  410. package/src/providers/openai/__tests__/chat-completions-provider-thought-signature.test.ts +0 -613
  411. package/src/providers/openai/__tests__/google-thought-signature.test.ts +0 -235
  412. package/src/providers/openai/google-thought-signature.ts +0 -320
  413. package/src/runtime/__tests__/channel-send.test.ts +0 -443
  414. package/src/runtime/__tests__/desktop-stream-upgrade.test.ts +0 -89
  415. package/src/runtime/__tests__/live-voice-upgrade.test.ts +0 -58
  416. package/src/runtime/__tests__/runtime-ws-test-utils.ts +0 -72
  417. package/src/runtime/__tests__/watch-stream-upgrade.test.ts +0 -59
  418. package/src/runtime/channel-send.ts +0 -316
  419. package/src/runtime/routes/__tests__/apps-refresh-route.test.ts +0 -205
  420. package/src/runtime/routes/__tests__/channel-send-routes.test.ts +0 -127
  421. package/src/runtime/routes/__tests__/dictation-cleanup-guard.test.ts +0 -107
  422. package/src/runtime/routes/channel-send-routes.ts +0 -85
  423. package/src/runtime/routes/desktop-setup-routes.test.ts +0 -74
  424. package/src/runtime/routes/desktop-setup-routes.ts +0 -35
  425. package/src/security/__tests__/ces-http-record-backend.test.ts +0 -137
  426. package/src/security/ces-http-record-backend.ts +0 -120
  427. package/src/skills/__tests__/workspace-skill-md-signature.test.ts +0 -60
  428. package/src/skills/workspace-skill-md-signature.ts +0 -50
  429. package/src/tools/acp/status.test.ts +0 -94
  430. package/src/tools/terminal/__tests__/sanitized-bash.test.ts +0 -57
  431. package/src/tools/terminal/sanitized-bash.ts +0 -105
  432. package/src/util/ca-bundle.ts +0 -13
  433. package/src/workspace/git-porcelain.ts +0 -66
  434. package/src/workspace/migrations/154-repair-retired-codex-gpt-5-4-model-ids.ts +0 -258
  435. package/src/workspace/migrations/155-move-front-model-config-to-voice.ts +0 -78
  436. package/src/workspace/migrations/156-extract-workspace-mcp-json.ts +0 -214
  437. package/src/workspace/migrations/__tests__/155-move-front-model-config-to-voice.test.ts +0 -102
  438. package/src/workspace/migrations/__tests__/156-extract-workspace-mcp-json.test.ts +0 -199
  439. /package/src/{calls → live-voice}/progress-phrases.ts +0 -0
@@ -159,31 +159,3 @@ describe("serializeConversationSummary · enabledPlugins", () => {
159
159
  expect("enabledPlugins" in summary).toBe(false);
160
160
  });
161
161
  });
162
-
163
- describe("serializeConversationSummary · title keys", () => {
164
- test("resolves a stored title key for the locale", () => {
165
- const summary = serializeConversationSummary({
166
- conversation: makeConversationRow({
167
- title: "conversation.title.generating",
168
- }),
169
- displayMeta: { displayOrder: null, isPinned: false, groupId: null },
170
- parentCache: new Map(),
171
- isProcessing: false,
172
- locale: "es",
173
- });
174
- expect(summary.title).toBe("Generando título...");
175
- expect("titleState" in summary).toBe(false);
176
- });
177
-
178
- test("passes a stored display string through", () => {
179
- const summary = serialize(
180
- makeConversationRow({ title: "Untitled Conversation" }),
181
- );
182
- expect(summary.title).toBe("Untitled Conversation");
183
- });
184
-
185
- test("passes a custom title through", () => {
186
- const summary = serialize(makeConversationRow({ title: "Weekly planning" }));
187
- expect(summary.title).toBe("Weekly planning");
188
- });
189
- });
@@ -8,10 +8,6 @@
8
8
 
9
9
  import { parseChannelId } from "../../channels/types.js";
10
10
  import { normalizeConversationType } from "../../daemon/message-types/shared.js";
11
- import {
12
- resolveConversationTitle,
13
- type SupportedLocale,
14
- } from "../../i18n/index.js";
15
11
  import { buildChannelBindingMetadata } from "../../messaging/channel-binding-metadata.js";
16
12
  import {
17
13
  type AttentionState,
@@ -82,7 +78,6 @@ interface ForkLineage {
82
78
  function buildForkLineage(
83
79
  conversation: ConversationRow,
84
80
  parentCache: Map<string, ConversationRow | null>,
85
- locale?: SupportedLocale,
86
81
  ): ForkLineage {
87
82
  const parentConversationId = conversation.forkParentConversationId;
88
83
  const parentMessageId = conversation.forkParentMessageId;
@@ -106,7 +101,7 @@ function buildForkLineage(
106
101
  forkParent: {
107
102
  conversationId: parentConversationId,
108
103
  messageId: parentMessageId,
109
- title: resolveConversationTitle(parentConversation.title, locale),
104
+ title: parentConversation.title ?? "Untitled",
110
105
  },
111
106
  };
112
107
  }
@@ -183,11 +178,6 @@ export function serializeConversationSummary(params: {
183
178
  * with no daemon-store coupling.
184
179
  */
185
180
  isProcessing: boolean;
186
- /**
187
- * Locale used to resolve stored title keys. Omitted locale is English
188
- * inside {@link resolveConversationTitle}.
189
- */
190
- locale?: SupportedLocale;
191
181
  }) {
192
182
  const {
193
183
  conversation,
@@ -196,15 +186,14 @@ export function serializeConversationSummary(params: {
196
186
  displayMeta,
197
187
  parentCache,
198
188
  isProcessing,
199
- locale,
200
189
  } = params;
201
190
  const originChannel = parseChannelId(conversation.originChannel);
202
191
  const assistantAttention = buildAssistantAttention(attentionState);
203
- const forkLineage = buildForkLineage(conversation, parentCache, locale);
192
+ const forkLineage = buildForkLineage(conversation, parentCache);
204
193
 
205
194
  return {
206
195
  id: conversation.id,
207
- title: resolveConversationTitle(conversation.title, locale),
196
+ title: conversation.title ?? "Untitled",
208
197
  createdAt: conversation.createdAt,
209
198
  updatedAt: conversation.updatedAt,
210
199
  lastMessageAt: conversation.lastMessageAt,
@@ -264,7 +253,6 @@ export function serializeConversationSummary(params: {
264
253
  */
265
254
  export function buildConversationDetailResponse(
266
255
  conversationId: string,
267
- locale?: SupportedLocale,
268
256
  ): { conversation: ReturnType<typeof serializeConversationSummary> } | null {
269
257
  const conversation = getConversation(conversationId);
270
258
  if (!conversation || conversation.conversationType === "private") {
@@ -286,7 +274,6 @@ export function buildConversationDetailResponse(
286
274
  // Checks in-memory flag first (hot path), falls back to the
287
275
  // persisted `processing_started_at` column for cold conversations.
288
276
  isProcessing: isConversationProcessing(conversation.id),
289
- locale,
290
277
  }),
291
278
  };
292
279
  }
@@ -4,7 +4,6 @@ import {
4
4
  conversationMetadataSyncTag,
5
5
  SYNC_TAGS,
6
6
  } from "../../daemon/message-types/sync.js";
7
- import { resolveConversationTitle } from "../../i18n/index.js";
8
7
  import { syncAvatarToPlatform } from "../../platform/sync-avatar.js";
9
8
  import { getAvatarImagePath } from "../../util/platform.js";
10
9
  import { broadcastMessage } from "../assistant-event-hub.js";
@@ -258,7 +257,7 @@ export function publishConversationTitleChanged(
258
257
  {
259
258
  type: "conversation_title_updated",
260
259
  conversationId,
261
- title: resolveConversationTitle(title),
260
+ title,
262
261
  },
263
262
  conversationId,
264
263
  );
@@ -195,7 +195,7 @@ async function main(): Promise<void> {
195
195
  //
196
196
  // Bounded by MCP_STARTUP_GRACE_MS: unreachable servers must not hold the
197
197
  // schedules that do not use them. The connect runs on past the deadline.
198
- const mcpStartup = startConfiguredMcpServers();
198
+ const mcpStartup = startConfiguredMcpServers(getConfig().mcp);
199
199
  await Promise.race([
200
200
  mcpStartup,
201
201
  // Unref'd so a connect that beats the deadline leaves nothing pending.
@@ -11,11 +11,6 @@ import { getLogger } from "../util/logger.js";
11
11
  const log = getLogger("ces-rpc-record-backend");
12
12
 
13
13
  export interface CredentialRecordBackend {
14
- /**
15
- * Transport id. `"ces-rpc"` is the attached CES socket backend; live
16
- * catalog listing fails over to CES HTTP when that transport is down.
17
- */
18
- readonly name?: string;
19
14
  isAvailable(): boolean;
20
15
  get(account: string): Promise<CredentialRecord | undefined>;
21
16
  set(account: string, record: CredentialRecord): Promise<boolean>;
@@ -34,8 +29,6 @@ export interface CredentialRecordBackend {
34
29
  }
35
30
 
36
31
  export class CesRpcRecordBackend implements CredentialRecordBackend {
37
- readonly name = "ces-rpc";
38
-
39
32
  constructor(private readonly client: CesClient) {}
40
33
 
41
34
  isAvailable(): boolean {
@@ -33,6 +33,7 @@
33
33
  import { readdir } from "node:fs/promises";
34
34
  import { join } from "node:path";
35
35
 
36
+ import type { SkillSummary } from "../config/skills.js";
36
37
  import type { TrustContext } from "../daemon/trust-context-types.js";
37
38
  import type { TrustClass } from "../runtime/actor-trust-resolver.js";
38
39
  import { truncate as truncateText } from "../util/truncate.js";
@@ -55,6 +56,15 @@ export interface AdvisorContextSources {
55
56
  * from the catalog section, mirroring the `skill_load` gate.
56
57
  */
57
58
  enabledPluginSet?: ReadonlySet<string> | null;
59
+ /**
60
+ * Pre-resolved skill catalog, typically the parent conversation's warm
61
+ * `skillProjectionCache.catalog`. Passing it keeps the synchronous on-disk
62
+ * catalog scan out of the consult path (and matches the catalog view the
63
+ * parent turn's tool projection used). When absent, the section falls back
64
+ * to a fresh `loadSkillCatalog()` scan, the same call every agent turn's
65
+ * projection already makes.
66
+ */
67
+ skillCatalog?: readonly SkillSummary[];
58
68
  }
59
69
 
60
70
  /** Cap a block so the assembled context never balloons the consult prompt. */
@@ -104,6 +114,7 @@ async function buildToolsSection(
104
114
  */
105
115
  async function buildSkillsSection(
106
116
  enabledPluginSet: ReadonlySet<string> | null | undefined,
117
+ preResolvedCatalog: readonly SkillSummary[] | undefined,
107
118
  ): Promise<string | null> {
108
119
  try {
109
120
  const [
@@ -119,17 +130,19 @@ async function buildSkillsSection(
119
130
  ]);
120
131
  const config = getConfig();
121
132
  const pluginScope = enabledPluginSet ?? null;
122
- const catalog = loadSkillCatalog().filter((skill) => {
123
- if (
124
- pluginScope !== null &&
125
- skill.owner?.kind === "plugin" &&
126
- !pluginScope.has(skill.owner.id)
127
- ) {
128
- return false;
129
- }
130
- const flagKey = skillFlagKey(skill);
131
- return !flagKey || isAssistantFeatureFlagEnabled(flagKey, config);
132
- });
133
+ const catalog = (preResolvedCatalog ?? loadSkillCatalog()).filter(
134
+ (skill) => {
135
+ if (
136
+ pluginScope !== null &&
137
+ skill.owner?.kind === "plugin" &&
138
+ !pluginScope.has(skill.owner.id)
139
+ ) {
140
+ return false;
141
+ }
142
+ const flagKey = skillFlagKey(skill);
143
+ return !flagKey || isAssistantFeatureFlagEnabled(flagKey, config);
144
+ },
145
+ );
133
146
  if (catalog.length === 0) {
134
147
  return null;
135
148
  }
@@ -371,7 +384,7 @@ export async function buildAdvisorContext(
371
384
  const sections = await Promise.all(
372
385
  [
373
386
  buildToolsSection(sources.allowedToolNames),
374
- buildSkillsSection(sources.enabledPluginSet),
387
+ buildSkillsSection(sources.enabledPluginSet, sources.skillCatalog),
375
388
  buildWorkspaceSection(sources),
376
389
  ].map((section) => withSectionTimeout(section, sectionTimeoutMs)),
377
390
  );
@@ -90,9 +90,7 @@ describe("executeAcpListAgents", () => {
90
90
  const codex = parsed.agents.find((a: { id: string }) => a.id === "codex");
91
91
  expect(codex.available).toBe(false);
92
92
  expect(codex.unavailableReason).toBe("'codex-acp' is not on PATH");
93
- expect(codex.setupHint).toBe(
94
- "bun add -g @agentclientprotocol/codex-acp@1.10.0",
95
- );
93
+ expect(codex.setupHint).toBe("bun add -g @agentclientprotocol/codex-acp");
96
94
 
97
95
  const claude = parsed.agents.find((a: { id: string }) => a.id === "claude");
98
96
  expect(claude.available).toBe(true);
@@ -124,22 +124,11 @@ const spawnMock = mock(
124
124
  _cwd: string,
125
125
  _parentConversationId: string,
126
126
  _sendToVellum: (msg: unknown) => void,
127
- _options?: { parentToolUseId?: string; model?: string },
128
- ): Promise<{
129
- acpSessionId: string;
130
- protocolSessionId: string;
131
- requestedModel?: string;
132
- effectiveModel?: string;
133
- modelWarning?: string;
134
- }> => {
135
- const requestedModel = _options?.model?.trim() || undefined;
136
- return {
137
- acpSessionId: "acp-session-test",
138
- protocolSessionId: "proto-session-test",
139
- requestedModel,
140
- effectiveModel: "opus",
141
- };
142
- },
127
+ _parentToolUseId?: string,
128
+ ) => ({
129
+ acpSessionId: "acp-session-test",
130
+ protocolSessionId: "proto-session-test",
131
+ }),
143
132
  );
144
133
 
145
134
  // Spread the real module's exports so transitive importers that pull other
@@ -212,8 +201,6 @@ describe("executeAcpSpawn - happy path", () => {
212
201
  const payload = JSON.parse(result.content);
213
202
  expect(payload.acpSessionId).toBe("acp-session-test");
214
203
  expect(payload.status).toBe("running");
215
- expect(payload.requestedModel).toBeNull();
216
- expect(payload.effectiveModel).toBe("opus");
217
204
  // The real adapter binary is spawned (no `bun x` wrapper).
218
205
  const agentConfigArg = spawnMock.mock.calls[0][1] as { command: string };
219
206
  expect(agentConfigArg.command).toBe("claude-agent-acp");
@@ -227,10 +214,8 @@ describe("executeAcpSpawn - happy path", () => {
227
214
 
228
215
  expect(result.isError).toBe(false);
229
216
  expect(spawnMock).toHaveBeenCalledTimes(1);
230
- // The options bag is the 7th positional arg to spawn().
231
- expect(spawnMock.mock.calls[0][6]).toEqual({
232
- parentToolUseId: "toolu_abc123",
233
- });
217
+ // parentToolUseId is the 7th positional arg to spawn().
218
+ expect(spawnMock.mock.calls[0][6]).toBe("toolu_abc123");
234
219
  });
235
220
 
236
221
  test("default-profile fallback when user config is empty", async () => {
@@ -287,7 +272,7 @@ describe("executeAcpSpawn — input validation", () => {
287
272
  expect(result.isError).toBe(true);
288
273
  expect(result.content).toContain("claude-agent-acp is not on PATH");
289
274
  expect(result.content).toContain(
290
- "bun add -g @agentclientprotocol/claude-agent-acp@0.75.1",
275
+ "bun add -g @agentclientprotocol/claude-agent-acp",
291
276
  );
292
277
  expect(execFileMock).not.toHaveBeenCalled();
293
278
  expect(spawnMock).not.toHaveBeenCalled();
@@ -324,7 +309,7 @@ describe("executeAcpSpawn: sandboxed bun auto-install on missing binary", () =>
324
309
  expect(spawnMock).toHaveBeenCalledTimes(1);
325
310
  const payload = JSON.parse(result.content);
326
311
  expect(payload.message).toContain(
327
- "Installed @agentclientprotocol/claude-agent-acp@0.75.1 automatically.",
312
+ "Installed @agentclientprotocol/claude-agent-acp automatically.",
328
313
  );
329
314
  // The real binary was spawned with cwd = the project dir and token
330
315
  // injected (trusted-binary config, no resolution at spawn).
@@ -345,7 +330,7 @@ describe("executeAcpSpawn: sandboxed bun auto-install on missing binary", () =>
345
330
  expect(args).toEqual([
346
331
  "add",
347
332
  "--global",
348
- "@agentclientprotocol/claude-agent-acp@0.75.1",
333
+ "@agentclientprotocol/claude-agent-acp",
349
334
  ]);
350
335
  });
351
336
 
@@ -434,7 +419,7 @@ describe("executeAcpSpawn: sandboxed bun auto-install on missing binary", () =>
434
419
  expect(result.isError).toBe(true);
435
420
  expect(result.content).toContain("claude-agent-acp is not on PATH");
436
421
  expect(result.content).toContain(
437
- "bun add -g @agentclientprotocol/claude-agent-acp@0.75.1",
422
+ "bun add -g @agentclientprotocol/claude-agent-acp",
438
423
  );
439
424
  expect(result.content).toContain("auto-install failed");
440
425
  expect(result.content).toContain("EACCES");
@@ -473,126 +458,6 @@ describe("executeAcpSpawn — per-agent resume hint", () => {
473
458
  });
474
459
  });
475
460
 
476
- describe("executeAcpSpawn - model selection", () => {
477
- test("threads the requested model into manager.spawn's options", async () => {
478
- const result = await executeAcpSpawn(
479
- { agent: "claude", task: "do something", model: "opus" },
480
- { ...makeContext(), toolUseId: "toolu_model" },
481
- );
482
-
483
- expect(result.isError).toBe(false);
484
- expect(spawnMock.mock.calls[0][6]).toEqual({
485
- parentToolUseId: "toolu_model",
486
- model: "opus",
487
- });
488
- const payload = JSON.parse(result.content);
489
- expect(payload.requestedModel).toBe("opus");
490
- expect(payload.effectiveModel).toBe("opus");
491
- expect(payload.message).toContain(
492
- 'The top-level ACP session reports "opus" as its effective model.',
493
- );
494
- });
495
-
496
- test("reports the manager-normalized requested model", async () => {
497
- const result = await executeAcpSpawn(
498
- { agent: "claude", task: "do something", model: " opus " },
499
- makeContext(),
500
- );
501
-
502
- expect(spawnMock.mock.calls[0][6]).toEqual({
503
- parentToolUseId: undefined,
504
- model: " opus ",
505
- });
506
- expect(JSON.parse(result.content).requestedModel).toBe("opus");
507
- });
508
-
509
- test("a null model is treated as omitted", async () => {
510
- const result = await executeAcpSpawn(
511
- { agent: "claude", task: "do something", model: null },
512
- makeContext(),
513
- );
514
-
515
- expect(result.isError).toBe(false);
516
- const options = spawnMock.mock.calls[0][6] as { model?: string };
517
- expect(options.model).toBeUndefined();
518
- });
519
-
520
- test("a modelWarning from the spawn is relayed in the result message", async () => {
521
- spawnMock.mockImplementationOnce(async () => ({
522
- acpSessionId: "acp-session-test",
523
- protocolSessionId: "proto-session-test",
524
- requestedModel: "nope",
525
- effectiveModel: "opus",
526
- modelWarning: "Unknown model: nope",
527
- }));
528
-
529
- const result = await executeAcpSpawn(
530
- { agent: "claude", task: "do something", model: "nope" },
531
- makeContext(),
532
- );
533
-
534
- expect(result.isError).toBe(false);
535
- const payload = JSON.parse(result.content);
536
- expect(payload.message).toContain(
537
- "The requested model was not applied: Unknown model: nope",
538
- );
539
- expect(payload.requestedModel).toBe("nope");
540
- expect(payload.effectiveModel).toBe("opus");
541
- });
542
-
543
- test("the note relays a no-selector warning without calling it a refusal", async () => {
544
- spawnMock.mockImplementationOnce(async () => ({
545
- acpSessionId: "acp-session-test",
546
- protocolSessionId: "proto-session-test",
547
- requestedModel: "opus",
548
- modelWarning:
549
- 'Agent "claude" does not support model selection, so the session is running on the agent\'s own model.',
550
- }));
551
-
552
- const result = await executeAcpSpawn(
553
- { agent: "claude", task: "do something", model: "opus" },
554
- makeContext(),
555
- );
556
-
557
- const payload = JSON.parse(result.content);
558
- expect(payload.message).toContain("does not support model selection");
559
- expect(payload.message).not.toContain("refused");
560
- });
561
-
562
- test("no model note when the spawn reports no warning", async () => {
563
- const result = await executeAcpSpawn(
564
- { agent: "claude", task: "do something", model: "opus" },
565
- makeContext(),
566
- );
567
-
568
- expect(result.isError).toBe(false);
569
- const payload = JSON.parse(result.content);
570
- expect(payload.message).not.toContain(
571
- "The requested model was not applied",
572
- );
573
- });
574
-
575
- test("reports when the adapter does not identify the effective model", async () => {
576
- spawnMock.mockImplementationOnce(async () => ({
577
- acpSessionId: "acp-session-test",
578
- protocolSessionId: "proto-session-test",
579
- requestedModel: "sonnet",
580
- }));
581
-
582
- const result = await executeAcpSpawn(
583
- { agent: "claude", task: "do something", model: "sonnet" },
584
- makeContext(),
585
- );
586
-
587
- const payload = JSON.parse(result.content);
588
- expect(payload.requestedModel).toBe("sonnet");
589
- expect(payload.effectiveModel).toBeNull();
590
- expect(payload.message).toContain(
591
- "The top-level ACP session did not report an effective model.",
592
- );
593
- });
594
- });
595
-
596
461
  // ---------------------------------------------------------------------------
597
462
  // executeAcpSpawn — CLAUDE_CODE_OAUTH_TOKEN env injection + preflight
598
463
  //
@@ -37,7 +37,6 @@ export const acpSpawnInputSchema = z.looseObject({
37
37
  agent: nullAsOmitted(z.string()),
38
38
  task: nullAsOmitted(z.string()),
39
39
  cwd: nullAsOmitted(z.string()),
40
- model: nullAsOmitted(z.string()),
41
40
  });
42
41
 
43
42
  /**
@@ -67,7 +66,6 @@ export async function executeAcpSpawn(
67
66
  }
68
67
  const agent = parsedInput.data.agent || "claude";
69
68
  const task = parsedInput.data.task;
70
- const model = parsedInput.data.model;
71
69
 
72
70
  if (!task) {
73
71
  return { content: '"task" is required.', isError: true };
@@ -126,20 +124,14 @@ export async function executeAcpSpawn(
126
124
  // Recheck: the auto-install and the agent-env preparation above are both
127
125
  // awaits, and this is the point a long-lived subprocess starts.
128
126
  throwIfCancelled(context);
129
- const {
130
- acpSessionId,
131
- protocolSessionId,
132
- requestedModel,
133
- effectiveModel,
134
- modelWarning,
135
- } = await manager.spawn(
127
+ const { acpSessionId, protocolSessionId } = await manager.spawn(
136
128
  agent,
137
129
  agentConfig,
138
130
  task,
139
131
  cwd,
140
132
  context.conversationId,
141
133
  sendToClient,
142
- { parentToolUseId: context.toolUseId, model },
134
+ context.toolUseId,
143
135
  // The manager rechecks after its own protocol handshake and session
144
136
  // creation, so a turn stopped in that window tears the child process
145
137
  // down instead of handing it the task.
@@ -158,26 +150,16 @@ export async function executeAcpSpawn(
158
150
  const installNote = autoInstalledPackage
159
151
  ? ` Installed ${autoInstalledPackage} automatically.`
160
152
  : "";
161
- // Relayed verbatim: the warning already distinguishes an adapter with no
162
- // selector from one that refused the value.
163
- const modelNote = modelWarning
164
- ? ` The requested model was not applied: ${modelWarning}`
165
- : "";
166
- const effectiveModelNote = effectiveModel
167
- ? ` The top-level ACP session reports "${effectiveModel}" as its effective model.`
168
- : " The top-level ACP session did not report an effective model.";
169
153
  const payload = JSON.stringify({
170
154
  acpSessionId,
171
155
  protocolSessionId,
172
156
  agent,
173
157
  cwd,
174
- requestedModel: requestedModel ?? null,
175
- effectiveModel: effectiveModel ?? null,
176
158
  status: "running",
177
159
  message:
178
160
  `ACP agent "${agent}" spawned (session: ${protocolSessionId}). ` +
179
161
  `Results stream back via SSE. You will be notified when it completes.` +
180
- `${installNote}${modelNote}${effectiveModelNote}${resumeHint}`,
162
+ `${installNote}${resumeHint}`,
181
163
  });
182
164
 
183
165
  return { content: payload, isError: false };
@@ -1,7 +1,6 @@
1
1
  import { z } from "zod";
2
2
 
3
3
  import { getAcpSessionManager } from "../../acp/index.js";
4
- import type { AcpSessionState } from "../../acp/types.js";
5
4
  import {
6
5
  invalidToolInputResult,
7
6
  nullAsOmitted,
@@ -17,40 +16,6 @@ export const acpStatusInputSchema = z.looseObject({
17
16
  acp_session_id: nullAsOmitted(z.string()),
18
17
  });
19
18
 
20
- /**
21
- * The session fields worth spending LLM context on. An allowlist rather than
22
- * an omission: `availableModels` is a picker for the human surfaces (HTTP and
23
- * SSE) that says nothing the agent can act on, and a field added to
24
- * `AcpSessionState` for those surfaces should not reach this one by default.
25
- * `model` stays: which model a session is running on is answerable.
26
- */
27
- function projectSession(state: AcpSessionState) {
28
- return {
29
- id: state.id,
30
- agentId: state.agentId,
31
- acpSessionId: state.acpSessionId,
32
- parentConversationId: state.parentConversationId,
33
- status: state.status,
34
- startedAt: state.startedAt,
35
- completedAt: state.completedAt,
36
- error: state.error,
37
- stopReason: state.stopReason,
38
- task: state.task,
39
- parentToolUseId: state.parentToolUseId,
40
- authErrorCode: state.authErrorCode,
41
- authErrorCredential: state.authErrorCredential,
42
- latestUsage: state.latestUsage,
43
- model: state.model,
44
- };
45
- }
46
-
47
- /** Projects either shape `getStatus` answers with. */
48
- function projectStatus(status: AcpSessionState | AcpSessionState[]): unknown {
49
- return Array.isArray(status)
50
- ? status.map(projectSession)
51
- : projectSession(status);
52
- }
53
-
54
19
  export async function executeAcpStatus(
55
20
  input: Record<string, unknown>,
56
21
  _context: ToolContext,
@@ -64,8 +29,9 @@ export async function executeAcpStatus(
64
29
 
65
30
  try {
66
31
  if (acpSessionId) {
32
+ const state = manager.getStatus(acpSessionId);
67
33
  return {
68
- content: JSON.stringify(projectStatus(manager.getStatus(acpSessionId))),
34
+ content: JSON.stringify(state),
69
35
  isError: false,
70
36
  };
71
37
  }
@@ -76,10 +42,7 @@ export async function executeAcpStatus(
76
42
  return { content: "No ACP sessions found.", isError: false };
77
43
  }
78
44
 
79
- return {
80
- content: JSON.stringify(projectStatus(allStates)),
81
- isError: false,
82
- };
45
+ return { content: JSON.stringify(allStates), isError: false };
83
46
  } catch (err) {
84
47
  const msg = err instanceof Error ? err.message : String(err);
85
48
  return { content: msg, isError: true };
@@ -5,7 +5,6 @@
5
5
  * the proxy resolver, which forwards the call to the connected client.
6
6
  */
7
7
 
8
- import { formatDesktopAppRequired } from "../capability-offer.js";
9
8
  import { throwIfCancelled } from "../shared/abort.js";
10
9
  import type { ToolContext, ToolExecutionResult } from "../types.js";
11
10
 
@@ -33,7 +32,7 @@ export function forwardAppControlProxyTool(
33
32
  }
34
33
  if (!context.proxyToolResolver) {
35
34
  return Promise.resolve({
36
- content: formatDesktopAppRequired("apps"),
35
+ content: `Cannot execute ${toolName}: no proxy resolver available. This tool requires a connected client.`,
37
36
  isError: true,
38
37
  });
39
38
  }
@@ -4,26 +4,11 @@ import {
4
4
  appendLoggedInBrowserOffer,
5
5
  CHROME_WEB_STORE_INSTALL_URL,
6
6
  DESKTOP_APP_DOWNLOAD_URL,
7
- formatDesktopAppRequired,
8
7
  formatLoggedInBrowserOffer,
9
8
  isPhoneSurface,
10
9
  shouldOfferLoggedInBrowser,
11
10
  } from "./capability-offer.js";
12
11
 
13
- describe("formatDesktopAppRequired", () => {
14
- test("offers a direct desktop-app download and retry step", () => {
15
- const message = formatDesktopAppRequired("shell");
16
-
17
- expect(message).toContain(
18
- "The Vellum desktop app is needed to run commands on your computer",
19
- );
20
- expect(message).toContain(DESKTOP_APP_DOWNLOAD_URL);
21
- expect(message).toContain("Open it, then retry.");
22
- expect(message).not.toContain("client");
23
- expect(message).not.toContain("daemon");
24
- });
25
- });
26
-
27
12
  describe("isPhoneSurface", () => {
28
13
  test("is true for iOS transport and mobile client OS", () => {
29
14
  expect(isPhoneSurface({ transportInterface: "ios" })).toBe(true);
@@ -64,9 +49,7 @@ describe("shouldOfferLoggedInBrowser", () => {
64
49
  expect(shouldOfferLoggedInBrowser('Invalid browser_mode "bogus"')).toBe(
65
50
  false,
66
51
  );
67
- expect(shouldOfferLoggedInBrowser("url must use http or https")).toBe(
68
- false,
69
- );
52
+ expect(shouldOfferLoggedInBrowser("url must use http or https")).toBe(false);
70
53
  });
71
54
  });
72
55
 
@@ -88,7 +71,6 @@ describe("formatLoggedInBrowserOffer", () => {
88
71
  });
89
72
  expect(offer).toContain("no in-app browser");
90
73
  expect(offer).toContain("Do not describe a browser panel");
91
- expect(offer).toContain("Mac or Windows PC");
92
74
  expect(offer).toContain(DESKTOP_APP_DOWNLOAD_URL);
93
75
  expect(offer).toContain(CHROME_WEB_STORE_INSTALL_URL);
94
76
  });
@@ -96,9 +78,7 @@ describe("formatLoggedInBrowserOffer", () => {
96
78
 
97
79
  describe("appendLoggedInBrowserOffer", () => {
98
80
  test("appends the offer once", () => {
99
- const once = appendLoggedInBrowserOffer(
100
- "Error: Navigation failed: timeout",
101
- );
81
+ const once = appendLoggedInBrowserOffer("Error: Navigation failed: timeout");
102
82
  expect(once).toContain("Error: Navigation failed: timeout");
103
83
  expect(once).toContain(DESKTOP_APP_DOWNLOAD_URL);
104
84
  const twice = appendLoggedInBrowserOffer(once);