@mcp-b/react-components 0.48.0 → 0.49.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (299) hide show
  1. package/dist/AgentChatQueue-C_Jaw3Ia.d.ts +48 -0
  2. package/dist/AgentToolRunsContext-GMe_hSnD.d.ts +35 -0
  3. package/dist/Avatar-o2NO1fCG.d.ts +124 -0
  4. package/dist/{Button-CZt3yywF.d.ts → Button-DjONW5UW.d.ts} +1 -1
  5. package/dist/{CodeBlock-C380GD5t.d.ts → CodeBlock--r6GS8YV.d.ts} +8 -2
  6. package/dist/{CodeBlock-BSJl682D.js → CodeBlock-g8sADidM.js} +8 -8
  7. package/dist/{FileTree-DvE0hNZu.js → FileTree-H8mMg4rV.js} +21 -30
  8. package/dist/{IconButton-BAUFhUk8.d.ts → IconButton-ByiyjkYE.d.ts} +2 -2
  9. package/dist/{Message-D_vCVEGB.d.ts → Message-DyaTBiV7.d.ts} +17 -4
  10. package/dist/MessageScrollerVirtual-D4afYwVB.d.ts +84 -0
  11. package/dist/{PromptInput-DtJHyp0S.d.ts → PromptInput-C4Mofitz.d.ts} +44 -31
  12. package/dist/PromptInputApproval-D2hpn54U.d.ts +44 -0
  13. package/dist/Separator-CzhtLYE1.d.ts +41 -0
  14. package/dist/Toolbar-CGY004u0.d.ts +155 -0
  15. package/dist/{Workspace-LIoU30n7.d.ts → Workspace-HzGrWDX3.d.ts} +1 -1
  16. package/dist/{WorkspaceFile-Dq-GC0_T.d.ts → WorkspaceFile-Bouauobc.d.ts} +1 -1
  17. package/dist/{WorkspaceFileView-C_WnYm-a.js → WorkspaceFileView-DYPtRVpM.js} +5 -4
  18. package/dist/{WorkspaceLink-B1d2GIGl.js → WorkspaceLink-BYZG-V_I.js} +8 -91
  19. package/dist/{WorkspaceMessageResponse-BqOezptB.js → WorkspaceMessageResponse-CUJk9_P5.js} +2 -2
  20. package/dist/components/agents-sdk/AgentActivity.js +1 -1
  21. package/dist/components/agents-sdk/AgentChat.d.ts +198 -2
  22. package/dist/components/agents-sdk/AgentChat.js +527 -672
  23. package/dist/components/agents-sdk/AgentChatQueue.d.ts +2 -0
  24. package/dist/components/agents-sdk/AgentChatQueue.js +206 -0
  25. package/dist/components/agents-sdk/AgentEvent.js +2 -2
  26. package/dist/components/agents-sdk/AgentToolRunsContext.d.ts +2 -2
  27. package/dist/components/agents-sdk/AgentToolRunsContext.js +1 -36
  28. package/dist/components/agents-sdk/BrowserLiveScreen.js +22 -14
  29. package/dist/components/agents-sdk/BrowserLiveView.js +1 -1
  30. package/dist/components/agents-sdk/BrowserReplay.d.ts +1 -1
  31. package/dist/components/agents-sdk/BrowserReplay.js +1 -1
  32. package/dist/components/agents-sdk/BrowserRunPanel.d.ts +3 -0
  33. package/dist/components/agents-sdk/BrowserRunPanel.js +32 -31
  34. package/dist/components/agents-sdk/EmployeeChrome.d.ts +212 -0
  35. package/dist/components/agents-sdk/EmployeeChrome.js +555 -0
  36. package/dist/components/agents-sdk/ManagerOffice.d.ts +79 -40
  37. package/dist/components/agents-sdk/ManagerOffice.js +291 -281
  38. package/dist/components/agents-sdk/McpConnectionRequest.d.ts +4 -4
  39. package/dist/components/agents-sdk/McpConnectionRequest.js +4 -3
  40. package/dist/components/agents-sdk/McpConnectorForm.d.ts +38 -1
  41. package/dist/components/agents-sdk/McpConnectorForm.js +1 -1
  42. package/dist/components/agents-sdk/McpPluginCatalog.d.ts +93 -1
  43. package/dist/components/agents-sdk/McpPluginCatalog.js +5 -4
  44. package/dist/components/agents-sdk/McpServerIcon.d.ts +17 -0
  45. package/dist/components/agents-sdk/McpServerIcon.js +25 -0
  46. package/dist/components/agents-sdk/McpServerPicker.d.ts +4 -3
  47. package/dist/components/agents-sdk/McpServerPicker.js +4 -3
  48. package/dist/components/agents-sdk/ModelSelector.d.ts +4 -4
  49. package/dist/components/agents-sdk/ModelSelector.js +4 -4
  50. package/dist/components/agents-sdk/PromptInputApproval.d.ts +1 -43
  51. package/dist/components/agents-sdk/PromptInputApproval.js +1 -1
  52. package/dist/components/agents-sdk/PromptInputCommands.d.ts +1 -1
  53. package/dist/components/agents-sdk/PromptInputCommands.js +2 -3
  54. package/dist/components/agents-sdk/SessionCompaction.d.ts +88 -1
  55. package/dist/components/agents-sdk/SessionCompaction.js +2 -2
  56. package/dist/components/agents-sdk/SubagentRunDetails.d.ts +30 -1
  57. package/dist/components/agents-sdk/SubagentRunDetails.js +57 -1
  58. package/dist/components/agents-sdk/SubagentRunIndicator.d.ts +9 -9
  59. package/dist/components/agents-sdk/SubagentRunIndicator.js +19 -24
  60. package/dist/components/agents-sdk/SubagentRunList.d.ts +6 -3
  61. package/dist/components/agents-sdk/SubagentRunList.js +4 -2
  62. package/dist/components/agents-sdk/SubagentRunPanel.d.ts +60 -0
  63. package/dist/components/agents-sdk/SubagentRunPanel.js +255 -0
  64. package/dist/components/agents-sdk/SubagentRunSelector.d.ts +8 -4
  65. package/dist/components/agents-sdk/SubagentRunSelector.js +5 -3
  66. package/dist/components/agents-sdk/ThinkChat.d.ts +102 -2
  67. package/dist/components/agents-sdk/ThinkChat.js +233 -2
  68. package/dist/components/agents-sdk/ThinkChatActivity.d.ts +76 -1
  69. package/dist/components/agents-sdk/ThinkChatActivity.js +18 -10
  70. package/dist/components/agents-sdk/ThinkChatContext.d.ts +27 -1
  71. package/dist/components/agents-sdk/ThinkChatContext.js +1 -1
  72. package/dist/components/agents-sdk/ThinkChatToolPanels.js +24 -19
  73. package/dist/components/agents-sdk/ThinkExecutionDetail.js +2 -2
  74. package/dist/components/agents-sdk/ThinkExecutionStatus.d.ts +1 -1
  75. package/dist/components/agents-sdk/ThinkExecutionStatus.js +1 -1
  76. package/dist/components/agents-sdk/ThinkExecutionWorkbench.d.ts +85 -28
  77. package/dist/components/agents-sdk/ThinkExecutionWorkbench.js +159 -102
  78. package/dist/components/agents-sdk/ThinkFullApp.d.ts +40 -158
  79. package/dist/components/agents-sdk/ThinkFullApp.js +71 -290
  80. package/dist/components/agents-sdk/ThinkRecoveryNotice.d.ts +18 -1
  81. package/dist/components/agents-sdk/ThinkRecoveryNotice.js +1 -1
  82. package/dist/components/agents-sdk/ThinkRoutineActions.d.ts +51 -0
  83. package/dist/components/agents-sdk/ThinkRoutineActions.js +201 -0
  84. package/dist/components/agents-sdk/ThinkRoutineBrowser.d.ts +4 -1
  85. package/dist/components/agents-sdk/ThinkRoutineBrowser.js +17 -15
  86. package/dist/components/agents-sdk/ThinkRoutineDetail.js +11 -11
  87. package/dist/components/agents-sdk/ThinkRoutineForm.d.ts +2 -1
  88. package/dist/components/agents-sdk/ThinkRoutineForm.js +14 -14
  89. package/dist/components/agents-sdk/ThinkRoutineRuns.js +7 -7
  90. package/dist/components/agents-sdk/ThinkThreadPicker.d.ts +90 -1
  91. package/dist/components/agents-sdk/ThinkThreadPicker.js +3 -3
  92. package/dist/components/agents-sdk/Workspace.d.ts +1 -1
  93. package/dist/components/agents-sdk/Workspace.js +7 -13
  94. package/dist/components/agents-sdk/WorkspaceBrowser.d.ts +1 -1
  95. package/dist/components/agents-sdk/WorkspaceBrowser.js +1 -1
  96. package/dist/components/agents-sdk/WorkspaceConcept.d.ts +1 -1
  97. package/dist/components/agents-sdk/WorkspaceCorrespondence.d.ts +10 -1
  98. package/dist/components/agents-sdk/WorkspaceCorrespondence.js +10 -7
  99. package/dist/components/agents-sdk/WorkspaceExecution.d.ts +5 -14
  100. package/dist/components/agents-sdk/WorkspaceExecution.js +24 -38
  101. package/dist/components/agents-sdk/WorkspaceExplorer.d.ts +5 -2
  102. package/dist/components/agents-sdk/WorkspaceExplorer.js +3 -2
  103. package/dist/components/agents-sdk/WorkspaceFile.d.ts +1 -1
  104. package/dist/components/agents-sdk/WorkspaceFileView.d.ts +1 -1
  105. package/dist/components/agents-sdk/WorkspaceFileView.js +1 -1
  106. package/dist/components/agents-sdk/WorkspaceHeader.js +1 -1
  107. package/dist/components/agents-sdk/WorkspaceLink.js +1 -1
  108. package/dist/components/agents-sdk/WorkspaceLive.d.ts +60 -1
  109. package/dist/components/agents-sdk/WorkspaceMessageResponse.d.ts +47 -1
  110. package/dist/components/agents-sdk/WorkspaceMessageResponse.js +1 -1
  111. package/dist/components/agents-sdk/WorkspaceMountManager.d.ts +3 -2
  112. package/dist/components/agents-sdk/WorkspaceMountManager.js +6 -9
  113. package/dist/components/agents-sdk/WorkspaceNavigationRestoration.d.ts +38 -0
  114. package/dist/components/agents-sdk/WorkspaceNavigationRestoration.js +86 -0
  115. package/dist/components/agents-sdk/WorkspaceProject.d.ts +5 -14
  116. package/dist/components/agents-sdk/WorkspaceProject.js +21 -35
  117. package/dist/components/agents-sdk/WorkspaceUserScript.d.ts +1 -1
  118. package/dist/components/agents-sdk/WorkspaceUserScript.js +8 -5
  119. package/dist/components/ai-sdk/Activity.d.ts +1 -1
  120. package/dist/components/ai-sdk/Activity.js +1 -1
  121. package/dist/components/ai-sdk/AgentAttention.d.ts +2 -2
  122. package/dist/components/ai-sdk/AgentChatStartScreen.d.ts +89 -2
  123. package/dist/components/ai-sdk/AgentChatStartScreen.js +64 -43
  124. package/dist/components/ai-sdk/AgentMessageParts.d.ts +45 -1
  125. package/dist/components/ai-sdk/Approval.d.ts +1 -1
  126. package/dist/components/ai-sdk/Approval.js +2 -2
  127. package/dist/components/ai-sdk/Artifact.d.ts +2 -2
  128. package/dist/components/ai-sdk/Artifact.js +1 -1
  129. package/dist/components/ai-sdk/ChainOfThought.d.ts +1 -1
  130. package/dist/components/ai-sdk/ChainOfThought.js +1 -1
  131. package/dist/components/ai-sdk/Checkpoint.js +1 -1
  132. package/dist/components/ai-sdk/CodeBlock.d.ts +1 -1
  133. package/dist/components/ai-sdk/CodeBlock.js +1 -1
  134. package/dist/components/ai-sdk/ComposerLink.js +2 -3
  135. package/dist/components/ai-sdk/ConnectedAppCards.d.ts +9 -1
  136. package/dist/components/ai-sdk/ConnectedAppCards.js +28 -21
  137. package/dist/components/ai-sdk/Context.d.ts +7 -3
  138. package/dist/components/ai-sdk/Context.js +7 -17
  139. package/dist/components/ai-sdk/Conversation.d.ts +2 -2
  140. package/dist/components/ai-sdk/Conversation.js +1 -1
  141. package/dist/components/ai-sdk/Goal.d.ts +3 -3
  142. package/dist/components/ai-sdk/Goal.js +3 -3
  143. package/dist/components/ai-sdk/InlineCitation.d.ts +1 -1
  144. package/dist/components/ai-sdk/MediaPreviewCard.d.ts +1 -1
  145. package/dist/components/ai-sdk/MediaPreviewCard.js +1 -1
  146. package/dist/components/ai-sdk/Message.d.ts +2 -2
  147. package/dist/components/ai-sdk/Message.js +12 -3
  148. package/dist/components/ai-sdk/MessageScroller.d.ts +1 -1
  149. package/dist/components/ai-sdk/MessageScroller.js +1 -1
  150. package/dist/components/ai-sdk/MessageScrollerVirtual.d.ts +2 -76
  151. package/dist/components/ai-sdk/MessageScrollerVirtual.js +39 -5
  152. package/dist/components/ai-sdk/Plan.d.ts +1 -1
  153. package/dist/components/ai-sdk/Plan.js +1 -1
  154. package/dist/components/ai-sdk/PromptInput.d.ts +2 -2
  155. package/dist/components/ai-sdk/PromptInput.js +175 -231
  156. package/dist/components/ai-sdk/PromptInputComposerEditor.js +32 -9
  157. package/dist/components/ai-sdk/Queue.d.ts +28 -5
  158. package/dist/components/ai-sdk/Queue.js +20 -5
  159. package/dist/components/ai-sdk/Reasoning.d.ts +1 -1
  160. package/dist/components/ai-sdk/Reasoning.js +5 -5
  161. package/dist/components/ai-sdk/Sources.d.ts +1 -1
  162. package/dist/components/ai-sdk/Sources.js +1 -1
  163. package/dist/components/ai-sdk/Task.d.ts +1 -1
  164. package/dist/components/ai-sdk/Task.js +1 -1
  165. package/dist/components/extension/ChatGptSignInScreen.d.ts +1 -1
  166. package/dist/components/extension/ChatGptSignInScreen.js +1 -1
  167. package/dist/components/extension/CodexModelSelector.d.ts +5 -0
  168. package/dist/components/extension/CodexModelSelector.js +2 -2
  169. package/dist/components/extension/ConversationTabPicker.d.ts +1 -0
  170. package/dist/components/extension/ConversationTabPicker.js +2 -2
  171. package/dist/components/foundations/AlertDialog.d.ts +1 -1
  172. package/dist/components/foundations/AppIcon.d.ts +3 -2
  173. package/dist/components/foundations/Autocomplete.js +6 -1
  174. package/dist/components/foundations/Avatar.d.ts +1 -121
  175. package/dist/components/foundations/Button.d.ts +1 -1
  176. package/dist/components/foundations/Card.d.ts +22 -27
  177. package/dist/components/foundations/Card.js +51 -32
  178. package/dist/components/foundations/Checkbox.js +1 -1
  179. package/dist/components/foundations/CheckboxGroup.d.ts +1 -1
  180. package/dist/components/foundations/Collapsible.d.ts +1 -1
  181. package/dist/components/foundations/Collapsible.js +1 -1
  182. package/dist/components/foundations/Combobox.js +6 -1
  183. package/dist/components/foundations/ContextMenu.js +1 -1
  184. package/dist/components/foundations/Dialog.d.ts +106 -1
  185. package/dist/components/foundations/EmptyState.d.ts +1 -1
  186. package/dist/components/foundations/Field.d.ts +2 -1
  187. package/dist/components/foundations/Fieldset.d.ts +1 -1
  188. package/dist/components/foundations/Form.d.ts +4 -4
  189. package/dist/components/foundations/IconButton.d.ts +1 -1
  190. package/dist/components/foundations/Label.d.ts +1 -1
  191. package/dist/components/foundations/LinkButton.d.ts +2 -2
  192. package/dist/components/foundations/Menubar.js +1 -1
  193. package/dist/components/foundations/Meter.d.ts +1 -1
  194. package/dist/components/foundations/NumberField.d.ts +1 -1
  195. package/dist/components/foundations/ScrollArea.d.ts +1 -1
  196. package/dist/components/foundations/SearchField.d.ts +1 -1
  197. package/dist/components/foundations/SearchField.js +1 -1
  198. package/dist/components/foundations/Select.js +7 -2
  199. package/dist/components/foundations/Separator.d.ts +1 -40
  200. package/dist/components/foundations/Stepper.d.ts +1 -1
  201. package/dist/components/foundations/Stepper.js +1 -1
  202. package/dist/components/foundations/Textarea.d.ts +1 -1
  203. package/dist/components/foundations/Toast.d.ts +5 -1
  204. package/dist/components/foundations/Toast.js +1 -1
  205. package/dist/components/foundations/Toggle.d.ts +70 -1
  206. package/dist/components/foundations/ToggleGroup.d.ts +4 -3
  207. package/dist/components/foundations/ToggleGroup.js +1 -1
  208. package/dist/components/foundations/Toolbar.d.ts +1 -151
  209. package/dist/components/foundations/TransitionSurface.d.ts +1 -1
  210. package/dist/components/foundations/icons.js +1 -1
  211. package/dist/components/general-purpose/ActionGuide.d.ts +10 -26
  212. package/dist/components/general-purpose/ActionGuide.js +4 -18
  213. package/dist/components/general-purpose/AppTopBar.d.ts +4 -2
  214. package/dist/components/general-purpose/Commit.d.ts +2 -2
  215. package/dist/components/general-purpose/Commit.js +2 -2
  216. package/dist/components/general-purpose/EnvironmentVariables.d.ts +2 -2
  217. package/dist/components/general-purpose/EnvironmentVariables.js +2 -2
  218. package/dist/components/general-purpose/FileTree.d.ts +1 -7
  219. package/dist/components/general-purpose/FileTree.js +1 -1
  220. package/dist/components/general-purpose/PricingPlanCard.d.ts +4 -0
  221. package/dist/components/general-purpose/PricingPlanCard.js +2 -2
  222. package/dist/components/general-purpose/PricingUsageCalculator.js +2 -2
  223. package/dist/components/general-purpose/ResizableSidePanel.d.ts +2 -2
  224. package/dist/components/general-purpose/ResponsiveSidebarShell.d.ts +128 -2
  225. package/dist/components/general-purpose/ResponsiveSidebarShell.js +120 -102
  226. package/dist/components/general-purpose/SettingsFormDialog.d.ts +14 -27
  227. package/dist/components/general-purpose/SettingsFormDialog.js +42 -72
  228. package/dist/components/general-purpose/SetupChecklist.d.ts +1 -0
  229. package/dist/components/general-purpose/SetupChecklist.js +76 -1
  230. package/dist/components/general-purpose/Terminal.d.ts +3 -3
  231. package/dist/components/general-purpose/Terminal.js +11 -6
  232. package/dist/components/general-purpose/TestResults.d.ts +23 -11
  233. package/dist/components/general-purpose/TestResults.js +49 -51
  234. package/dist/components/general-purpose/ThemeModeControl.d.ts +2 -0
  235. package/dist/components/general-purpose/ThemeModeControl.js +2 -2
  236. package/dist/components/general-purpose/WebPreview.d.ts +29 -4
  237. package/dist/components/general-purpose/WebPreview.js +39 -14
  238. package/dist/components/nanites/AgentConnection.js +2 -2
  239. package/dist/components/nanites/AgentToolDetail.d.ts +13 -11
  240. package/dist/components/nanites/AgentToolDetail.js +21 -42
  241. package/dist/{copy-button-Dk2vRe9j.js → copy-button-CSDuDfdP.js} +1 -1
  242. package/dist/{copy-button-C0JyjClr.d.ts → copy-button-OUwOdgEm.d.ts} +1 -1
  243. package/dist/mcp-server-mAErsxHU.js +27 -0
  244. package/dist/styles/activity.css +1 -96
  245. package/dist/styles/agent-chat.css +75 -102
  246. package/dist/styles/agent-tool-detail.css +0 -16
  247. package/dist/styles/base.css +1 -1
  248. package/dist/styles/browser-run-panel.css +1 -15
  249. package/dist/styles/button.css +7 -1
  250. package/dist/styles/code-block.css +12 -0
  251. package/dist/styles/composition-motion.css +0 -2
  252. package/dist/styles/employee-chrome.css +43 -0
  253. package/dist/styles/file-tree.css +5 -0
  254. package/dist/styles/index.css +4 -2
  255. package/dist/styles/message.css +2 -10
  256. package/dist/styles/queue.css +71 -0
  257. package/dist/styles/subagent-run.css +122 -6
  258. package/dist/styles/test-results.css +2 -5
  259. package/dist/styles/think-chat-activity.css +13 -0
  260. package/dist/styles/think-chat-tool-panels.css +81 -0
  261. package/dist/styles/think-execution-workbench.css +2 -8
  262. package/dist/styles/think-full-app.css +42 -251
  263. package/dist/styles/{think-routine-library.css → think-routine.css} +64 -80
  264. package/dist/styles/web-preview.css +15 -1
  265. package/dist/utils/mcp-server-catalog.d.ts +1112 -2
  266. package/dist/utils/mcp-server-catalog.js +28 -9
  267. package/dist/utils/structured-code.d.ts +1 -1
  268. package/dist/{workspace-assets-GqsCYxqT.js → workspace-assets-Bg7XhPsk.js} +2 -2
  269. package/package.json +7 -3
  270. package/dist/AgentChat-BLmQghkt.d.ts +0 -327
  271. package/dist/AgentChatStartScreen-Bkv7Avni.d.ts +0 -84
  272. package/dist/AgentMessageParts-C7L-Mv9U.d.ts +0 -46
  273. package/dist/AgentToolRunsContext-jtmveaRE.d.ts +0 -57
  274. package/dist/Dialog-B_FhRWaz.d.ts +0 -107
  275. package/dist/McpConnectorForm-CeYNY0MI.d.ts +0 -39
  276. package/dist/McpPluginCatalog-3qWu8oK1.d.ts +0 -92
  277. package/dist/ResponsiveSidebarShell-BTVPxLJK.d.ts +0 -123
  278. package/dist/SessionCompaction-CmTJFpzj.d.ts +0 -89
  279. package/dist/SetupChecklist-DeTU9YpW.js +0 -77
  280. package/dist/ThinkChat-CwMdEum8.d.ts +0 -185
  281. package/dist/ThinkChat-DiI6hhDP.js +0 -332
  282. package/dist/ThinkChatActivity-B3lGVS-6.d.ts +0 -77
  283. package/dist/ThinkChatContext-COIgzkYp.d.ts +0 -28
  284. package/dist/ThinkRecoveryNotice-DGWr94rk.d.ts +0 -19
  285. package/dist/ThinkThreadPicker-yFz4vvIf.d.ts +0 -91
  286. package/dist/Toggle-DLrIf5YH.d.ts +0 -69
  287. package/dist/WorkspaceLive-DfjH1Ypm.d.ts +0 -61
  288. package/dist/WorkspaceMessageResponse-kJYU8Onj.d.ts +0 -48
  289. package/dist/components/agents-sdk/ThinkFullAppViewSwitch.d.ts +0 -31
  290. package/dist/components/agents-sdk/ThinkFullAppViewSwitch.js +0 -34
  291. package/dist/components/agents-sdk/ThinkRoutineLibrary.d.ts +0 -80
  292. package/dist/components/agents-sdk/ThinkRoutineLibrary.js +0 -159
  293. package/dist/components/agents-sdk/ThinkSidepanel.d.ts +0 -200
  294. package/dist/components/agents-sdk/ThinkSidepanel.js +0 -775
  295. package/dist/mcp-server-7NR24ASj.js +0 -69
  296. package/dist/mcp-server-catalog-C_g7C-9o.d.ts +0 -1108
  297. package/dist/styles/think-sidepanel.css +0 -78
  298. package/dist/think-agent-Cip5KAPj.d.ts +0 -7
  299. package/dist/{icons-CeGfXO21.js → icons-cuEtsgj9.js} +1 -1
