@agent-native/core 0.149.1 → 0.149.3

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 (422) hide show
  1. package/corpus/README.md +1 -1
  2. package/corpus/templates/analytics/.agents/skills/actions/SKILL.md +54 -488
  3. package/corpus/templates/analytics/.agents/skills/actions/references/action-fields.md +136 -0
  4. package/corpus/templates/analytics/.agents/skills/actions/references/examples.md +94 -0
  5. package/corpus/templates/analytics/.agents/skills/actions/references/provider-apis.md +95 -0
  6. package/corpus/templates/analytics/.agents/skills/create-skill/SKILL.md +9 -35
  7. package/corpus/templates/analytics/.agents/skills/creative-context/SKILL.md +4 -2
  8. package/corpus/templates/analytics/.agents/skills/dashboard-management/SKILL.md +2 -0
  9. package/corpus/templates/analytics/.agents/skills/frontend-design/SKILL.md +4 -5
  10. package/corpus/templates/analytics/.agents/skills/turn-into-app/SKILL.md +18 -31
  11. package/corpus/templates/analytics/AGENTS.md +25 -32
  12. package/corpus/templates/analytics/app/components/dashboard/SqlChart.tsx +150 -46
  13. package/corpus/templates/analytics/app/global.css +1 -1
  14. package/corpus/templates/analytics/app/i18n-data.ts +37 -0
  15. package/corpus/templates/analytics/app/pages/adhoc/sql-dashboard/PanelEditorDialog.tsx +1 -1
  16. package/corpus/templates/analytics/app/pages/adhoc/sql-dashboard/SqlChartCard.tsx +32 -0
  17. package/corpus/templates/analytics/app/pages/adhoc/sql-dashboard/types.ts +2 -0
  18. package/corpus/templates/analytics/changelog/2026-08-10-dashboard-tables-can-be-copied-and-sorted-by-multiple-column.md +6 -0
  19. package/corpus/templates/analytics/changelog/2026-08-10-full-page-chat-now-uses-the-available-width-up-to-1000px-for.md +6 -0
  20. package/corpus/templates/analytics/changelog/2026-08-11-full-page-chat-composers-stay-at-a-focused-750px-width.md +6 -0
  21. package/corpus/templates/assets/.agents/skills/actions/SKILL.md +54 -488
  22. package/corpus/templates/assets/.agents/skills/actions/references/action-fields.md +136 -0
  23. package/corpus/templates/assets/.agents/skills/actions/references/examples.md +94 -0
  24. package/corpus/templates/assets/.agents/skills/actions/references/provider-apis.md +95 -0
  25. package/corpus/templates/assets/.agents/skills/create-skill/SKILL.md +9 -35
  26. package/corpus/templates/assets/.agents/skills/creative-context/SKILL.md +4 -2
  27. package/corpus/templates/assets/.agents/skills/frontend-design/SKILL.md +4 -5
  28. package/corpus/templates/assets/.agents/skills/turn-into-app/SKILL.md +18 -31
  29. package/corpus/templates/assets/AGENTS.md +6 -9
  30. package/corpus/templates/assets/app/global.css +1 -1
  31. package/corpus/templates/assets/changelog/2026-08-10-full-page-chat-now-uses-the-available-width-up-to-1000px-for.md +6 -0
  32. package/corpus/templates/assets/changelog/2026-08-11-full-page-chat-composers-stay-at-a-focused-750px-width.md +6 -0
  33. package/corpus/templates/brain/.agents/skills/actions/SKILL.md +54 -488
  34. package/corpus/templates/brain/.agents/skills/actions/references/action-fields.md +136 -0
  35. package/corpus/templates/brain/.agents/skills/actions/references/examples.md +94 -0
  36. package/corpus/templates/brain/.agents/skills/actions/references/provider-apis.md +95 -0
  37. package/corpus/templates/brain/.agents/skills/create-skill/SKILL.md +9 -35
  38. package/corpus/templates/brain/.agents/skills/frontend-design/SKILL.md +4 -5
  39. package/corpus/templates/brain/.agents/skills/turn-into-app/SKILL.md +18 -31
  40. package/corpus/templates/brain/AGENTS.md +5 -12
  41. package/corpus/templates/brain/app/global.css +1 -1
  42. package/corpus/templates/brain/changelog/2026-08-10-full-page-chat-now-uses-the-available-width-up-to-1000px-for.md +6 -0
  43. package/corpus/templates/brain/changelog/2026-08-11-full-page-chat-composers-stay-at-a-focused-750px-width.md +6 -0
  44. package/corpus/templates/calendar/.agents/skills/actions/SKILL.md +54 -488
  45. package/corpus/templates/calendar/.agents/skills/actions/references/action-fields.md +136 -0
  46. package/corpus/templates/calendar/.agents/skills/actions/references/examples.md +94 -0
  47. package/corpus/templates/calendar/.agents/skills/actions/references/provider-apis.md +95 -0
  48. package/corpus/templates/calendar/.agents/skills/create-skill/SKILL.md +9 -35
  49. package/corpus/templates/calendar/.agents/skills/frontend-design/SKILL.md +4 -5
  50. package/corpus/templates/calendar/.agents/skills/turn-into-app/SKILL.md +18 -31
  51. package/corpus/templates/calendar/AGENTS.md +8 -9
  52. package/corpus/templates/chat/.agents/skills/actions/SKILL.md +54 -488
  53. package/corpus/templates/chat/.agents/skills/actions/references/action-fields.md +136 -0
  54. package/corpus/templates/chat/.agents/skills/actions/references/examples.md +94 -0
  55. package/corpus/templates/chat/.agents/skills/actions/references/provider-apis.md +95 -0
  56. package/corpus/templates/chat/.agents/skills/create-skill/SKILL.md +9 -35
  57. package/corpus/templates/chat/.agents/skills/frontend-design/SKILL.md +4 -5
  58. package/corpus/templates/chat/.agents/skills/turn-into-app/SKILL.md +18 -31
  59. package/corpus/templates/chat/AGENTS.md +32 -80
  60. package/corpus/templates/chat/changelog/2026-08-10-full-page-chat-now-uses-the-available-width-up-to-1000px-for.md +6 -0
  61. package/corpus/templates/clips/.agents/skills/actions/SKILL.md +54 -488
  62. package/corpus/templates/clips/.agents/skills/actions/references/action-fields.md +136 -0
  63. package/corpus/templates/clips/.agents/skills/actions/references/examples.md +94 -0
  64. package/corpus/templates/clips/.agents/skills/actions/references/provider-apis.md +95 -0
  65. package/corpus/templates/clips/.agents/skills/create-skill/SKILL.md +9 -35
  66. package/corpus/templates/clips/.agents/skills/frontend-design/SKILL.md +4 -5
  67. package/corpus/templates/clips/.agents/skills/turn-into-app/SKILL.md +18 -31
  68. package/corpus/templates/clips/AGENTS.md +25 -31
  69. package/corpus/templates/clips/changelog/2026-08-10-clips-desktop-sign-in-now-starts-with-magic-links-and-google.md +6 -0
  70. package/corpus/templates/clips/chrome-extension/src/overlay.css +1 -0
  71. package/corpus/templates/clips/desktop/src/app.tsx +274 -137
  72. package/corpus/templates/clips/desktop/src/styles.css +35 -0
  73. package/corpus/templates/content/.agents/skills/actions/SKILL.md +54 -488
  74. package/corpus/templates/content/.agents/skills/actions/references/action-fields.md +136 -0
  75. package/corpus/templates/content/.agents/skills/actions/references/examples.md +94 -0
  76. package/corpus/templates/content/.agents/skills/actions/references/provider-apis.md +95 -0
  77. package/corpus/templates/content/.agents/skills/create-skill/SKILL.md +9 -35
  78. package/corpus/templates/content/.agents/skills/creative-context/SKILL.md +4 -2
  79. package/corpus/templates/content/.agents/skills/frontend-design/SKILL.md +4 -5
  80. package/corpus/templates/content/.agents/skills/turn-into-app/SKILL.md +18 -31
  81. package/corpus/templates/content/AGENTS.md +5 -9
  82. package/corpus/templates/content/app/global.css +1 -0
  83. package/corpus/templates/crm/.agents/skills/turn-into-app/SKILL.md +18 -31
  84. package/corpus/templates/crm/AGENTS.md +7 -11
  85. package/corpus/templates/crm/app/global.css +1 -1
  86. package/corpus/templates/crm/changelog/2026-08-10-full-page-chat-now-uses-the-available-width-up-to-1000px-for.md +6 -0
  87. package/corpus/templates/crm/changelog/2026-08-11-full-page-chat-composers-stay-at-a-focused-750px-width.md +6 -0
  88. package/corpus/templates/design/.agents/skills/actions/SKILL.md +54 -488
  89. package/corpus/templates/design/.agents/skills/actions/references/action-fields.md +136 -0
  90. package/corpus/templates/design/.agents/skills/actions/references/examples.md +94 -0
  91. package/corpus/templates/design/.agents/skills/actions/references/provider-apis.md +95 -0
  92. package/corpus/templates/design/.agents/skills/create-skill/SKILL.md +9 -35
  93. package/corpus/templates/design/.agents/skills/creative-context/SKILL.md +4 -2
  94. package/corpus/templates/design/.agents/skills/frontend-design/SKILL.md +4 -5
  95. package/corpus/templates/design/.agents/skills/turn-into-app/SKILL.md +18 -31
  96. package/corpus/templates/design/.generated/bridge/editor-chrome.generated.ts +70 -3
  97. package/corpus/templates/design/AGENTS.md +13 -21
  98. package/corpus/templates/design/app/components/design/DesignCanvas.tsx +12 -0
  99. package/corpus/templates/design/app/components/design/LayersPanel.tsx +19 -2
  100. package/corpus/templates/design/app/components/design/MultiScreenCanvas.tsx +115 -7
  101. package/corpus/templates/design/app/components/design/bridge/editor-chrome.bridge.ts +82 -7
  102. package/corpus/templates/design/app/components/design/design-trace.ts +120 -0
  103. package/corpus/templates/design/app/components/design/dnd-debug.ts +2 -1
  104. package/corpus/templates/design/app/components/design/edit-panel/position-layout-properties.tsx +40 -26
  105. package/corpus/templates/design/app/components/design/multi-screen/board-surface-html.ts +4 -1
  106. package/corpus/templates/design/app/components/design/multi-screen/frame-geometry.ts +12 -3
  107. package/corpus/templates/design/app/components/design/multi-screen/screen-content-cache.ts +4 -0
  108. package/corpus/templates/design/app/components/design/multi-screen/types.ts +7 -0
  109. package/corpus/templates/design/app/components/editor/PromptDialog.tsx +3 -2
  110. package/corpus/templates/design/app/components/layout/Sidebar.tsx +2 -2
  111. package/corpus/templates/design/app/hooks/useDesignHotkeys.ts +3 -0
  112. package/corpus/templates/design/app/i18n-data.ts +1 -0
  113. package/corpus/templates/design/app/pages/DesignSystemSetup.tsx +5 -5
  114. package/corpus/templates/design/app/pages/DesignSystems.tsx +3 -2
  115. package/corpus/templates/design/app/pages/design-editor/canvas-primitive-insert.ts +100 -13
  116. package/corpus/templates/design/app/pages/design-editor/cross-screen-text-color.ts +1 -1
  117. package/corpus/templates/design/app/pages/design-editor/data-operations.ts +14 -0
  118. package/corpus/templates/design/changelog/2026-08-10-marquee-selecting-layers-far-down-a-tall-screen-now-selects-.md +6 -0
  119. package/corpus/templates/design/changelog/2026-08-10-the-frame-tool-draws-a-plain-frame-by-default-with-screen-av.md +6 -0
  120. package/corpus/templates/design/e2e/global-setup.ts +27 -32
  121. package/corpus/templates/design/playwright.config.ts +3 -5
  122. package/corpus/templates/design/shared/breakpoint-media.ts +9 -2
  123. package/corpus/templates/dispatch/.agents/skills/actions/SKILL.md +54 -488
  124. package/corpus/templates/dispatch/.agents/skills/actions/references/action-fields.md +136 -0
  125. package/corpus/templates/dispatch/.agents/skills/actions/references/examples.md +94 -0
  126. package/corpus/templates/dispatch/.agents/skills/actions/references/provider-apis.md +95 -0
  127. package/corpus/templates/dispatch/.agents/skills/create-skill/SKILL.md +9 -35
  128. package/corpus/templates/dispatch/.agents/skills/frontend-design/SKILL.md +4 -5
  129. package/corpus/templates/dispatch/.agents/skills/turn-into-app/SKILL.md +18 -31
  130. package/corpus/templates/dispatch/AGENTS.md +9 -16
  131. package/corpus/templates/dispatch/changelog/2026-08-10-full-page-chat-now-uses-the-available-width-up-to-1000px-for.md +6 -0
  132. package/corpus/templates/factory/.agents/skills/actions/SKILL.md +54 -488
  133. package/corpus/templates/factory/.agents/skills/actions/references/action-fields.md +136 -0
  134. package/corpus/templates/factory/.agents/skills/actions/references/examples.md +94 -0
  135. package/corpus/templates/factory/.agents/skills/actions/references/provider-apis.md +95 -0
  136. package/corpus/templates/factory/.agents/skills/create-skill/SKILL.md +9 -35
  137. package/corpus/templates/factory/.agents/skills/frontend-design/SKILL.md +4 -5
  138. package/corpus/templates/factory/.agents/skills/turn-into-app/SKILL.md +18 -31
  139. package/corpus/templates/factory/AGENTS.md +10 -24
  140. package/corpus/templates/factory/changelog/2026-08-10-full-page-chat-now-uses-the-available-width-up-to-1000px-for.md +6 -0
  141. package/corpus/templates/forms/.agents/skills/actions/SKILL.md +54 -488
  142. package/corpus/templates/forms/.agents/skills/actions/references/action-fields.md +136 -0
  143. package/corpus/templates/forms/.agents/skills/actions/references/examples.md +94 -0
  144. package/corpus/templates/forms/.agents/skills/actions/references/provider-apis.md +95 -0
  145. package/corpus/templates/forms/.agents/skills/create-skill/SKILL.md +9 -35
  146. package/corpus/templates/forms/.agents/skills/frontend-design/SKILL.md +4 -5
  147. package/corpus/templates/forms/.agents/skills/turn-into-app/SKILL.md +18 -31
  148. package/corpus/templates/forms/AGENTS.md +11 -17
  149. package/corpus/templates/forms/app/global.css +1 -0
  150. package/corpus/templates/forms/changelog/2026-08-10-full-page-chat-now-uses-the-available-width-up-to-1000px-for.md +6 -0
  151. package/corpus/templates/forms/changelog/2026-08-11-full-page-chat-composers-stay-at-a-focused-750px-width.md +6 -0
  152. package/corpus/templates/macros/.agents/skills/frontend-design/SKILL.md +4 -5
  153. package/corpus/templates/macros/.agents/skills/turn-into-app/SKILL.md +18 -31
  154. package/corpus/templates/macros/AGENTS.md +8 -8
  155. package/corpus/templates/mail/.agents/skills/actions/SKILL.md +54 -488
  156. package/corpus/templates/mail/.agents/skills/actions/references/action-fields.md +136 -0
  157. package/corpus/templates/mail/.agents/skills/actions/references/examples.md +94 -0
  158. package/corpus/templates/mail/.agents/skills/actions/references/provider-apis.md +95 -0
  159. package/corpus/templates/mail/.agents/skills/create-skill/SKILL.md +9 -35
  160. package/corpus/templates/mail/.agents/skills/frontend-design/SKILL.md +4 -5
  161. package/corpus/templates/mail/.agents/skills/turn-into-app/SKILL.md +18 -31
  162. package/corpus/templates/mail/AGENTS.md +5 -6
  163. package/corpus/templates/plan/.agents/skills/actions/SKILL.md +54 -488
  164. package/corpus/templates/plan/.agents/skills/actions/references/action-fields.md +136 -0
  165. package/corpus/templates/plan/.agents/skills/actions/references/examples.md +94 -0
  166. package/corpus/templates/plan/.agents/skills/actions/references/provider-apis.md +95 -0
  167. package/corpus/templates/plan/.agents/skills/create-skill/SKILL.md +9 -35
  168. package/corpus/templates/plan/.agents/skills/frontend-design/SKILL.md +4 -5
  169. package/corpus/templates/plan/.agents/skills/turn-into-app/SKILL.md +18 -31
  170. package/corpus/templates/plan/AGENTS.md +5 -14
  171. package/corpus/templates/plan/app/global.css +1 -0
  172. package/corpus/templates/plan/changelog/2026-08-10-full-page-chat-now-uses-the-available-width-up-to-1000px-for.md +6 -0
  173. package/corpus/templates/plan/changelog/2026-08-11-plan-no-longer-reloads-when-runtime-state-changes.md +6 -0
  174. package/corpus/templates/plan/server/ui-plan-html.ts +4 -1
  175. package/corpus/templates/plan/vite.config.ts +5 -0
  176. package/corpus/templates/slides/.agents/skills/actions/SKILL.md +54 -488
  177. package/corpus/templates/slides/.agents/skills/actions/references/action-fields.md +136 -0
  178. package/corpus/templates/slides/.agents/skills/actions/references/examples.md +94 -0
  179. package/corpus/templates/slides/.agents/skills/actions/references/provider-apis.md +95 -0
  180. package/corpus/templates/slides/.agents/skills/create-deck/SKILL.md +2 -2
  181. package/corpus/templates/slides/.agents/skills/create-skill/SKILL.md +9 -35
  182. package/corpus/templates/slides/.agents/skills/creative-context/SKILL.md +6 -3
  183. package/corpus/templates/slides/.agents/skills/deck-management/SKILL.md +6 -1
  184. package/corpus/templates/slides/.agents/skills/frontend-design/SKILL.md +4 -5
  185. package/corpus/templates/slides/.agents/skills/image-generation-via-a2a/SKILL.md +3 -2
  186. package/corpus/templates/slides/.agents/skills/slide-editing/SKILL.md +3 -0
  187. package/corpus/templates/slides/.agents/skills/slide-images/SKILL.md +3 -3
  188. package/corpus/templates/slides/.agents/skills/turn-into-app/SKILL.md +18 -31
  189. package/corpus/templates/slides/AGENTS.md +33 -35
  190. package/corpus/templates/slides/actions/add-deck.ts +2 -0
  191. package/corpus/templates/slides/actions/add-slide.ts +15 -1
  192. package/corpus/templates/slides/actions/create-deck.ts +18 -6
  193. package/corpus/templates/slides/actions/get-deck-reference-context.ts +2 -2
  194. package/corpus/templates/slides/actions/get-deck.ts +83 -7
  195. package/corpus/templates/slides/actions/import-file.ts +2 -1
  196. package/corpus/templates/slides/actions/patch-deck.ts +165 -9
  197. package/corpus/templates/slides/actions/save-deck.ts +24 -1
  198. package/corpus/templates/slides/actions/update-slide.ts +1 -1
  199. package/corpus/templates/slides/app/components/comments/SlideCommentsPanel.tsx +2 -2
  200. package/corpus/templates/slides/app/components/deck/DeckCard.tsx +1 -23
  201. package/corpus/templates/slides/app/components/design-system/DesignSystemCard.tsx +2 -2
  202. package/corpus/templates/slides/app/components/design-system/DesignSystemSetup.tsx +6 -6
  203. package/corpus/templates/slides/app/components/editor/AnimationsPanel.tsx +3 -3
  204. package/corpus/templates/slides/app/components/editor/DeckEditorSkeleton.tsx +4 -4
  205. package/corpus/templates/slides/app/components/editor/EditorSidebar.tsx +1 -1
  206. package/corpus/templates/slides/app/components/editor/EditorToolbar.tsx +432 -668
  207. package/corpus/templates/slides/app/components/editor/ExportMenu.tsx +296 -259
  208. package/corpus/templates/slides/app/components/editor/GeneratingSlidePreview.tsx +1 -1
  209. package/corpus/templates/slides/app/components/editor/GoogleDriveConnectionCta.tsx +13 -1
  210. package/corpus/templates/slides/app/components/editor/NewDeckReferenceStep.tsx +56 -174
  211. package/corpus/templates/slides/app/components/editor/PromptDialog.tsx +241 -116
  212. package/corpus/templates/slides/app/components/editor/SlideContextToolbar.tsx +1 -1
  213. package/corpus/templates/slides/app/components/editor/SlideEditor.tsx +42 -14
  214. package/corpus/templates/slides/app/components/editor/SpeakerNotesPanel.tsx +6 -12
  215. package/corpus/templates/slides/app/components/editor/editor-command-model.ts +35 -0
  216. package/corpus/templates/slides/app/components/layout/AgentWorkIndicator.tsx +1 -1
  217. package/corpus/templates/slides/app/components/layout/Layout.tsx +34 -35
  218. package/corpus/templates/slides/app/components/layout/Sidebar.tsx +8 -10
  219. package/corpus/templates/slides/app/components/layout/layout-route-policy.ts +2 -5
  220. package/corpus/templates/slides/app/components/onboarding/FirstDeckOnboardingFlow.tsx +45 -40
  221. package/corpus/templates/slides/app/components/presentation/PresentationView.tsx +63 -16
  222. package/corpus/templates/slides/app/context/DeckContext.tsx +2 -1
  223. package/corpus/templates/slides/app/global.css +76 -1
  224. package/corpus/templates/slides/app/hooks/use-generating-slide-preview.ts +25 -3
  225. package/corpus/templates/slides/app/i18n/en-US.ts +2 -0
  226. package/corpus/templates/slides/app/lib/create-deck-generation.ts +52 -23
  227. package/corpus/templates/slides/app/lib/recent-references.ts +23 -1
  228. package/corpus/templates/slides/app/lib/slide-animation-elements.ts +104 -3
  229. package/corpus/templates/slides/app/pages/DeckEditor.tsx +17 -33
  230. package/corpus/templates/slides/app/pages/DesignSystems.tsx +2 -2
  231. package/corpus/templates/slides/app/pages/Index.tsx +315 -151
  232. package/corpus/templates/slides/app/root.tsx +43 -0
  233. package/corpus/templates/slides/changelog/2026-08-10-ai-editing-avatar-badge.md +6 -0
  234. package/corpus/templates/slides/changelog/2026-08-10-generated-decks-keep-a-clear-human-readable-title.md +6 -0
  235. package/corpus/templates/slides/changelog/2026-08-10-new-deck-creation-now-shows-progress-opens-the-editor-direct.md +6 -0
  236. package/corpus/templates/slides/changelog/2026-08-10-presentation-reveals-now-follow-valid-targets.md +6 -0
  237. package/corpus/templates/slides/changelog/2026-08-10-slides-editing-controls-are-consolidated-into-one-focused-me.md +6 -0
  238. package/corpus/templates/slides/changelog/2026-08-10-slides-now-verify-and-restyle-every-imported-slide-in-one-pa.md +6 -0
  239. package/corpus/templates/slides/changelog/2026-08-10-slides-only-suggests-a-google-connection-for-relevant-reques.md +6 -0
  240. package/corpus/templates/slides/changelog/2026-08-10-the-google-slides-import-option-is-now-labeled-slides.md +6 -0
  241. package/corpus/templates/slides/changelog/2026-08-11-faster-slides-chat-deck-reads.md +6 -0
  242. package/corpus/templates/slides/changelog/2026-08-11-slides-chat-can-read-one-slide-without-loading-the-full-deck.md +6 -0
  243. package/corpus/templates/slides/changelog/2026-08-11-slides-clearly-indicate-when-an-ai-agent-is-editing-alongsid.md +6 -0
  244. package/corpus/templates/slides/package.json +1 -0
  245. package/corpus/templates/slides/server/lib/chat-attachments.ts +1 -1
  246. package/corpus/templates/slides/server/lib/validate-slide-animations.ts +163 -0
  247. package/corpus/templates/slides/server/plugins/agent-chat.ts +8 -5
  248. package/corpus/templates/slides/shared/api.ts +47 -15
  249. package/corpus/templates/slides/shared/deck-title.ts +135 -0
  250. package/corpus/templates/tasks/.agents/skills/actions/SKILL.md +54 -488
  251. package/corpus/templates/tasks/.agents/skills/actions/references/action-fields.md +136 -0
  252. package/corpus/templates/tasks/.agents/skills/actions/references/examples.md +94 -0
  253. package/corpus/templates/tasks/.agents/skills/actions/references/provider-apis.md +95 -0
  254. package/corpus/templates/tasks/.agents/skills/agent-watchdog/SKILL.md +1 -0
  255. package/corpus/templates/tasks/.agents/skills/create-skill/SKILL.md +9 -35
  256. package/corpus/templates/tasks/.agents/skills/efficient-fable/SKILL.md +1 -0
  257. package/corpus/templates/tasks/.agents/skills/efficient-frontier/SKILL.md +1 -0
  258. package/corpus/templates/tasks/.agents/skills/frontend-design/SKILL.md +4 -5
  259. package/corpus/templates/tasks/.agents/skills/plan-arbiter/SKILL.md +1 -0
  260. package/corpus/templates/tasks/.agents/skills/plow-ahead/SKILL.md +1 -0
  261. package/corpus/templates/tasks/.agents/skills/quick-recap/SKILL.md +1 -0
  262. package/corpus/templates/tasks/.agents/skills/read-the-damn-docs/SKILL.md +1 -0
  263. package/corpus/templates/tasks/.agents/skills/stay-within-limits/SKILL.md +1 -0
  264. package/corpus/templates/tasks/.agents/skills/turn-into-app/SKILL.md +18 -31
  265. package/corpus/templates/tasks/AGENTS.md +5 -20
  266. package/corpus/templates/tasks/app/components/tasks/TaskListRow.tsx +4 -1
  267. package/dist/agent/engine/ai-sdk-engine.js +1 -1
  268. package/dist/agent/production-agent.d.ts +21 -1
  269. package/dist/agent/production-agent.js +505 -355
  270. package/dist/agent/run-manager.js +156 -14
  271. package/dist/agent/run-store.d.ts +11 -10
  272. package/dist/agent/run-store.js +17 -13
  273. package/dist/agent/tool-approval-store.d.ts +18 -0
  274. package/dist/agent/tool-approval-store.js +122 -0
  275. package/dist/agent/types.d.ts +1 -1
  276. package/dist/cli/code-agent-executor.js +11 -2
  277. package/dist/client/AgentPanel.js +31 -6
  278. package/dist/client/AssistantChat.d.ts +9 -4
  279. package/dist/client/AssistantChat.js +221 -149
  280. package/dist/client/active-run-state.d.ts +9 -1
  281. package/dist/client/active-run-state.js +34 -3
  282. package/dist/client/agent-chat/index.d.ts +1 -1
  283. package/dist/client/agent-chat-adapter.d.ts +8 -0
  284. package/dist/client/agent-chat-adapter.js +125 -28
  285. package/dist/client/agent-chat.d.ts +1 -1
  286. package/dist/client/chat/markdown-renderer.js +14 -2
  287. package/dist/client/chat/message-components.d.ts +13 -3
  288. package/dist/client/chat/message-components.js +57 -52
  289. package/dist/client/chat/run-recovery.d.ts +1 -0
  290. package/dist/client/chat/run-recovery.js +8 -0
  291. package/dist/client/chat/tool-call-display.d.ts +5 -5
  292. package/dist/client/chat/tool-call-display.js +9 -212
  293. package/dist/client/chat-first/apps-rail.js +3 -3
  294. package/dist/client/chat-first/browser-pane.js +4 -1
  295. package/dist/client/chat-first/chat-history.d.ts +3 -1
  296. package/dist/client/chat-first/chat-history.js +7 -4
  297. package/dist/client/chat-first/surface-tabs.d.ts +1 -1
  298. package/dist/client/chat-first/surface-tabs.js +52 -41
  299. package/dist/client/chat-first/types.d.ts +3 -0
  300. package/dist/client/chat-first.d.ts +10 -0
  301. package/dist/client/chat-first.js +37 -2
  302. package/dist/client/components/ui/message-scroller.js +4 -1
  303. package/dist/client/i18n.js +3 -1
  304. package/dist/client/resources/McpConnectionSuggestion.js +9 -1
  305. package/dist/client/sse-event-processor.d.ts +4 -2
  306. package/dist/client/sse-event-processor.js +46 -6
  307. package/dist/client/use-chat-models.js +156 -80
  308. package/dist/client/use-run-stuck-detection.d.ts +2 -0
  309. package/dist/client/use-run-stuck-detection.js +85 -9
  310. package/dist/collab/awareness.d.ts +2 -2
  311. package/dist/collab/routes.d.ts +1 -1
  312. package/dist/collab/struct-routes.d.ts +1 -1
  313. package/dist/integrations/adapters/slack.d.ts +0 -4
  314. package/dist/integrations/adapters/slack.js +6 -30
  315. package/dist/integrations/catalog.js +1 -1
  316. package/dist/integrations/pending-tasks-store.d.ts +0 -8
  317. package/dist/integrations/pending-tasks-store.js +0 -21
  318. package/dist/integrations/slack-manifest.d.ts +2 -2
  319. package/dist/integrations/slack-manifest.js +0 -3
  320. package/dist/integrations/webhook-handler.js +1 -1
  321. package/dist/mcp/screen-memory-stdio.d.ts +7 -7
  322. package/dist/observability/routes.d.ts +3 -3
  323. package/dist/provider-api/actions/custom-provider-registration.d.ts +4 -4
  324. package/dist/provider-api/actions/provider-api.d.ts +8 -8
  325. package/dist/scripts/docs/source-search.js +2 -2
  326. package/dist/server/agent-chat/framework-prompts.js +7 -2
  327. package/dist/server/agent-chat/prompt-resources.js +2 -2
  328. package/dist/server/agent-chat/skill-frontmatter.d.ts +31 -2
  329. package/dist/server/agent-chat/skill-frontmatter.js +41 -15
  330. package/dist/server/agent-chat-plugin.js +3 -3
  331. package/dist/server/agent-engine-api-key-route.d.ts +1 -1
  332. package/dist/server/agents-bundle.d.ts +16 -19
  333. package/dist/server/agents-bundle.js +19 -35
  334. package/dist/server/auth.js +262 -31
  335. package/dist/server/better-auth-instance.d.ts +1 -0
  336. package/dist/server/better-auth-instance.js +17 -2
  337. package/dist/server/onboarding-html.js +56 -9
  338. package/dist/server/prompts/framework-core-compact.d.ts +6 -1
  339. package/dist/server/prompts/framework-core-compact.js +12 -9
  340. package/dist/server/prompts/framework-core.d.ts +6 -1
  341. package/dist/server/prompts/framework-core.js +11 -9
  342. package/dist/server/prompts/index.d.ts +1 -1
  343. package/dist/server/prompts/index.js +1 -1
  344. package/dist/server/prompts/shared-rules.d.ts +15 -11
  345. package/dist/server/prompts/shared-rules.js +17 -13
  346. package/dist/server/realtime-token.d.ts +1 -1
  347. package/dist/server/transcribe-voice.d.ts +1 -1
  348. package/dist/shared/reasoning-effort.d.ts +8 -8
  349. package/dist/shared/reasoning-effort.js +10 -10
  350. package/dist/shared/streaming-text-smoothing.js +41 -11
  351. package/dist/styles/agent-native.css +19 -32
  352. package/dist/templates/chat/.agents/skills/actions/SKILL.md +54 -488
  353. package/dist/templates/chat/.agents/skills/actions/references/action-fields.md +136 -0
  354. package/dist/templates/chat/.agents/skills/actions/references/examples.md +94 -0
  355. package/dist/templates/chat/.agents/skills/actions/references/provider-apis.md +95 -0
  356. package/dist/templates/chat/.agents/skills/create-skill/SKILL.md +9 -35
  357. package/dist/templates/chat/.agents/skills/frontend-design/SKILL.md +4 -5
  358. package/dist/templates/chat/.agents/skills/turn-into-app/SKILL.md +18 -31
  359. package/dist/templates/chat/AGENTS.md +32 -80
  360. package/dist/templates/chat/changelog/2026-08-10-full-page-chat-now-uses-the-available-width-up-to-1000px-for.md +6 -0
  361. package/dist/templates/default/.agents/skills/actions/SKILL.md +54 -488
  362. package/dist/templates/default/.agents/skills/actions/references/action-fields.md +136 -0
  363. package/dist/templates/default/.agents/skills/actions/references/examples.md +94 -0
  364. package/dist/templates/default/.agents/skills/actions/references/provider-apis.md +95 -0
  365. package/dist/templates/default/.agents/skills/create-skill/SKILL.md +9 -35
  366. package/dist/templates/default/.agents/skills/frontend-design/SKILL.md +4 -5
  367. package/dist/templates/default/.agents/skills/turn-into-app/SKILL.md +18 -31
  368. package/dist/templates/headless/.agents/skills/actions/SKILL.md +54 -488
  369. package/dist/templates/headless/.agents/skills/actions/references/action-fields.md +136 -0
  370. package/dist/templates/headless/.agents/skills/actions/references/examples.md +94 -0
  371. package/dist/templates/headless/.agents/skills/actions/references/provider-apis.md +95 -0
  372. package/dist/templates/headless/.agents/skills/turn-into-app/SKILL.md +18 -31
  373. package/dist/templates/workspace-core/.agents/skills/actions/SKILL.md +54 -488
  374. package/dist/templates/workspace-core/.agents/skills/actions/references/action-fields.md +136 -0
  375. package/dist/templates/workspace-core/.agents/skills/actions/references/examples.md +94 -0
  376. package/dist/templates/workspace-core/.agents/skills/actions/references/provider-apis.md +95 -0
  377. package/dist/templates/workspace-core/.agents/skills/adding-workspace-apps/SKILL.md +1 -0
  378. package/dist/templates/workspace-core/.agents/skills/agent-page/SKILL.md +1 -0
  379. package/dist/templates/workspace-core/.agents/skills/create-skill/SKILL.md +9 -35
  380. package/dist/templates/workspace-core/.agents/skills/frontend-design/SKILL.md +4 -5
  381. package/dist/templates/workspace-core/.agents/skills/recurring-jobs/SKILL.md +21 -29
  382. package/dist/templates/workspace-core/.agents/skills/turn-into-app/SKILL.md +18 -31
  383. package/dist/templates/workspace-core/.agents/skills/workspace-conventions/SKILL.md +7 -17
  384. package/dist/templates/workspace-core/.agents/skills/writing-agent-instructions/SKILL.md +3 -3
  385. package/dist/templates/workspace-core/AGENTS.md +7 -16
  386. package/docs/content/messaging.mdx +6 -7
  387. package/docs/content/template-chat.mdx +1 -1
  388. package/package.json +2 -2
  389. package/src/templates/chat/.agents/skills/actions/SKILL.md +54 -488
  390. package/src/templates/chat/.agents/skills/actions/references/action-fields.md +136 -0
  391. package/src/templates/chat/.agents/skills/actions/references/examples.md +94 -0
  392. package/src/templates/chat/.agents/skills/actions/references/provider-apis.md +95 -0
  393. package/src/templates/chat/.agents/skills/create-skill/SKILL.md +9 -35
  394. package/src/templates/chat/.agents/skills/frontend-design/SKILL.md +4 -5
  395. package/src/templates/chat/.agents/skills/turn-into-app/SKILL.md +18 -31
  396. package/src/templates/chat/AGENTS.md +32 -80
  397. package/src/templates/chat/changelog/2026-08-10-full-page-chat-now-uses-the-available-width-up-to-1000px-for.md +6 -0
  398. package/src/templates/default/.agents/skills/actions/SKILL.md +54 -488
  399. package/src/templates/default/.agents/skills/actions/references/action-fields.md +136 -0
  400. package/src/templates/default/.agents/skills/actions/references/examples.md +94 -0
  401. package/src/templates/default/.agents/skills/actions/references/provider-apis.md +95 -0
  402. package/src/templates/default/.agents/skills/create-skill/SKILL.md +9 -35
  403. package/src/templates/default/.agents/skills/frontend-design/SKILL.md +4 -5
  404. package/src/templates/default/.agents/skills/turn-into-app/SKILL.md +18 -31
  405. package/src/templates/headless/.agents/skills/actions/SKILL.md +54 -488
  406. package/src/templates/headless/.agents/skills/actions/references/action-fields.md +136 -0
  407. package/src/templates/headless/.agents/skills/actions/references/examples.md +94 -0
  408. package/src/templates/headless/.agents/skills/actions/references/provider-apis.md +95 -0
  409. package/src/templates/headless/.agents/skills/turn-into-app/SKILL.md +18 -31
  410. package/src/templates/workspace-core/.agents/skills/actions/SKILL.md +54 -488
  411. package/src/templates/workspace-core/.agents/skills/actions/references/action-fields.md +136 -0
  412. package/src/templates/workspace-core/.agents/skills/actions/references/examples.md +94 -0
  413. package/src/templates/workspace-core/.agents/skills/actions/references/provider-apis.md +95 -0
  414. package/src/templates/workspace-core/.agents/skills/adding-workspace-apps/SKILL.md +1 -0
  415. package/src/templates/workspace-core/.agents/skills/agent-page/SKILL.md +1 -0
  416. package/src/templates/workspace-core/.agents/skills/create-skill/SKILL.md +9 -35
  417. package/src/templates/workspace-core/.agents/skills/frontend-design/SKILL.md +4 -5
  418. package/src/templates/workspace-core/.agents/skills/recurring-jobs/SKILL.md +21 -29
  419. package/src/templates/workspace-core/.agents/skills/turn-into-app/SKILL.md +18 -31
  420. package/src/templates/workspace-core/.agents/skills/workspace-conventions/SKILL.md +7 -17
  421. package/src/templates/workspace-core/.agents/skills/writing-agent-instructions/SKILL.md +3 -3
  422. package/src/templates/workspace-core/AGENTS.md +7 -16
