@agent-native/core 0.118.0 → 0.119.0

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 (480) hide show
  1. package/corpus/README.md +2 -2
  2. package/corpus/core/CHANGELOG.md +32 -0
  3. package/corpus/core/docs/content/a2a-protocol.mdx +15 -0
  4. package/corpus/core/docs/content/template-chat.mdx +1 -1
  5. package/corpus/core/docs/content/template-plan.mdx +3 -3
  6. package/corpus/core/package.json +1 -1
  7. package/corpus/core/src/a2a/activity.ts +371 -0
  8. package/corpus/core/src/a2a/client.ts +35 -11
  9. package/corpus/core/src/a2a/index.ts +21 -0
  10. package/corpus/core/src/a2a/types.ts +8 -0
  11. package/corpus/core/src/agent/model-config.ts +19 -23
  12. package/corpus/core/src/agent/production-agent.ts +167 -100
  13. package/corpus/core/src/agent/types.ts +16 -1
  14. package/corpus/core/src/cli/index.ts +18 -10
  15. package/corpus/core/src/cli/multi-frontier-runs.ts +5 -3
  16. package/corpus/core/src/cli/templates-meta.ts +0 -12
  17. package/corpus/core/src/cli/workspace-dev.ts +1 -1
  18. package/corpus/core/src/client/AgentPanel.tsx +9 -1
  19. package/corpus/core/src/client/RunStuckBanner.tsx +39 -47
  20. package/corpus/core/src/client/chat/action-chat-ui-surface.tsx +32 -0
  21. package/corpus/core/src/client/chat/message-components.tsx +53 -8
  22. package/corpus/core/src/client/chat/tool-call-display.tsx +214 -44
  23. package/corpus/core/src/client/chat/widgets/InlineExtensionWidget.tsx +0 -1
  24. package/corpus/core/src/client/chat/widgets/builtin-tool-renderers.tsx +7 -3
  25. package/corpus/core/src/client/chat-model-groups.ts +67 -27
  26. package/corpus/core/src/client/conversation/AgentConversation.tsx +12 -1
  27. package/corpus/core/src/client/error-capture.ts +2 -6
  28. package/corpus/core/src/client/resources/McpConnectionSuggestion.tsx +20 -14
  29. package/corpus/core/src/client/resources/ResourcesPanel.tsx +5 -1
  30. package/corpus/core/src/client/resources/mcp-integration-catalog.ts +7 -17
  31. package/corpus/core/src/client/resources/mcp-integration-logos.ts +2 -2
  32. package/corpus/core/src/client/route-chunk-recovery.ts +5 -3
  33. package/corpus/core/src/client/session-replay.ts +3 -3
  34. package/corpus/core/src/client/settings/SettingsPanel.tsx +15 -6
  35. package/corpus/core/src/client/sharing/ShareButton.tsx +1 -27
  36. package/corpus/core/src/client/sharing/ShareDialog.tsx +0 -16
  37. package/corpus/core/src/client/sharing/useShareButtonController.ts +0 -7
  38. package/corpus/core/src/client/sharing/useShareDialogController.ts +0 -2
  39. package/corpus/core/src/client/sse-event-processor.ts +85 -1
  40. package/corpus/core/src/client/transcription/use-live-transcription.ts +64 -45
  41. package/corpus/core/src/deploy/build.ts +2 -1
  42. package/corpus/core/src/guards/db-tool-scoping.ts +1 -1
  43. package/corpus/core/src/integrations/adapters/slack.ts +84 -5
  44. package/corpus/core/src/integrations/index.ts +5 -1
  45. package/corpus/core/src/localization/default-messages.ts +7 -1
  46. package/corpus/core/src/mcp-client/oauth-routes.ts +45 -12
  47. package/corpus/core/src/scripts/agent-engines/list-agent-engines.ts +1 -18
  48. package/corpus/core/src/scripts/call-agent.ts +49 -6
  49. package/corpus/core/src/server/agent-chat-plugin.ts +50 -10
  50. package/corpus/core/src/server/realtime-voice.ts +4 -1
  51. package/corpus/core/src/templates/workspace-core/.agents/skills/a2a-protocol/SKILL.md +16 -0
  52. package/corpus/core/src/templates/workspace-core/.agents/skills/voice-transcription/SKILL.md +7 -5
  53. package/corpus/core/src/terminal/cli-registry.ts +1 -1
  54. package/corpus/core/src/vite/client.ts +166 -1
  55. package/corpus/templates/analytics/app/hooks/use-dashboard-views.ts +13 -1
  56. package/corpus/templates/analytics/app/pages/adhoc/sql-dashboard/ViewsMenu.tsx +10 -0
  57. package/corpus/templates/analytics/changelog/2026-07-22-show-a-useful-error-when-saving-a-dashboard-view-fails.md +6 -0
  58. package/corpus/templates/brain/app/routes/sources.tsx +181 -114
  59. package/corpus/templates/clips/AGENTS.md +8 -6
  60. package/corpus/templates/clips/actions/request-transcript.ts +90 -420
  61. package/corpus/templates/clips/actions/save-browser-transcript.ts +11 -28
  62. package/corpus/templates/clips/app/components/capture-install-options.tsx +5 -3
  63. package/corpus/templates/clips/app/components/player/transcript-panel.tsx +3 -136
  64. package/corpus/templates/clips/app/lib/capture-install-options.ts +15 -4
  65. package/corpus/templates/clips/app/routes/download.tsx +3 -2
  66. package/corpus/templates/clips/changelog/2026-07-22-fixed-an-intermittent-hydration-error-on-the-download-page.md +6 -0
  67. package/corpus/templates/clips/changelog/2026-07-22-fixed-transcript-generation-when-native-speech-capture-retur.md +6 -0
  68. package/corpus/templates/clips/changelog/2026-07-22-transcript-generation-now-retries-with-backup-speech-recogni.md +6 -0
  69. package/corpus/templates/clips/changelog/2026-07-23-fixed-recordings-failing-to-save-with-a-cancelled-or-cleanup.md +6 -0
  70. package/corpus/templates/clips/server/lib/public-agent-context.ts +2 -2
  71. package/corpus/templates/clips/server/plugins/db.ts +9 -1
  72. package/corpus/templates/clips/server/register-secrets.ts +7 -6
  73. package/corpus/templates/content/app/components/editor/SlashCommandMenu.tsx +16 -84
  74. package/corpus/templates/content/app/components/editor/VisualEditor.tsx +13 -7
  75. package/corpus/templates/content/app/components/editor/extensions/ImageBlock.tsx +2 -2
  76. package/corpus/templates/content/app/i18n-data.ts +10 -0
  77. package/corpus/templates/design/server/lib/fig-file-decoder.ts +1 -0
  78. package/corpus/templates/plan/app/entry.client.tsx +3 -0
  79. package/corpus/templates/plan/changelog/2026-07-22-recover-stale-pages-after-a-deployment-refresh-automatically.md +6 -0
  80. package/corpus/templates/slides/app/hooks/use-agent-generating.ts +10 -3
  81. package/corpus/templates/slides/app/pages/Index.tsx +1 -0
  82. package/corpus/templates/slides/changelog/2026-07-22-new-deck-prompts-now-open-in-their-own-visible-chat-thread.md +6 -0
  83. package/corpus/toolkit/CHANGELOG.md +9 -0
  84. package/corpus/toolkit/package.json +1 -1
  85. package/corpus/toolkit/src/composer/PromptComposer.tsx +5 -1
  86. package/corpus/toolkit/src/composer/RealtimeVoiceMode.tsx +119 -31
  87. package/corpus/toolkit/src/composer/useRealtimeVoiceMode.tsx +30 -0
  88. package/corpus/toolkit/src/conformance/runner.tsx +153 -1
  89. package/corpus/toolkit/src/editor/SharedRichEditor.tsx +13 -2
  90. package/corpus/toolkit/src/editor/SlashCommandMenu.tsx +20 -0
  91. package/corpus/toolkit/src/editor/index.ts +2 -0
  92. package/corpus/toolkit/src/styles.css +52 -23
  93. package/dist/a2a/activity.d.ts +50 -0
  94. package/dist/a2a/activity.d.ts.map +1 -0
  95. package/dist/a2a/activity.js +236 -0
  96. package/dist/a2a/activity.js.map +1 -0
  97. package/dist/a2a/client.d.ts +5 -1
  98. package/dist/a2a/client.d.ts.map +1 -1
  99. package/dist/a2a/client.js +18 -13
  100. package/dist/a2a/client.js.map +1 -1
  101. package/dist/a2a/index.d.ts +2 -1
  102. package/dist/a2a/index.d.ts.map +1 -1
  103. package/dist/a2a/index.js +1 -0
  104. package/dist/a2a/index.js.map +1 -1
  105. package/dist/a2a/types.d.ts +1 -0
  106. package/dist/a2a/types.d.ts.map +1 -1
  107. package/dist/a2a/types.js.map +1 -1
  108. package/dist/agent/engine/anthropic-engine.d.ts +1 -1
  109. package/dist/agent/engine/builder-engine.d.ts +2 -2
  110. package/dist/agent/engine/builder-engine.d.ts.map +1 -1
  111. package/dist/agent/model-config.d.ts +16 -16
  112. package/dist/agent/model-config.d.ts.map +1 -1
  113. package/dist/agent/model-config.js +19 -23
  114. package/dist/agent/model-config.js.map +1 -1
  115. package/dist/agent/production-agent.d.ts +26 -0
  116. package/dist/agent/production-agent.d.ts.map +1 -1
  117. package/dist/agent/production-agent.js +137 -80
  118. package/dist/agent/production-agent.js.map +1 -1
  119. package/dist/agent/types.d.ts +10 -0
  120. package/dist/agent/types.d.ts.map +1 -1
  121. package/dist/agent/types.js.map +1 -1
  122. package/dist/cli/index.js +18 -8
  123. package/dist/cli/index.js.map +1 -1
  124. package/dist/cli/multi-frontier-runs.js +3 -3
  125. package/dist/cli/multi-frontier-runs.js.map +1 -1
  126. package/dist/cli/templates-meta.d.ts.map +1 -1
  127. package/dist/cli/templates-meta.js +0 -12
  128. package/dist/cli/templates-meta.js.map +1 -1
  129. package/dist/cli/workspace-dev.js +1 -1
  130. package/dist/cli/workspace-dev.js.map +1 -1
  131. package/dist/client/AgentPanel.d.ts.map +1 -1
  132. package/dist/client/AgentPanel.js +4 -1
  133. package/dist/client/AgentPanel.js.map +1 -1
  134. package/dist/client/RunStuckBanner.d.ts +3 -5
  135. package/dist/client/RunStuckBanner.d.ts.map +1 -1
  136. package/dist/client/RunStuckBanner.js +17 -18
  137. package/dist/client/RunStuckBanner.js.map +1 -1
  138. package/dist/client/chat/action-chat-ui-surface.d.ts +8 -0
  139. package/dist/client/chat/action-chat-ui-surface.d.ts.map +1 -0
  140. package/dist/client/chat/action-chat-ui-surface.js +10 -0
  141. package/dist/client/chat/action-chat-ui-surface.js.map +1 -0
  142. package/dist/client/chat/message-components.d.ts +3 -0
  143. package/dist/client/chat/message-components.d.ts.map +1 -1
  144. package/dist/client/chat/message-components.js +40 -7
  145. package/dist/client/chat/message-components.js.map +1 -1
  146. package/dist/client/chat/tool-call-display.d.ts +3 -1
  147. package/dist/client/chat/tool-call-display.d.ts.map +1 -1
  148. package/dist/client/chat/tool-call-display.js +76 -23
  149. package/dist/client/chat/tool-call-display.js.map +1 -1
  150. package/dist/client/chat/widgets/InlineExtensionWidget.d.ts.map +1 -1
  151. package/dist/client/chat/widgets/InlineExtensionWidget.js +1 -1
  152. package/dist/client/chat/widgets/InlineExtensionWidget.js.map +1 -1
  153. package/dist/client/chat/widgets/builtin-tool-renderers.d.ts.map +1 -1
  154. package/dist/client/chat/widgets/builtin-tool-renderers.js +5 -3
  155. package/dist/client/chat/widgets/builtin-tool-renderers.js.map +1 -1
  156. package/dist/client/chat-model-groups.d.ts.map +1 -1
  157. package/dist/client/chat-model-groups.js +44 -21
  158. package/dist/client/chat-model-groups.js.map +1 -1
  159. package/dist/client/conversation/AgentConversation.d.ts.map +1 -1
  160. package/dist/client/conversation/AgentConversation.js +3 -2
  161. package/dist/client/conversation/AgentConversation.js.map +1 -1
  162. package/dist/client/error-capture.d.ts.map +1 -1
  163. package/dist/client/error-capture.js +2 -2
  164. package/dist/client/error-capture.js.map +1 -1
  165. package/dist/client/resources/McpConnectionSuggestion.d.ts +1 -0
  166. package/dist/client/resources/McpConnectionSuggestion.d.ts.map +1 -1
  167. package/dist/client/resources/McpConnectionSuggestion.js +9 -8
  168. package/dist/client/resources/McpConnectionSuggestion.js.map +1 -1
  169. package/dist/client/resources/ResourcesPanel.d.ts.map +1 -1
  170. package/dist/client/resources/ResourcesPanel.js +3 -1
  171. package/dist/client/resources/ResourcesPanel.js.map +1 -1
  172. package/dist/client/resources/mcp-integration-catalog.d.ts +1 -0
  173. package/dist/client/resources/mcp-integration-catalog.d.ts.map +1 -1
  174. package/dist/client/resources/mcp-integration-catalog.js +4 -17
  175. package/dist/client/resources/mcp-integration-catalog.js.map +1 -1
  176. package/dist/client/resources/mcp-integration-logos.js +2 -2
  177. package/dist/client/resources/mcp-integration-logos.js.map +1 -1
  178. package/dist/client/route-chunk-recovery.d.ts.map +1 -1
  179. package/dist/client/route-chunk-recovery.js +5 -3
  180. package/dist/client/route-chunk-recovery.js.map +1 -1
  181. package/dist/client/session-replay.js +3 -3
  182. package/dist/client/session-replay.js.map +1 -1
  183. package/dist/client/settings/SettingsPanel.d.ts.map +1 -1
  184. package/dist/client/settings/SettingsPanel.js +2 -2
  185. package/dist/client/settings/SettingsPanel.js.map +1 -1
  186. package/dist/client/sharing/ShareButton.d.ts +1 -1
  187. package/dist/client/sharing/ShareButton.d.ts.map +1 -1
  188. package/dist/client/sharing/ShareButton.js +3 -4
  189. package/dist/client/sharing/ShareButton.js.map +1 -1
  190. package/dist/client/sharing/ShareDialog.d.ts.map +1 -1
  191. package/dist/client/sharing/ShareDialog.js +1 -2
  192. package/dist/client/sharing/ShareDialog.js.map +1 -1
  193. package/dist/client/sharing/useShareButtonController.d.ts +0 -1
  194. package/dist/client/sharing/useShareButtonController.d.ts.map +1 -1
  195. package/dist/client/sharing/useShareButtonController.js +0 -6
  196. package/dist/client/sharing/useShareButtonController.js.map +1 -1
  197. package/dist/client/sharing/useShareDialogController.d.ts +0 -1
  198. package/dist/client/sharing/useShareDialogController.d.ts.map +1 -1
  199. package/dist/client/sharing/useShareDialogController.js +0 -1
  200. package/dist/client/sharing/useShareDialogController.js.map +1 -1
  201. package/dist/client/sse-event-processor.d.ts +12 -0
  202. package/dist/client/sse-event-processor.d.ts.map +1 -1
  203. package/dist/client/sse-event-processor.js +63 -1
  204. package/dist/client/sse-event-processor.js.map +1 -1
  205. package/dist/client/transcription/use-live-transcription.d.ts +3 -3
  206. package/dist/client/transcription/use-live-transcription.d.ts.map +1 -1
  207. package/dist/client/transcription/use-live-transcription.js +22 -11
  208. package/dist/client/transcription/use-live-transcription.js.map +1 -1
  209. package/dist/collab/awareness.d.ts +2 -2
  210. package/dist/collab/awareness.d.ts.map +1 -1
  211. package/dist/deploy/build.d.ts.map +1 -1
  212. package/dist/deploy/build.js +1 -1
  213. package/dist/deploy/build.js.map +1 -1
  214. package/dist/guards/db-tool-scoping.js +1 -1
  215. package/dist/guards/db-tool-scoping.js.map +1 -1
  216. package/dist/integrations/adapters/slack.d.ts +1 -0
  217. package/dist/integrations/adapters/slack.d.ts.map +1 -1
  218. package/dist/integrations/adapters/slack.js +61 -5
  219. package/dist/integrations/adapters/slack.js.map +1 -1
  220. package/dist/integrations/index.d.ts +1 -1
  221. package/dist/integrations/index.d.ts.map +1 -1
  222. package/dist/integrations/index.js +1 -1
  223. package/dist/integrations/index.js.map +1 -1
  224. package/dist/localization/default-messages.d.ts +6 -0
  225. package/dist/localization/default-messages.d.ts.map +1 -1
  226. package/dist/localization/default-messages.js +7 -1
  227. package/dist/localization/default-messages.js.map +1 -1
  228. package/dist/mcp-client/oauth-routes.d.ts +3 -0
  229. package/dist/mcp-client/oauth-routes.d.ts.map +1 -1
  230. package/dist/mcp-client/oauth-routes.js +41 -12
  231. package/dist/mcp-client/oauth-routes.js.map +1 -1
  232. package/dist/observability/routes.d.ts +3 -3
  233. package/dist/provider-api/actions/custom-provider-registration.d.ts +8 -8
  234. package/dist/provider-api/actions/provider-api.d.ts +11 -11
  235. package/dist/scripts/agent-engines/list-agent-engines.d.ts.map +1 -1
  236. package/dist/scripts/agent-engines/list-agent-engines.js +1 -18
  237. package/dist/scripts/agent-engines/list-agent-engines.js.map +1 -1
  238. package/dist/scripts/call-agent.d.ts.map +1 -1
  239. package/dist/scripts/call-agent.js +49 -6
  240. package/dist/scripts/call-agent.js.map +1 -1
  241. package/dist/secrets/routes.d.ts +6 -6
  242. package/dist/server/agent-chat-plugin.d.ts.map +1 -1
  243. package/dist/server/agent-chat-plugin.js +38 -10
  244. package/dist/server/agent-chat-plugin.js.map +1 -1
  245. package/dist/server/agent-engine-api-key-route.d.ts +1 -1
  246. package/dist/server/realtime-voice.d.ts.map +1 -1
  247. package/dist/server/realtime-voice.js +1 -1
  248. package/dist/server/realtime-voice.js.map +1 -1
  249. package/dist/server/transcribe-voice.d.ts +1 -1
  250. package/dist/templates/workspace-core/.agents/skills/a2a-protocol/SKILL.md +16 -0
  251. package/dist/templates/workspace-core/.agents/skills/voice-transcription/SKILL.md +7 -5
  252. package/dist/terminal/cli-registry.js +1 -1
  253. package/dist/terminal/cli-registry.js.map +1 -1
  254. package/dist/vite/client.d.ts +8 -1
  255. package/dist/vite/client.d.ts.map +1 -1
  256. package/dist/vite/client.js +113 -2
  257. package/dist/vite/client.js.map +1 -1
  258. package/docs/content/a2a-protocol.mdx +15 -0
  259. package/docs/content/template-chat.mdx +1 -1
  260. package/docs/content/template-plan.mdx +3 -3
  261. package/package.json +2 -2
  262. package/src/a2a/activity.ts +371 -0
  263. package/src/a2a/client.ts +35 -11
  264. package/src/a2a/index.ts +21 -0
  265. package/src/a2a/types.ts +8 -0
  266. package/src/agent/model-config.ts +19 -23
  267. package/src/agent/production-agent.ts +167 -100
  268. package/src/agent/types.ts +16 -1
  269. package/src/cli/index.ts +18 -10
  270. package/src/cli/multi-frontier-runs.ts +5 -3
  271. package/src/cli/templates-meta.ts +0 -12
  272. package/src/cli/workspace-dev.ts +1 -1
  273. package/src/client/AgentPanel.tsx +9 -1
  274. package/src/client/RunStuckBanner.tsx +39 -47
  275. package/src/client/chat/action-chat-ui-surface.tsx +32 -0
  276. package/src/client/chat/message-components.tsx +53 -8
  277. package/src/client/chat/tool-call-display.tsx +214 -44
  278. package/src/client/chat/widgets/InlineExtensionWidget.tsx +0 -1
  279. package/src/client/chat/widgets/builtin-tool-renderers.tsx +7 -3
  280. package/src/client/chat-model-groups.ts +67 -27
  281. package/src/client/conversation/AgentConversation.tsx +12 -1
  282. package/src/client/error-capture.ts +2 -6
  283. package/src/client/resources/McpConnectionSuggestion.tsx +20 -14
  284. package/src/client/resources/ResourcesPanel.tsx +5 -1
  285. package/src/client/resources/mcp-integration-catalog.ts +7 -17
  286. package/src/client/resources/mcp-integration-logos.ts +2 -2
  287. package/src/client/route-chunk-recovery.ts +5 -3
  288. package/src/client/session-replay.ts +3 -3
  289. package/src/client/settings/SettingsPanel.tsx +15 -6
  290. package/src/client/sharing/ShareButton.tsx +1 -27
  291. package/src/client/sharing/ShareDialog.tsx +0 -16
  292. package/src/client/sharing/useShareButtonController.ts +0 -7
  293. package/src/client/sharing/useShareDialogController.ts +0 -2
  294. package/src/client/sse-event-processor.ts +85 -1
  295. package/src/client/transcription/use-live-transcription.ts +64 -45
  296. package/src/deploy/build.ts +2 -1
  297. package/src/guards/db-tool-scoping.ts +1 -1
  298. package/src/integrations/adapters/slack.ts +84 -5
  299. package/src/integrations/index.ts +5 -1
  300. package/src/localization/default-messages.ts +7 -1
  301. package/src/mcp-client/oauth-routes.ts +45 -12
  302. package/src/scripts/agent-engines/list-agent-engines.ts +1 -18
  303. package/src/scripts/call-agent.ts +49 -6
  304. package/src/server/agent-chat-plugin.ts +50 -10
  305. package/src/server/realtime-voice.ts +4 -1
  306. package/src/templates/workspace-core/.agents/skills/a2a-protocol/SKILL.md +16 -0
  307. package/src/templates/workspace-core/.agents/skills/voice-transcription/SKILL.md +7 -5
  308. package/src/terminal/cli-registry.ts +1 -1
  309. package/src/vite/client.ts +166 -1
  310. package/corpus/core/src/observability/hosted-model-experiment.ts +0 -118
  311. package/corpus/templates/crm/.agents/skills/agent-native-docs/SKILL.md +0 -115
  312. package/corpus/templates/crm/.agents/skills/agent-native-toolkit/SKILL.md +0 -177
  313. package/corpus/templates/crm/.agents/skills/crm/SKILL.md +0 -128
  314. package/corpus/templates/crm/.agents/skills/customizing-agent-native/SKILL.md +0 -220
  315. package/corpus/templates/crm/.agents/skills/feature-flags/SKILL.md +0 -169
  316. package/corpus/templates/crm/.agents/skills/upgrade-agent-native/SKILL.md +0 -100
  317. package/corpus/templates/crm/.env.example +0 -5
  318. package/corpus/templates/crm/AGENTS.md +0 -120
  319. package/corpus/templates/crm/CHANGELOG.md +0 -1
  320. package/corpus/templates/crm/DEVELOPING.md +0 -66
  321. package/corpus/templates/crm/README.md +0 -106
  322. package/corpus/templates/crm/_gitignore +0 -12
  323. package/corpus/templates/crm/actions/_crm-action-utils.ts +0 -87
  324. package/corpus/templates/crm/actions/_crm-dashboard.ts +0 -69
  325. package/corpus/templates/crm/actions/_crm-data-program-actions.ts +0 -15
  326. package/corpus/templates/crm/actions/_crm-signal-utils.ts +0 -79
  327. package/corpus/templates/crm/actions/apply-crm-proposals.ts +0 -203
  328. package/corpus/templates/crm/actions/attach-call-evidence.ts +0 -170
  329. package/corpus/templates/crm/actions/configure-crm-connection.ts +0 -126
  330. package/corpus/templates/crm/actions/configure-native-crm.ts +0 -44
  331. package/corpus/templates/crm/actions/create-crm-record.ts +0 -148
  332. package/corpus/templates/crm/actions/create-crm-signal-tracker.ts +0 -58
  333. package/corpus/templates/crm/actions/delete-staged-dataset.ts +0 -14
  334. package/corpus/templates/crm/actions/get-crm-automation-recipe.ts +0 -36
  335. package/corpus/templates/crm/actions/get-crm-dashboard-panel.ts +0 -35
  336. package/corpus/templates/crm/actions/get-crm-dashboard.ts +0 -14
  337. package/corpus/templates/crm/actions/get-crm-overview.ts +0 -13
  338. package/corpus/templates/crm/actions/get-crm-pipeline-data.ts +0 -61
  339. package/corpus/templates/crm/actions/get-crm-record.ts +0 -75
  340. package/corpus/templates/crm/actions/install-crm-pipeline-dashboard.ts +0 -81
  341. package/corpus/templates/crm/actions/list-crm-dashboard-revisions.ts +0 -15
  342. package/corpus/templates/crm/actions/list-crm-dashboards.ts +0 -15
  343. package/corpus/templates/crm/actions/list-crm-proposals.ts +0 -31
  344. package/corpus/templates/crm/actions/list-crm-records.ts +0 -79
  345. package/corpus/templates/crm/actions/list-crm-saved-views.ts +0 -15
  346. package/corpus/templates/crm/actions/list-crm-signal-hits.ts +0 -43
  347. package/corpus/templates/crm/actions/list-crm-signal-trackers.ts +0 -32
  348. package/corpus/templates/crm/actions/list-crm-tasks.ts +0 -22
  349. package/corpus/templates/crm/actions/list-staged-datasets.ts +0 -14
  350. package/corpus/templates/crm/actions/list-workspace-connections.ts +0 -47
  351. package/corpus/templates/crm/actions/manage-crm-signal-tracker.ts +0 -87
  352. package/corpus/templates/crm/actions/manage-crm-task.ts +0 -132
  353. package/corpus/templates/crm/actions/navigate.ts +0 -63
  354. package/corpus/templates/crm/actions/provider-api-catalog.ts +0 -22
  355. package/corpus/templates/crm/actions/provider-api-docs.ts +0 -54
  356. package/corpus/templates/crm/actions/provider-api-request.ts +0 -92
  357. package/corpus/templates/crm/actions/query-staged-dataset.ts +0 -44
  358. package/corpus/templates/crm/actions/record-crm-call-insight.ts +0 -160
  359. package/corpus/templates/crm/actions/record-crm-smart-signal.ts +0 -150
  360. package/corpus/templates/crm/actions/restore-crm-dashboard-revision.ts +0 -23
  361. package/corpus/templates/crm/actions/review-crm-signal.ts +0 -31
  362. package/corpus/templates/crm/actions/run-crm-saved-view-program.ts +0 -103
  363. package/corpus/templates/crm/actions/run-crm-signal-trackers.ts +0 -275
  364. package/corpus/templates/crm/actions/run.ts +0 -7
  365. package/corpus/templates/crm/actions/save-crm-dashboard.ts +0 -51
  366. package/corpus/templates/crm/actions/save-crm-saved-view.ts +0 -119
  367. package/corpus/templates/crm/actions/sync-crm.ts +0 -146
  368. package/corpus/templates/crm/actions/update-crm-record.ts +0 -510
  369. package/corpus/templates/crm/actions/view-screen.ts +0 -218
  370. package/corpus/templates/crm/agent-native.app-skill.json +0 -58
  371. package/corpus/templates/crm/app/components/crm/CreateCrmRecordDialog.tsx +0 -158
  372. package/corpus/templates/crm/app/components/crm/CrmDashboardPanel.tsx +0 -78
  373. package/corpus/templates/crm/app/components/crm/CrmSignalsPanel.tsx +0 -226
  374. package/corpus/templates/crm/app/components/crm/IntelligenceSettings.tsx +0 -414
  375. package/corpus/templates/crm/app/components/crm/RecordActions.tsx +0 -510
  376. package/corpus/templates/crm/app/components/crm/RecordGrid.tsx +0 -134
  377. package/corpus/templates/crm/app/components/crm/RecordWorkspace.tsx +0 -362
  378. package/corpus/templates/crm/app/components/crm/SavedViewDataProgram.tsx +0 -93
  379. package/corpus/templates/crm/app/components/crm/Surface.tsx +0 -97
  380. package/corpus/templates/crm/app/components/crm/WorkOverview.tsx +0 -180
  381. package/corpus/templates/crm/app/components/layout/CrmLayout.tsx +0 -112
  382. package/corpus/templates/crm/app/components/layout/CrmSidebar.tsx +0 -84
  383. package/corpus/templates/crm/app/components/ui/alert-dialog.tsx +0 -1
  384. package/corpus/templates/crm/app/components/ui/badge.tsx +0 -1
  385. package/corpus/templates/crm/app/components/ui/button.tsx +0 -1
  386. package/corpus/templates/crm/app/components/ui/card.tsx +0 -1
  387. package/corpus/templates/crm/app/components/ui/dialog.tsx +0 -1
  388. package/corpus/templates/crm/app/components/ui/input.tsx +0 -1
  389. package/corpus/templates/crm/app/components/ui/label.tsx +0 -1
  390. package/corpus/templates/crm/app/components/ui/select.tsx +0 -1
  391. package/corpus/templates/crm/app/components/ui/sheet.tsx +0 -1
  392. package/corpus/templates/crm/app/components/ui/skeleton.tsx +0 -1
  393. package/corpus/templates/crm/app/components/ui/switch.tsx +0 -1
  394. package/corpus/templates/crm/app/components/ui/table.tsx +0 -1
  395. package/corpus/templates/crm/app/components/ui/tabs.tsx +0 -1
  396. package/corpus/templates/crm/app/components/ui/textarea.tsx +0 -1
  397. package/corpus/templates/crm/app/components/ui/toolkit-provider.tsx +0 -17
  398. package/corpus/templates/crm/app/design-system.ts +0 -3
  399. package/corpus/templates/crm/app/entry.client.tsx +0 -16
  400. package/corpus/templates/crm/app/entry.server.tsx +0 -10
  401. package/corpus/templates/crm/app/global.css +0 -167
  402. package/corpus/templates/crm/app/hooks/use-navigation-state.ts +0 -60
  403. package/corpus/templates/crm/app/i18n/en-US.ts +0 -89
  404. package/corpus/templates/crm/app/i18n/index.ts +0 -34
  405. package/corpus/templates/crm/app/lib/dashboard.ts +0 -13
  406. package/corpus/templates/crm/app/lib/navigation.ts +0 -54
  407. package/corpus/templates/crm/app/lib/tab-id.ts +0 -1
  408. package/corpus/templates/crm/app/lib/types.ts +0 -172
  409. package/corpus/templates/crm/app/lib/utils.ts +0 -1
  410. package/corpus/templates/crm/app/root.tsx +0 -91
  411. package/corpus/templates/crm/app/routes/_index.tsx +0 -26
  412. package/corpus/templates/crm/app/routes/accounts.tsx +0 -41
  413. package/corpus/templates/crm/app/routes/agent.tsx +0 -5
  414. package/corpus/templates/crm/app/routes/ask.tsx +0 -53
  415. package/corpus/templates/crm/app/routes/dashboard.tsx +0 -118
  416. package/corpus/templates/crm/app/routes/opportunities.tsx +0 -41
  417. package/corpus/templates/crm/app/routes/people.tsx +0 -41
  418. package/corpus/templates/crm/app/routes/proposals.tsx +0 -266
  419. package/corpus/templates/crm/app/routes/records.$recordId.tsx +0 -35
  420. package/corpus/templates/crm/app/routes/settings.tsx +0 -63
  421. package/corpus/templates/crm/app/routes/setup.tsx +0 -308
  422. package/corpus/templates/crm/app/routes/tasks.tsx +0 -252
  423. package/corpus/templates/crm/app/routes/views.tsx +0 -333
  424. package/corpus/templates/crm/app/routes.ts +0 -17
  425. package/corpus/templates/crm/app/vite-env.d.ts +0 -6
  426. package/corpus/templates/crm/changelog/2026-07-21-agent-native-crm.md +0 -6
  427. package/corpus/templates/crm/changelog/2026-07-21-clips-call-evidence-review-recipe.md +0 -6
  428. package/corpus/templates/crm/changelog/2026-07-21-crm-can-now-find-and-review-evidence-grounded-call-signals-w.md +0 -6
  429. package/corpus/templates/crm/changelog/2026-07-21-crm-can-now-manage-keyword-and-smart-call-signal-trackers-fr.md +0 -6
  430. package/corpus/templates/crm/changelog/2026-07-21-delegated-local-crm-automation.md +0 -6
  431. package/corpus/templates/crm/changelog/2026-07-21-native-sql.md +0 -6
  432. package/corpus/templates/crm/changelog/2026-07-21-pipeline-dashboard.md +0 -6
  433. package/corpus/templates/crm/changelog/2026-07-21-pipeline-dashboards-now-install-correctly-from-the-crm-actio.md +0 -6
  434. package/corpus/templates/crm/changelog/2026-07-21-salesforce-connection.md +0 -6
  435. package/corpus/templates/crm/changelog/2026-07-22-crm-field-validation-now-explains-which-fields-cannot-be-edi.md +0 -6
  436. package/corpus/templates/crm/changelog/2026-07-22-fixed-hubspot-contact-syncs-missing-records-updated-after-th.md +0 -6
  437. package/corpus/templates/crm/changelog/2026-07-22-fixed-pipeline-dashboard-panels-so-their-opportunity-data-lo.md +0 -6
  438. package/corpus/templates/crm/changelog/2026-07-22-full-page-chat-keeps-the-active-conversation-when-moving-to-.md +0 -6
  439. package/corpus/templates/crm/components.json +0 -20
  440. package/corpus/templates/crm/docs/architecture/crm-contract.md +0 -180
  441. package/corpus/templates/crm/learnings.defaults.md +0 -5
  442. package/corpus/templates/crm/package.json +0 -59
  443. package/corpus/templates/crm/public/favicon.svg +0 -1
  444. package/corpus/templates/crm/public/icon-180.svg +0 -1
  445. package/corpus/templates/crm/public/manifest.json +0 -11
  446. package/corpus/templates/crm/react-router.config.ts +0 -7
  447. package/corpus/templates/crm/server/crm/adapter.ts +0 -32
  448. package/corpus/templates/crm/server/crm/crm-field-firewall.ts +0 -64
  449. package/corpus/templates/crm/server/crm/crm-mirror.ts +0 -711
  450. package/corpus/templates/crm/server/crm/hubspot-adapter.ts +0 -1146
  451. package/corpus/templates/crm/server/crm/native-adapter.ts +0 -1715
  452. package/corpus/templates/crm/server/crm/read-through.ts +0 -207
  453. package/corpus/templates/crm/server/crm/salesforce-adapter.ts +0 -1255
  454. package/corpus/templates/crm/server/db/crm-store.ts +0 -1170
  455. package/corpus/templates/crm/server/db/index.ts +0 -169
  456. package/corpus/templates/crm/server/db/schema.ts +0 -441
  457. package/corpus/templates/crm/server/lib/intelligence/default-detectors.ts +0 -65
  458. package/corpus/templates/crm/server/lib/intelligence/evidence.ts +0 -105
  459. package/corpus/templates/crm/server/lib/intelligence/keyword-detector.ts +0 -100
  460. package/corpus/templates/crm/server/lib/intelligence/smart-detector.ts +0 -144
  461. package/corpus/templates/crm/server/lib/intelligence/summary.ts +0 -141
  462. package/corpus/templates/crm/server/lib/provider-api.ts +0 -64
  463. package/corpus/templates/crm/server/middleware/auth.ts +0 -4
  464. package/corpus/templates/crm/server/plugins/agent-chat.ts +0 -68
  465. package/corpus/templates/crm/server/plugins/auth.ts +0 -14
  466. package/corpus/templates/crm/server/plugins/core-routes.ts +0 -17
  467. package/corpus/templates/crm/server/plugins/db.ts +0 -454
  468. package/corpus/templates/crm/server/routes/[...page].get.ts +0 -5
  469. package/corpus/templates/crm/shared/crm-automation-recipes.ts +0 -132
  470. package/corpus/templates/crm/shared/crm-contract.ts +0 -254
  471. package/corpus/templates/crm/shared/crm-sales-config.ts +0 -63
  472. package/corpus/templates/crm/ssr-entry.ts +0 -11
  473. package/corpus/templates/crm/tsconfig.json +0 -24
  474. package/corpus/templates/crm/vite.config.ts +0 -15
  475. package/corpus/templates/crm/vitest.config.ts +0 -5
  476. package/dist/observability/hosted-model-experiment.d.ts +0 -39
  477. package/dist/observability/hosted-model-experiment.d.ts.map +0 -1
  478. package/dist/observability/hosted-model-experiment.js +0 -90
  479. package/dist/observability/hosted-model-experiment.js.map +0 -1
  480. package/src/observability/hosted-model-experiment.ts +0 -118
