@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
@@ -45,11 +45,9 @@ export interface RunStuckBannerProps {
45
45
  * `chatHandle.hasInFlightWork()`. "No progress" for a stretch of time does
46
46
  * not mean the run is dead: a long provider query or a cross-app `call
47
47
  * agent` can legitimately emit nothing for minutes. When this returns
48
- * true, Retry (which aborts the run) is hidden — aborting would destroy
49
- * real in-flight work and re-execute the same long call from scratch.
50
- * Only Cancel, an explicit destructive choice, remains available. Checked
51
- * fresh on every render; omit to keep the unconditional Retry/Cancel
52
- * behavior.
48
+ * true, the stuck warning is hidden — aborting would destroy real in-flight
49
+ * work and re-execute the same long call from scratch. Checked fresh on every
50
+ * render; omit to keep the unconditional Retry/Cancel behavior.
53
51
  */
54
52
  hasInFlightWork?: () => boolean;
55
53
  /**
@@ -191,9 +189,9 @@ export function RunStuckBanner({
191
189
  const backgroundWorkerStillAlive = isFreshBackgroundWorker(state);
192
190
  // A live tool call or sub-agent (A2A) call means "no progress" is not the
193
191
  // same as "dead" — the process is genuinely still doing the user's work.
194
- // Retry aborts the run, so it must not be offered as the (implicitly
195
- // safe-looking) primary action while real work is in flight; see the
196
- // `hasInFlightWork` prop doc comment. Re-checked on every render (the
192
+ // Retry aborts the run, so the stuck warning stays out of the way while real
193
+ // work is in flight; see the `hasInFlightWork` prop doc comment. Re-checked
194
+ // on every render (the
197
195
  // underlying source mutates in place as tool/agent-call events stream in),
198
196
  // which is why this is a function prop rather than a plain boolean.
199
197
  //
@@ -308,7 +306,18 @@ export function RunStuckBanner({
308
306
  threadId,
309
307
  ]);
310
308
 
311
- if (!state.isStuck || !state.runId) return null;
309
+ // A stale progress timestamp is not actionable while the server is still
310
+ // heartbeating or an unresolved tool/A2A call is known to be running. Keep
311
+ // those healthy long-running states in the chat's inline activity UI; the
312
+ // warning is reserved for runs that may actually need recovery.
313
+ if (
314
+ !state.isStuck ||
315
+ !state.runId ||
316
+ backgroundWorkerStillAlive ||
317
+ inFlightWork
318
+ ) {
319
+ return null;
320
+ }
312
321
 
313
322
  const handleCancel = async () => {
314
323
  if (!state.runId || busy.type !== "none") return;
@@ -323,9 +332,9 @@ export function RunStuckBanner({
323
332
  };
324
333
 
325
334
  const handleRetry = async () => {
326
- // Defense in depth: Retry is hidden while a background worker is still
327
- // heartbeating or work is explicitly in flight (see render below). Guard
328
- // the handler too so this path cannot abort a run the server says is alive.
335
+ // Defense in depth: the banner is hidden while a background worker is
336
+ // still heartbeating or work is explicitly in flight. Guard the handler
337
+ // too so a render transition cannot abort a run the server says is alive.
329
338
  if (
330
339
  !state.runId ||
331
340
  busy.type !== "none" ||
@@ -350,8 +359,6 @@ export function RunStuckBanner({
350
359
  const stuckSeconds =
351
360
  state.stuckSinceMs != null ? Math.floor(state.stuckSinceMs / 1000) : null;
352
361
 
353
- const stillWorking = backgroundWorkerStillAlive || inFlightWork;
354
-
355
362
  return (
356
363
  <div
357
364
  role="status"
@@ -368,51 +375,36 @@ export function RunStuckBanner({
368
375
  />
369
376
  <div className="flex min-w-0 flex-1 flex-col gap-1.5">
370
377
  <div className="leading-snug">
371
- <span className="font-medium">
372
- {stillWorking
373
- ? "The agent is still working."
374
- : "This chat looks stuck."}
375
- </span>{" "}
378
+ <span className="font-medium">This chat looks stuck.</span>{" "}
376
379
  <span className="text-muted-foreground">
377
380
  No progress
378
- {stuckSeconds != null ? ` for ${stuckSeconds}s` : ""}.{" "}
379
- {inFlightWork
380
- ? "It's waiting on a call to another app or a long tool — canceling will stop that work."
381
- : backgroundWorkerStillAlive
382
- ? "The background worker is still alive; large updates can take a few minutes."
383
- : "The agent may have hit a server timeout or lost its connection."}
381
+ {stuckSeconds != null ? ` for ${stuckSeconds}s` : ""}. The agent may
382
+ have hit a server timeout or lost its connection.
384
383
  {autoRetry && busyType === "retry"
385
384
  ? " Retrying automatically now."
386
385
  : ""}
387
386
  </span>
388
387
  </div>
389
388
  <div className="flex flex-wrap items-center gap-2">
390
- {stillWorking ? null : (
391
- <button
392
- type="button"
393
- onClick={handleRetry}
394
- disabled={busyType !== "none"}
395
- className="inline-flex h-7 cursor-pointer items-center gap-1.5 rounded-md bg-foreground px-2.5 text-[11px] font-medium text-background transition-colors hover:bg-foreground/90 disabled:cursor-not-allowed disabled:opacity-60"
396
- >
397
- {busyType === "retry" ? (
398
- <IconLoader2
399
- size={12}
400
- className="animate-spin"
401
- aria-hidden="true"
402
- />
403
- ) : null}
404
- Retry
405
- </button>
406
- )}
389
+ <button
390
+ type="button"
391
+ onClick={handleRetry}
392
+ disabled={busyType !== "none"}
393
+ className="inline-flex h-7 cursor-pointer items-center gap-1.5 rounded-md bg-foreground px-2.5 text-[11px] font-medium text-background transition-colors hover:bg-foreground/90 disabled:cursor-not-allowed disabled:opacity-60"
394
+ >
395
+ {busyType === "retry" ? (
396
+ <IconLoader2
397
+ size={12}
398
+ className="animate-spin"
399
+ aria-hidden="true"
400
+ />
401
+ ) : null}
402
+ Retry
403
+ </button>
407
404
  <button
408
405
  type="button"
409
406
  onClick={handleCancel}
410
407
  disabled={busyType !== "none"}
411
- title={
412
- inFlightWork
413
- ? "Stop the in-progress run. Work that hasn't finished will be lost."
414
- : undefined
415
- }
416
408
  className="inline-flex h-7 cursor-pointer items-center gap-1.5 rounded-md border border-border bg-background px-2.5 text-[11px] font-medium text-foreground transition-colors hover:bg-accent disabled:cursor-not-allowed disabled:opacity-60"
417
409
  >
418
410
  {busyType === "cancel" ? (
@@ -0,0 +1,32 @@
1
+ import type { ReactNode } from "react";
2
+
3
+ import { ACTION_CHAT_UI_INLINE_EXTENSION_RENDERER } from "../../action-ui.js";
4
+ import { cn } from "../utils.js";
5
+ import type { ToolRendererContext } from "./tool-render-registry.js";
6
+
7
+ export function ActionChatUiSurface({
8
+ context,
9
+ isBuiltinDataWidget,
10
+ children,
11
+ }: {
12
+ context: ToolRendererContext;
13
+ isBuiltinDataWidget: boolean;
14
+ children: ReactNode;
15
+ }) {
16
+ if (!context.chatUI || isBuiltinDataWidget) return <>{children}</>;
17
+
18
+ const containsPaddedIframe =
19
+ context.chatUI.renderer === ACTION_CHAT_UI_INLINE_EXTENSION_RENDERER;
20
+
21
+ return (
22
+ <div
23
+ data-agent-native-custom-ui=""
24
+ className={cn(
25
+ "my-3 overflow-hidden rounded-lg border border-border bg-card text-card-foreground shadow-sm empty:hidden",
26
+ !containsPaddedIframe && "p-3",
27
+ )}
28
+ >
29
+ {children}
30
+ </div>
31
+ );
32
+ }
@@ -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,