@@ -8,8 +8,8 @@ import { CompositeAttachmentAdapter } from "@assistant-ui/react";
8
8
  import { IconArrowUp, IconClock, IconMessage, IconX, IconPlayerStopFilled, IconTerminal, IconAlertTriangle, IconChevronDown, IconRefresh, } from "@tabler/icons-react";
9
9
  import { useState, useRef, useEffect, useCallback, useMemo, useLayoutEffect, forwardRef, useImperativeHandle, } from "react";
10
10
  import { createPollEngine } from "../shared/poll-engine.js";
11
- import { clearPendingTurnIfMatches, clearActiveRunIfMatches, getPendingTurn, getActiveRunActivityTool, getActiveRun, resolveReconnectAfterSeq, setActiveRun, updateActiveRunActivity, updateActiveRunSeq, } from "./active-run-state.js";
12
- import { activeRunLooksAlive, createAgentChatAdapter, } from "./agent-chat-adapter.js";
11
+ import { clearPendingTurnIfMatches, clearActiveRunIfMatches, getPendingTurn, getActiveRunActivityTool, getActiveRun, hasRecentActiveRunProgress, resolveReconnectAfterSeq, setActiveRun, updateActiveRunActivity, updateActiveRunSeq, } from "./active-run-state.js";
12
+ import { activeRunLooksAlive, createAgentChatAdapter, hasInFlightToolCall, } from "./agent-chat-adapter.js";
13
13
  import { appendAgentChatContextToMessage, formatAgentChatContextItemsForPrompt, getAgentChatContextState, isAgentChatSubmitCancelled, normalizeAgentChatContextItem, publishAgentChatContextItems, refreshAgentChatContext, reportAgentChatSubmitResult, subscribeAgentChatContext, } from "./agent-chat.js";