@@ -122,6 +122,9 @@ interface FormattedMessageTimestamp {
122
122
  full: string;
123
123
  }
124
124
 
125
+ const messageFooterFadeClassName =
126
+ "opacity-0 transition-[color,opacity] duration-150 group-hover:opacity-100 group-focus-within:opacity-100";
127
+
125
128
  function coerceMessageDate(value: unknown): Date | null {
126
129
  if (value instanceof Date) {
127
130
  return Number.isNaN(value.getTime()) ? null : value;
@@ -793,7 +796,7 @@ export function UserMessage() {
793
796
  {timestamp && (
794
797
  <MessageTimestamp
795
798
  timestamp={timestamp}
796
- className="opacity-0 transition-opacity duration-150 group-hover:opacity-100 group-focus-within:opacity-100"
799
+ className={messageFooterFadeClassName}
797
800
  />
798
801
  )}
799
802
  </div>
@@ -845,12 +848,33 @@ export function messageTextFromContent(content: unknown): string {
845
848
  .join("\n");
846
849
  }
847
850
 
848
- function latestUserMessageText(messages: readonly unknown[]): string {
851
+ export function latestUserMessageText(messages: readonly unknown[]): string {
849
852
  for (let index = messages.length - 1; index >= 0; index -= 1) {
850
853
  const message = messages[index];
851
854
  if (!message || typeof message !== "object") continue;
852
855
  const record = message as { role?: unknown; content?: unknown };
853
- if (record.role === "user") return messageTextFromContent(record.content);
856
+ if (record.role !== "user" || isHiddenUserMessage(message)) continue;
857
+ return displayableUserMessageText(messageTextFromContent(record.content));
858
+ }
859
+ return "";
860
+ }
861
+
862
+ export function userMessageTextBeforeAssistant(
863
+ messages: readonly unknown[],
864
+ assistantMessageId: string,
865
+ ): string {
866
+ const assistantIndex = messages.findIndex((message) => {
867
+ if (!message || typeof message !== "object") return false;
868
+ return (message as { id?: unknown }).id === assistantMessageId;
869
+ });
870
+ if (assistantIndex < 1) return "";
871
+
872
+ for (let index = assistantIndex - 1; index >= 0; index -= 1) {
873
+ const message = messages[index];
874
+ if (!message || typeof message !== "object") continue;
875
+ const record = message as { role?: unknown; content?: unknown };
876
+ if (record.role !== "user" || isHiddenUserMessage(message)) continue;
877
+ return displayableUserMessageText(messageTextFromContent(record.content));
854
878
  }
855
879
  return "";
856
880
  }
@@ -907,6 +931,22 @@ export function assistantMessageHasCompletedCustomUi(
907
931
  return hasCompletedTool && lastCompletedToolIsCustomUi;
908
932
  }
909
933
 
934
+ export function assistantMessageHasCustomUi(content: unknown): boolean {
935
+ if (!Array.isArray(content)) return false;
936
+ return content.some((part) => {
937
+ if (!part || typeof part !== "object") return false;
938
+ const record = part as {
939
+ type?: unknown;
940
+ chatUI?: unknown;
941
+ mcpApp?: unknown;
942
+ };
943
+ return (
944
+ record.type === "tool-call" &&
945
+ (record.chatUI !== undefined || record.mcpApp !== undefined)
946
+ );
947
+ });
948
+ }
949
+
910
950
  // Only the last assistant message may shimmer as "the currently running
911
951
  // tool" — an older message's dangling unresolved tool-call must never
912
952
  // shimmer once a later run is active.
@@ -1173,13 +1213,17 @@ export function AssistantMessage() {
1173
1213
  const hasCompletedCustomUi = assistantMessageHasCompletedCustomUi(
1174
1214
  msg.content,
1175
1215
  );
1216
+ const hasCustomUi = assistantMessageHasCustomUi(msg.content);
1176
1217
  const showMissingFinalResponse = shouldShowMissingFinalResponse({
1177
1218
  statusIsTerminal,
1178
1219
  hasAssistantText: responseConnectionText.trim().length > 0,
1179
1220
  hasUnresolvedTool,
1180
1221
  hasCompletedCustomUi,
1181
1222
  });
1182
- const responseConnectionContext = latestUserMessageText(thread.messages);
1223
+ const responseConnectionContext = userMessageTextBeforeAssistant(
1224
+ thread.messages,
1225
+ msg.id,
1226
+ );
1183
1227
  const isComplete = shouldShowAssistantMessageFooter({
1184
1228
  isLast,
1185
1229
  chatRunning,
@@ -1327,7 +1371,8 @@ export function AssistantMessage() {
1327
1371
  return (
1328
1372
  <WorkedForSummary
1329
1373
  durationMs={capturedDurationMs}
1330
- autoCollapse={animateCollapse}
1374
+ defaultOpen={hasCustomUi}
1375
+ autoCollapse={animateCollapse && !hasCustomUi}
1331
1376
  >
1332
1377
  {children}
1333
1378
  </WorkedForSummary>
@@ -1377,7 +1422,7 @@ export function AssistantMessage() {
1377
1422
  {isComplete && hasCodeAgentTools && msgContent && (
1378
1423
  <FilesChangedSummary parts={msgContent} />
1379
1424
  )}
1380
- {isComplete && isLast && (
1425
+ {isComplete && (
1381
1426
  <McpConnectionSuggestion
1382
1427
  text={responseConnectionText}
1383
1428
  contextText={responseConnectionContext}
@@ -1404,7 +1449,7 @@ export function AssistantMessage() {
1404
1449
  <button
1405
1450
  type="button"
1406
1451
  aria-label="Regenerate response"
1407
- className="flex h-6 w-6 cursor-pointer items-center justify-center rounded-md text-muted-foreground/70 transition-colors duration-150 hover:bg-accent hover:text-foreground opacity-0 group-hover:opacity-100 group-focus-within:opacity-100 disabled:cursor-not-allowed disabled:opacity-40"
1452
+ className={`flex h-6 w-6 cursor-pointer items-center justify-center rounded-md text-muted-foreground/70 hover:bg-accent hover:text-foreground ${messageFooterFadeClassName} disabled:cursor-not-allowed disabled:opacity-40`}
1408
1453
  >
1409
1454
  <IconRefresh className="h-3.5 w-3.5" />
1410
1455
  </button>
@@ -1420,7 +1465,7 @@ export function AssistantMessage() {
1420
1465
  {timestamp && (
1421
1466
  <MessageTimestamp
1422
1467
  timestamp={timestamp}
1423
- className="opacity-0 transition-opacity duration-150 group-hover:opacity-100 group-focus-within:opacity-100"
1468
+ className={messageFooterFadeClassName}
1424
1469
  />
1425
1470
  )}
1426
1471
  </div>
@@ -25,6 +25,7 @@ import React, {
25
25
  useRef,
26
26
  } from "react";
27
27
 
28
+ import type { A2AAgentActivitySnapshot } from "../../a2a/activity.js";
28
29
  import type { ActionChatUIConfig } from "../../action-ui.js";
29
30
  import type { AgentMcpAppPayload } from "../../mcp-client/app-result.js";
30
31
  import { AgentTaskCard } from "../AgentTaskCard.js";
@@ -35,8 +36,9 @@ import {
35
36
  PopoverTrigger,
36
37
  } from "../components/ui/popover.js";
37
38
  import { ConnectBuilderCard } from "../ConnectBuilderCard.js";
39
+ import { useT } from "../i18n.js";
38
40
  import { McpAppRenderer } from "../mcp-apps/McpAppRenderer.js";
39
- import type { ContentPart } from "../sse-event-processor.js";
41
+ import type { AgentCallProgress, ContentPart } from "../sse-event-processor.js";
40
42
  import {
41
43
  BashCell,
42
44
  EditCell,
@@ -48,13 +50,10 @@ import {
48
50
  isCallAgentToolCallShadowed,
49
51
  } from "../tool-display.js";
50
52
  import { cn } from "../utils.js";
53
+ import { ActionChatUiSurface } from "./action-chat-ui-surface.js";
51
54
  import {
52
55
  SmoothMarkdownText,
53
56
  HighlightedCodeBlock,
54
- markdownComponents,
55
- markdownModule,
56
- remarkGfmFn,
57
- markdownUrlTransform,
58
57
  useSmoothStreamingText,
59
58
  } from "./markdown-renderer.js";
60
59
  import { resolveToolRenderer } from "./tool-render-registry.js";
@@ -133,11 +132,10 @@ export function ToolActivityPresentation({
133
132
  animateEntry && "agent-tool-call--entering",
134
133
  )}
135
134
  data-running={isRunning ? "true" : undefined}
136
- data-active-tail={isActiveTail ? "true" : undefined}
137
135
  >
138
136
  {children}
139
137
  {isRunning && showLongRunningHint && (
140
- <div className="mt-0.5 px-2.5 text-[11px] leading-snug text-muted-foreground/80">
138
+ <div className="mt-0.5 px-2.5 pb-2 text-[11px] leading-snug text-muted-foreground/80">
141
139
  Still working. Large updates can take a minute or two.
142
140
  </div>
143
141
  )}
@@ -631,6 +629,7 @@ export function ToolCallDisplay({
631
629
  chatUI={chatUI}
632
630
  isRunning={isRunning}
633
631
  isActiveTail={showActiveTail}
632
+ structuredMeta={structuredMeta}
634
633
  approval={approval}
635
634
  repeatCount={repeatCount}
636
635
  />,
@@ -646,6 +645,7 @@ function ToolCallDisplayGeneric({
646
645
  chatUI,
647
646
  isRunning,
648
647
  isActiveTail,
648
+ structuredMeta,
649
649
  approval,
650
650
  repeatCount,
651
651
  }: {
@@ -657,27 +657,34 @@ function ToolCallDisplayGeneric({
657
657
  chatUI?: ActionChatUIConfig;
658
658
  isRunning: boolean;
659
659
  isActiveTail: boolean;
660
+ structuredMeta?: Record<string, unknown>;
660
661
  approval?: { approvalKey: string; dismissed?: boolean };
661
662
  repeatCount?: number;
662
663
  }) {
663
- const streamRef = useRef<HTMLDivElement>(null);
664
-
665
- const isAgentCall = toolName.startsWith("agent:");
664
+ const isRawCallAgent = toolName === "call-agent";
665
+ const isAgentCall = toolName.startsWith("agent:") || isRawCallAgent;
666
666
  const [expanded, setExpanded] = useState(isAgentCall);
667
667
  const [outputOpen, setOutputOpen] = useState(false);
668
- const agentName = isAgentCall ? toolName.slice(6) : null;
668
+ const agentName = toolName.startsWith("agent:")
669
+ ? toolName.slice(6)
670
+ : typeof args.agent === "string"
671
+ ? args.agent
672
+ : null;
669
673
  const isAgentError = isAgentCall && result === "Error calling agent";
670
- const agentStreamText = isAgentCall ? (argsText ?? "") : "";
674
+ const agentStreamText = isRawCallAgent
675
+ ? (result ?? "")
676
+ : isAgentCall
677
+ ? (argsText ?? "")
678
+ : "";
679
+ const agentActivity = structuredMeta?.agentActivity as
680
+ | A2AAgentActivitySnapshot
681
+ | undefined;
682
+ const agentProgress = structuredMeta?.agentProgress as
683
+ | AgentCallProgress
684
+ | undefined;
671
685
  const hasStreamText = agentStreamText.length > 0;
672
686
  const hasArgs = !isAgentCall && Object.keys(args).length > 0;
673
687
 
674
- // NOTE: All hooks must be above any conditional returns
675
- useEffect(() => {
676
- if (isAgentCall && isRunning && streamRef.current) {
677
- streamRef.current.scrollTop = streamRef.current.scrollHeight;
678
- }
679
- }, [agentStreamText, isAgentCall, isRunning]);
680
-
681
688
  // Render connect-builder as ConnectBuilderCard once the result is available
682
689
  if (toolName === "connect-builder" && result) {
683
690
  try {
@@ -759,7 +766,16 @@ function ToolCallDisplayGeneric({
759
766
  (skipRegistryRenderer ? null : resolveToolRenderer(nativeToolContext)) ??
760
767
  resolveBuiltinFallbackToolRenderer(nativeToolContext));
761
768
  if (NativeToolRenderer) {
762
- return <NativeToolRenderer context={nativeToolContext} />;
769
+ return (
770
+ <ActionChatUiSurface
771
+ context={nativeToolContext}
772
+ isBuiltinDataWidget={isBuiltinDataWidgetActionRenderer(
773
+ nativeToolContext,
774
+ )}
775
+ >
776
+ <NativeToolRenderer context={nativeToolContext} />
777
+ </ActionChatUiSurface>
778
+ );
763
779
  }
764
780
 
765
781
  const inputPayload = hasArgs ? toolInputPayload(toolName, args) : null;
@@ -780,6 +796,24 @@ function ToolCallDisplayGeneric({
780
796
  const ToolIcon = resolveToolIcon(toolName);
781
797
  const outputTitle = `Raw ${toolName} tool call output`;
782
798
 
799
+ if (isAgentCall) {
800
+ return (
801
+ <AgentCallCell
802
+ agentName={agentName ?? "agent"}
803
+ activity={agentActivity}
804
+ progress={agentProgress}
805
+ responseText={agentStreamText}
806
+ isRunning={isRunning}
807
+ isError={isAgentError}
808
+ durationMs={
809
+ typeof structuredMeta?.agentDurationMs === "number"
810
+ ? structuredMeta.agentDurationMs
811
+ : agentActivity?.durationMs
812
+ }
813
+ />
814
+ );
815
+ }
816
+
783
817
  return (
784
818
  <div className="group/tool my-0.5 w-full overflow-hidden">
785
819
  {mcpApp && <McpAppRenderer app={mcpApp} className="mb-1.5" />}
@@ -834,24 +868,6 @@ function ToolCallDisplayGeneric({
834
868
  </span>
835
869
  )}
836
870
  </button>
837
- <AnimatedCollapse open={isExpanded && isAgentCall && hasStreamText}>
838
- <div
839
- ref={streamRef}
840
- className="mt-1 rounded-md bg-muted/50 px-3 py-2 text-xs text-muted-foreground break-words max-h-48 overflow-y-auto agent-markdown prose prose-sm prose-invert max-w-none"
841
- >
842
- {markdownModule?.default && remarkGfmFn ? (
843
- <markdownModule.default
844
- remarkPlugins={[remarkGfmFn]}
845
- components={markdownComponents}
846
- urlTransform={markdownUrlTransform}
847
- >
848
- {agentStreamText}
849
- </markdownModule.default>
850
- ) : (
851
- <span style={{ whiteSpace: "pre-wrap" }}>{agentStreamText}</span>
852
- )}
853
- </div>
854
- </AnimatedCollapse>
855
871
  <AnimatedCollapse
856
872
  open={isExpanded && !isAgentCall && (hasArgs || result !== undefined)}
857
873
  >
@@ -887,6 +903,154 @@ function ToolCallDisplayGeneric({
887
903
  );
888
904
  }
889
905
 
906
+ function AgentCallCell({
907
+ agentName,
908
+ activity,
909
+ progress,
910
+ responseText,
911
+ isRunning,
912
+ isError,
913
+ durationMs,
914
+ }: {
915
+ agentName: string;
916
+ activity?: A2AAgentActivitySnapshot;
917
+ progress?: AgentCallProgress;
918
+ responseText: string;
919
+ isRunning: boolean;
920
+ isError: boolean;
921
+ durationMs?: number;
922
+ }) {
923
+ const t = useT();
924
+ const [open, setOpen] = useState(true);
925
+ const finalText = isRunning
926
+ ? activity?.responseText || responseText
927
+ : responseText || activity?.responseText;
928
+ const work = activity?.reasoning?.length || activity?.toolCalls?.length;
929
+ const workItemCount = Math.max(
930
+ activity?.reasoning?.length ?? 0,
931
+ activity?.toolCalls?.length ?? 0,
932
+ );
933
+ const label = isRunning
934
+ ? t("agentPanel.delegatedAgent.asking", { name: agentName })
935
+ : isError
936
+ ? t("agentPanel.delegatedAgent.error", { name: agentName })
937
+ : t("agentPanel.delegatedAgent.asked", { name: agentName });
938
+ const workContent = work ? (
939
+ <div className="space-y-1 ps-5">
940
+ {Array.from({ length: workItemCount }, (_, index) => {
941
+ const reasoningText = activity?.reasoning?.[index];
942
+ const tool = activity?.toolCalls?.[index];
943
+ return (
944
+ <React.Fragment key={`activity-${index}`}>
945
+ {reasoningText && (
946
+ <ReasoningCell
947
+ text={reasoningText}
948
+ isStreaming={
949
+ isRunning &&
950
+ activity.activePhase === "reasoning" &&
951
+ index === activity.reasoning.length - 1
952
+ }
953
+ defaultOpen={index === activity.reasoning.length - 1}
954
+ collapseWhenReplaced={index < activity.toolCalls.length}
955
+ />
956
+ )}
957
+ {tool && (
958
+ <ToolCallDisplay
959
+ toolName={tool.name}
960
+ args={{}}
961
+ argsText=""
962
+ isRunning={tool.status === "running"}
963
+ result={
964
+ tool.status === "failed"
965
+ ? "Failed"
966
+ : tool.status === "completed"
967
+ ? "Done"
968
+ : undefined
969
+ }
970
+ isActiveTail={
971
+ isRunning && index === activity.toolCalls.length - 1
972
+ }
973
+ />
974
+ )}
975
+ </React.Fragment>
976
+ );
977
+ })}
978
+ </div>
979
+ ) : null;
980
+ const progressState = progress?.state.replaceAll(/[-_]+/g, " ");
981
+ const progressText =
982
+ isRunning && !activity && progress && progressState
983
+ ? [
984
+ progressState.charAt(0).toUpperCase() + progressState.slice(1),
985
+ t("agentPanel.delegatedAgent.elapsed", {
986
+ duration: formatWorkedDuration(progress.elapsedSeconds * 1000),
987
+ }),
988
+ progress.detail,
989
+ ]
990
+ .filter(Boolean)
991
+ .join(" · ")
992
+ : null;
993
+ return (
994
+ <div className="group/tool my-0.5 w-full">
995
+ <button
996
+ type="button"
997
+ onClick={() => setOpen((value) => !value)}
998
+ aria-expanded={open}
999
+ className="flex w-full items-center gap-1.5 rounded-md py-0.5 text-left text-[13px] text-muted-foreground transition-colors hover:text-foreground"
1000
+ >
1001
+ {isRunning ? (
1002
+ <IconLoader2 className="size-3.5 animate-spin" />
1003
+ ) : isError ? (
1004
+ <IconCircleX className="size-3.5 text-destructive" />
1005
+ ) : (
1006
+ <IconChevronRight
1007
+ className={cn("size-3.5 transition-transform", open && "rotate-90")}
1008
+ />
1009
+ )}
1010
+ <span
1011
+ className={cn(
1012
+ "min-w-0 truncate font-normal",
1013
+ isRunning && "agent-running-shimmer",
1014
+ )}
1015
+ >
1016
+ {label}
1017
+ </span>
1018
+ </button>
1019
+ <AnimatedCollapse open={open}>
1020
+ <div className="ms-1 border-s border-border/50 ps-2 pt-1">
1021
+ {workContent &&
1022
+ (isRunning ? (
1023
+ workContent
1024
+ ) : (
1025
+ <WorkedForSummary durationMs={durationMs}>
1026
+ {workContent}
1027
+ </WorkedForSummary>
1028
+ ))}
1029
+ {progressText && (
1030
+ <p
1031
+ className="ps-5 pb-1 text-xs text-muted-foreground"
1032
+ data-testid="agent-call-progress"
1033
+ aria-live="polite"
1034
+ >
1035
+ {progressText}
1036
+ </p>
1037
+ )}
1038
+ {finalText && (
1039
+ <div className="ps-5 pb-1">
1040
+ <SmoothMarkdownText
1041
+ text={finalText}
1042
+ streaming={isRunning}
1043
+ resetKey={`agent-response-${agentName}`}
1044
+ statusType={isRunning ? "running" : "complete"}
1045
+ />
1046
+ </div>
1047
+ )}
1048
+ </div>
1049
+ </AnimatedCollapse>
1050
+ </div>
1051
+ );
1052
+ }
1053
+
890
1054
  // ─── ToolCallFallback ──────────────────────────────────────────────────────────
891
1055
 
892
1056
  export function ToolCallFallback({
@@ -1252,22 +1416,28 @@ export function formatWorkedDuration(ms: number): string {
1252
1416
 
1253
1417
  export function WorkedForSummary({
1254
1418
  durationMs,
1419
+ defaultOpen = false,
1255
1420
  autoCollapse = false,
1256
1421
  children,
1257
1422
  }: {
1258
1423
  durationMs?: number | null;
1424
+ /** Keep completed work visible when the turn contains interactive UI. */
1425
+ defaultOpen?: boolean;
1259
1426
  /** When true, close the summary after a run has completed. */
1260
1427
  autoCollapse?: boolean;
1261
1428
  children: React.ReactNode;
1262
1429
  }) {
1263
- // Start closed so a remounted completed message never flashes its work
1264
- // details open while auto-collapse settles. If the summary was already
1265
- // open when autoCollapse changes, AnimatedCollapse still animates it shut.
1266
- const [open, setOpen] = useState(false);
1430
+ // Ordinary completed work starts closed so a remount never flashes details
1431
+ // while auto-collapse settles. Interactive UI opts into an open summary.
1432
+ const [open, setOpen] = useState(defaultOpen);
1267
1433
 
1268
1434
  useEffect(() => {
1269
- if (autoCollapse) setOpen(false);
1270
- }, [autoCollapse]);
1435
+ if (defaultOpen) {
1436
+ setOpen(true);
1437
+ } else if (autoCollapse) {
1438
+ setOpen(false);
1439
+ }
1440
+ }, [autoCollapse, defaultOpen]);
1271
1441
 
1272
1442
  const label =
1273
1443
  durationMs != null && durationMs >= 1000
@@ -17,7 +17,6 @@ export function InlineExtensionWidget({
17
17
 
18
18
  return (
19
19
  <InlineExtensionFrame
20
- className="my-1.5"
21
20
  extensionId={result.mode === "persisted" ? result.id : undefined}
22
21
  extension={{
23
22
  id: result.id,
@@ -126,11 +126,15 @@ function renderDataWidget(context: ToolRendererContext) {
126
126
  return null;
127
127
  }
128
128
 
129
- function BuiltinToolRendererSkeleton() {
129
+ function BuiltinToolRendererSkeleton({ framed = true }: { framed?: boolean }) {
130
130
  return (
131
131
  <div
132
132
  aria-label="Loading tool result"
133
- className="my-1.5 h-24 animate-pulse rounded-lg border border-border bg-muted/30"
133
+ className={
134
+ framed
135
+ ? "my-1.5 h-24 animate-pulse rounded-lg border border-border bg-muted/30"
136
+ : "h-24 animate-pulse bg-muted/30"
137
+ }
134
138
  />
135
139
  );
136
140
  }
@@ -140,7 +144,7 @@ const BuiltinDataWidgetRenderer: ToolRendererComponent = ({ context }) =>
140
144
 
141
145
  const BuiltinInlineExtensionRenderer: ToolRendererComponent = ({ context }) =>
142
146
  normalizeInlineExtensionToolResult(context) ? (
143
- <Suspense fallback={<BuiltinToolRendererSkeleton />}>
147
+ <Suspense fallback={<BuiltinToolRendererSkeleton framed={false} />}>
144
148
  <LazyInlineExtensionWidget context={context} />
145
149
  </Suspense>
146
150
  ) : null;
@@ -40,34 +40,64 @@ function addCurrentModel(
40
40
  return next;
41
41
  }
42
42
 
43
+ const MODEL_COST_ORDER = [
44
+ "luna",
45
+ "terra",
46
+ "sol",
47
+ "haiku",
48
+ "sonnet",
49
+ "opus",
50
+ "fable",
51
+ "flash",
52
+ "pro",
53
+ ] as const;
54
+
55
+ function modelCostRank(model: string): number {
56
+ const normalized = model.toLowerCase();
57
+ const rank = MODEL_COST_ORDER.findIndex((tier) => normalized.includes(tier));
58
+ return rank === -1 ? MODEL_COST_ORDER.length : rank;
59
+ }
60
+
61
+ function sortModelsByCost(models: readonly string[]): string[] {
62
+ return [...models].sort((a, b) => modelCostRank(a) - modelCostRank(b));
63
+ }
64
+
43
65
  function groupBuilderModels(models: readonly string[]): EngineModelGroup[] {
44
- const claude = models.filter((model) => model.startsWith("claude-"));
45
- const openai = models.filter((model) => model.startsWith("gpt-"));
46
- const gemini = models.filter((model) => model.startsWith("gemini-"));
47
- const other = models.filter(
48
- (model) =>
49
- !model.startsWith("claude-") &&
50
- !model.startsWith("gpt-") &&
51
- !model.startsWith("gemini-"),
66
+ const claude = sortModelsByCost(
67
+ models.filter((model) => model.startsWith("claude-")),
68
+ );
69
+ const openai = sortModelsByCost(
70
+ models.filter((model) => model.startsWith("gpt-")),
71
+ );
72
+ const gemini = sortModelsByCost(
73
+ models.filter((model) => model.startsWith("gemini-")),
74
+ );
75
+ const other = sortModelsByCost(
76
+ models.filter(
77
+ (model) =>
78
+ !model.startsWith("claude-") &&
79
+ !model.startsWith("gpt-") &&
80
+ !model.startsWith("gemini-"),
81
+ ),
52
82
  );
53
83
 
54
84
  return [
55
- ...(claude.length
85
+ ...(openai.length
56
86
  ? [
57
87
  {
58
88
  engine: "builder",
59
- label: "Claude",
60
- models: claude,
89
+ label: "OpenAI",
90
+ models: openai,
61
91
  configured: true,
62
92
  },
63
93
  ]
64
94
  : []),
65
- ...(openai.length
95
+ ...(claude.length
66
96
  ? [
67
97
  {
68
98
  engine: "builder",
69
- label: "OpenAI",
70
- models: openai,
99
+ label: "Claude",
100
+ models: claude,
71
101
  configured: true,
72
102
  },
73
103
  ]
@@ -115,16 +145,24 @@ function shouldShowDirectEngine(
115
145
  return true;
116
146
  }
117
147
 
118
- function putOpenRouterLast(
148
+ function modelPickerEngineRank(engine: ChatModelEngineEntry): number {
149
+ if (engine.name === "ai-sdk:openai" || engine.label === "OpenAI") return 0;
150
+ if (
151
+ engine.name === "anthropic" ||
152
+ engine.name === "ai-sdk:anthropic" ||
153
+ engine.label === "Claude"
154
+ ) {
155
+ return 1;
156
+ }
157
+ if (engine.name === "ai-sdk:openrouter") return 100;
158
+ return 2;
159
+ }
160
+
161
+ function sortModelPickerEngines(
119
162
  a: ChatModelEngineEntry,
120
163
  b: ChatModelEngineEntry,
121
164
  ): number {
122
- const aIsOpenRouter = a.name === "ai-sdk:openrouter";
123
- const bIsOpenRouter = b.name === "ai-sdk:openrouter";
124
- if (aIsOpenRouter === bIsOpenRouter) return 0;
125
- if (aIsOpenRouter) return 1;
126
- if (bIsOpenRouter) return -1;
127
- return 0;
165
+ return modelPickerEngineRank(a) - modelPickerEngineRank(b);
128
166
  }
129
167
 
130
168
  export function buildChatModelGroups({
@@ -150,17 +188,19 @@ export function buildChatModelGroups({
150
188
  return engines
151
189
  .filter((engine) => engine.packageInstalled !== false)
152
190
  .filter((engine) => shouldShowDirectEngine(engine, currentEngineName))
153
- .sort(putOpenRouterLast)
191
+ .sort(sortModelPickerEngines)
154
192
  .map((engine) => {
155
193
  const requiredEnvVars = engine.requiredEnvVars ?? [];
156
194
  return {
157
195
  engine: engine.name,
158
196
  label: engine.label,
159
- models: addCurrentModel(
160
- engine.supportedModels ?? [],
161
- engine.name,
162
- currentEngineName,
163
- currentModel,
197
+ models: sortModelsByCost(
198
+ addCurrentModel(
199
+ engine.supportedModels ?? [],
200
+ engine.name,
201
+ currentEngineName,
202
+ currentModel,
203
+ ),
164
204
  ),
165
205
  configured:
166
206
  requiredEnvVars.length === 0 ||