@@ -1,67 +1,28 @@
1
- import { replaceComposerTrigger } from "../../utils/composer-link.js";
2
1
  import { t as cx } from "../../class-names-BiMDVpUo.js";
2
+ import { H as RefreshIcon, K as SpinnerIcon, Q as TrashIcon, R as PencilIcon, t as ArchiveIcon } from "../../icons-cuEtsgj9.js";
3
3
  import { ExpansionStateProvider } from "../ai-sdk/ExpansionState.js";
4
- import { B as PlusIcon, H as RefreshIcon, K as SpinnerIcon, Q as TrashIcon, R as PencilIcon, V as QueueIcon, t as ArchiveIcon } from "../../icons-CeGfXO21.js";
5
- import { Button } from "../foundations/Button.js";
6
- import { AgentChatMessageEditor } from "../ai-sdk/AgentChatMessageEditor.js";
7
- import { IconButton } from "../foundations/IconButton.js";
8
- import { Menu } from "../foundations/Menu.js";
9
- import { PromptInput, PromptInputActionAddAttachments, PromptInputActionMenu, PromptInputActionMenuContent, PromptInputActionMenuTrigger, PromptInputAttachments, PromptInputBody, PromptInputButton, PromptInputCommandComposer, PromptInputContextSelector, PromptInputDictation, PromptInputFooter, PromptInputHeader, PromptInputPermissionSelector, PromptInputSubmit, PromptInputTextarea, PromptInputTools, PromptInputTray, composerLinksToReferences, usePromptInputAttachments } from "../ai-sdk/PromptInput.js";
10
- import { AgentChatStartScreen } from "../ai-sdk/AgentChatStartScreen.js";
11
- import { Message, MessageAction, MessageActions, MessageMeta, MessageTimestamp } from "../ai-sdk/Message.js";
4
+ import { Message, MessageAction, MessageActions, MessageCopyAction, MessageMeta, MessageTimestamp } from "../ai-sdk/Message.js";
5
+ import { AgentEventRow, getAgentEvent } from "./AgentEvent.js";
6
+ import { AgentChatQueueProvider, useOptionalAgentChatQueue } from "./AgentChatQueue.js";
12
7
  import { AgentMessageParts } from "../ai-sdk/AgentMessageParts.js";