14
14
  import { captureError } from "./analytics.js";
15
15
  import { agentNativePath } from "./api-path.js";
@@ -23,7 +23,7 @@ import { CheckpointContext, MessageActionsContext, assistantMessageRunId, UserMe
23
23
  import { repoHasAssistantMessage, getRepoMessages, getRepoMessage, shouldImportServerThreadData, dedupeRepoMessagesById, dropEmptyAssistantMessages, withLastAssistantRunDuration, } from "./chat/repo-helpers.js";
24
24
  import { BuilderSetupCard, BuilderSetupContent, LoopLimitContinueCard, RunErrorRecoveryCard, PlanModeCallout, getLoopLimitMetadata, getRunErrorMetadata, getRequestModeMetadata, runErrorKey, } from "./chat/run-recovery.js";
25
25
  import { createAgentChatRuntimeAdapter, } from "./chat/runtime.js";
26
- import { ChatRunningContext, ChatRunDurationContext, ApprovalContext, ReconnectStreamMessage, } from "./chat/tool-call-display.js";
26
+ import { ChatRunningContext, ChatRunningRunIdContext, ChatRunningTurnIdContext, ChatRunDurationContext, ApprovalContext, ReconnectStreamMessage, } from "./chat/tool-call-display.js";
27
27
  import { useAgentChatLifecycleTracking } from "./chat/use-agent-chat-lifecycle-tracking.js";
28
28
  import { useReconnectReaderOwner } from "./chat/use-reconnect-reader-owner.js";
29
29
  import { MessageScroller, MessageScrollerContent, MessageScrollerItem, MessageScrollerProvider, MessageScrollerViewport, } from "./components/ui/message-scroller.js";
@@ -59,7 +59,7 @@ export function assistantUiMessageListStructureKey(messages) {
59
59
  (message.attachments ?? []).map((attachment) => attachment.id),
60
60
  ]));
61
61
  }
62
- export function createUserMessageRunConfig(references, requestMode, recoveryAction, trackInRunsTray, approvedToolCalls, queuedMessageId, hideUserMessage, modelSnapshot) {
62
+ export function createUserMessageRunConfig(references, requestMode, recoveryAction, trackInRunsTray, approvedToolCalls, queuedMessageId, hideUserMessage, modelSnapshot, turnId) {
63
63
  const custom = {};
64
64
  if (modelSnapshot?.model)
65
65
  custom.model = modelSnapshot.model;
@@ -82,6 +82,9 @@ export function createUserMessageRunConfig(references, requestMode, recoveryActi
82
82
  if (approvedToolCalls && approvedToolCalls.length > 0) {
83
83
  custom.approvedToolCalls = approvedToolCalls;
84
84
  }
85
+ if (turnId) {
86
+ custom.turnId = turnId;
87
+ }
85
88
  const options = {};
86
89
  if (Object.keys(custom).length > 0) {
87
90
  options.runConfig = { custom };
@@ -144,6 +147,12 @@ function activeRunLooksStale(runInfo) {
144
147
  : null;
145
148
  const nowMs = typeof runInfo.serverNow === "number" ? runInfo.serverNow : Date.now();
146
149
  const thresholdMs = activeRunStuckThresholdMs(runInfo);
150
+ // A healthy stream can outrun a delayed durable progress write. The local
151
+ // SSE cursor is independent evidence that this browser is receiving real
152
+ // work, so do not abort or replace that run while its own progress is fresh.
153
+ if (hasRecentActiveRunProgress(runInfo.threadId, runInfo.runId, thresholdMs)) {
154
+ return false;
155
+ }
147
156
  return (runInfo.status === "running" &&
148
157
  lastProgressAt != null &&
149
158
  nowMs - lastProgressAt > thresholdMs);
@@ -296,6 +305,7 @@ export async function waitForThreadRunToClear(apiUrl, threadId) {
296
305
  setActiveRun({
297
306
  threadId,
298
307
  runId: info.runId,
308
+ ...(info.turnId ? { turnId: info.turnId } : {}),
299
309
  lastSeq: sameStoredRun ? stored.lastSeq : -1,
300
310
  ...(sameStoredRun && stored.activityTool
301
311
  ? { activityTool: stored.activityTool }
@@ -987,7 +997,7 @@ export function resolveAssistantChatSubmitIntent({ isRunning, requestedIntent, }
987
997
  return "queued";
988
998
  return requestedIntent ?? "immediate";
989
999
  }
990
- export function resolveAssistantChatRunningState({ forceStopped, isRuntimeRunning, isReconnecting, optimisticRunning, isAutoResuming, hasActiveServerRun, }) {
1000
+ export function resolveAssistantChatRunningState({ forceStopped, isRuntimeRunning, isReconnecting, optimisticRunning, isAutoResuming, hasActiveServerRun, hasTerminalRunError, }) {
991
1001
  const isRunning = !forceStopped &&
992
1002
  (isRuntimeRunning ||
993
1003
  isReconnecting ||
@@ -999,7 +1009,7 @@ export function resolveAssistantChatRunningState({ forceStopped, isRuntimeRunnin
999
1009
  // between chunks even though the adapter is about to POST the next run.
1000
1010
  // Keep the visible chat state running so the latest assistant message shows
1001
1011
  // Thinking/Resuming and does not expose footer actions prematurely.
1002
- showRunningInUI: !forceStopped && (isRunning || isAutoResuming),
1012
+ showRunningInUI: !forceStopped && !hasTerminalRunError && (isRunning || isAutoResuming),
1003
1013
  };
1004
1014
  }
1005
1015
  export function resolveAssistantChatRunningStatusLabel({ runningActivityLabel, isAutoResuming, isReconnecting, hasReconnectContent, }) {
@@ -1634,12 +1644,27 @@ const AssistantChatInner = forwardRef(function AssistantChatInner({ emptyStateTe
1634
1644
  // overlay until the adapter message catches up so we don't flash an empty gap.
1635
1645
  const [adapterHandoffPending, setAdapterHandoffPending] = useState(false);
1636
1646
  const reconnectRunIdRef = useRef(null);
1647
+ const reconnectTurnIdRef = useRef(null);
1637
1648
  const reconnectTailOnlyRef = useRef(false);
1638
1649
  const reconnectCanMaterializeRef = useRef(false);
1639
1650
  const reconnectAbortRef = useRef(null);
1640
1651
  const reconnectAutoRecoveryCountRef = useRef(0);
1641
1652
  const reconnectOwnerMountedRef = useReconnectReaderOwner(reconnectRunIdRef, reconnectAbortRef);
1642
1653
  const [pendingReconnectRecovery, setPendingReconnectRecovery] = useState(null);
1654
+ const clearReconnectReaderForTerminalError = useCallback(() => {
1655
+ reconnectAbortRef.current?.abort();
1656
+ reconnectAbortRef.current = null;
1657
+ reconnectRunIdRef.current = null;
1658
+ reconnectTurnIdRef.current = null;
1659
+ reconnectTailOnlyRef.current = false;
1660
+ reconnectCanMaterializeRef.current = false;
1661
+ setIsReconnecting(false);
1662
+ setReconnectFrozen(false);
1663
+ setReconnectContent([]);
1664
+ setAdapterHandoffPending(false);
1665
+ setPendingReconnectRecovery(null);
1666
+ resetRunningActivity();
1667
+ }, [resetRunningActivity]);
1643
1668
  // Nuclear stop: user clicked stop. Clears the stop button/indicator AND
1644
1669
  // lets new submissions go through immediately — prevents the "stuck
1645
1670
  // queueing forever" state where isReconnecting or isRuntimeRunning gets
@@ -1670,6 +1695,7 @@ const AssistantChatInner = forwardRef(function AssistantChatInner({ emptyStateTe
1670
1695
  optimisticRunning,
1671
1696
  isAutoResuming,
1672
1697
  hasActiveServerRun,
1698
+ hasTerminalRunError: runErrorInfo !== null,
1673
1699
  });
1674
1700
  const textStreaming = showRunningInUI || externalStreaming;
1675
1701
  // Server truth about this thread's run, used to suppress the "agent stopped
@@ -1681,6 +1707,14 @@ const AssistantChatInner = forwardRef(function AssistantChatInner({ emptyStateTe
1681
1707
  apiUrl,
1682
1708
  });
1683
1709
  const serverRunActive = serverRunState.runId != null && serverRunState.status === "running";
1710
+ const storedActiveRun = getActiveRun();
1711
+ const activeChatRunId = (serverRunState.status === "running" ? serverRunState.runId : null) ??
1712
+ (activeRunMatchesThread(storedActiveRun, threadId)
1713
+ ? (storedActiveRun?.runId ?? null)
1714
+ : null);
1715
+ const activeChatTurnId = (activeRunMatchesThread(storedActiveRun, threadId)
1716
+ ? storedActiveRun?.turnId
1717
+ : undefined) ?? (showRunningInUI ? reconnectTurnIdRef.current : null);
1684
1718
  const chatRunStartedAtRef = useRef(null);
1685
1719
  const [lastChatRunDurationMs, setLastChatRunDurationMs] = useState(null);
1686
1720
  useEffect(() => {
@@ -2033,6 +2067,10 @@ const AssistantChatInner = forwardRef(function AssistantChatInner({ emptyStateTe
2033
2067
  reconnectAbortRef.current = null;
2034
2068
  }
2035
2069
  reconnectRunIdRef.current = runId;
2070
+ reconnectTurnIdRef.current =
2071
+ typeof runInfo.turnId === "string" && runInfo.turnId.length > 0
2072
+ ? runInfo.turnId
2073
+ : (getActiveRun()?.turnId ?? null);
2036
2074
  const afterSeq = resolveReconnectAfterSeq(threadId, runId);
2037
2075
  reconnectTailOnlyRef.current = afterSeq > 0;
2038
2076
  reconnectCanMaterializeRef.current = afterSeq === 0;
@@ -2041,6 +2079,9 @@ const AssistantChatInner = forwardRef(function AssistantChatInner({ emptyStateTe
2041
2079
  setActiveRun({
2042
2080
  threadId,
2043
2081
  runId,
2082
+ ...(reconnectTurnIdRef.current
2083
+ ? { turnId: reconnectTurnIdRef.current }
2084
+ : {}),
2044
2085
  lastSeq: afterSeq > 0 ? afterSeq - 1 : -1,
2045
2086
  ...(storedActivityTool ? { activityTool: storedActivityTool } : {}),
2046
2087
  });
@@ -2200,10 +2241,10 @@ const AssistantChatInner = forwardRef(function AssistantChatInner({ emptyStateTe
2200
2241
  });
2201
2242
  };
2202
2243
  try {
2203
- await readSSEStreamRaw(sseRes.body, content, toolCallCounter, tabId, scheduleUpdate, (seq) => {
2244
+ await readSSEStreamRaw(sseRes.body, content, toolCallCounter, tabId, scheduleUpdate, (seq, isProgress) => {
2204
2245
  markReconnectProgress();
2205
2246
  reconnectRetryCount = 0;
2206
- updateActiveRunSeq(seq);
2247
+ updateActiveRunSeq(seq, isProgress);
2207
2248
  }, { preparingActionState });
2208
2249
  if (reconnectAfterSeq === 0) {
2209
2250
  setReconnectContent([...content]);
@@ -2313,6 +2354,7 @@ const AssistantChatInner = forwardRef(function AssistantChatInner({ emptyStateTe
2313
2354
  MAX_RECONNECT_AUTO_RECOVERIES;
2314
2355
  if (canAutoRecoverReconnect) {
2315
2356
  reconnectAutoRecoveryCountRef.current += 1;
2357
+ const reconnectTurnId = reconnectTurnIdRef.current ?? undefined;
2316
2358
  setRunErrorInfo(null);
2317
2359
  setDismissedRunErrorKey(null);
2318
2360
  clearActiveRunIfMatches(threadId, runId);
@@ -2328,6 +2370,7 @@ const AssistantChatInner = forwardRef(function AssistantChatInner({ emptyStateTe
2328
2370
  }));
2329
2371
  setPendingReconnectRecovery({
2330
2372
  id: Date.now(),
2373
+ ...(reconnectTurnId ? { turnId: reconnectTurnId } : {}),
2331
2374
  // With no partial work on screen there is nothing to "continue
2332
2375
  // from"; the long recovery brief only wastes context.
2333
2376
  message: latestContent.length > 0
@@ -2348,6 +2391,9 @@ const AssistantChatInner = forwardRef(function AssistantChatInner({ emptyStateTe
2348
2391
  errorCode: reconnectErrorCode,
2349
2392
  recoverable: true,
2350
2393
  runId,
2394
+ ...(reconnectTurnIdRef.current
2395
+ ? { turnId: reconnectTurnIdRef.current }
2396
+ : {}),
2351
2397
  });
2352
2398
  setDismissedRunErrorKey(null);
2353
2399
  clearActiveRunIfMatches(threadId, runId);
@@ -2660,6 +2706,7 @@ const AssistantChatInner = forwardRef(function AssistantChatInner({ emptyStateTe
2660
2706
  !threadId ||
2661
2707
  forceStopped ||
2662
2708
  isReconnecting ||
2709
+ runErrorInfo ||
2663
2710
  wasRecentlyStoppedRun()) {
2664
2711
  return;
2665
2712
  }
@@ -2678,6 +2725,7 @@ const AssistantChatInner = forwardRef(function AssistantChatInner({ emptyStateTe
2678
2725
  isReconnecting,
2679
2726
  isRuntimeRunning,
2680
2727
  reconnectActiveRunForThread,
2728
+ runErrorInfo,
2681
2729
  threadId,
2682
2730
  wasRecentlyStoppedRun,
2683
2731
  ]);
@@ -2969,11 +3017,17 @@ const AssistantChatInner = forwardRef(function AssistantChatInner({ emptyStateTe
2969
3017
  (!stopped.runId || !detail.runId || stopped.runId === detail.runId)) {
2970
3018
  return;
2971
3019
  }
3020
+ // A terminal adapter error wins over any read-only reconnect reader that
3021
+ // was following the same run. Leave the server run alone, but tear down
3022
+ // its presentation immediately so the error cannot coexist with stale
3023
+ // tool cards or a second Thinking/Stop state.
3024
+ clearReconnectReaderForTerminalError();
2972
3025
  setRunErrorInfo({
2973
3026
  message: detail.message,
2974
3027
  ...(detail.details ? { details: detail.details } : {}),
2975
3028
  ...(detail.errorCode ? { errorCode: detail.errorCode } : {}),
2976
3029
  ...(detail.runId ? { runId: detail.runId } : {}),
3030
+ ...(detail.turnId ? { turnId: detail.turnId } : {}),
2977
3031
  ...(detail.recoverable ? { recoverable: detail.recoverable } : {}),
2978
3032
  });
2979
3033
  setDismissedRunErrorKey(null);
@@ -2983,7 +3037,13 @@ const AssistantChatInner = forwardRef(function AssistantChatInner({ emptyStateTe
2983
3037
  };
2984
3038
  window.addEventListener("agent-chat:run-error", handler);
2985
3039
  return () => window.removeEventListener("agent-chat:run-error", handler);
2986
- }, [clearAutoResume, latestAssistantRunId, tabId, threadId]);
3040
+ }, [
3041
+ clearAutoResume,
3042
+ clearReconnectReaderForTerminalError,
3043
+ latestAssistantRunId,
3044
+ tabId,
3045
+ threadId,
3046
+ ]);
2987
3047
  // Real activity means the next chunk has started. Surface longer-lived
2988
3048
  // activity such as "Still generating image" so active-run reconnects do not
2989
3049
  // look like failures while the server is still making progress.
@@ -3102,11 +3162,11 @@ const AssistantChatInner = forwardRef(function AssistantChatInner({ emptyStateTe
3102
3162
  ...(messageAttachments.length > 0
3103
3163
  ? { attachments: messageAttachments }
3104
3164
  : {}),
3105
- ...createUserMessageRunConfig(next.references, next.requestMode, next.recoveryAction, next.trackInRunsTray, undefined, next.id, next.hideUserMessage, {
3165
+ ...createUserMessageRunConfig(next.references, next.requestMode, next.recoveryAction, next.trackInRunsTray, next.approvedToolCalls, next.id, next.hideUserMessage, {
3106
3166
  model: next.model,
3107
3167
  engine: next.engine,
3108
3168
  effort: next.effort,
3109
- }),
3169
+ }, next.turnId),
3110
3170
  });
3111
3171
  appended = true;
3112
3172
  }
@@ -3265,6 +3325,9 @@ const AssistantChatInner = forwardRef(function AssistantChatInner({ emptyStateTe
3265
3325
  ? lastMessage.id
3266
3326
  : null;
3267
3327
  const runId = runErrorInfo?.runId ?? reconnectRunIdRef.current;
3328
+ const turnId = runErrorInfo?.turnId ??
3329
+ reconnectTurnIdRef.current ??
3330
+ getActiveRun()?.turnId;
3268
3331
  const id = `reconnect-${runId ?? Date.now()}-${Math.random().toString(36).slice(2, 8)}`;
3269
3332
  repo.messages = [
3270
3333
  ...messages,
@@ -3280,6 +3343,7 @@ const AssistantChatInner = forwardRef(function AssistantChatInner({ emptyStateTe
3280
3343
  custom: {
3281
3344
  reconnectFrozen: true,
3282
3345
  ...(runId ? { runId } : {}),
3346
+ ...(turnId ? { turnId } : {}),
3283
3347
  },
3284
3348
  },
3285
3349
  },
@@ -3291,6 +3355,7 @@ const AssistantChatInner = forwardRef(function AssistantChatInner({ emptyStateTe
3291
3355
  setReconnectContent([]);
3292
3356
  setAdapterHandoffPending(false);
3293
3357
  reconnectCanMaterializeRef.current = false;
3358
+ reconnectTurnIdRef.current = null;
3294
3359
  }
3295
3360
  catch (err) {
3296
3361
  captureError(err, {
@@ -3309,6 +3374,7 @@ const AssistantChatInner = forwardRef(function AssistantChatInner({ emptyStateTe
3309
3374
  reconnectFrozen,
3310
3375
  reconnectContent,
3311
3376
  runErrorInfo?.runId,
3377
+ runErrorInfo?.turnId,
3312
3378
  tabId,
3313
3379
  threadId,
3314
3380
  threadRuntime,
@@ -3396,6 +3462,7 @@ const AssistantChatInner = forwardRef(function AssistantChatInner({ emptyStateTe
3396
3462
  setReconnectFrozen(false);
3397
3463
  setReconnectContent([]);
3398
3464
  reconnectCanMaterializeRef.current = false;
3465
+ reconnectTurnIdRef.current = null;
3399
3466
  }
3400
3467
  reconnectTailOnlyRef.current = false;
3401
3468
  }
@@ -3433,7 +3500,7 @@ const AssistantChatInner = forwardRef(function AssistantChatInner({ emptyStateTe
3433
3500
  stopActiveRunRef.current({ preserveQueuedMessages: true });
3434
3501
  }, [applyLocalQueuedMessages]);
3435
3502
  const visibleQueuedMessages = useMemo(() => queuedMessages.filter((message) => !message.hideUserMessage), [queuedMessages]);
3436
- const addToQueue = useCallback(async (text, images, references, attachments, requestMode, intent = "queued", recoveryAction, includeComposerContext = false, trackInRunsTray = false, preserveReconnectAutoRecoveryBudget = false, hideUserMessage = false, submitMessageId) => {
3503
+ const addToQueue = useCallback(async (text, images, references, attachments, requestMode, intent = "queued", recoveryAction, includeComposerContext = false, trackInRunsTray = false, preserveReconnectAutoRecoveryBudget = false, hideUserMessage = false, submitMessageId, approvedToolCalls, continuationTurnId) => {
3437
3504
  if (isAgentChatSubmitCancelled(submitMessageId))
3438
3505
  return;
3439
3506
  if (engineSetupRequired) {
@@ -3582,6 +3649,8 @@ const AssistantChatInner = forwardRef(function AssistantChatInner({ emptyStateTe
3582
3649
  recoveryAction,
3583
3650
  trackInRunsTray,
3584
3651
  hideUserMessage,
3652
+ approvedToolCalls,
3653
+ ...(continuationTurnId ? { turnId: continuationTurnId } : {}),
3585
3654
  ...modelSnapshot,
3586
3655
  },
3587
3656
  ]);
@@ -3602,6 +3671,8 @@ const AssistantChatInner = forwardRef(function AssistantChatInner({ emptyStateTe
3602
3671
  recoveryAction,
3603
3672
  trackInRunsTray,
3604
3673
  hideUserMessage,
3674
+ approvedToolCalls,
3675
+ ...(continuationTurnId ? { turnId: continuationTurnId } : {}),
3605
3676
  ...modelSnapshot,
3606
3677
  },
3607
3678
  ]);
@@ -3615,7 +3686,7 @@ const AssistantChatInner = forwardRef(function AssistantChatInner({ emptyStateTe
3615
3686
  ...(messageAttachments.length > 0
3616
3687
  ? { attachments: messageAttachments }
3617
3688
  : {}),
3618
- ...createUserMessageRunConfig(references, effectiveRequestMode, recoveryAction, trackInRunsTray, undefined, undefined, hideUserMessage),
3689
+ ...createUserMessageRunConfig(references, effectiveRequestMode, recoveryAction, trackInRunsTray, approvedToolCalls, undefined, hideUserMessage, undefined, continuationTurnId),
3619
3690
  });
3620
3691
  }
3621
3692
  catch (error) {
@@ -3685,7 +3756,7 @@ const AssistantChatInner = forwardRef(function AssistantChatInner({ emptyStateTe
3685
3756
  const recovery = pendingReconnectRecovery;
3686
3757
  const timer = window.setTimeout(() => {
3687
3758
  setPendingReconnectRecovery((current) => current?.id === recovery.id ? null : current);
3688
- addToQueue(recovery.message, undefined, undefined, undefined, undefined, "queued", "continue", false, false, true, true);
3759
+ addToQueue(recovery.message, undefined, undefined, undefined, undefined, "queued", "continue", false, false, true, true, undefined, undefined, recovery.turnId);
3689
3760
  }, 0);
3690
3761
  return () => window.clearTimeout(timer);
3691
3762
  }, [addToQueue, pendingReconnectRecovery]);
@@ -3731,10 +3802,7 @@ const AssistantChatInner = forwardRef(function AssistantChatInner({ emptyStateTe
3731
3802
  !Array.isArray(last.content)) {
3732
3803
  return false;
3733
3804
  }
3734
- return last.content.some((part) => part &&
3735
- typeof part === "object" &&
3736
- part.type === "tool-call" &&
3737
- !toolCallPartHasResult(part));
3805
+ return hasInFlightToolCall(last.content);
3738
3806
  },
3739
3807
  focusComposer() {
3740
3808
  tiptapRef.current?.focus();
@@ -4006,148 +4074,152 @@ const AssistantChatInner = forwardRef(function AssistantChatInner({ emptyStateTe
4006
4074
  getApprovalResolution,
4007
4075
  onApprovalResolved: recordApprovalResolution,
4008
4076
  onApprove: (approvalKey) => {
4009
- markOptimisticRunning();
4010
- appendThreadMessage({
4011
- role: "user",
4012
- content: [
4013
- {
4014
- type: "text",
4015
- text: "Approved. Go ahead and run the requested action.",
4016
- },
4017
- ],
4018
- ...createUserMessageRunConfig(undefined, execMode === "plan"
4019
- ? "plan"
4020
- : execMode === "build"
4021
- ? "act"
4022
- : undefined, undefined, undefined, [approvalKey]),
4023
- });
4077
+ void addToQueue("Approved. Go ahead and run the requested action.", undefined, undefined, undefined, undefined, "queued", undefined, false, false, false, false, undefined, [approvalKey]);
4024
4078
  },
4025
4079
  ...(approvalActions?.onDeny ? { onDeny: approvalActions.onDeny } : {}),
4026
4080
  ...(approvalActions?.onAlwaysAllow
4027
4081
  ? { onAlwaysAllow: approvalActions.onAlwaysAllow }
4028
4082
  : {}),
4029
4083
  }), [
4030
- appendThreadMessage,
4084
+ addToQueue,
4031
4085
  execMode,
4032
4086
  getApprovalResolution,
4033
- markOptimisticRunning,
4034
4087
  approvalActions,
4035
4088
  recordApprovalResolution,
4036
4089
  ]);
4037
- return (_jsx(CheckpointContext.Provider, { value: checkpointCtx, children: _jsx(MessageActionsContext.Provider, { value: messageActionsCtx, children: _jsx(ApprovalContext.Provider, { value: approvalCtx, children: _jsx(ChatRunDurationContext.Provider, { value: lastChatRunDurationMs, children: _jsx(ServerRunActiveContext.Provider, { value: serverRunActive, children: _jsx(ChatRunningContext.Provider, { value: showRunningInUI, children: _jsx(TextStreamingContext.Provider, { value: textStreaming, children: _jsxs("div", { "data-agent-empty-state": centeredEmptyState
4038
- ? "centered"
4039
- : compactMissingKeyEmptyState
4040
- ? "compact-setup"
4041
- : undefined, className: cn("relative flex flex-1 flex-col h-full min-h-0 text-foreground", className), onDragEnter: handleChatDragEnter, onDragOver: handleChatDragOver, onDragLeave: handleChatDragLeave, onDropCapture: handleChatDropCapture, onDrop: handleChatDrop, children: [dropActive && (_jsx("div", { "aria-hidden": "true", className: "pointer-events-none absolute inset-0 z-50 flex items-center justify-center rounded-md border-2 border-dashed border-primary/70 bg-primary/5 backdrop-blur-[1px]", children: _jsx("span", { className: "rounded-md bg-background/90 px-3 py-1.5 text-xs font-medium text-foreground shadow-sm", children: "Drop to attach" }) })), showHeader && (_jsxs("div", { className: "flex h-11 shrink-0 items-center justify-between border-b border-border px-4", children: [_jsx("span", { className: "text-[13px] font-medium text-muted-foreground", children: "Agent" }), _jsx("div", { className: "flex items-center gap-1", children: onSwitchToCli && (_jsx(TooltipProvider, { delayDuration: 200, children: _jsxs(Tooltip, { children: [_jsx(TooltipTrigger, { asChild: true, children: _jsxs("button", { onClick: onSwitchToCli, "aria-label": "Switch to CLI", className: "flex items-center gap-1 text-[12px] text-muted-foreground hover:text-foreground px-2 py-1 rounded-md hover:bg-accent", children: [_jsx(IconTerminal, { className: "h-3.5 w-3.5" }), "CLI"] }) }), _jsx(TooltipContent, { children: "Switch to CLI" })] }) })) })] })), _jsx(MessageScrollerProvider, { autoScroll: false, children: _jsxs(MessageScroller, { className: "agent-chat-scroll", children: [_jsx(MessageScrollerViewport, { ref: scrollRef, children: authError ? (_jsxs("div", { className: "flex flex-col items-center justify-center h-full px-4 gap-3", children: [_jsx("div", { className: "flex h-10 w-10 items-center justify-center rounded-full bg-muted", children: authSessionAvailable ? (_jsx(IconRefresh, { className: "h-5 w-5 text-muted-foreground" })) : (_jsx(IconMessage, { className: "h-5 w-5 text-muted-foreground" })) }), _jsxs("div", { className: "text-center max-w-[280px]", children: [_jsx("p", { className: "text-sm font-medium text-foreground mb-1", children: authSessionAvailable
4042
- ? "Chat session needs refresh"
4043
- : authError.sessionExpired
4044
- ? "Session expired"
4045
- : "Authentication required" }), _jsx("p", { className: "text-xs text-muted-foreground leading-relaxed", children: authSessionAvailable
4046
- ? "You're signed in, but this chat connection needs to reconnect."
4047
- : authError.sessionExpired
4048
- ? "Your session may have expired. Log out and log back in to reconnect."
4049
- : "You need to log in to use the agent." })] }), _jsxs("div", { className: "flex gap-2", children: [!authError.sessionExpired &&
4050
- !authSessionAvailable && (_jsx("button", { onClick: () => {
4051
- window.location.href =
4052
- buildSignInReturnHref();
4053
- }, className: "text-xs text-background bg-foreground hover:opacity-90 px-3 py-1.5 rounded-md", children: "Log in" })), authError.sessionExpired &&
4054
- !authSessionAvailable && (_jsx("button", { onClick: async () => {
4055
- try {
4056
- await fetch(agentNativePath("/_agent-native/auth/logout"), {
4057
- method: "POST",
4058
- });
4059
- }
4060
- catch { }
4061
- window.location.reload();
4062
- }, className: "text-xs text-destructive hover:text-destructive/80 px-3 py-1.5 rounded-md border border-destructive/30 hover:bg-destructive/10", children: "Log out" })), _jsx("button", { onClick: () => {
4063
- setAuthError(null);
4064
- window.location.reload();
4065
- }, className: authSessionAvailable
4066
- ? "text-xs text-background bg-foreground hover:opacity-90 px-3 py-1.5 rounded-md"
4067
- : "text-xs text-muted-foreground hover:text-foreground px-3 py-1.5 rounded-md border border-border hover:bg-accent", children: "Refresh chat" })] })] })) : isRestoring && centeredRestoringState ? (_jsxs("div", { className: cn("agent-empty-state", emptyStateDisplay === "hidden"
4068
- ? "sr-only"
4069
- : "flex h-full flex-col items-center justify-center gap-3 px-4 py-16"), "aria-busy": "true", children: [_jsx(IconMessage, { className: "h-5 w-5 text-muted-foreground/60" }), _jsx("p", { className: "sr-only", children: emptyStateText ?? "Loading chat..." })] })) : isRestoring ? (_jsxs("div", { className: "flex flex-col gap-3 p-4", children: [_jsx("div", { className: "flex justify-end", children: _jsx("div", { className: "h-8 w-32 rounded-lg bg-muted animate-pulse" }) }), _jsxs("div", { className: "flex flex-col gap-1.5", children: [_jsx("div", { className: "h-4 w-48 rounded bg-muted animate-pulse" }), _jsx("div", { className: "h-4 w-64 rounded bg-muted animate-pulse" }), _jsx("div", { className: "h-4 w-40 rounded bg-muted animate-pulse" })] })] })) : showEmptyState ? (_jsxs("div", { className: cn("agent-empty-state", emptyStateDisplay === "hidden"
4070
- ? "sr-only"
4071
- : "flex h-full flex-col items-center justify-center gap-3 px-4 py-16"), children: [_jsx(IconMessage, { className: "h-5 w-5 text-muted-foreground/60" }), _jsx("p", { className: "sr-only", children: emptyStateText ?? "How can I help you?" }), emptyStateAddon, resolvedSuggestions &&
4072
- resolvedSuggestions.length > 0 ? (_jsx("div", { className: "flex w-full max-w-[280px] flex-col gap-1", children: resolvedSuggestions.map((suggestion) => (_jsx("button", { onClick: () => {
4073
- if (engineSetupRequired) {
4074
- requestMissingKeySetup();
4075
- return;
4076
- }
4077
- void addToQueue(suggestion);
4078
- }, className: "w-full px-2 py-1 text-center text-[13px] text-muted-foreground transition-colors hover:text-foreground focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2", children: suggestion }, suggestion))) })) : null, showInlineEmptyThreadFooterSlot ? (_jsx("div", { className: "agent-thread-footer-slot agent-thread-footer-slot--empty", children: resolvedThreadFooterSlot })) : null] })) : (_jsxs(MessageScrollerContent, { className: "agent-thread-content gap-4 px-4 py-4", children: [_jsx(AssistantMessageListErrorBoundary, { resetKey: messageListResetKey, children: _jsx(ThreadPrimitive.Messages
4079
- // assistant-ui indexes message parts through tap resources.
4080
- // Keep this key tied to that shape so clear/add transitions remount stale
4081
- // lookups without remounting on every streamed text update.
4082
- , { components: {
4083
- UserMessage: AssistantChatUserMessageItem,
4084
- AssistantMessage: AssistantChatAssistantMessageItem,
4085
- } }, messageListResetKey) }), visibleLoopLimit && !showRunningInUI && (_jsx(MessageScrollerItem, { children: _jsx(LoopLimitContinueCard, { info: visibleLoopLimit, onContinue: () => {
4086
- setShowContinue(false);
4087
- setLoopLimitInfo(null);
4088
- addToQueue("Continue from where you left off.", undefined, undefined, undefined, undefined, "queued", "continue");
4089
- } }) })), shouldShowRunError && visibleRunError && (_jsx(MessageScrollerItem, { children: _jsx(RunErrorRecoveryCard, { info: visibleRunError, onContinue: () => {
4090
- setRunErrorInfo(null);
4091
- addToQueue(RECONNECT_NO_PROGRESS_CONTINUE_MESSAGE, undefined, undefined, undefined, undefined, "queued", "continue");
4092
- }, onRetry: retryAfterRunError, onFork: onForkChat, onProviderConnected: handleBuilderConnected, onDismiss: () => {
4093
- if (visibleRunErrorKey) {
4094
- setDismissedRunErrorKey(visibleRunErrorKey);
4095
- }
4096
- setRunErrorInfo(null);
4097
- } }) })), (isReconnecting ||
4098
- reconnectFrozen ||
4099
- adapterHandoffPending) &&
4100
- visibleReconnectContent.length > 0 && (_jsx(MessageScrollerItem, { children: _jsx(ReconnectStreamMessage, { content: visibleReconnectContent, allowActivitySpinner: !reconnectFrozen }) })), (isReconnecting ||
4101
- reconnectFrozen ||
4102
- adapterHandoffPending) &&
4103
- visibleReconnectContent.length === 0 &&
4104
- reconnectContent.length === 0 &&
4105
- reconnectActivityContent.length > 0 && (_jsx(MessageScrollerItem, { children: _jsx(ReconnectStreamMessage, { content: reconnectActivityContent, allowActivitySpinner: !reconnectFrozen }) })), showGlobalRunningStatus && (_jsx(MessageScrollerItem, { children: _jsx(RunningActivityStatus, { label: runningStatusLabel }) })), visibleQueuedMessages.length > 0 && (_jsx(MessageScrollerItem, { children: _jsxs("div", { className: "flex items-center justify-end gap-1.5 pr-0.5 text-xs text-muted-foreground", children: [_jsx(IconClock, { className: "h-3 w-3" }), _jsxs("span", { children: [visibleQueuedMessages.length, " queued"] })] }) })), visibleQueuedMessages.map((msg) => {
4106
- const displayText = displayableUserMessageText(msg.text);
4107
- const imageSources = queuedMessageImageSources(msg);
4108
- return (_jsx(MessageScrollerItem, { messageId: msg.id, children: _jsxs("div", { className: "group flex items-start justify-end gap-1.5", children: [isRunning && (_jsxs(Tooltip, { children: [_jsx(TooltipTrigger, { asChild: true, children: _jsx("button", { type: "button", onClick: () => sendQueuedMessageNow(msg.id), "aria-label": "Send now", className: "mt-1.5 flex h-5 w-5 cursor-pointer items-center justify-center rounded-full border border-border bg-background text-muted-foreground opacity-0 shadow-sm transition-opacity hover:bg-accent hover:text-foreground focus-visible:opacity-100 group-hover:opacity-100", children: _jsx(IconArrowUp, { className: "h-3 w-3" }) }) }), _jsx(TooltipContent, { children: "Send now (stops the current response)" })] })), _jsx("button", { type: "button", onClick: () => applyLocalQueuedMessages((prev) => prev.filter((m) => m.id !== msg.id)), "aria-label": "Remove from queue", className: "mt-1.5 flex h-5 w-5 cursor-pointer items-center justify-center rounded-full border border-border bg-background text-muted-foreground opacity-0 shadow-sm transition-opacity hover:bg-accent hover:text-foreground focus-visible:opacity-100 group-hover:opacity-100", children: _jsx(IconX, { className: "h-3 w-3" }) }), _jsxs("div", { className: "max-w-[85%] rounded-lg bg-accent/50 px-3 py-2 text-sm leading-relaxed text-foreground/60 whitespace-pre-wrap break-words", children: [displayText, imageSources.length > 0 && (_jsx("div", { className: "flex flex-wrap gap-1.5 mt-1.5", children: imageSources.map((img, j) => (_jsx("img", { src: img, alt: "", className: "h-12 w-12 rounded object-cover border border-border/50" }, j))) }))] })] }) }, msg.id));
4109
- }), resolvedThreadFooterSlot ? (_jsx(MessageScrollerItem, { children: _jsx("div", { className: "agent-thread-footer-slot", children: resolvedThreadFooterSlot }) })) : null] })) }), !authError &&
4110
- !isRestoring &&
4111
- !showEmptyState &&
4112
- showScrollToBottom ? (_jsx("div", { className: "shrink-0 flex justify-center -mb-1", children: _jsx("button", { type: "button", onClick: scrollToBottom, className: "flex h-7 w-7 items-center justify-center rounded-full border border-border bg-background shadow-sm hover:bg-accent", "aria-label": "Scroll to bottom", children: _jsx(IconChevronDown, { className: "h-3.5 w-3.5 text-muted-foreground" }) }) })) : null] }) }, chatScrollResetKey), showComposerSlot ? composerSlot : null, isActiveComposer && (_jsx(McpConnectionSuggestion, { text: composerText })), showCenteredEmptyThreadFooterSlot ? (_jsx("div", { className: "agent-thread-footer-slot agent-thread-footer-slot--centered-empty", children: resolvedThreadFooterSlot })) : null, guidedQuestions && guidedQuestions.length > 0 && (_jsx("div", { className: "shrink-0 px-3 pb-2", children: _jsx(GuidedQuestionFlow, { questions: guidedQuestions, onSubmit: handleGuidedQuestionsSubmit, onSkip: handleGuidedQuestionsSkip, ...(guidedQuestionsTitle
4113
- ? { title: guidedQuestionsTitle }
4114
- : {}), ...(guidedQuestionsDescription
4115
- ? { description: guidedQuestionsDescription }
4116
- : {}), ...(guidedQuestionsSkipLabel
4117
- ? { skipLabel: guidedQuestionsSkipLabel }
4118
- : {}), ...(guidedQuestionsSubmitLabel
4119
- ? { submitLabel: guidedQuestionsSubmitLabel }
4120
- : {}), className: "h-auto items-stretch justify-stretch bg-transparent" }) })), composerError && (_jsxs("div", { role: "alert", className: "shrink-0 mx-3 mb-1.5 flex items-start gap-2 rounded-md border border-destructive/40 bg-destructive/10 px-3 py-2 text-xs text-destructive", children: [_jsx(IconAlertTriangle, { className: "h-3.5 w-3.5 mt-0.5 shrink-0" }), _jsx("span", { className: "flex-1 leading-snug", children: composerError }), _jsx("button", { type: "button", "aria-label": "Dismiss error", onClick: () => setComposerError(null), className: "shrink-0 opacity-70 hover:opacity-100", children: _jsx(IconX, { className: "h-3 w-3" }) })] })), _jsxs("div", { className: "agent-composer-stack", "data-agent-composer-adjacent-ui": hasComposerAccessoryAboveStack ? "true" : undefined, children: [_jsx(SelectionAttachedPill, {}), showPlanModeCallout && (_jsx(PlanModeCallout, { canImplementPlan: canImplementPlan, onImplementPlan: handleImplementPlan, onSwitchToAct: handleSwitchToAct })), showInlineMissingKeySetup ? (_jsx(BuilderSetupCard, { fullWidth: true, layout: "sidebar", onConnected: handleBuilderConnected })) : null, _jsxs(Popover, { open: showMissingKeySetup &&
4121
- !showInlineMissingKeySetup &&
4122
- missingKeySetupOpen, onOpenChange: setMissingKeySetupOpen, children: [_jsx(AgentComposerFrame, { layoutVariant: composerLayoutVariant, className: cn(composerAreaClassName, isComposerDisabled &&
4123
- !showMissingKeySetup &&
4124
- "opacity-70"), rootClassName: cn(showMissingKeySetup &&
4125
- "agent-composer-root--missing-key"), children: showMissingKeySetup && !showInlineMissingKeySetup ? (_jsx(PopoverTrigger, { asChild: true, children: _jsx("button", { type: "button", className: "agent-composer-missing-key-trigger", "aria-label": "Connect AI to start chatting", children: _jsxs("span", { className: "agent-composer-missing-key-content", children: [_jsxs("span", { className: "agent-composer-missing-key-copy", children: [_jsx("span", { className: "agent-composer-missing-key-title", children: missingApiKeySetupLayout === "sidebar"
4126
- ? "Connect AI to chat"
4127
- : "Connect AI to start chatting" }), missingApiKeySetupLayout !== "sidebar" ? (_jsx("span", { className: "agent-composer-missing-key-description", children: "Builder.io includes free credits, or use your own API key." })) : null] }), _jsx("span", { className: "agent-composer-missing-key-cta", children: "Connect AI" })] }) }) })) : (_jsxs(_Fragment, { children: [_jsx(ComposerAttachmentPreviewStrip, {}), _jsx(TiptapComposer, { focusRef: tiptapRef, onTextChange: isActiveComposer
4128
- ? handleComposerTextChange
4129
- : undefined, disabled: isComposerDisabled ||
4130
- showInlineMissingKeySetup, placeholder: showInlineMissingKeySetup
4131
- ? "Connect AI above to start chatting..."
4132
- : engineSetupRequired
4133
- ? "Connect AI to start chatting..."
4134
- : composerDisabled
4135
- ? (composerDisabledPlaceholder ??
4136
- "Open Desktop to use this chat.")
4137
- : isRunning
4138
- ? queuedMessages.length > 0
4139
- ? `${queuedMessages.length} queued — send a follow-up...`
4140
- : "Send a follow-up..."
4141
- : composerPlaceholder, onSubmit: isRunning || composerContextItems.length > 0
4142
- ? (text, references, attachments, options) => void addToQueue(text, undefined, references.length > 0
4143
- ? references
4144
- : undefined, attachments, undefined, resolveAssistantChatSubmitIntent({
4145
- isRunning,
4146
- requestedIntent: options?.intent,
4147
- }), undefined, true)
4148
- : undefined, willQueue: engineSetupRequired || isRunning, onSlashCommand: onSlashCommand, execMode: execMode, onExecModeChange: onExecModeChange, planModeDisabled: planModeDisabled, planModeDisabledReason: planModeDisabledReason, selectedModel: selectedModel ?? defaultModel, selectedEffort: selectedEffort, availableModels: availableModels, modelListLoading: modelListLoading, onModelChange: onModelChange, onEffortChange: onEffortChange, imageModelMenu: imageModelMenu, onConnectProvider: onConnectProvider, onConnectLocalRuntime: onConnectLocalRuntime, toolbarSlot: composerToolbarSlot, contextItems: composerContextItems, onRemoveContextItem: removeComposerContextItem, plusMenuMode: plusMenuMode, layoutVariant: composerLayoutVariant, providerConnectStatusEnabled: providerStatusChecksEnabled, voiceEnabled: true, draftScope: threadId || tabId, interceptBuildRequestsForBuilder: true, onAttachmentError: setComposerError, extraActionButton: composerExtraActionButton, stopButton: showRunningInUI ? (_jsxs(Tooltip, { children: [_jsx(TooltipTrigger, { asChild: true, children: _jsx("button", { type: "button", onClick: () => stopActiveRun(), "aria-label": "Stop response", "data-agent-composer-slot": "stop-button", className: "shrink-0 flex h-7 w-7 cursor-pointer items-center justify-center rounded-full bg-primary text-primary-foreground shadow-sm transition-opacity hover:opacity-90 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2", children: _jsx(IconPlayerStopFilled, { className: "h-3 w-3" }) }) }), _jsx(TooltipContent, { children: "Stop response" })] })) : undefined })] })) }), showMissingKeySetup && !showInlineMissingKeySetup ? (_jsx(PopoverContent, { side: missingApiKeySetupLayout === "sidebar"
4149
- ? "top"
4150
- : "bottom", align: "center", sideOffset: 8, collisionPadding: 12, "data-agent-native-composer-popover": "true", className: "z-[260] box-border w-[min(calc(100vw-2rem),var(--radix-popover-content-available-width,26rem),26rem)] rounded-lg border-border p-3 shadow-lg", children: _jsx(BuilderSetupContent, { onConnected: handleBuilderConnected, layout: missingApiKeySetupLayout }) })) : null] })] })] }) }) }) }) }) }) }) }));
4090
+ return (_jsx(CheckpointContext.Provider, { value: checkpointCtx, children: _jsx(MessageActionsContext.Provider, { value: messageActionsCtx, children: _jsx(ApprovalContext.Provider, { value: approvalCtx, children: _jsx(ChatRunDurationContext.Provider, { value: lastChatRunDurationMs, children: _jsx(ServerRunActiveContext.Provider, { value: serverRunActive, children: _jsx(ChatRunningRunIdContext.Provider, { value: activeChatRunId, children: _jsx(ChatRunningTurnIdContext.Provider, { value: activeChatTurnId, children: _jsx(ChatRunningContext.Provider
4091
+ // Keep the current message in a non-complete state while
4092
+ // the terminal error card is visible, even if the server
4093
+ // still reports the prior run for a short time while its
4094
+ // claim is released. Historical messages use turn
4095
+ // ownership below.
4096
+ , {
4097
+ // Keep the current message in a non-complete state while
4098
+ // the terminal error card is visible, even if the server
4099
+ // still reports the prior run for a short time while its
4100
+ // claim is released. Historical messages use turn
4101
+ // ownership below.
4102
+ value: showRunningInUI || runErrorInfo !== null, children: _jsx(TextStreamingContext.Provider, { value: textStreaming, children: _jsxs("div", { "data-agent-empty-state": centeredEmptyState
4103
+ ? "centered"
4104
+ : compactMissingKeyEmptyState
4105
+ ? "compact-setup"
4106
+ : undefined, className: cn("relative flex flex-1 flex-col h-full min-h-0 text-foreground", className), onDragEnter: handleChatDragEnter, onDragOver: handleChatDragOver, onDragLeave: handleChatDragLeave, onDropCapture: handleChatDropCapture, onDrop: handleChatDrop, children: [dropActive && (_jsx("div", { "aria-hidden": "true", className: "pointer-events-none absolute inset-0 z-50 flex items-center justify-center rounded-md border-2 border-dashed border-primary/70 bg-primary/5 backdrop-blur-[1px]", children: _jsx("span", { className: "rounded-md bg-background/90 px-3 py-1.5 text-xs font-medium text-foreground shadow-sm", children: "Drop to attach" }) })), showHeader && (_jsxs("div", { className: "flex h-11 shrink-0 items-center justify-between border-b border-border px-4", children: [_jsx("span", { className: "text-[13px] font-medium text-muted-foreground", children: "Agent" }), _jsx("div", { className: "flex items-center gap-1", children: onSwitchToCli && (_jsx(TooltipProvider, { delayDuration: 200, children: _jsxs(Tooltip, { children: [_jsx(TooltipTrigger, { asChild: true, children: _jsxs("button", { onClick: onSwitchToCli, "aria-label": "Switch to CLI", className: "flex items-center gap-1 text-[12px] text-muted-foreground hover:text-foreground px-2 py-1 rounded-md hover:bg-accent", children: [_jsx(IconTerminal, { className: "h-3.5 w-3.5" }), "CLI"] }) }), _jsx(TooltipContent, { children: "Switch to CLI" })] }) })) })] })), _jsx(MessageScrollerProvider, { autoScroll: false, children: _jsxs(MessageScroller, { className: "agent-chat-scroll", children: [_jsx(MessageScrollerViewport, { ref: scrollRef, children: authError ? (_jsxs("div", { className: "flex flex-col items-center justify-center h-full px-4 gap-3", children: [_jsx("div", { className: "flex h-10 w-10 items-center justify-center rounded-full bg-muted", children: authSessionAvailable ? (_jsx(IconRefresh, { className: "h-5 w-5 text-muted-foreground" })) : (_jsx(IconMessage, { className: "h-5 w-5 text-muted-foreground" })) }), _jsxs("div", { className: "text-center max-w-[280px]", children: [_jsx("p", { className: "text-sm font-medium text-foreground mb-1", children: authSessionAvailable
4107
+ ? "Chat session needs refresh"
4108
+ : authError.sessionExpired
4109
+ ? "Session expired"
4110
+ : "Authentication required" }), _jsx("p", { className: "text-xs text-muted-foreground leading-relaxed", children: authSessionAvailable
4111
+ ? "You're signed in, but this chat connection needs to reconnect."
4112
+ : authError.sessionExpired
4113
+ ? "Your session may have expired. Log out and log back in to reconnect."
4114
+ : "You need to log in to use the agent." })] }), _jsxs("div", { className: "flex gap-2", children: [!authError.sessionExpired &&
4115
+ !authSessionAvailable && (_jsx("button", { onClick: () => {
4116
+ window.location.href =
4117
+ buildSignInReturnHref();
4118
+ }, className: "text-xs text-background bg-foreground hover:opacity-90 px-3 py-1.5 rounded-md", children: "Log in" })), authError.sessionExpired &&
4119
+ !authSessionAvailable && (_jsx("button", { onClick: async () => {
4120
+ try {
4121
+ await fetch(agentNativePath("/_agent-native/auth/logout"), {
4122
+ method: "POST",
4123
+ });
4124
+ }
4125
+ catch (error) {
4126
+ console.error("Failed to log out before reloading the chat", error);
4127
+ }
4128
+ window.location.reload();
4129
+ }, className: "text-xs text-destructive hover:text-destructive/80 px-3 py-1.5 rounded-md border border-destructive/30 hover:bg-destructive/10", children: "Log out" })), _jsx("button", { onClick: () => {
4130
+ setAuthError(null);
4131
+ window.location.reload();
4132
+ }, className: authSessionAvailable
4133
+ ? "text-xs text-background bg-foreground hover:opacity-90 px-3 py-1.5 rounded-md"
4134
+ : "text-xs text-muted-foreground hover:text-foreground px-3 py-1.5 rounded-md border border-border hover:bg-accent", children: "Refresh chat" })] })] })) : isRestoring && centeredRestoringState ? (_jsxs("div", { className: cn("agent-empty-state", emptyStateDisplay === "hidden"
4135
+ ? "sr-only"
4136
+ : "flex h-full flex-col items-center justify-center gap-3 px-4 py-16"), "aria-busy": "true", children: [_jsx(IconMessage, { className: "h-5 w-5 text-muted-foreground/60" }), _jsx("p", { className: "sr-only", children: emptyStateText ?? "Loading chat..." })] })) : isRestoring ? (_jsxs("div", { className: "flex flex-col gap-3 p-4", children: [_jsx("div", { className: "flex justify-end", children: _jsx("div", { className: "h-8 w-32 rounded-lg bg-muted animate-pulse" }) }), _jsxs("div", { className: "flex flex-col gap-1.5", children: [_jsx("div", { className: "h-4 w-48 rounded bg-muted animate-pulse" }), _jsx("div", { className: "h-4 w-64 rounded bg-muted animate-pulse" }), _jsx("div", { className: "h-4 w-40 rounded bg-muted animate-pulse" })] })] })) : showEmptyState ? (_jsxs("div", { className: cn("agent-empty-state", emptyStateDisplay === "hidden"
4137
+ ? "sr-only"
4138
+ : "flex h-full flex-col items-center justify-center gap-3 px-4 py-16"), children: [_jsx(IconMessage, { className: "h-5 w-5 text-muted-foreground/60" }), _jsx("p", { className: "sr-only", children: emptyStateText ?? "How can I help you?" }), emptyStateAddon, resolvedSuggestions &&
4139
+ resolvedSuggestions.length > 0 ? (_jsx("div", { className: "flex w-full max-w-[280px] flex-col gap-1", children: resolvedSuggestions.map((suggestion) => (_jsx("button", { onClick: () => {
4140
+ if (engineSetupRequired) {
4141
+ requestMissingKeySetup();
4142
+ return;
4143
+ }
4144
+ void addToQueue(suggestion);
4145
+ }, className: "w-full px-2 py-1 text-center text-[13px] text-muted-foreground transition-colors hover:text-foreground focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2", children: suggestion }, suggestion))) })) : null, showInlineEmptyThreadFooterSlot ? (_jsx("div", { className: "agent-thread-footer-slot agent-thread-footer-slot--empty", children: resolvedThreadFooterSlot })) : null] })) : (_jsxs(MessageScrollerContent, { className: "agent-thread-content gap-4 px-4 py-4", children: [_jsx(AssistantMessageListErrorBoundary, { resetKey: messageListResetKey, children: _jsx(ThreadPrimitive.Messages
4146
+ // assistant-ui indexes message parts through tap resources.
4147
+ // Keep this key tied to that shape so clear/add transitions remount stale
4148
+ // lookups without remounting on every streamed text update.
4149
+ , { components: {
4150
+ UserMessage: AssistantChatUserMessageItem,
4151
+ AssistantMessage: AssistantChatAssistantMessageItem,
4152
+ } }, messageListResetKey) }), visibleLoopLimit && !showRunningInUI && (_jsx(MessageScrollerItem, { children: _jsx(LoopLimitContinueCard, { info: visibleLoopLimit, onContinue: () => {
4153
+ setShowContinue(false);
4154
+ setLoopLimitInfo(null);
4155
+ addToQueue("Continue from where you left off.", undefined, undefined, undefined, undefined, "queued", "continue");
4156
+ } }) })), shouldShowRunError && visibleRunError && (_jsx(MessageScrollerItem, { children: _jsx(RunErrorRecoveryCard, { info: visibleRunError, onContinue: () => {
4157
+ setRunErrorInfo(null);
4158
+ addToQueue(RECONNECT_NO_PROGRESS_CONTINUE_MESSAGE, undefined, undefined, undefined, undefined, "queued", "continue");
4159
+ }, onRetry: retryAfterRunError, onFork: onForkChat, onProviderConnected: handleBuilderConnected, onDismiss: () => {
4160
+ if (visibleRunErrorKey) {
4161
+ setDismissedRunErrorKey(visibleRunErrorKey);
4162
+ }
4163
+ setRunErrorInfo(null);
4164
+ } }) })), (isReconnecting ||
4165
+ reconnectFrozen ||
4166
+ adapterHandoffPending) &&
4167
+ visibleReconnectContent.length > 0 && (_jsx(MessageScrollerItem, { children: _jsx(ReconnectStreamMessage, { content: visibleReconnectContent, allowActivitySpinner: !reconnectFrozen }) })), (isReconnecting ||
4168
+ reconnectFrozen ||
4169
+ adapterHandoffPending) &&
4170
+ visibleReconnectContent.length === 0 &&
4171
+ reconnectContent.length === 0 &&
4172
+ reconnectActivityContent.length > 0 && (_jsx(MessageScrollerItem, { children: _jsx(ReconnectStreamMessage, { content: reconnectActivityContent, allowActivitySpinner: !reconnectFrozen }) })), showGlobalRunningStatus && (_jsx(MessageScrollerItem, { children: _jsx(RunningActivityStatus, { label: runningStatusLabel }) })), visibleQueuedMessages.length > 0 && (_jsx(MessageScrollerItem, { children: _jsxs("div", { className: "flex items-center justify-end gap-1.5 pr-0.5 text-xs text-muted-foreground", children: [_jsx(IconClock, { className: "h-3 w-3" }), _jsxs("span", { children: [visibleQueuedMessages.length, " queued"] })] }) })), visibleQueuedMessages.map((msg) => {
4173
+ const displayText = displayableUserMessageText(msg.text);
4174
+ const imageSources = queuedMessageImageSources(msg);
4175
+ return (_jsx(MessageScrollerItem, { messageId: msg.id, children: _jsxs("div", { className: "group flex items-start justify-end gap-1.5", children: [isRunning && (_jsxs(Tooltip, { children: [_jsx(TooltipTrigger, { asChild: true, children: _jsx("button", { type: "button", onClick: () => sendQueuedMessageNow(msg.id), "aria-label": "Send now", className: "mt-1.5 flex h-5 w-5 cursor-pointer items-center justify-center rounded-full border border-border bg-background text-muted-foreground opacity-0 shadow-sm transition-opacity hover:bg-accent hover:text-foreground focus-visible:opacity-100 group-hover:opacity-100", children: _jsx(IconArrowUp, { className: "h-3 w-3" }) }) }), _jsx(TooltipContent, { children: "Send now (stops the current response)" })] })), _jsx("button", { type: "button", onClick: () => applyLocalQueuedMessages((prev) => prev.filter((m) => m.id !== msg.id)), "aria-label": "Remove from queue", className: "mt-1.5 flex h-5 w-5 cursor-pointer items-center justify-center rounded-full border border-border bg-background text-muted-foreground opacity-0 shadow-sm transition-opacity hover:bg-accent hover:text-foreground focus-visible:opacity-100 group-hover:opacity-100", children: _jsx(IconX, { className: "h-3 w-3" }) }), _jsxs("div", { className: "max-w-[85%] rounded-lg bg-accent/50 px-3 py-2 text-sm leading-relaxed text-foreground/60 whitespace-pre-wrap break-words", children: [displayText, imageSources.length > 0 && (_jsx("div", { className: "flex flex-wrap gap-1.5 mt-1.5", children: imageSources.map((img, j) => (_jsx("img", { src: img, alt: "", className: "h-12 w-12 rounded object-cover border border-border/50" }, j))) }))] })] }) }, msg.id));
4176
+ }), resolvedThreadFooterSlot ? (_jsx(MessageScrollerItem, { children: _jsx("div", { className: "agent-thread-footer-slot", children: resolvedThreadFooterSlot }) })) : null] })) }), !authError &&
4177
+ !isRestoring &&
4178
+ !showEmptyState &&
4179
+ showScrollToBottom ? (_jsx("div", { className: "shrink-0 flex justify-center -mb-1", children: _jsx("button", { type: "button", onClick: scrollToBottom, className: "flex h-7 w-7 items-center justify-center rounded-full border border-border bg-background shadow-sm hover:bg-accent", "aria-label": "Scroll to bottom", children: _jsx(IconChevronDown, { className: "h-3.5 w-3.5 text-muted-foreground" }) }) })) : null] }) }, chatScrollResetKey), showComposerSlot ? composerSlot : null, isActiveComposer && (_jsx(McpConnectionSuggestion, { text: composerText })), showCenteredEmptyThreadFooterSlot ? (_jsx("div", { className: "agent-thread-footer-slot agent-thread-footer-slot--centered-empty", children: resolvedThreadFooterSlot })) : null, guidedQuestions && guidedQuestions.length > 0 && (_jsx("div", { className: "shrink-0 px-3 pb-2", children: _jsx(GuidedQuestionFlow, { questions: guidedQuestions, onSubmit: handleGuidedQuestionsSubmit, onSkip: handleGuidedQuestionsSkip, ...(guidedQuestionsTitle
4180
+ ? { title: guidedQuestionsTitle }
4181
+ : {}), ...(guidedQuestionsDescription
4182
+ ? { description: guidedQuestionsDescription }
4183
+ : {}), ...(guidedQuestionsSkipLabel
4184
+ ? { skipLabel: guidedQuestionsSkipLabel }
4185
+ : {}), ...(guidedQuestionsSubmitLabel
4186
+ ? { submitLabel: guidedQuestionsSubmitLabel }
4187
+ : {}), className: "h-auto items-stretch justify-stretch bg-transparent" }) })), composerError && (_jsxs("div", { role: "alert", className: "shrink-0 mx-3 mb-1.5 flex items-start gap-2 rounded-md border border-destructive/40 bg-destructive/10 px-3 py-2 text-xs text-destructive", children: [_jsx(IconAlertTriangle, { className: "h-3.5 w-3.5 mt-0.5 shrink-0" }), _jsx("span", { className: "flex-1 leading-snug", children: composerError }), _jsx("button", { type: "button", "aria-label": "Dismiss error", onClick: () => setComposerError(null), className: "shrink-0 opacity-70 hover:opacity-100", children: _jsx(IconX, { className: "h-3 w-3" }) })] })), _jsxs("div", { className: "agent-composer-stack", "data-agent-composer-adjacent-ui": hasComposerAccessoryAboveStack ? "true" : undefined, children: [_jsx(SelectionAttachedPill, {}), showPlanModeCallout && (_jsx(PlanModeCallout, { canImplementPlan: canImplementPlan, onImplementPlan: handleImplementPlan, onSwitchToAct: handleSwitchToAct })), showInlineMissingKeySetup ? (_jsx(BuilderSetupCard, { fullWidth: true, layout: "sidebar", onConnected: handleBuilderConnected })) : null, _jsxs(Popover, { open: showMissingKeySetup &&
4188
+ !showInlineMissingKeySetup &&
4189
+ missingKeySetupOpen, onOpenChange: setMissingKeySetupOpen, children: [_jsx(AgentComposerFrame, { layoutVariant: composerLayoutVariant, className: cn(composerAreaClassName, isComposerDisabled &&
4190
+ !showMissingKeySetup &&
4191
+ "opacity-70"), rootClassName: cn(showMissingKeySetup &&
4192
+ "agent-composer-root--missing-key"), children: showMissingKeySetup &&
4193
+ !showInlineMissingKeySetup ? (_jsx(PopoverTrigger, { asChild: true, children: _jsx("button", { type: "button", className: "agent-composer-missing-key-trigger", "aria-label": "Connect AI to start chatting", children: _jsxs("span", { className: "agent-composer-missing-key-content", children: [_jsxs("span", { className: "agent-composer-missing-key-copy", children: [_jsx("span", { className: "agent-composer-missing-key-title", children: missingApiKeySetupLayout ===
4194
+ "sidebar"
4195
+ ? "Connect AI to chat"
4196
+ : "Connect AI to start chatting" }), missingApiKeySetupLayout !==
4197
+ "sidebar" ? (_jsx("span", { className: "agent-composer-missing-key-description", children: "Builder.io includes free credits, or use your own API key." })) : null] }), _jsx("span", { className: "agent-composer-missing-key-cta", children: "Connect AI" })] }) }) })) : (_jsxs(_Fragment, { children: [_jsx(ComposerAttachmentPreviewStrip, {}), _jsx(TiptapComposer, { focusRef: tiptapRef, onTextChange: isActiveComposer
4198
+ ? handleComposerTextChange
4199
+ : undefined, disabled: isComposerDisabled ||
4200
+ showInlineMissingKeySetup, placeholder: showInlineMissingKeySetup
4201
+ ? "Connect AI above to start chatting..."
4202
+ : engineSetupRequired
4203
+ ? "Connect AI to start chatting..."
4204
+ : composerDisabled
4205
+ ? (composerDisabledPlaceholder ??
4206
+ "Open Desktop to use this chat.")
4207
+ : isRunning
4208
+ ? queuedMessages.length > 0
4209
+ ? `${queuedMessages.length} queued — send a follow-up...`
4210
+ : "Send a follow-up..."
4211
+ : composerPlaceholder, onSubmit: isRunning ||
4212
+ composerContextItems.length > 0
4213
+ ? (text, references, attachments, options) => void addToQueue(text, undefined, references.length > 0
4214
+ ? references
4215
+ : undefined, attachments, undefined, resolveAssistantChatSubmitIntent({
4216
+ isRunning,
4217
+ requestedIntent: options?.intent,
4218
+ }), undefined, true)
4219
+ : undefined, willQueue: engineSetupRequired || isRunning, onSlashCommand: onSlashCommand, execMode: execMode, onExecModeChange: onExecModeChange, planModeDisabled: planModeDisabled, planModeDisabledReason: planModeDisabledReason, selectedModel: selectedModel ?? defaultModel, selectedEffort: selectedEffort, availableModels: availableModels, modelListLoading: modelListLoading, onModelChange: onModelChange, onEffortChange: onEffortChange, imageModelMenu: imageModelMenu, onConnectProvider: onConnectProvider, onConnectLocalRuntime: onConnectLocalRuntime, toolbarSlot: composerToolbarSlot, contextItems: composerContextItems, onRemoveContextItem: removeComposerContextItem, plusMenuMode: plusMenuMode, layoutVariant: composerLayoutVariant, providerConnectStatusEnabled: providerStatusChecksEnabled, voiceEnabled: true, draftScope: threadId || tabId, interceptBuildRequestsForBuilder: true, onAttachmentError: setComposerError, extraActionButton: composerExtraActionButton, stopButton: showRunningInUI ? (_jsxs(Tooltip, { children: [_jsx(TooltipTrigger, { asChild: true, children: _jsx("button", { type: "button", onClick: () => stopActiveRun(), "aria-label": "Stop response", "data-agent-composer-slot": "stop-button", className: "shrink-0 flex h-7 w-7 cursor-pointer items-center justify-center rounded-full bg-primary text-primary-foreground shadow-sm transition-opacity hover:opacity-90 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2", children: _jsx(IconPlayerStopFilled, { className: "h-3 w-3" }) }) }), _jsx(TooltipContent, { children: "Stop response" })] })) : undefined })] })) }), showMissingKeySetup &&
4220
+ !showInlineMissingKeySetup ? (_jsx(PopoverContent, { side: missingApiKeySetupLayout === "sidebar"
4221
+ ? "top"
4222
+ : "bottom", align: "center", sideOffset: 8, collisionPadding: 12, "data-agent-native-composer-popover": "true", className: "z-[260] box-border w-[min(calc(100vw-2rem),var(--radix-popover-content-available-width,26rem),26rem)] rounded-lg border-border p-3 shadow-lg", children: _jsx(BuilderSetupContent, { onConnected: handleBuilderConnected, layout: missingApiKeySetupLayout }) })) : null] })] })] }) }) }) }) }) }) }) }) }) }));
4151
4223
  });
4152
4224
  export const AssistantChat = forwardRef(function AssistantChat({ apiUrl = agentNativePath("/_agent-native/agent-chat"), tabId, browserTabId, threadId, contextScope, isActiveComposer, ...props }, ref) {
4153
4225
  const modelRef = useRef(props.selectedModel);