13
- import { Marker, MarkerContent } from "../foundations/Marker.js";
14
- import { t as CopyButton } from "../../copy-button-Dk2vRe9j.js";
15
- import { Context, ContextContent, ContextContentBody, ContextContentHeader, ContextTrigger, getContextUsage, getContextUsedTokens } from "../ai-sdk/Context.js";
8
+ import { AgentChatMessageEditor } from "../ai-sdk/AgentChatMessageEditor.js";
16
9
  import { VirtualMessageScroller } from "../ai-sdk/MessageScrollerVirtual.js";
17
- import { QueueItem, QueueItemActions, QueueItemContent } from "../ai-sdk/Queue.js";
10
+ import { PromptInput, PromptInputSubmit, PromptInputTray, composerLinksToReferences, usePromptInputController } from "../ai-sdk/PromptInput.js";
11
+ import { Queue, QueueItem, QueueItemAction, QueueItemActions, QueueItemContent, QueueItemIndicator, QueueList } from "../ai-sdk/Queue.js";
12
+ import { PromptInputApproval, getApprovalStateKey, getPendingToolApprovals } from "./PromptInputApproval.js";
18
13
  import { EmptyState } from "../foundations/EmptyState.js";
14
+ import { Marker, MarkerContent } from "../foundations/Marker.js";
19
15
  import { TransitionSurface } from "../foundations/TransitionSurface.js";
20
- import { AgentEventRow, getAgentEvent } from "./AgentEvent.js";
21
- import { PromptInputApproval, getApprovalRequestId, getApprovalStateKey, getPendingToolApprovals } from "./PromptInputApproval.js";
22
16
  import * as React from "react";
23
17
  import { Fragment, jsx, jsxs } from "react/jsx-runtime";
24
- import { isTextUIPart } from "ai";
18
+ import { useRender } from "@base-ui/react/use-render";
19
+ import { mergeProps } from "@base-ui/react/merge-props";
25
20
  import { isCompactionMessage } from "agents/experimental/memory/utils";
21
+ import { isTextUIPart } from "ai";
26
22
  //#region src/components/agents-sdk/AgentChat.tsx
27
- /**
28
- * Agents exports this helper from `agents/sessions` after cloudflare/agents#1896;
29
- * the current 0.19.0 release still publishes it from the experimental path.
30
- * It checks the canonical `compaction_` id prefix used when Session history
31
- * materializes a summary overlay. `UIMessage` is structurally compatible with
32
- * the `SessionMessage` fields it reads, so use the upstream helper directly
33
- * instead of duplicating the prefix contract locally.
34
- */
35
- /**
36
- * Built-in `/compact` entry, present whenever `onCompact` is provided and the
37
- * agent is not mid-turn. Selection is intercepted in `selectComposerCommand`
38
- * before any reference chip or host `onSelect` runs.
39
- */
40
- const COMPACT_SLASH_COMMAND = {
41
- id: "agent-chat:compact",
42
- value: "compact",
43
- label: "compact",
44
- description: "Summarize earlier messages to free up context",
45
- icon: /* @__PURE__ */ jsx(ArchiveIcon, {}),
46
- group: "Conversation",
47
- meta: "Built in"
48
- };
49
- /**
50
- * The affordance for a compaction that is running right now, for the `notice`
51
- * slot. Exported because Think's session frames report the same state from
52
- * outside this component's own `/compact` lifecycle, and one running
53
- * compaction must not read two ways.
54
- */
55
- const compactingNotice = /* @__PURE__ */ jsxs(Fragment, { children: [/* @__PURE__ */ jsx(SpinnerIcon, {}), "Compacting context…"] });
56
- const COMPACTION_NOTICES = {
57
- compacted: "Context compacted. Context usage updates after your next message.",
58
- failed: "Compaction failed — run /compact to try again.",
59
- pending: compactingNotice,
60
- unchanged: "No context was compacted. Recent context is already protected."
61
- };
62
- function observeAgentChatComposer(element) {
23
+ function observeAgentChatDock(element) {
63
24
  if (!element || typeof ResizeObserver === "undefined") return;
64
- const root = element.parentElement;
25
+ const root = element.closest(".agent-chat");
65
26
  let written;
66
27
  let frame = 0;
67
28
  const observer = new ResizeObserver(() => {
@@ -71,7 +32,7 @@ function observeAgentChatComposer(element) {
71
32
  const size = `${element.offsetHeight}px`;
72
33
  if (size === written) return;
73
34
  written = size;
74
- root?.style.setProperty("--agent-chat-composer-size", size);
35
+ root?.style.setProperty("--agent-chat-dock-size", size);
75
36
  });
76
37
  });
77
38
  observer.observe(element);
@@ -80,655 +41,549 @@ function observeAgentChatComposer(element) {
80
41
  observer.disconnect();
81
42
  };
82
43
  }
83
- function getAgentChatMessageTime(message) {
84
- const metadata = message.metadata;
85
- if (!metadata || typeof metadata !== "object" || !("createdAt" in metadata)) return void 0;
86
- const value = metadata.createdAt;
87
- if (!(value instanceof Date) && typeof value !== "number" && typeof value !== "string") return;
88
- const date = value instanceof Date ? value : new Date(value);
89
- return Number.isNaN(date.getTime()) ? void 0 : date;
44
+ const AgentChatContext = React.createContext(null);
45
+ function useAgentChatRuntime() {
46
+ const value = React.useContext(AgentChatContext);
47
+ if (!value) throw new Error("Chat parts must be used inside AgentChat.Root or ThinkChat.Root.");
48
+ return value;
90
49
  }
91
- const EMPTY_PENDING_APPROVALS = [];
92
- const EMPTY_SKIPPED_APPROVAL_IDS = [];
93
- function createApprovalSessionState(thinkStub) {
94
- return {
95
- thinkStub,
96
- skippedApprovalIds: EMPTY_SKIPPED_APPROVAL_IDS,
97
- permissionMode: "bypass"
98
- };
50
+ /** Layout and runtime adapter over the nearest queue owner; connections remain host-owned. */
51
+ function AgentChatRoot({ onSubmit, onStop, onPromptQueued, ...props }) {
52
+ const queue = useOptionalAgentChatQueue();
53
+ const root = /* @__PURE__ */ jsx(AgentChatRuntimeRoot, { ...props });
54
+ return queue ? root : /* @__PURE__ */ jsx(AgentChatQueueProvider, {
55
+ status: props.status ?? "ready",
56
+ onSubmit,
57
+ onStop,
58
+ onPromptQueued,
59
+ children: root
60
+ });
99
61
  }
100
- function AgentChatAttachButton() {
101
- const attachments = usePromptInputAttachments();
102
- return /* @__PURE__ */ jsx(PromptInputButton, {
103
- tooltip: "Add photos or files",
104
- onClick: () => attachments.openFileDialog(),
105
- children: /* @__PURE__ */ jsx(PlusIcon, {})
62
+ function AgentChatRuntimeRoot({ messages, status = "ready", onRegenerate, onEditAndResend, onApprovalResponse, children, className, ref, ...props }) {
63
+ const queue = useOptionalAgentChatQueue();
64
+ if (!queue) throw new Error("AgentChat requires its queue owner.");
65
+ const [announcement, setAnnouncement] = React.useState("");
66
+ const announcementTimer = React.useRef(void 0);
67
+ React.useEffect(() => () => clearTimeout(announcementTimer.current), []);
68
+ const announce = React.useCallback((text) => {
69
+ setAnnouncement("");
70
+ clearTimeout(announcementTimer.current);
71
+ announcementTimer.current = setTimeout(() => setAnnouncement(text), 50);
72
+ }, []);
73
+ const { items: queued, submit, captureSubmit, remove: removeQueued, steer, error: queueError, submissionVersion } = queue;
74
+ const busy = status === "submitted" || status === "streaming";
75
+ const dockRef = React.useRef(null);
76
+ const stop = React.useMemo(() => queue.canStop ? () => {
77
+ queue.stop().catch(() => void 0);
78
+ } : void 0, [queue]);
79
+ const value = React.useMemo(() => ({
80
+ messages,
81
+ status,
82
+ busy,
83
+ submit,
84
+ captureSubmit,
85
+ stop,
86
+ canSubmit: queue.canSubmit,
87
+ onRegenerate,
88
+ onEditAndResend,
89
+ onApprovalResponse,
90
+ queued,
91
+ removeQueued,
92
+ steer,
93
+ queueError,
94
+ submissionVersion,
95
+ dockRef,
96
+ announce
97
+ }), [
98
+ messages,
99
+ status,
100
+ busy,
101
+ submit,
102
+ captureSubmit,
103
+ stop,
104
+ queue.canSubmit,
105
+ onRegenerate,
106
+ onEditAndResend,
107
+ onApprovalResponse,
108
+ queued,
109
+ removeQueued,
110
+ steer,
111
+ queueError,
112
+ submissionVersion,
113
+ announce
114
+ ]);
115
+ return /* @__PURE__ */ jsx(AgentChatContext.Provider, {
116
+ value,
117
+ children: /* @__PURE__ */ jsxs(TransitionSurface, {
118
+ ref,
119
+ variant: "fade",
120
+ className: cx("agent-chat", className),
121
+ "data-recipe": "fill-host",
122
+ ...props,
123
+ children: [children, /* @__PURE__ */ jsx("span", {
124
+ className: "sigvelo-visually-hidden",
125
+ role: "status",
126
+ "aria-live": "polite",
127
+ "aria-atomic": "true",
128
+ children: announcement
129
+ })]
130
+ })
106
131
  });
107
132
  }
108
- function AgentChatAddMenu({ children }) {
109
- if (!children) return /* @__PURE__ */ jsx(AgentChatAttachButton, {});
110
- return /* @__PURE__ */ jsxs(PromptInputActionMenu, { children: [/* @__PURE__ */ jsx(PromptInputActionMenuTrigger, { "aria-label": "Add context" }), /* @__PURE__ */ jsxs(PromptInputActionMenuContent, {
111
- side: "top",
112
- align: "start",
113
- sideOffset: 12,
114
- collisionPadding: 8,
115
- className: "agent-chat__add-menu",
116
- "data-recipe": "composer-command-surface wide-scroll-picker",
117
- children: [/* @__PURE__ */ jsxs(Menu.Group, { children: [/* @__PURE__ */ jsx(Menu.GroupLabel, { children: "Add" }), /* @__PURE__ */ jsx(PromptInputActionAddAttachments, {})] }), children]
118
- })] });
133
+ /** Windowed transcript. Historical rows are never a live region; their disclosure state survives windowing. */
134
+ function AgentChatTranscript({ children, emptyState, className, scrollAnchor }) {
135
+ const { messages, busy } = useAgentChatRuntime();
136
+ return /* @__PURE__ */ jsx(ExpansionStateProvider, { children: /* @__PURE__ */ jsx(VirtualMessageScroller, {
137
+ className: cx("agent-chat__conversation", className),
138
+ items: messages,
139
+ scrollAnchor,
140
+ getItemKey: (message) => message.id,
141
+ emptyState,
142
+ contentProps: {
143
+ role: "log",
144
+ "aria-live": "off",
145
+ "aria-busy": busy,
146
+ className: "agent-chat__transcript-content"
147
+ },
148
+ scrollButtonLabel: "Scroll to latest",
149
+ scrollButtonProps: { className: "agent-chat__scroll-button" },
150
+ renderItem: (message, messageIndex) => children({
151
+ message,
152
+ messageIndex
153
+ })
154
+ }) });
119
155
  }
120
- function AgentChatSubmitAction({ status, onStop, disabled, hasDraft }) {
121
- const attachments = usePromptInputAttachments();
122
- return /* @__PURE__ */ jsx(PromptInputSubmit, {
123
- status,
124
- onStop,
125
- hasContent: hasDraft || attachments.files.length > 0,
126
- disabled
156
+ function AgentChatLoading() {
157
+ return /* @__PURE__ */ jsx("div", {
158
+ className: "agent-chat__transcript-loading",
159
+ role: "status",
160
+ children: /* @__PURE__ */ jsx(EmptyState, {
161
+ icon: /* @__PURE__ */ jsx(SpinnerIcon, {}),
162
+ description: "Loading conversation"
163
+ })
127
164
  });
128
165
  }
129
- function getCopyableResponseText(message) {
130
- return message.parts.filter(isTextUIPart).map((part) => part.text).join("\n\n").trim() || void 0;
166
+ const ChatMessageContext = React.createContext(null);
167
+ function useChatMessage() {
168
+ const value = React.useContext(ChatMessageContext);
169
+ if (!value) throw new Error("Message actions must be used inside AgentChat.Message.");
170
+ return value;
131
171
  }
132
- function AgentChatAssistantActions({ message, responseNumber, showCopy, showRetry, onRegenerate, onCopyStatus }) {
133
- const copyText = getCopyableResponseText(message);
134
- const hasCopy = showCopy && copyText !== void 0;
135
- const hasRetry = showRetry && onRegenerate !== void 0;
136
- const hasActions = hasCopy || hasRetry;
137
- return /* @__PURE__ */ jsxs(MessageActions, {
138
- "aria-label": `Actions for response ${responseNumber}`,
139
- "aria-hidden": hasActions ? void 0 : true,
140
- className: "message__actions--reserved",
141
- children: [hasCopy ? /* @__PURE__ */ jsx(CopyButton, {
142
- className: "message__action",
143
- label: `Copy response ${responseNumber}`,
144
- tooltip: "Copy response",
145
- text: copyText,
146
- size: "xs",
147
- onCopy: () => onCopyStatus(`Response ${responseNumber} copied.`),
148
- onError: () => onCopyStatus(`Could not copy response ${responseNumber}. Try again.`)
149
- }) : null, hasRetry ? /* @__PURE__ */ jsx(MessageAction, {
150
- label: "Retry",
151
- tooltip: "Regenerate response",
152
- size: "xs",
153
- onClick: () => onRegenerate(message.id),
154
- children: /* @__PURE__ */ jsx(RefreshIcon, { size: 14 })
155
- }) : null]
172
+ /** Preserves runtime-authored event/compaction provenance and owns only the local edit lifecycle. */
173
+ function AgentChatMessage({ message, messageIndex, children }) {
174
+ const { onEditAndResend } = useAgentChatRuntime();
175
+ const [editing, setEditing] = React.useState(false);
176
+ const editRef = React.useRef(null);
177
+ const restoreFocus = React.useRef(false);
178
+ React.useLayoutEffect(() => {
179
+ if (!editing && restoreFocus.current) {
180
+ editRef.current?.focus();
181
+ restoreFocus.current = false;
182
+ }
183
+ }, [editing]);
184
+ const value = React.useMemo(() => ({
185
+ message,
186
+ messageIndex,
187
+ editRef,
188
+ startEdit: () => setEditing(true)
189
+ }), [message, messageIndex]);
190
+ if (isCompactionMessage(message)) return /* @__PURE__ */ jsx(Marker, {
191
+ variant: "separator",
192
+ children: /* @__PURE__ */ jsx(MarkerContent, { children: "Context compacted" })
193
+ });
194
+ const event = getAgentEvent(message);
195
+ if (event) return /* @__PURE__ */ jsx(AgentEventRow, {
196
+ message,
197
+ event
198
+ });
199
+ return /* @__PURE__ */ jsx(ChatMessageContext.Provider, {
200
+ value,
201
+ children: /* @__PURE__ */ jsx(Message, {
202
+ from: message.role,
203
+ children: editing && onEditAndResend ? /* @__PURE__ */ jsx(AgentChatMessageEditor, {
204
+ message,
205
+ originalText: editableText(message) ?? "",
206
+ onSubmit: onEditAndResend,
207
+ onCancel: () => {
208
+ restoreFocus.current = true;
209
+ setEditing(false);
210
+ },
211
+ onSuccess: () => setEditing(false)
212
+ }) : children
213
+ })
156
214
  });
157
215
  }
158
- function getEditableUserText(message) {
159
- if (message.role !== "user" || message.parts.length !== 1) return void 0;
216
+ function editableText(message) {
160
217
  const part = message.parts[0];
161
- return isTextUIPart(part) && part.text.trim() ? part.text : void 0;
218
+ return message.role === "user" && message.parts.length === 1 && isTextUIPart(part) && part.text.trim() ? part.text : void 0;
162
219
  }
163
- /** Agents row-size compaction metadata is intentionally handled at the Agents seam. */
164
220
  function isCompactedPart(message, partIndex) {
165
221
  const part = message.parts[partIndex];
166
222
  const metadata = message.metadata;
167
- if (isTextUIPart(part)) return Array.isArray(metadata?.compactedTextParts) && metadata.compactedTextParts.includes(partIndex);
168
- return part !== void 0 && "toolCallId" in part && typeof part.toolCallId === "string" && Array.isArray(metadata?.compactedToolOutputs) && metadata.compactedToolOutputs.includes(part.toolCallId);
223
+ return isTextUIPart(part) ? Array.isArray(metadata?.compactedTextParts) && metadata.compactedTextParts.includes(partIndex) : part !== void 0 && "toolCallId" in part && Array.isArray(metadata?.compactedToolOutputs) && metadata.compactedToolOutputs.includes(part.toolCallId);
169
224
  }
170
- /**
171
- * One transcript row's content, memoized so a streaming delta re-renders only
172
- * the rows whose props changed — in practice the live message. This only
173
- * holds up if the host keeps unchanged message objects and render callbacks
174
- * referentially stable across updates (AI SDK chat state does); see
175
- * "Transcript rendering performance" in docs/think-chat.md.
176
- */
177
- function AgentChatTranscriptRowBodyImpl({ message, messageIndex, status, renderPart, renderMessageAfter, editing, canEdit, editDisabled, onEditAndResend, onStartEdit, onCancelEdit, onFinishEdit, editButtonRef, responseNumber, showAssistantActions, showCopy, showRetry, onRegenerate, onCopyStatus }) {
178
- const messageTime = getAgentChatMessageTime(message);
179
- const userText = getEditableUserText(message);
180
- const agentEvent = getAgentEvent(message);
181
- return /* @__PURE__ */ jsx(Fragment, { children: isCompactionMessage(message) ? /* @__PURE__ */ jsx(Marker, {
182
- variant: "separator",
183
- children: /* @__PURE__ */ jsx(MarkerContent, { children: "Context compacted" })
184
- }) : agentEvent ? /* @__PURE__ */ jsx(AgentEventRow, {
225
+ function AgentChatMessageContent({ message, renderPart }) {
226
+ const { messages, status } = useAgentChatRuntime();
227
+ return /* @__PURE__ */ jsx(MemoizedMessageParts, {
185
228
  message,
186
- event: agentEvent
187
- }) : /* @__PURE__ */ jsx(Message, {
188
- from: message.role,
189
- children: editing && onEditAndResend ? /* @__PURE__ */ jsx(AgentChatMessageEditor, {
190
- message,
191
- originalText: getEditableUserText(message) ?? "",
192
- onSubmit: onEditAndResend,
193
- onCancel: onCancelEdit,
194
- onSuccess: onFinishEdit
195
- }) : /* @__PURE__ */ jsxs(Fragment, { children: [
196
- /* @__PURE__ */ jsx(AgentMessageParts, {
197
- message,
198
- status,
199
- renderPart: (context) => {
200
- const custom = renderPart?.(context);
201
- if (!isCompactedPart(message, context.partIndex)) return custom;
202
- const rendered = custom === void 0 ? context.defaultRender() : custom;
203
- return rendered ? /* @__PURE__ */ jsxs(Fragment, { children: [rendered, /* @__PURE__ */ jsx("div", {
204
- className: "message__compacted",
205
- children: "Output truncated for storage"
206
- })] }) : null;
207
- }
208
- }),
209
- renderMessageAfter?.({
210
- message,
211
- messageIndex
212
- }),
213
- message.role === "user" && (messageTime !== void 0 || userText !== void 0) ? /* @__PURE__ */ jsxs(MessageMeta, { children: [
214
- messageTime ? /* @__PURE__ */ jsx(MessageTimestamp, { date: messageTime }) : null,
215
- userText ? /* @__PURE__ */ jsx(CopyButton, {
216
- className: "message__action",
217
- label: `Copy message ${messageIndex + 1}`,
218
- tooltip: "Copy message",
219
- text: userText,
220
- size: "xs",
221
- onCopy: () => onCopyStatus(`Message ${messageIndex + 1} copied.`),
222
- onError: () => onCopyStatus(`Could not copy message ${messageIndex + 1}. Try again.`)
223
- }) : null,
224
- canEdit && userText ? /* @__PURE__ */ jsx(MessageActions, {
225
- "aria-label": "Message actions",
226
- "aria-hidden": editDisabled || void 0,
227
- "data-unavailable": editDisabled || void 0,
228
- children: /* @__PURE__ */ jsx(MessageAction, {
229
- ref: editButtonRef,
230
- disabled: editDisabled,
231
- label: "Edit message",
232
- tooltip: "Edit and resend",
233
- size: "xs",
234
- onClick: () => onStartEdit(message.id),
235
- children: /* @__PURE__ */ jsx(PencilIcon, {})
236
- })
237
- }) : null
238
- ] }) : null,
239
- showAssistantActions ? /* @__PURE__ */ jsx(AgentChatAssistantActions, {
240
- message,
241
- responseNumber,
242
- showCopy,
243
- showRetry,
244
- onRegenerate,
245
- onCopyStatus
246
- }) : null
247
- ] })
229
+ renderPart,
230
+ status: message.id === messages.at(-1)?.id ? status : "ready"
231
+ });
232
+ }
233
+ function MessageParts({ message, renderPart, status }) {
234
+ return /* @__PURE__ */ jsx(AgentMessageParts, {
235
+ message,
236
+ status,
237
+ renderPart: (context) => {
238
+ const custom = renderPart?.(context);
239
+ if (!isCompactedPart(message, context.partIndex)) return custom;
240
+ const rendered = custom === void 0 ? context.defaultRender() : custom;
241
+ return rendered ? /* @__PURE__ */ jsxs(Fragment, { children: [rendered, /* @__PURE__ */ jsx("div", {
242
+ className: "agent-chat__compacted",
243
+ children: "Output truncated for storage"
244
+ })] }) : null;
245
+ }
246
+ });
247
+ }
248
+ const MemoizedMessageParts = React.memo(MessageParts);
249
+ /** Stable action space for a message; callers choose every action inside it. */
250
+ function AgentChatActions({ children, ...props }) {
251
+ const { message, messageIndex } = useChatMessage();
252
+ const { messages, busy } = useAgentChatRuntime();
253
+ const number = messages.slice(0, messageIndex + 1).filter((m) => m.role === message.role && !isCompactionMessage(m) && !getAgentEvent(m)).length;
254
+ const unavailable = busy && (message.role === "user" ? message.id === messages.findLast((item) => item.role === "user" && !getAgentEvent(item))?.id : message.id === messages.at(-1)?.id);
255
+ const actions = /* @__PURE__ */ jsx(MessageActions, {
256
+ reserveSpace: message.role === "assistant",
257
+ "aria-label": `Actions for ${message.role === "assistant" ? "response" : "message"} ${number}`,
258
+ "data-unavailable": unavailable ? true : void 0,
259
+ "aria-hidden": unavailable ? true : void 0,
260
+ inert: unavailable ? true : void 0,
261
+ ...props,
262
+ children
263
+ });
264
+ return message.role === "user" ? /* @__PURE__ */ jsx(MessageMeta, { children: actions }) : actions;
265
+ }
266
+ function AgentChatCopyAction() {
267
+ const { message, messageIndex } = useChatMessage();
268
+ const { messages, busy, announce } = useAgentChatRuntime();
269
+ const text = message.parts.filter(isTextUIPart).map((part) => part.text).join("\n\n").trim();
270
+ if (!text) return null;
271
+ const label = message.role === "assistant" ? `Copy response ${messages.slice(0, messageIndex + 1).filter((m) => m.role === "assistant" && !isCompactionMessage(m) && !getAgentEvent(m)).length}` : `Copy message ${messageIndex + 1}`;
272
+ return /* @__PURE__ */ jsx(Fragment, { children: /* @__PURE__ */ jsx(MessageCopyAction, {
273
+ label,
274
+ disabled: busy && message.id === messages.at(-1)?.id,
275
+ tooltip: message.role === "assistant" ? "Copy response" : "Copy message",
276
+ text,
277
+ size: "xs",
278
+ onCopy: () => announce(`${label.replace("Copy response", "Response").replace("Copy message", "Message")} copied.`),
279
+ onError: () => announce("Could not copy. Try again.")
248
280
  }) });
249
281
  }
250
- const AgentChatTranscriptRowBody = React.memo(AgentChatTranscriptRowBodyImpl);
251
- /**
252
- * Low-level transcript/composer surface used by `ThinkChat`: props in, no
253
- * transport. Product code that talks to a Cloudflare Think agent should render
254
- * `ThinkChat`; use this directly only for plain AI SDK or read-only messages.
255
- *
256
- * The transcript is always windowed with TanStack Virtual (end-anchored,
257
- * follow-on-append): only the visible rows exist in the DOM, so hours-long
258
- * runs stay cheap. Consequences and the host-side contract:
259
- * - Every message needs a stable `id`; keys must survive prepends and stream
260
- * growth.
261
- * - Keep unchanged message objects referentially stable across updates.
262
- * Structured-cloning the array per delta over a worker/extension boundary
263
- * rebuilds every identity and defeats row memoization — clone once per
264
- * throttled batch instead.
265
- * - Throttle stream deltas before React state (AI SDK
266
- * `experimental_throttle: 50` or equivalent).
267
- * - Bound the data itself: windowing caps DOM size, not JS memory. Truncate
268
- * stored tool output at the buffer (~20k chars) and keep history
269
- * compaction on.
270
- * - Unmount the transcript to hide it; don't `display: none` it — hidden
271
- * rows measure 0 and corrupt the virtualizer's cached heights.
272
- * - Rows unmount off-screen: find-in-page only searches the window;
273
- * disclosure state persists via the built-in `ExpansionStateProvider`
274
- * (pass your own store via a wrapper to survive route remounts), but the
275
- * default `Reasoning` disclosure resets.
276
- * - The transcript is not a screen-reader live region (windowing would
277
- * announce re-inserted old rows as new); announce new messages from a
278
- * host-owned live region if that matters.
279
- */
280
- function AgentChat({ className, messages, status = "ready", onSubmit, showComposer = onSubmit !== void 0, onStop, onPromptQueued, placeholder = "Ask anything...", disabled: composerDisabled, emptyState, loading, startScreen, composerHeader, composerTray, composerTools, slashCommands, onCompact, mentionCommands, contextSelector, composerEndTools, voiceInput, beforeVoiceStart, composerAddMenuItems, notice, onRegenerate, onEditAndResend, onApprovalResponse, thinkStub, approvalsEnabled = true, permissionModeControl, onExecutionSettled, pendingApprovals: durableApprovals = EMPTY_PENDING_APPROVALS, contextWindow, renderPart, renderMessageAfter, showAssistantActions, ref }) {
281
- const disabled = composerDisabled || loading;
282
- const [copyAnnouncement, setCopyAnnouncement] = React.useState("");
283
- const [composerDraft, setComposerDraft] = React.useState("");
284
- const composerInputRef = React.useRef(null);
285
- const restoreComposerFocusAfterApproval = React.useRef(false);
286
- const respondToPendingApproval = React.useCallback((response) => {
287
- restoreComposerFocusAfterApproval.current = true;
288
- return onApprovalResponse?.(response);
289
- }, [onApprovalResponse]);
290
- const handlePendingExecutionSettled = React.useCallback(async () => {
291
- restoreComposerFocusAfterApproval.current = true;
292
- await onExecutionSettled?.();
293
- }, [onExecutionSettled]);
294
- const [pendingPrompts, setPendingPrompts] = React.useState([]);
295
- const [queueHeld, setQueueHeld] = React.useState(false);
296
- const busy = status === "submitted" || status === "streaming";
297
- const wasBusy = React.useRef(busy);
298
- const [compactionState, setCompactionState] = React.useState(null);
299
- const compactionInFlight = React.useRef(false);
300
- const addComposerReference = React.useCallback((reference) => {
301
- setComposerDraft((current) => {
302
- if (composerLinksToReferences(current).some((item) => item.id === reference.id && item.trigger === reference.trigger)) return current;
303
- return replaceComposerTrigger(current, {
304
- id: reference.id,
305
- value: reference.value,
306
- label: reference.label,
307
- href: reference.href,
308
- iconSrc: reference.iconSrc
309
- }, reference.trigger ?? "/");
310
- });
311
- }, []);
312
- const removeComposerReference = React.useCallback((reference) => {
313
- if (!reference.href) return;
314
- setComposerDraft((current) => current.replace(`[${reference.label}](${reference.href})`, "").replace(/\s{2,}/g, " "));
315
- }, []);
316
- const copyAnnouncementTimer = React.useRef(null);
317
- const announceCopyStatus = React.useCallback((message) => {
318
- if (copyAnnouncementTimer.current !== null) window.clearTimeout(copyAnnouncementTimer.current);
319
- setCopyAnnouncement("");
320
- copyAnnouncementTimer.current = window.setTimeout(() => {
321
- setCopyAnnouncement(message);
322
- copyAnnouncementTimer.current = null;
323
- }, 50);
324
- }, []);
325
- React.useEffect(() => () => {
326
- if (copyAnnouncementTimer.current !== null) window.clearTimeout(copyAnnouncementTimer.current);
327
- }, []);
328
- const handleSubmit = React.useCallback((message) => {
329
- const text = message.text || composerDraft;
330
- const references = composerLinksToReferences(text);
331
- const prompt = {
332
- ...message,
333
- text,
334
- ...references.length ? { references } : {}
282
+ function AgentChatRetryAction() {
283
+ const { message } = useChatMessage();
284
+ const { messages, busy, onRegenerate } = useAgentChatRuntime();
285
+ if (!onRegenerate || message.id !== messages.findLast((m) => m.role === "assistant" && !isCompactionMessage(m) && !getAgentEvent(m))?.id) return null;
286
+ return /* @__PURE__ */ jsx(MessageAction, {
287
+ disabled: busy,
288
+ label: "Retry",
289
+ tooltip: "Regenerate response",
290
+ size: "xs",
291
+ onClick: () => onRegenerate(message.id),
292
+ children: /* @__PURE__ */ jsx(RefreshIcon, { size: 14 })
293
+ });
294
+ }
295
+ function AgentChatEditAction() {
296
+ const { message, startEdit, editRef } = useChatMessage();
297
+ const { messages, busy, onEditAndResend } = useAgentChatRuntime();
298
+ if (!onEditAndResend || !editableText(message) || message.id !== messages.findLast((m) => m.role === "user" && !getAgentEvent(m))?.id) return null;
299
+ return /* @__PURE__ */ jsx(MessageAction, {
300
+ ref: editRef,
301
+ disabled: busy,
302
+ label: "Edit message",
303
+ tooltip: "Edit and resend",
304
+ size: "xs",
305
+ onClick: startEdit,
306
+ children: /* @__PURE__ */ jsx(PencilIcon, {})
307
+ });
308
+ }
309
+ function AgentChatTimestamp() {
310
+ const { message } = useChatMessage();
311
+ const metadata = message.metadata;
312
+ if (!metadata || typeof metadata !== "object" || !("createdAt" in metadata)) return null;
313
+ const value = metadata.createdAt;
314
+ if (!(value instanceof Date) && typeof value !== "number" && typeof value !== "string") return null;
315
+ const date = new Date(value);
316
+ return Number.isNaN(date.getTime()) ? null : /* @__PURE__ */ jsx(MessageTimestamp, { date });
317
+ }
318
+ /** Measured bottom surface for notices, queued prompts, approvals and the form. */
319
+ function AgentChatDock({ children, render, ref, ...props }) {
320
+ const { dockRef } = useAgentChatRuntime();
321
+ const observe = React.useCallback((element) => {
322
+ dockRef.current = element;
323
+ return observeAgentChatDock(element);
324
+ }, [dockRef]);
325
+ return useRender({
326
+ defaultTagName: "div",
327
+ render,
328
+ ref: [ref ?? null, observe],
329
+ props: mergeProps({
330
+ className: "agent-chat__dock",
331
+ children: /* @__PURE__ */ jsx("div", {
332
+ className: "agent-chat__dock-content",
333
+ children
334
+ })
335
+ }, props)
336
+ });
337
+ }
338
+ /** Submission adapter only. Compose it inside Dock; the caller owns its inputs and controls. */
339
+ function AgentChatComposer({ children, disabled = false, className, onSubmitCapture, ...props }) {
340
+ const { submit, captureSubmit, canSubmit } = useAgentChatRuntime();
341
+ const submissions = React.useRef(/* @__PURE__ */ new WeakMap());
342
+ return /* @__PURE__ */ jsx(PromptInput, {
343
+ ...props,
344
+ className: cx("agent-chat__composer", className),
345
+ onSubmitCapture: (event) => {
346
+ onSubmitCapture?.(event);
347
+ submissions.current.set(event.nativeEvent, captureSubmit());
348
+ },
349
+ onSubmit: (message, event) => {
350
+ const references = composerLinksToReferences(message.text);
351
+ return (submissions.current.get(event.nativeEvent) ?? submit)(references.length ? {
352
+ ...message,
353
+ references
354
+ } : message);
355
+ },
356
+ inert: disabled || !canSubmit ? true : void 0,
357
+ children
358
+ });
359
+ }
360
+ function AgentChatSubmit({ disabled = false }) {
361
+ const { status, stop, canSubmit } = useAgentChatRuntime();
362
+ const { textInput, attachments } = usePromptInputController();
363
+ return /* @__PURE__ */ jsx(PromptInputSubmit, {
364
+ status,
365
+ onStop: stop,
366
+ disabled: disabled || !canSubmit,
367
+ hasContent: Boolean(textInput.value.trim()) || attachments.files.length > 0
368
+ });
369
+ }
370
+ /** A queue tray aligned with the chat composer. */
371
+ function AgentChatPromptTray({ className, ...props }) {
372
+ return /* @__PURE__ */ jsx(PromptInputTray, {
373
+ ...props,
374
+ side: "top",
375
+ className: cx("agent-chat__prompt-tray", className)
376
+ });
377
+ }
378
+ function AgentChatQueue() {
379
+ const { queued, busy, stop, steer, removeQueued, queueError } = useAgentChatRuntime();
380
+ if (!queued.length && !queueError) return null;
381
+ return /* @__PURE__ */ jsx(AgentChatPromptTray, {
382
+ "data-agent-chat-queue": "",
383
+ children: /* @__PURE__ */ jsxs(Queue, {
384
+ density: "compact",
385
+ children: [queueError ? /* @__PURE__ */ jsx(AgentChatNotice, {
386
+ "data-tone": "danger",
387
+ role: "alert",
388
+ children: queueError
389
+ }) : null, /* @__PURE__ */ jsx(QueueList, {
390
+ "aria-label": "Queued messages",
391
+ children: queued.map((pending) => {
392
+ const label = pending.message.text || "Queued message";
393
+ return /* @__PURE__ */ jsxs(QueueItem, {
394
+ "data-slot": "agent-chat-queued-message",
395
+ children: [
396
+ /* @__PURE__ */ jsx(QueueItemIndicator, {}),
397
+ /* @__PURE__ */ jsx(QueueItemContent, { children: /* @__PURE__ */ jsx("span", {
398
+ "data-slot": "agent-chat-queued-text",
399
+ className: "sigvelo-truncate sigvelo-truncate-grow",
400
+ children: label
401
+ }) }),
402
+ /* @__PURE__ */ jsxs(QueueItemActions, {
403
+ persistent: true,
404
+ children: [!busy || stop ? /* @__PURE__ */ jsx(QueueItemAction, {
405
+ "aria-label": `${busy ? "Steer" : "Send"} queued message: ${label}`,
406
+ onClick: () => {
407
+ steer(pending.id).catch(() => void 0);
408
+ },
409
+ children: busy ? "Steer" : "Send now"
410
+ }) : null, /* @__PURE__ */ jsx(QueueItemAction, {
411
+ "aria-label": `Remove queued message: ${label}`,
412
+ onClick: () => removeQueued(pending.id),
413
+ children: /* @__PURE__ */ jsx(TrashIcon, {})
414
+ })]
415
+ })
416
+ ]
417
+ }, pending.id);
418
+ })
419
+ })]
420
+ })
421
+ });
422
+ }
423
+ function AgentChatNotice({ children, ...props }) {
424
+ return /* @__PURE__ */ jsx("div", {
425
+ className: "agent-chat__notice",
426
+ role: "status",
427
+ "aria-atomic": "true",
428
+ ...props,
429
+ children
430
+ });
431
+ }
432
+ const EMPTY_APPROVAL_ITEMS = [];
433
+ const EMPTY_SKIPPED_IDS = [];
434
+ const ApprovalsContext = React.createContext(null);
435
+ function useAgentChatApprovals() {
436
+ const value = React.useContext(ApprovalsContext);
437
+ if (!value) throw new Error("Approval parts require AgentChat.Approvals or ThinkChat.Approvals.");
438
+ return value;
439
+ }
440
+ function AgentChatApprovals({ thinkStub, pendingApprovals = [], onExecutionSettled, children }) {
441
+ const { messages, onApprovalResponse, dockRef } = useAgentChatRuntime();
442
+ const [skipped, setSkipped] = React.useState({
443
+ source: thinkStub,
444
+ ids: []
445
+ });
446
+ const ids = skipped.source === thinkStub ? skipped.ids : EMPTY_SKIPPED_IDS;
447
+ const items = [...getPendingToolApprovals(messages, { pausedExecutions: Boolean(thinkStub) }).filter((part) => (part.state !== "approval-requested" || onApprovalResponse) && !ids.includes(getApprovalStateKey(part) ?? "")).map((part) => ({ part })), ...pendingApprovals.filter((a) => a.source === "action" && !ids.includes(a.executionId)).map((approval) => ({ approval }))];
448
+ const pending = items.length ? items : EMPTY_APPROVAL_ITEMS;
449
+ const restore = React.useRef(false);
450
+ const active = React.useRef(false);
451
+ React.useLayoutEffect(() => {
452
+ active.current = true;
453
+ return () => {
454
+ active.current = false;
455
+ restore.current = false;
335
456
  };
336
- setQueueHeld(false);
337
- setComposerDraft("");
338
- setCompactionState(null);
339
- if (busy || pendingPrompts.length && !queueHeld) {
340
- setPendingPrompts((current) => [...current, {
341
- id: crypto.randomUUID(),
342
- message: prompt
343
- }]);
344
- onPromptQueued?.();
345
- return;
346
- }
347
- return onSubmit?.(prompt);
348
- }, [
349
- busy,
350
- composerDraft,
351
- onPromptQueued,
352
- onSubmit,
353
- pendingPrompts.length,
354
- queueHeld
355
- ]);
356
- const handleStop = onStop ? () => {
357
- setQueueHeld(true);
358
- onStop();
359
- } : void 0;
360
- React.useEffect(() => {
361
- const becameReady = wasBusy.current && !busy;
362
- wasBusy.current = busy;
363
- const next = pendingPrompts[0];
364
- if (!becameReady || queueHeld || !next || !onSubmit) return;
365
- setPendingPrompts((current) => current.slice(1));
366
- onSubmit(next.message);
367
- }, [
368
- busy,
369
- onSubmit,
370
- pendingPrompts,
371
- queueHeld
372
- ]);
373
- const selectComposerCommand = React.useCallback((command, trigger) => {
374
- if (trigger === "/" && onCompact && command.id === COMPACT_SLASH_COMMAND.id) {
375
- if (compactionInFlight.current || busy) return;
376
- compactionInFlight.current = true;
377
- setCompactionState("pending");
378
- setComposerDraft("");
379
- Promise.resolve().then(onCompact).then((result) => {
380
- compactionInFlight.current = false;
381
- setCompactionState(result?.compacted ? "compacted" : "unchanged");
382
- }, (error) => {
383
- compactionInFlight.current = false;
384
- console.error("Manual compaction failed", error);
385
- setCompactionState("failed");
386
- });
387
- return;
457
+ }, []);
458
+ const pendingCount = React.useRef(pending.length);
459
+ const restoreFocus = React.useCallback(() => {
460
+ if (active.current && !pendingCount.current && restore.current) {
461
+ restore.current = false;
462
+ dockRef.current?.querySelector("textarea,[contenteditable=\"true\"]")?.focus();
388
463
  }
389
- const nextDraft = replaceComposerTrigger(composerDraft, command, trigger);
390
- const nextReferences = composerLinksToReferences(nextDraft);
391
- (trigger === "@" ? mentionCommands : slashCommands)?.onSelect?.(command, {
392
- value: nextDraft,
393
- references: nextReferences,
394
- setValue: setComposerDraft,
395
- clear: () => setComposerDraft(""),
396
- addReference: addComposerReference,
397
- removeReference: removeComposerReference
464
+ }, [dockRef]);
465
+ React.useLayoutEffect(() => {
466
+ pendingCount.current = pending.length;
467
+ restoreFocus();
468
+ }, [pending.length, restoreFocus]);
469
+ const skip = React.useCallback(() => {
470
+ const item = pending[0];
471
+ if (!item) return;
472
+ restore.current = true;
473
+ const id = "part" in item ? getApprovalStateKey(item.part) : item.approval.executionId;
474
+ if (id) setSkipped({
475
+ source: thinkStub,
476
+ ids: [...ids, id]
398
477
  });
399
478
  }, [
400
- addComposerReference,
401
- busy,
402
- composerDraft,
403
- mentionCommands,
404
- onCompact,
405
- removeComposerReference,
406
- slashCommands
479
+ pending,
480
+ thinkStub,
481
+ ids
407
482
  ]);
408
- const [approvalSession, setApprovalSession] = React.useState(() => createApprovalSessionState(thinkStub));
409
- const approvalSessionIsCurrent = approvalSession.thinkStub === thinkStub;
410
- const skippedApprovalIds = approvalSessionIsCurrent ? approvalSession.skippedApprovalIds : EMPTY_SKIPPED_APPROVAL_IDS;
411
- const localPermissionMode = approvalSessionIsCurrent ? approvalSession.permissionMode : "bypass";
412
- const permissionMode = permissionModeControl?.value ?? localPermissionMode;
413
- const updateApprovalSession = React.useCallback((update) => {
414
- setApprovalSession((previous) => update(previous.thinkStub === thinkStub ? previous : createApprovalSessionState(thinkStub)));
415
- }, [thinkStub]);
416
- const setPermissionMode = React.useCallback((next) => {
417
- if (permissionModeControl) {
418
- permissionModeControl.onChange(next);
419
- return;
483
+ const settled = React.useCallback(async () => {
484
+ if (active.current) {
485
+ restore.current = true;
486
+ restoreFocus();
420
487
  }
421
- updateApprovalSession((current) => ({
422
- ...current,
423
- permissionMode: next
424
- }));
425
- }, [permissionModeControl, updateApprovalSession]);
426
- React.useLayoutEffect(() => {
427
- setApprovalSession((previous) => previous.thinkStub === thinkStub ? previous : createApprovalSessionState(thinkStub));
428
- }, [thinkStub]);
429
- const skippedApprovalIdSet = React.useMemo(() => new Set(skippedApprovalIds), [skippedApprovalIds]);
430
- const pendingApprovalItems = React.useMemo(() => {
431
- if (!approvalsEnabled) return [];
432
- return [...getPendingToolApprovals(messages, { pausedExecutions: Boolean(thinkStub) }).filter((part) => {
433
- if (part.state === "approval-requested" && !onApprovalResponse) return false;
434
- const id = getApprovalStateKey(part);
435
- return Boolean(id) && !skippedApprovalIdSet.has(id);
436
- }).map((part) => ({ part })), ...thinkStub ? durableApprovals.filter((approval) => approval.source === "action" && !skippedApprovalIdSet.has(approval.executionId)).map((approval) => ({ approval })) : []];
437
- }, [
438
- approvalsEnabled,
439
- durableApprovals,
440
- messages,
441
- onApprovalResponse,
442
- skippedApprovalIdSet,
488
+ await onExecutionSettled?.();
489
+ }, [onExecutionSettled, restoreFocus]);
490
+ const value = React.useMemo(() => ({
491
+ pending,
492
+ skip,
493
+ settled,
494
+ thinkStub
495
+ }), [
496
+ pending,
497
+ skip,
498
+ settled,
443
499
  thinkStub
444
500
  ]);
445
- const approvalsWired = approvalsEnabled && Boolean(onApprovalResponse || thinkStub);
446
- const autoApprovedIds = React.useRef({
447
- thinkStub,
448
- ids: /* @__PURE__ */ new Set()
501
+ return /* @__PURE__ */ jsx(ApprovalsContext.Provider, {
502
+ value,
503
+ children
449
504
  });
450
- const respondToApproval = React.useEffectEvent((id) => {
451
- onApprovalResponse?.({
452
- id,
453
- approved: true
454
- });
455
- });
456
- const notifyExecutionSettled = React.useEffectEvent(() => {
457
- onExecutionSettled?.();
505
+ }
506
+ function AgentChatApproval() {
507
+ const { onApprovalResponse } = useAgentChatRuntime();
508
+ const { pending, skip, settled, thinkStub } = useAgentChatApprovals();
509
+ const first = pending[0];
510
+ if (!first) return null;
511
+ return /* @__PURE__ */ jsx(PromptInputApproval, {
512
+ part: "part" in first ? first.part : void 0,
513
+ approval: "approval" in first ? first.approval : void 0,
514
+ count: pending.length,
515
+ thinkStub,
516
+ onRespond: onApprovalResponse ? async (response) => {
517
+ await onApprovalResponse(response);
518
+ await settled();
519
+ } : void 0,
520
+ onExecutionSettled: settled,
521
+ onSkip: skip
458
522
  });
459
- React.useLayoutEffect(() => {
460
- if (autoApprovedIds.current.thinkStub === thinkStub) return;
461
- autoApprovedIds.current = {
462
- thinkStub,
463
- ids: /* @__PURE__ */ new Set()
464
- };
465
- }, [thinkStub]);
523
+ }
524
+ const compactingNotice = /* @__PURE__ */ jsxs(Fragment, { children: [/* @__PURE__ */ jsx(SpinnerIcon, {}), "Compacting context…"] });
525
+ const COMPACTION_NOTICES = {
526
+ pending: compactingNotice,
527
+ compacted: "Context compacted. Context usage updates after your next message.",
528
+ unchanged: "No context was compacted. Recent context is already protected.",
529
+ failed: "Compaction failed — run /compact to try again."
530
+ };
531
+ const COMPACTION_COMMAND = {
532
+ id: "agent-chat:compact",
533
+ value: "compact",
534
+ label: "compact",
535
+ description: "Summarize earlier messages to free up context",
536
+ icon: /* @__PURE__ */ jsx(ArchiveIcon, {}),
537
+ group: "Conversation",
538
+ meta: "Built in"
539
+ };
540
+ /** Explicit command action controller; callers put its command in the catalog and its notice where appropriate. */
541
+ function useAgentChatCompaction(onCompact) {
542
+ const { busy, submissionVersion } = useAgentChatRuntime();
543
+ const { textInput } = usePromptInputController();
544
+ const [state, setState] = React.useState(null);
466
545
  React.useEffect(() => {
467
- if (permissionModeControl || permissionMode !== "bypass") return;
468
- for (const item of pendingApprovalItems) {
469
- const id = "part" in item ? getApprovalRequestId(item.part) : item.approval.executionId;
470
- const key = "part" in item ? getApprovalStateKey(item.part) : item.approval.executionId;
471
- if (!id || !key || autoApprovedIds.current.ids.has(key)) continue;
472
- autoApprovedIds.current.ids.add(key);
473
- if ("part" in item && item.part.state === "approval-requested") respondToApproval(id);
474
- else if (thinkStub) thinkStub.approveExecution(id).finally(() => {
475
- notifyExecutionSettled();
476
- });
477
- }
546
+ setState(null);
547
+ }, [submissionVersion]);
548
+ const inFlight = React.useRef(false);
549
+ const run = React.useCallback(() => {
550
+ if (busy || inFlight.current) return;
551
+ inFlight.current = true;
552
+ setState("pending");
553
+ textInput.clear();
554
+ Promise.resolve().then(onCompact).then((result) => setState(result.compacted ? "compacted" : "unchanged"), () => setState("failed")).finally(() => {
555
+ inFlight.current = false;
556
+ });
478
557
  }, [
479
- pendingApprovalItems,
480
- permissionMode,
481
- permissionModeControl,
482
- thinkStub
558
+ busy,
559
+ onCompact,
560
+ textInput
483
561
  ]);
484
- const pendingApproval = !permissionModeControl && permissionMode === "bypass" ? void 0 : pendingApprovalItems[0];
485
- const pendingApprovalKey = pendingApproval ? "part" in pendingApproval ? getApprovalStateKey(pendingApproval.part) : pendingApproval.approval.executionId : void 0;
486
- React.useLayoutEffect(() => {
487
- if (pendingApprovalKey || !restoreComposerFocusAfterApproval.current) return;
488
- restoreComposerFocusAfterApproval.current = false;
489
- composerInputRef.current?.focus();
490
- }, [pendingApprovalKey]);
491
- const contextUsage = contextWindow ? getContextUsage(messages) : void 0;
492
- const newestAssistantIndex = messages.findLastIndex((message) => message.role === "assistant" && !isCompactionMessage(message) && !getAgentEvent(message));
493
- const lastAssistantIndex = onRegenerate && status !== "streaming" && status !== "submitted" ? newestAssistantIndex : -1;
494
- const lastUserIndex = onEditAndResend ? messages.findLastIndex((message) => message.role === "user" && !getAgentEvent(message)) : -1;
495
- const [editingMessageId, setEditingMessageId] = React.useState();
496
- const restoreEditFocus = React.useRef(false);
497
- const editButtonRef = React.useRef(null);
498
- const handleStartEdit = React.useCallback((messageId) => {
499
- restoreEditFocus.current = false;
500
- setEditingMessageId(messageId);
501
- }, []);
502
- const handleCancelEdit = React.useCallback(() => {
503
- restoreEditFocus.current = true;
504
- setEditingMessageId(void 0);
505
- }, []);
506
- const handleFinishEdit = React.useCallback(() => {
507
- restoreEditFocus.current = false;
508
- setEditingMessageId(void 0);
509
- }, []);
510
- let assistantResponseCount = 0;
511
- const assistantResponseNumbers = messages.map((message) => {
512
- if (message.role !== "assistant" || isCompactionMessage(message) || getAgentEvent(message)) return 0;
513
- assistantResponseCount += 1;
514
- return assistantResponseCount;
515
- });
516
- React.useLayoutEffect(() => {
517
- if (editingMessageId || !restoreEditFocus.current) return;
518
- editButtonRef.current?.focus();
519
- restoreEditFocus.current = false;
520
- }, [editingMessageId]);
521
- const transcriptRowProps = (message, messageIndex) => ({
522
- message,
523
- messageIndex,
524
- status: messageIndex === messages.length - 1 ? status : "ready",
525
- renderPart,
526
- renderMessageAfter,
527
- editing: editingMessageId === message.id,
528
- canEdit: messageIndex === lastUserIndex,
529
- editDisabled: disabled || busy,
530
- onEditAndResend,
531
- onStartEdit: handleStartEdit,
532
- onCancelEdit: handleCancelEdit,
533
- onFinishEdit: handleFinishEdit,
534
- editButtonRef,
535
- responseNumber: assistantResponseNumbers[messageIndex] ?? 0,
536
- showAssistantActions: message.role === "assistant" && (showAssistantActions?.({
537
- message,
538
- messageIndex
539
- }) ?? true),
540
- showCopy: messageIndex !== newestAssistantIndex || status !== "streaming" && status !== "submitted",
541
- showRetry: messageIndex === lastAssistantIndex,
542
- onRegenerate,
543
- onCopyStatus: announceCopyStatus
544
- });
545
- const composer = showComposer ? /* @__PURE__ */ jsxs("div", {
546
- ref: observeAgentChatComposer,
547
- className: "agent-chat__composer",
548
- children: [
549
- /* @__PURE__ */ jsx("div", {
550
- className: "agent-chat__notice",
551
- role: "status",
552
- "aria-atomic": "true",
553
- children: notice ?? (compactionState ? COMPACTION_NOTICES[compactionState] : null)
554
- }),
555
- composerTray || pendingPrompts.length ? /* @__PURE__ */ jsxs(PromptInputTray, {
556
- side: "top",
557
- className: "agent-chat__queued",
558
- children: [composerTray, pendingPrompts.length ? /* @__PURE__ */ jsx("ul", {
559
- className: "agent-chat__queued-list",
560
- "aria-label": "Queued messages",
561
- children: pendingPrompts.map((pending) => {
562
- const messageText = pending.message.text || "Queued message";
563
- return /* @__PURE__ */ jsxs(QueueItem, {
564
- className: "agent-chat__queued-message",
565
- children: [
566
- /* @__PURE__ */ jsx("span", {
567
- className: "agent-chat__queued-indicator",
568
- "aria-hidden": "true",
569
- children: /* @__PURE__ */ jsx(QueueIcon, {})
570
- }),
571
- /* @__PURE__ */ jsx(QueueItemContent, {
572
- className: "agent-chat__queued-content",
573
- children: /* @__PURE__ */ jsx("span", {
574
- className: "agent-chat__queued-text sigvelo-truncate sigvelo-truncate-grow",
575
- children: messageText
576
- })
577
- }),
578
- /* @__PURE__ */ jsxs(QueueItemActions, {
579
- className: "agent-chat__queued-actions",
580
- children: [busy && onStop ? /* @__PURE__ */ jsx(Button, {
581
- className: "agent-chat__queued-action",
582
- "aria-label": `Steer queued message: ${messageText}`,
583
- color: "neutral",
584
- size: "xs",
585
- variant: "ghost",
586
- onClick: () => {
587
- setPendingPrompts((current) => [pending, ...current.filter((item) => item.id !== pending.id)]);
588
- setQueueHeld(false);
589
- onStop();
590
- },
591
- children: "Steer"
592
- }) : null, /* @__PURE__ */ jsx(IconButton, {
593
- className: "agent-chat__queued-action agent-chat__queued-remove",
594
- color: "neutral",
595
- label: `Remove queued message: ${messageText}`,
596
- size: "xs",
597
- variant: "ghost",
598
- onClick: () => setPendingPrompts((current) => current.filter((item) => item.id !== pending.id)),
599
- children: /* @__PURE__ */ jsx(TrashIcon, {})
600
- })]
601
- })
602
- ]
603
- }, pending.id);
604
- })
605
- }) : null]
606
- }) : null,
607
- /* @__PURE__ */ jsx(PromptInput, {
608
- multiple: true,
609
- onSubmit: handleSubmit,
610
- children: pendingApproval ? /* @__PURE__ */ jsx(PromptInputApproval, {
611
- part: "part" in pendingApproval ? pendingApproval.part : void 0,
612
- approval: "approval" in pendingApproval ? pendingApproval.approval : void 0,
613
- count: pendingApprovalItems.length,
614
- onRespond: onApprovalResponse ? respondToPendingApproval : void 0,
615
- thinkStub,
616
- onExecutionSettled: handlePendingExecutionSettled,
617
- onSkip: () => {
618
- restoreComposerFocusAfterApproval.current = true;
619
- const id = "part" in pendingApproval ? getApprovalStateKey(pendingApproval.part) : pendingApproval.approval.executionId;
620
- if (id) updateApprovalSession((current) => ({
621
- ...current,
622
- skippedApprovalIds: [...current.skippedApprovalIds, id]
623
- }));
624
- }
625
- }) : /* @__PURE__ */ jsxs(Fragment, { children: [
626
- composerHeader ? /* @__PURE__ */ jsx(PromptInputHeader, { children: composerHeader }) : null,
627
- /* @__PURE__ */ jsx(PromptInputAttachments, {}),
628
- /* @__PURE__ */ jsx(PromptInputBody, { children: slashCommands || mentionCommands || onCompact ? /* @__PURE__ */ jsx(PromptInputCommandComposer, {
629
- ref: composerInputRef,
630
- "aria-label": "Message",
631
- placeholder,
632
- disabled,
633
- commands: onCompact && !busy ? [COMPACT_SLASH_COMMAND, ...slashCommands?.items ?? []] : slashCommands?.items ?? [],
634
- mentionCommands: mentionCommands?.items,
635
- value: composerDraft,
636
- onValueChange: setComposerDraft,
637
- onCommandSelect: selectComposerCommand
638
- }) : /* @__PURE__ */ jsx(PromptInputTextarea, {
639
- ref: composerInputRef,
640
- "aria-label": "Message",
641
- placeholder,
642
- disabled,
643
- value: composerDraft,
644
- onChange: (event) => setComposerDraft(event.currentTarget.value)
645
- }) }),
646
- /* @__PURE__ */ jsxs(PromptInputFooter, { children: [/* @__PURE__ */ jsxs(PromptInputTools, { children: [
647
- /* @__PURE__ */ jsx(AgentChatAddMenu, { children: composerAddMenuItems }),
648
- contextSelector ? /* @__PURE__ */ jsx(PromptInputContextSelector, { ...contextSelector }) : null,
649
- approvalsWired ? /* @__PURE__ */ jsx(PromptInputPermissionSelector, {
650
- value: permissionMode,
651
- onValueChange: setPermissionMode
652
- }) : null,
653
- composerTools
654
- ] }), /* @__PURE__ */ jsxs("div", {
655
- className: "prompt-input__footer-end",
656
- children: [
657
- composerEndTools,
658
- voiceInput ? /* @__PURE__ */ jsx(PromptInputDictation, {
659
- voice: voiceInput,
660
- beforeStart: beforeVoiceStart,
661
- disabled
662
- }) : null,
663
- contextWindow ? /* @__PURE__ */ jsxs(Context, {
664
- usedTokens: getContextUsedTokens(contextUsage),
665
- maxTokens: contextWindow.maxTokens,
666
- usage: contextUsage,
667
- modelId: contextWindow.modelId,
668
- children: [/* @__PURE__ */ jsx(ContextTrigger, {}), /* @__PURE__ */ jsxs(ContextContent, { children: [/* @__PURE__ */ jsx(ContextContentHeader, {}), /* @__PURE__ */ jsx(ContextContentBody, {})] })]
669
- }) : null,
670
- /* @__PURE__ */ jsx(AgentChatSubmitAction, {
671
- status,
672
- onStop: handleStop,
673
- disabled,
674
- hasDraft: Boolean(composerDraft.trim())
675
- })
676
- ]
677
- })] })
678
- ] })
679
- })
680
- ]
681
- }) : null;
682
- const emptyRow = emptyState ?? /* @__PURE__ */ jsx(EmptyState, {
683
- title: "Start a conversation",
684
- description: "Ask the agent to inspect, plan, or build."
685
- });
686
- const showsStartScreen = !loading && messages.length === 0 && showComposer && startScreen !== false && (startScreen !== void 0 || emptyState === void 0);
687
- const startScreenProps = startScreen && typeof startScreen === "object" ? startScreen : void 0;
688
- return /* @__PURE__ */ jsxs(TransitionSurface, {
689
- ref,
690
- variant: "fade",
691
- className: cx("agent-chat", className),
692
- "data-recipe": "fill-host",
693
- "data-composer-hidden": showComposer ? void 0 : "",
694
- children: [
695
- /* @__PURE__ */ jsx("span", {
696
- className: "message__copy-status sigvelo-visually-hidden",
697
- role: "status",
698
- "aria-atomic": "true",
699
- children: copyAnnouncement
700
- }),
701
- loading ? /* @__PURE__ */ jsx("div", {
702
- className: "agent-chat__transcript-loading",
703
- role: "status",
704
- children: /* @__PURE__ */ jsx(EmptyState, {
705
- icon: /* @__PURE__ */ jsx(SpinnerIcon, {}),
706
- description: "Loading conversation"
707
- })
708
- }) : showsStartScreen ? /* @__PURE__ */ jsx(AgentChatStartScreen, {
709
- ...startScreenProps,
710
- composer
711
- }) : /* @__PURE__ */ jsx(ExpansionStateProvider, { children: /* @__PURE__ */ jsx(VirtualMessageScroller, {
712
- className: "agent-chat__conversation",
713
- items: messages,
714
- getItemKey: (message) => message.id,
715
- emptyState: /* @__PURE__ */ jsx("div", {
716
- className: "conversation__empty-row",
717
- children: emptyRow
718
- }),
719
- contentProps: {
720
- role: "log",
721
- "aria-live": "off",
722
- "aria-busy": status === "streaming" || status === "submitted",
723
- className: "agent-chat__transcript-content"
724
- },
725
- scrollButtonLabel: "Scroll to latest",
726
- scrollButtonProps: { className: "agent-chat__scroll-button" },
727
- renderItem: (message, messageIndex) => /* @__PURE__ */ jsx(AgentChatTranscriptRowBody, { ...transcriptRowProps(message, messageIndex) })
728
- }) }),
729
- showsStartScreen ? null : composer
730
- ]
731
- });
562
+ return {
563
+ command: busy ? void 0 : COMPACTION_COMMAND,
564
+ run,
565
+ notice: state ? COMPACTION_NOTICES[state] : null
566
+ };
732
567
  }
568
+ const AgentChat = {
569
+ Root: AgentChatRoot,
570
+ Transcript: AgentChatTranscript,
571
+ Message: AgentChatMessage,
572
+ MessageContent: AgentChatMessageContent,
573
+ Actions: AgentChatActions,
574
+ CopyAction: AgentChatCopyAction,
575
+ RetryAction: AgentChatRetryAction,
576
+ EditAction: AgentChatEditAction,
577
+ Timestamp: AgentChatTimestamp,
578
+ Dock: AgentChatDock,
579
+ Composer: AgentChatComposer,
580
+ Submit: AgentChatSubmit,
581
+ PromptTray: AgentChatPromptTray,
582
+ Queue: AgentChatQueue,
583
+ Notice: AgentChatNotice,
584
+ Loading: AgentChatLoading,
585
+ Approvals: AgentChatApprovals,
586
+ Approval: AgentChatApproval
587
+ };
733
588
  //#endregion
734
- export { AgentChat, compactingNotice };
589
+ export { AgentChat, AgentChatActions, AgentChatApproval, AgentChatApprovals, AgentChatComposer, AgentChatCopyAction, AgentChatDock, AgentChatEditAction, AgentChatLoading, AgentChatMessage, AgentChatMessageContent, AgentChatNotice, AgentChatPromptTray, AgentChatQueue, AgentChatRetryAction, AgentChatRoot, AgentChatSubmit, AgentChatTimestamp, AgentChatTranscript, compactingNotice, useAgentChatApprovals, useAgentChatCompaction, useAgentChatRuntime };