@datalayer/agent-runtimes 1.0.2 → 1.0.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 (615) hide show
  1. package/README.md +1 -1
  2. package/lib/Agent.js +2 -2
  3. package/lib/AgentLexical.d.ts +1 -12
  4. package/lib/AgentLexical.js +3 -14
  5. package/lib/AgentNotebook.js +3 -3
  6. package/lib/App.js +2 -2
  7. package/lib/{components/chat/components → agents}/AgentDetails.d.ts +13 -2
  8. package/lib/{components/chat/components → agents}/AgentDetails.js +6 -12
  9. package/lib/api/agents.d.ts +47 -0
  10. package/lib/api/agents.js +106 -0
  11. package/lib/api/context.d.ts +17 -0
  12. package/lib/api/context.js +45 -0
  13. package/lib/api/evals.d.ts +27 -0
  14. package/lib/api/evals.js +63 -0
  15. package/lib/api/events.d.ts +17 -0
  16. package/lib/api/events.js +93 -0
  17. package/lib/{components/chat → api}/handler.js +1 -1
  18. package/lib/api/index.d.ts +15 -0
  19. package/lib/api/index.js +20 -0
  20. package/lib/api/notifications.d.ts +39 -0
  21. package/lib/api/notifications.js +103 -0
  22. package/lib/api/output.d.ts +28 -0
  23. package/lib/api/output.js +64 -0
  24. package/lib/api/tool-approvals.d.ts +62 -0
  25. package/lib/api/tool-approvals.js +145 -0
  26. package/lib/{components/chat/components → chat}/Chat.d.ts +24 -15
  27. package/lib/{components/chat/components → chat}/Chat.js +16 -16
  28. package/lib/{components/chat/components → chat}/ChatFloating.d.ts +17 -9
  29. package/lib/{components/chat/components → chat}/ChatFloating.js +17 -9
  30. package/lib/{components/chat/components → chat}/ChatInline.d.ts +2 -2
  31. package/lib/{components/chat/components → chat}/ChatInline.js +8 -6
  32. package/lib/{components/chat/components → chat}/ChatPopupStandalone.d.ts +3 -4
  33. package/lib/{components/chat/components → chat}/ChatPopupStandalone.js +6 -6
  34. package/lib/{components/chat/components → chat}/ChatSidebar.d.ts +14 -5
  35. package/lib/{components/chat/components → chat}/ChatSidebar.js +48 -26
  36. package/lib/{components/chat/components → chat}/ChatStandalone.d.ts +3 -4
  37. package/lib/{components/chat/components → chat}/ChatStandalone.js +5 -5
  38. package/lib/chat/base/ChatBase.d.ts +6 -0
  39. package/lib/chat/base/ChatBase.js +1287 -0
  40. package/lib/chat/display/EmptyState.d.ts +27 -0
  41. package/lib/chat/display/EmptyState.js +41 -0
  42. package/lib/{components/chat/components/elements → chat/display}/FloatingBrandButton.d.ts +1 -1
  43. package/lib/{components/chat/components/elements → chat/display}/FloatingBrandButton.js +1 -1
  44. package/lib/{components/chat/components/elements → chat/display}/PoweredByTag.d.ts +1 -1
  45. package/lib/{components/chat/components/elements → chat/header}/ChatHeader.d.ts +1 -4
  46. package/lib/{components/chat/components/elements → chat/header}/ChatHeader.js +1 -1
  47. package/lib/chat/header/ChatHeaderBase.d.ts +38 -0
  48. package/lib/chat/header/ChatHeaderBase.js +83 -0
  49. package/lib/chat/index.d.ts +66 -0
  50. package/lib/chat/index.js +74 -0
  51. package/lib/chat/indicators/McpStatusIndicator.d.ts +9 -0
  52. package/lib/chat/indicators/McpStatusIndicator.js +128 -0
  53. package/lib/chat/indicators/SandboxStatusIndicator.d.ts +10 -0
  54. package/lib/chat/indicators/SandboxStatusIndicator.js +175 -0
  55. package/lib/chat/indicators/index.d.ts +17 -0
  56. package/lib/chat/indicators/index.js +19 -0
  57. package/lib/chat/messages/ChatMessageList.d.ts +49 -0
  58. package/lib/chat/messages/ChatMessageList.js +319 -0
  59. package/lib/{components/chat/components/elements → chat/messages}/ChatMessages.d.ts +2 -2
  60. package/lib/{components/chat/components/elements → chat/messages}/ChatMessages.js +6 -4
  61. package/lib/{components/chat/components → chat}/parts/DynamicToolPart.d.ts +1 -1
  62. package/lib/{components/chat/components/elements → chat/parts}/MessagePart.d.ts +1 -1
  63. package/lib/{components/chat/components/elements → chat/parts}/MessagePart.js +4 -4
  64. package/lib/{components/chat/components → chat}/parts/ReasoningPart.js +1 -1
  65. package/lib/{components/chat/components → chat}/parts/TextPart.d.ts +1 -1
  66. package/lib/{components/chat/components → chat}/parts/ToolPart.js +1 -1
  67. package/lib/{components/chat/components → chat}/parts/index.d.ts +2 -1
  68. package/lib/{components/chat/components → chat}/parts/index.js +2 -1
  69. package/lib/chat/prompt/InputFooter.d.ts +43 -0
  70. package/lib/chat/prompt/InputFooter.js +135 -0
  71. package/lib/chat/prompt/InputPrompt.d.ts +60 -0
  72. package/lib/chat/prompt/InputPrompt.js +83 -0
  73. package/lib/chat/prompt/InputPromptFooter.d.ts +25 -0
  74. package/lib/chat/prompt/InputPromptFooter.js +15 -0
  75. package/lib/chat/prompt/InputPromptHeader.d.ts +15 -0
  76. package/lib/chat/prompt/InputPromptHeader.js +15 -0
  77. package/lib/chat/prompt/InputPromptLexical.d.ts +16 -0
  78. package/lib/chat/prompt/InputPromptLexical.js +122 -0
  79. package/lib/chat/prompt/InputPromptText.d.ts +24 -0
  80. package/lib/chat/prompt/InputPromptText.js +66 -0
  81. package/lib/chat/prompt/index.d.ts +11 -0
  82. package/lib/chat/prompt/index.js +15 -0
  83. package/lib/{components/chat/components → chat}/styles/streamdownStyles.d.ts +1 -1
  84. package/lib/chat/tools/ToolApprovalBanner.d.ts +31 -0
  85. package/lib/chat/tools/ToolApprovalBanner.js +62 -0
  86. package/lib/{components/chat/components/elements → chat/tools}/ToolApprovalDialog.js +1 -1
  87. package/lib/{components/chat/components/display → chat/tools}/ToolCallDisplay.d.ts +13 -4
  88. package/lib/{components/chat/components/display → chat/tools}/ToolCallDisplay.js +18 -8
  89. package/lib/chat/tools/index.d.ts +8 -0
  90. package/lib/{components/chat/components/display → chat/tools}/index.js +3 -1
  91. package/lib/chat/usage/TokenUsageBar.d.ts +8 -0
  92. package/lib/chat/usage/TokenUsageBar.js +213 -0
  93. package/lib/client/AgentsMixin.d.ts +169 -0
  94. package/lib/client/AgentsMixin.js +279 -0
  95. package/lib/client/index.d.ts +6 -0
  96. package/lib/client/index.js +10 -0
  97. package/lib/components/NotificationEventCard.d.ts +8 -0
  98. package/lib/components/NotificationEventCard.js +152 -0
  99. package/lib/components/OutputCard.d.ts +8 -0
  100. package/lib/components/OutputCard.js +80 -0
  101. package/lib/components/ToolApprovalCard.d.ts +33 -0
  102. package/lib/components/ToolApprovalCard.js +60 -0
  103. package/lib/components/index.d.ts +3 -7
  104. package/lib/components/index.js +3 -4
  105. package/lib/{components → config}/AgentConfiguration.d.ts +43 -21
  106. package/lib/{components → config}/AgentConfiguration.js +48 -28
  107. package/lib/config/index.d.ts +2 -0
  108. package/lib/config/index.js +1 -0
  109. package/lib/{components/chat/components → context}/ContextInspector.js +38 -8
  110. package/lib/{components/chat/components → context}/ContextPanel.js +27 -6
  111. package/lib/context/CostTracker.d.ts +37 -0
  112. package/lib/context/CostTracker.js +124 -0
  113. package/lib/context/TokenUsageChart.d.ts +10 -0
  114. package/lib/context/TokenUsageChart.js +288 -0
  115. package/lib/examples/A2UiComponentGalleryExample.d.ts +20 -0
  116. package/lib/examples/A2UiComponentGalleryExample.js +568 -0
  117. package/lib/examples/A2UiContactCardExample.d.ts +21 -0
  118. package/lib/examples/A2UiContactCardExample.js +432 -0
  119. package/lib/examples/A2UiRestaurantExample.d.ts +11 -3
  120. package/lib/examples/A2UiRestaurantExample.js +63 -98
  121. package/lib/examples/A2UiViewerExample.d.ts +21 -0
  122. package/lib/examples/A2UiViewerExample.js +563 -0
  123. package/lib/examples/AgUiAgenticExample.js +3 -3
  124. package/lib/examples/AgUiBackendToolRenderingExample.js +3 -3
  125. package/lib/examples/{AgUiHaikuGenUIExample.d.ts → AgUiHaikuGenUiExample.d.ts} +4 -4
  126. package/lib/examples/{AgUiHaikuGenUIExample.js → AgUiHaikuGenUiExample.js} +7 -7
  127. package/lib/examples/AgUiHumanInTheLoopExample.js +3 -3
  128. package/lib/examples/AgUiSharedStateExample.js +3 -3
  129. package/lib/examples/{AgUiToolsBasedGenUIExample.d.ts → AgUiToolsBasedGenUiExample.d.ts} +4 -4
  130. package/lib/examples/{AgUiToolsBasedGenUIExample.js → AgUiToolsBasedGenUiExample.js} +7 -7
  131. package/lib/examples/AgentCheckpointsExample.d.ts +19 -0
  132. package/lib/examples/AgentCheckpointsExample.js +506 -0
  133. package/lib/examples/AgentCodemodeExample.d.ts +14 -0
  134. package/lib/examples/AgentCodemodeExample.js +262 -0
  135. package/lib/examples/AgentEvalsExample.d.ts +14 -0
  136. package/lib/examples/AgentEvalsExample.js +216 -0
  137. package/lib/examples/AgentGuardrailsExample.d.ts +14 -0
  138. package/lib/examples/AgentGuardrailsExample.js +218 -0
  139. package/lib/examples/AgentMemoryExample.d.ts +14 -0
  140. package/lib/examples/AgentMemoryExample.js +234 -0
  141. package/lib/examples/AgentMonitoringExample.d.ts +13 -0
  142. package/lib/examples/AgentMonitoringExample.js +311 -0
  143. package/lib/examples/AgentNotificationsExample.d.ts +14 -0
  144. package/lib/examples/AgentNotificationsExample.js +273 -0
  145. package/lib/examples/AgentOtelExample.d.ts +25 -0
  146. package/lib/examples/AgentOtelExample.js +281 -0
  147. package/lib/examples/AgentOutputsExample.d.ts +14 -0
  148. package/lib/examples/AgentOutputsExample.js +211 -0
  149. package/lib/examples/AgentSandboxExample.d.ts +17 -0
  150. package/lib/examples/AgentSandboxExample.js +496 -0
  151. package/lib/examples/AgentSkillsExample.d.ts +3 -0
  152. package/lib/examples/AgentSkillsExample.js +290 -0
  153. package/lib/examples/AgentToolApprovalsExample.d.ts +3 -0
  154. package/lib/examples/AgentToolApprovalsExample.js +672 -0
  155. package/lib/examples/AgentTriggersExample.d.ts +14 -0
  156. package/lib/examples/AgentTriggersExample.js +523 -0
  157. package/lib/examples/{AgentRuntimeFormExample.d.ts → AgentspecExample.d.ts} +3 -4
  158. package/lib/examples/{AgentRuntimeFormExample.js → AgentspecExample.js} +92 -34
  159. package/lib/examples/{JupyterCellExample.js → CellSimpleExample.js} +1 -1
  160. package/lib/examples/{AgentRuntimeCustomExample.js → ChatCustomExample.js} +3 -3
  161. package/lib/examples/{AgentRuntimeChatExample.js → ChatExample.js} +4 -4
  162. package/lib/examples/{AgentRuntimeStandaloneExample.js → ChatStandaloneExample.js} +2 -2
  163. package/lib/examples/CopilotKitLexicalExample.d.ts +3 -14
  164. package/lib/examples/CopilotKitLexicalExample.js +4 -15
  165. package/lib/examples/CopilotKitNotebookExample.js +4 -6
  166. package/lib/examples/DatalayerNotebookExample.js +2 -2
  167. package/lib/examples/{AgentRuntimeLexical2Example.d.ts → Lexical2Example.d.ts} +2 -13
  168. package/lib/examples/{AgentRuntimeLexical2Example.js → Lexical2Example.js} +8 -17
  169. package/lib/examples/{AgentRuntimeLexicalExample.d.ts → LexicalExample.d.ts} +1 -12
  170. package/lib/examples/{AgentRuntimeLexicalExample.js → LexicalExample.js} +28 -27
  171. package/lib/examples/{AgentRuntimeLexicalSidebarExample.d.ts → LexicalSidebarExample.d.ts} +2 -13
  172. package/lib/examples/{AgentRuntimeLexicalSidebarExample.js → LexicalSidebarExample.js} +6 -18
  173. package/lib/examples/{AgentRuntimeNotebookExample.js → NotebookExample.js} +14 -10
  174. package/lib/examples/{AgentRuntimeNotebookSidebarExample.js → NotebookSidebarExample.js} +5 -8
  175. package/lib/examples/{JupyterNotebookExample.js → NotebookSimpleExample.js} +2 -2
  176. package/lib/examples/ag-ui/weather/InlineWeatherCard.js +1 -1
  177. package/lib/examples/components/ExampleWrapper.d.ts +12 -0
  178. package/lib/examples/components/ExampleWrapper.js +16 -0
  179. package/lib/examples/components/Header.d.ts +2 -2
  180. package/lib/examples/components/HeaderControls.js +1 -1
  181. package/lib/examples/components/LexicalEditor.d.ts +1 -12
  182. package/lib/examples/components/LexicalEditor.js +1 -12
  183. package/lib/examples/components/MainContent.d.ts +4 -11
  184. package/lib/examples/components/MainContent.js +6 -60
  185. package/lib/examples/components/index.d.ts +1 -0
  186. package/lib/examples/components/index.js +1 -0
  187. package/lib/examples/example-selector.d.ts +1 -1
  188. package/lib/examples/example-selector.js +35 -22
  189. package/lib/examples/index.d.ts +26 -13
  190. package/lib/examples/index.js +26 -12
  191. package/lib/examples/main.d.ts +6 -0
  192. package/lib/examples/main.js +20 -43
  193. package/lib/examples/utils/examplesStore.d.ts +4 -0
  194. package/lib/examples/{stores → utils}/examplesStore.js +1 -1
  195. package/lib/examples/utils/notebooks/Empty.ipynb.json +33 -0
  196. package/lib/examples/utils/notebooks/NotebookExample2.ipynb.json +48 -0
  197. package/lib/examples/utils/themeStore.d.ts +8 -0
  198. package/lib/examples/utils/themeStore.js +14 -0
  199. package/lib/extensions/A2UIExtension.d.ts +65 -0
  200. package/lib/extensions/A2UIExtension.js +202 -0
  201. package/lib/{components/chat/extensions → extensions}/ExtensionRegistry.d.ts +2 -3
  202. package/lib/{components/chat/extensions → extensions}/ExtensionRegistry.js +0 -2
  203. package/lib/{components/chat/extensions → extensions}/MCPUIExtension.d.ts +2 -2
  204. package/lib/{components/chat/extensions → extensions}/MCPUIExtension.js +1 -1
  205. package/lib/extensions/index.d.ts +9 -0
  206. package/lib/{components/chat/extensions → extensions}/index.js +2 -2
  207. package/lib/hooks/index.d.ts +33 -16
  208. package/lib/hooks/index.js +33 -16
  209. package/lib/hooks/useAIAgentsWebSocket.d.ts +29 -0
  210. package/lib/hooks/useAIAgentsWebSocket.js +136 -0
  211. package/lib/hooks/{useAGUI.d.ts → useAgUi.d.ts} +2 -2
  212. package/lib/hooks/{useAGUI.js → useAgUi.js} +2 -2
  213. package/lib/hooks/useAgents.d.ts +150 -11
  214. package/lib/hooks/useAgents.js +623 -61
  215. package/lib/hooks/{useAgentStore.d.ts → useAgentsCatalog.d.ts} +3 -8
  216. package/lib/hooks/{useAgentStore.js → useAgentsCatalog.js} +9 -3
  217. package/lib/hooks/useAgentsRegistry.d.ts +10 -0
  218. package/lib/hooks/useAgentsRegistry.js +20 -0
  219. package/lib/hooks/useAgentsService.d.ts +22 -0
  220. package/lib/hooks/useAgentsService.js +146 -0
  221. package/lib/hooks/useChat.d.ts +2 -2
  222. package/lib/hooks/useChat.js +14 -8
  223. package/lib/hooks/useCheckpoints.d.ts +176 -0
  224. package/lib/hooks/useCheckpoints.js +466 -0
  225. package/lib/hooks/useConfig.d.ts +11 -0
  226. package/lib/hooks/useConfig.js +46 -0
  227. package/lib/hooks/useContextSnapshot.d.ts +11 -0
  228. package/lib/hooks/useContextSnapshot.js +44 -0
  229. package/lib/hooks/useMonitoring.d.ts +24 -0
  230. package/lib/hooks/useMonitoring.js +111 -0
  231. package/lib/hooks/useNotifications.d.ts +67 -0
  232. package/lib/hooks/useNotifications.js +208 -0
  233. package/lib/hooks/useSandbox.d.ts +12 -0
  234. package/lib/hooks/useSandbox.js +49 -0
  235. package/lib/hooks/useSkills.d.ts +13 -0
  236. package/lib/hooks/useSkills.js +46 -0
  237. package/lib/hooks/useToolApprovals.d.ts +45 -0
  238. package/lib/hooks/useToolApprovals.js +126 -0
  239. package/lib/hooks/useTools.d.ts +4 -4
  240. package/lib/hooks/useTools.js +2 -2
  241. package/lib/hooks/{useVercelChat.d.ts → useVercelAI.d.ts} +3 -3
  242. package/lib/hooks/{useVercelChat.js → useVercelAI.js} +2 -2
  243. package/lib/{components/chat/components → identity}/AgentIdentity.d.ts +1 -1
  244. package/lib/{components/chat/components → identity}/AgentIdentity.js +4 -3
  245. package/lib/identity/index.d.ts +1 -0
  246. package/lib/identity/index.js +2 -0
  247. package/lib/index.d.ts +4 -3
  248. package/lib/index.js +3 -2
  249. package/lib/{components/chat/inference → inference}/BaseInferenceProvider.d.ts +3 -3
  250. package/lib/{components/chat/inference → inference}/DatalayerInferenceProvider.d.ts +3 -3
  251. package/lib/{components/chat/inference → inference}/DatalayerInferenceProvider.js +1 -1
  252. package/lib/{components/chat/inference → inference}/SelfHostedInferenceProvider.d.ts +2 -2
  253. package/lib/{components/chat/inference → inference}/SelfHostedInferenceProvider.js +1 -1
  254. package/lib/{components/chat/inference → inference}/index.d.ts +1 -1
  255. package/lib/{components/chat/inference → inference}/index.js +1 -1
  256. package/lib/lexical/ChatInlinePlugin.d.ts +1 -1
  257. package/lib/lexical/ChatInlinePlugin.js +1 -1
  258. package/lib/{components → mcp}/McpServerManager.d.ts +1 -2
  259. package/lib/mcp/index.d.ts +1 -0
  260. package/lib/{specs/agents/codeai → mcp}/index.js +1 -1
  261. package/lib/{components/chat/middleware → middleware}/MiddlewarePipeline.d.ts +3 -3
  262. package/lib/{components/chat/middleware → middleware}/index.d.ts +1 -1
  263. package/lib/{components/chat/middleware → middleware}/index.js +1 -1
  264. package/lib/{components/chat/protocols → protocols}/A2AAdapter.d.ts +6 -6
  265. package/lib/{components/chat/protocols → protocols}/A2AAdapter.js +3 -3
  266. package/lib/{components/chat/protocols → protocols}/ACPAdapter.d.ts +6 -6
  267. package/lib/{components/chat/protocols → protocols}/ACPAdapter.js +4 -4
  268. package/lib/{components/chat/protocols → protocols}/AGUIAdapter.d.ts +14 -6
  269. package/lib/{components/chat/protocols → protocols}/AGUIAdapter.js +72 -10
  270. package/lib/{components/chat/protocols → protocols}/BaseProtocolAdapter.d.ts +6 -6
  271. package/lib/{components/chat/protocols → protocols}/BaseProtocolAdapter.js +1 -1
  272. package/lib/{components/chat/protocols → protocols}/VercelAIAdapter.d.ts +31 -7
  273. package/lib/protocols/VercelAIAdapter.js +682 -0
  274. package/lib/{components/chat/protocols → protocols}/index.d.ts +1 -2
  275. package/lib/{components/chat/protocols → protocols}/index.js +1 -1
  276. package/lib/specs/agents/agents.d.ts +54 -0
  277. package/lib/specs/agents/{mocks/agents.js → agents.js} +1144 -799
  278. package/lib/specs/agents/index.js +14 -9
  279. package/lib/specs/envvars.d.ts +11 -19
  280. package/lib/specs/envvars.js +42 -21
  281. package/lib/specs/evals.d.ts +20 -0
  282. package/lib/specs/evals.js +133 -0
  283. package/lib/specs/events.d.ts +18 -0
  284. package/lib/specs/events.js +182 -0
  285. package/lib/specs/frontendTools.d.ts +14 -0
  286. package/lib/specs/frontendTools.js +53 -0
  287. package/lib/specs/guardrails.d.ts +22 -0
  288. package/lib/specs/guardrails.js +391 -0
  289. package/lib/specs/index.d.ts +15 -2
  290. package/lib/specs/index.js +15 -2
  291. package/lib/specs/mcpServers.d.ts +13 -11
  292. package/lib/specs/mcpServers.js +82 -28
  293. package/lib/specs/memory.d.ts +34 -0
  294. package/lib/specs/memory.js +99 -0
  295. package/lib/specs/models.d.ts +21 -34
  296. package/lib/specs/models.js +61 -41
  297. package/lib/specs/notifications.d.ts +17 -0
  298. package/lib/specs/notifications.js +187 -0
  299. package/lib/specs/outputs.d.ts +19 -0
  300. package/lib/specs/outputs.js +112 -0
  301. package/lib/specs/skills.d.ts +7 -16
  302. package/lib/specs/skills.js +89 -12
  303. package/lib/specs/teams/index.d.ts +17 -0
  304. package/lib/specs/teams/index.js +37 -0
  305. package/lib/specs/teams/teams.d.ts +27 -0
  306. package/lib/specs/teams/teams.js +1120 -0
  307. package/lib/specs/tools.d.ts +15 -0
  308. package/lib/specs/tools.js +83 -0
  309. package/lib/specs/triggers.d.ts +15 -0
  310. package/lib/specs/triggers.js +117 -0
  311. package/lib/stores/agentsStore.d.ts +123 -0
  312. package/lib/stores/agentsStore.js +270 -0
  313. package/lib/{components/chat/store → stores}/chatStore.d.ts +3 -2
  314. package/lib/{components/chat/store → stores}/chatStore.js +2 -2
  315. package/lib/{components/chat/store → stores}/conversationStore.d.ts +1 -1
  316. package/lib/{components/chat/store → stores}/conversationStore.js +1 -1
  317. package/lib/{components/chat/store → stores}/index.d.ts +3 -2
  318. package/lib/{components/chat/store → stores}/index.js +3 -2
  319. package/lib/{components/chat/tools → tools}/ToolExecutor.d.ts +2 -2
  320. package/lib/{components/chat/tools → tools}/ToolExecutor.js +1 -1
  321. package/lib/tools/adapters/agent-runtimes/AgentRuntimesToolAdapter.d.ts +1 -1
  322. package/lib/tools/adapters/agent-runtimes/lexicalHooks.d.ts +14 -10
  323. package/lib/tools/adapters/agent-runtimes/lexicalHooks.js +31 -21
  324. package/lib/tools/adapters/agent-runtimes/notebookHooks.d.ts +1 -1
  325. package/lib/tools/index.d.ts +3 -0
  326. package/lib/tools/index.js +3 -7
  327. package/lib/types/a2a.d.ts +39 -0
  328. package/lib/types/acp.d.ts +21 -0
  329. package/lib/types/ag-ui.d.ts +25 -0
  330. package/lib/types/agents-lifecycle.d.ts +36 -0
  331. package/lib/types/agents.d.ts +80 -0
  332. package/lib/types/agents.js +22 -0
  333. package/lib/types/agentspecs.d.ts +90 -0
  334. package/lib/{components/chat/components/base/ChatBase.d.ts → types/chat.d.ts} +59 -99
  335. package/lib/types/checkpoints.d.ts +32 -0
  336. package/lib/types/checkpoints.js +5 -0
  337. package/lib/types/config.d.ts +67 -0
  338. package/lib/{runtime/types.js → types/config.js} +2 -2
  339. package/lib/types/connection.d.ts +31 -0
  340. package/lib/types/connection.js +5 -0
  341. package/lib/types/context.d.ts +67 -0
  342. package/lib/types/context.js +5 -0
  343. package/lib/types/cost.d.ts +42 -0
  344. package/lib/types/cost.js +5 -0
  345. package/lib/types/envvars.d.ts +21 -0
  346. package/lib/types/envvars.js +5 -0
  347. package/lib/types/evals.d.ts +66 -0
  348. package/lib/types/evals.js +5 -0
  349. package/lib/types/events.d.ts +49 -0
  350. package/lib/types/events.js +5 -0
  351. package/lib/types/eventspecs.d.ts +39 -0
  352. package/lib/types/eventspecs.js +5 -0
  353. package/lib/types/examples.d.ts +31 -0
  354. package/lib/types/examples.js +5 -0
  355. package/lib/{components/chat/types → types}/execution.d.ts +10 -1
  356. package/lib/{components/chat/types/extension.d.ts → types/extensions.d.ts} +3 -3
  357. package/lib/types/guardrails.d.ts +106 -0
  358. package/lib/types/guardrails.js +5 -0
  359. package/lib/types/index.d.ts +36 -2
  360. package/lib/types/index.js +35 -2
  361. package/lib/{components/chat/types → types}/inference.d.ts +3 -3
  362. package/lib/types/inference.js +5 -0
  363. package/lib/types/mcp.d.ts +117 -0
  364. package/lib/types/mcp.js +27 -0
  365. package/lib/types/memory.d.ts +23 -0
  366. package/lib/types/memory.js +5 -0
  367. package/lib/{components/chat/types/message.d.ts → types/messages.d.ts} +20 -1
  368. package/lib/{components/chat/types → types}/middleware.d.ts +3 -3
  369. package/lib/types/models.d.ts +63 -0
  370. package/lib/types/models.js +5 -0
  371. package/lib/types/notifications.d.ts +85 -0
  372. package/lib/types/notifications.js +5 -0
  373. package/lib/types/outputs.d.ts +51 -0
  374. package/lib/types/outputs.js +5 -0
  375. package/lib/{components/chat/types → types}/protocol.d.ts +37 -99
  376. package/lib/types/protocol.js +5 -0
  377. package/lib/types/sandbox.d.ts +27 -0
  378. package/lib/types/sandbox.js +24 -0
  379. package/lib/types/skills.d.ts +74 -0
  380. package/lib/types/skills.js +5 -0
  381. package/lib/types/teams.d.ts +133 -0
  382. package/lib/types/teams.js +5 -0
  383. package/lib/types/tool-approvals.d.ts +39 -0
  384. package/lib/types/tool-approvals.js +5 -0
  385. package/lib/{components/chat/types/tool.d.ts → types/tools.d.ts} +59 -4
  386. package/lib/types/triggers.d.ts +48 -0
  387. package/lib/types/triggers.js +5 -0
  388. package/lib/types/usage.d.ts +36 -0
  389. package/lib/types/usage.js +5 -0
  390. package/lib/utils/index.d.ts +1 -0
  391. package/lib/utils/index.js +5 -0
  392. package/lib/utils/utils.d.ts +60 -0
  393. package/lib/utils/utils.js +205 -0
  394. package/package.json +13 -14
  395. package/scripts/codegen/__pycache__/generate_agents.cpython-313.pyc +0 -0
  396. package/scripts/codegen/__pycache__/generate_envvars.cpython-313.pyc +0 -0
  397. package/scripts/codegen/__pycache__/generate_evals.cpython-313.pyc +0 -0
  398. package/scripts/codegen/__pycache__/generate_guardrails.cpython-313.pyc +0 -0
  399. package/scripts/codegen/__pycache__/generate_mcp_servers.cpython-313.pyc +0 -0
  400. package/scripts/codegen/__pycache__/generate_memory.cpython-313.pyc +0 -0
  401. package/scripts/codegen/__pycache__/generate_models.cpython-313.pyc +0 -0
  402. package/scripts/codegen/__pycache__/generate_notifications.cpython-313.pyc +0 -0
  403. package/scripts/codegen/__pycache__/generate_outputs.cpython-313.pyc +0 -0
  404. package/scripts/codegen/__pycache__/generate_skills.cpython-313.pyc +0 -0
  405. package/scripts/codegen/__pycache__/generate_teams.cpython-313.pyc +0 -0
  406. package/scripts/codegen/__pycache__/generate_tools.cpython-313.pyc +0 -0
  407. package/scripts/codegen/__pycache__/generate_triggers.cpython-313.pyc +0 -0
  408. package/scripts/codegen/__pycache__/versioning.cpython-313.pyc +0 -0
  409. package/scripts/codegen/generate_agents.py +373 -60
  410. package/scripts/codegen/generate_envvars.py +36 -35
  411. package/scripts/codegen/generate_evals.py +279 -0
  412. package/scripts/codegen/generate_events.py +312 -0
  413. package/scripts/codegen/generate_frontend_tools.py +266 -0
  414. package/scripts/codegen/generate_guardrails.py +475 -0
  415. package/scripts/codegen/generate_mcp_servers.py +36 -9
  416. package/scripts/codegen/generate_memory.py +468 -0
  417. package/scripts/codegen/generate_models.py +22 -46
  418. package/scripts/codegen/generate_notifications.py +309 -0
  419. package/scripts/codegen/generate_outputs.py +267 -0
  420. package/scripts/codegen/generate_skills.py +108 -51
  421. package/scripts/codegen/generate_teams.py +922 -0
  422. package/scripts/codegen/generate_tools.py +326 -0
  423. package/scripts/codegen/generate_triggers.py +295 -0
  424. package/scripts/codegen/versioning.py +53 -0
  425. package/lib/components/chat/components/base/ChatBase.js +0 -2242
  426. package/lib/components/chat/components/base/InputPrompt.d.ts +0 -42
  427. package/lib/components/chat/components/base/InputPrompt.js +0 -131
  428. package/lib/components/chat/components/display/index.d.ts +0 -6
  429. package/lib/components/chat/components/index.d.ts +0 -26
  430. package/lib/components/chat/components/index.js +0 -39
  431. package/lib/components/chat/extensions/A2UIExtension.d.ts +0 -87
  432. package/lib/components/chat/extensions/A2UIExtension.js +0 -312
  433. package/lib/components/chat/extensions/index.d.ts +0 -10
  434. package/lib/components/chat/index.d.ts +0 -61
  435. package/lib/components/chat/index.js +0 -76
  436. package/lib/components/chat/protocols/VercelAIAdapter.js +0 -315
  437. package/lib/components/chat/tools/index.d.ts +0 -8
  438. package/lib/components/chat/tools/index.js +0 -11
  439. package/lib/components/chat/types/index.d.ts +0 -12
  440. package/lib/components/chat/types/index.js +0 -17
  441. package/lib/components/sparklines/Sparklines.d.ts +0 -16
  442. package/lib/components/sparklines/Sparklines.js +0 -65
  443. package/lib/components/sparklines/SparklinesLine.d.ts +0 -8
  444. package/lib/components/sparklines/SparklinesLine.js +0 -37
  445. package/lib/components/sparklines/dataProcessing.d.ts +0 -25
  446. package/lib/components/sparklines/dataProcessing.js +0 -35
  447. package/lib/components/sparklines/index.d.ts +0 -4
  448. package/lib/components/sparklines/index.js +0 -7
  449. package/lib/components/sparklines/types.d.ts +0 -36
  450. package/lib/examples/stores/examplesStore.d.ts +0 -5
  451. package/lib/examples/stores/notebooks/Empty.ipynb.json +0 -33
  452. package/lib/examples/stores/notebooks/NotebookExample2.ipynb.json +0 -48
  453. package/lib/examples/stores/themeStore.d.ts +0 -33
  454. package/lib/examples/stores/themeStore.js +0 -38
  455. package/lib/hooks/useAgentRuntimes.d.ts +0 -350
  456. package/lib/hooks/useAgentRuntimes.js +0 -78
  457. package/lib/hooks/useKeyboardShortcuts.d.ts +0 -47
  458. package/lib/hooks/useKeyboardShortcuts.js +0 -153
  459. package/lib/hooks/useMobile.d.ts +0 -1
  460. package/lib/hooks/useMobile.js +0 -19
  461. package/lib/hooks/useNotebookAIAgent.d.ts +0 -8
  462. package/lib/hooks/useNotebookAIAgent.js +0 -73
  463. package/lib/renderers/a2ui/components/A2UIRenderer.d.ts +0 -7
  464. package/lib/renderers/a2ui/components/A2UIRenderer.js +0 -102
  465. package/lib/renderers/a2ui/components/SurfaceRenderer.d.ts +0 -7
  466. package/lib/renderers/a2ui/components/SurfaceRenderer.js +0 -101
  467. package/lib/renderers/a2ui/components/content/AudioPlayer.d.ts +0 -9
  468. package/lib/renderers/a2ui/components/content/AudioPlayer.js +0 -38
  469. package/lib/renderers/a2ui/components/content/Divider.d.ts +0 -9
  470. package/lib/renderers/a2ui/components/content/Divider.js +0 -35
  471. package/lib/renderers/a2ui/components/content/Icon.d.ts +0 -9
  472. package/lib/renderers/a2ui/components/content/Icon.js +0 -110
  473. package/lib/renderers/a2ui/components/content/Image.d.ts +0 -9
  474. package/lib/renderers/a2ui/components/content/Image.js +0 -61
  475. package/lib/renderers/a2ui/components/content/Text.d.ts +0 -9
  476. package/lib/renderers/a2ui/components/content/Text.js +0 -64
  477. package/lib/renderers/a2ui/components/content/Video.d.ts +0 -9
  478. package/lib/renderers/a2ui/components/content/Video.js +0 -37
  479. package/lib/renderers/a2ui/components/content/index.d.ts +0 -6
  480. package/lib/renderers/a2ui/components/content/index.js +0 -25
  481. package/lib/renderers/a2ui/components/index.d.ts +0 -5
  482. package/lib/renderers/a2ui/components/index.js +0 -24
  483. package/lib/renderers/a2ui/components/interactive/Button.d.ts +0 -11
  484. package/lib/renderers/a2ui/components/interactive/Button.js +0 -71
  485. package/lib/renderers/a2ui/components/interactive/CheckBox.d.ts +0 -9
  486. package/lib/renderers/a2ui/components/interactive/CheckBox.js +0 -48
  487. package/lib/renderers/a2ui/components/interactive/DateTimeInput.d.ts +0 -9
  488. package/lib/renderers/a2ui/components/interactive/DateTimeInput.js +0 -62
  489. package/lib/renderers/a2ui/components/interactive/MultipleChoice.d.ts +0 -9
  490. package/lib/renderers/a2ui/components/interactive/MultipleChoice.js +0 -73
  491. package/lib/renderers/a2ui/components/interactive/Slider.d.ts +0 -9
  492. package/lib/renderers/a2ui/components/interactive/Slider.js +0 -53
  493. package/lib/renderers/a2ui/components/interactive/TextField.d.ts +0 -9
  494. package/lib/renderers/a2ui/components/interactive/TextField.js +0 -72
  495. package/lib/renderers/a2ui/components/interactive/index.d.ts +0 -6
  496. package/lib/renderers/a2ui/components/interactive/index.js +0 -25
  497. package/lib/renderers/a2ui/components/layout/Card.d.ts +0 -11
  498. package/lib/renderers/a2ui/components/layout/Card.js +0 -30
  499. package/lib/renderers/a2ui/components/layout/Column.d.ts +0 -11
  500. package/lib/renderers/a2ui/components/layout/Column.js +0 -65
  501. package/lib/renderers/a2ui/components/layout/List.d.ts +0 -11
  502. package/lib/renderers/a2ui/components/layout/List.js +0 -55
  503. package/lib/renderers/a2ui/components/layout/Modal.d.ts +0 -11
  504. package/lib/renderers/a2ui/components/layout/Modal.js +0 -58
  505. package/lib/renderers/a2ui/components/layout/Row.d.ts +0 -11
  506. package/lib/renderers/a2ui/components/layout/Row.js +0 -65
  507. package/lib/renderers/a2ui/components/layout/Tabs.d.ts +0 -11
  508. package/lib/renderers/a2ui/components/layout/Tabs.js +0 -48
  509. package/lib/renderers/a2ui/components/layout/index.d.ts +0 -6
  510. package/lib/renderers/a2ui/components/layout/index.js +0 -25
  511. package/lib/renderers/a2ui/context/A2UIContext.d.ts +0 -17
  512. package/lib/renderers/a2ui/context/A2UIContext.js +0 -54
  513. package/lib/renderers/a2ui/context/ThemeContext.d.ts +0 -20
  514. package/lib/renderers/a2ui/context/ThemeContext.js +0 -333
  515. package/lib/renderers/a2ui/hooks/useA2UI.d.ts +0 -36
  516. package/lib/renderers/a2ui/hooks/useA2UI.js +0 -62
  517. package/lib/renderers/a2ui/hooks/useDataBinding.d.ts +0 -8
  518. package/lib/renderers/a2ui/hooks/useDataBinding.js +0 -83
  519. package/lib/renderers/a2ui/index.d.ts +0 -9
  520. package/lib/renderers/a2ui/index.js +0 -28
  521. package/lib/renderers/a2ui/lib/utils.d.ts +0 -11
  522. package/lib/renderers/a2ui/lib/utils.js +0 -38
  523. package/lib/renderers/a2ui/types/index.d.ts +0 -17
  524. package/lib/runtime/index.d.ts +0 -38
  525. package/lib/runtime/index.js +0 -40
  526. package/lib/runtime/runtimeStore.d.ts +0 -76
  527. package/lib/runtime/runtimeStore.js +0 -184
  528. package/lib/runtime/types.d.ts +0 -84
  529. package/lib/runtime/useAgentConnection.d.ts +0 -45
  530. package/lib/runtime/useAgentConnection.js +0 -112
  531. package/lib/runtime/useAgentRuntime.d.ts +0 -93
  532. package/lib/runtime/useAgentRuntime.js +0 -125
  533. package/lib/specs/agents/codeai/agents.d.ts +0 -28
  534. package/lib/specs/agents/codeai/agents.js +0 -179
  535. package/lib/specs/agents/codeai/index.d.ts +0 -1
  536. package/lib/specs/agents/codemode-paper/agents.d.ts +0 -31
  537. package/lib/specs/agents/codemode-paper/agents.js +0 -378
  538. package/lib/specs/agents/codemode-paper/index.d.ts +0 -1
  539. package/lib/specs/agents/codemode-paper/index.js +0 -5
  540. package/lib/specs/agents/datalayer-ai/agents.d.ts +0 -31
  541. package/lib/specs/agents/datalayer-ai/agents.js +0 -352
  542. package/lib/specs/agents/datalayer-ai/index.d.ts +0 -1
  543. package/lib/specs/agents/datalayer-ai/index.js +0 -5
  544. package/lib/specs/agents/mocks/agents.d.ts +0 -43
  545. package/lib/specs/agents/mocks/index.d.ts +0 -1
  546. package/lib/specs/agents/mocks/index.js +0 -5
  547. package/lib/state/index.d.ts +0 -1
  548. package/lib/state/index.js +0 -5
  549. package/lib/state/substates/AIAgentState.d.ts +0 -80
  550. package/lib/state/substates/AIAgentState.js +0 -108
  551. package/lib/state/substates/index.d.ts +0 -1
  552. package/lib/state/substates/index.js +0 -5
  553. package/lib/types/AIAgent.d.ts +0 -17
  554. package/lib/types/Types.d.ts +0 -217
  555. /package/lib/{components/chat → api}/handler.d.ts +0 -0
  556. /package/lib/{renderers/index.d.ts → api/utils.d.ts} +0 -0
  557. /package/lib/{renderers/index.js → api/utils.js} +0 -0
  558. /package/lib/{components/chat/components/elements → chat/display}/PoweredByTag.js +0 -0
  559. /package/lib/{components/chat/components → chat}/parts/DynamicToolPart.js +0 -0
  560. /package/lib/{components/chat/components → chat}/parts/ReasoningPart.d.ts +0 -0
  561. /package/lib/{components/chat/components → chat}/parts/TextPart.js +0 -0
  562. /package/lib/{components/chat/components → chat}/parts/ToolPart.d.ts +0 -0
  563. /package/lib/{components/chat/components → chat}/styles/streamdownStyles.js +0 -0
  564. /package/lib/{components/chat/components/elements → chat/tools}/ToolApprovalDialog.d.ts +0 -0
  565. /package/lib/{components/chat/components → context}/ContextDistribution.d.ts +0 -0
  566. /package/lib/{components/chat/components → context}/ContextDistribution.js +0 -0
  567. /package/lib/{components/chat/components → context}/ContextInspector.d.ts +0 -0
  568. /package/lib/{components/chat/components → context}/ContextPanel.d.ts +0 -0
  569. /package/lib/{components/chat/components → context}/ContextUsage.d.ts +0 -0
  570. /package/lib/{components/chat/components → context}/ContextUsage.js +0 -0
  571. /package/lib/examples/{JupyterCellExample.d.ts → CellSimpleExample.d.ts} +0 -0
  572. /package/lib/examples/{AgentRuntimeCustomExample.d.ts → ChatCustomExample.d.ts} +0 -0
  573. /package/lib/examples/{AgentRuntimeChatExample.d.ts → ChatExample.d.ts} +0 -0
  574. /package/lib/examples/{AgentRuntimeStandaloneExample.d.ts → ChatStandaloneExample.d.ts} +0 -0
  575. /package/lib/examples/{AgentRuntimeNotebookExample.d.ts → NotebookExample.d.ts} +0 -0
  576. /package/lib/examples/{AgentRuntimeNotebookSidebarExample.d.ts → NotebookSidebarExample.d.ts} +0 -0
  577. /package/lib/examples/{JupyterNotebookExample.d.ts → NotebookSimpleExample.d.ts} +0 -0
  578. /package/lib/examples/{stores → utils}/agents/earthquake-detector.ipynb.json +0 -0
  579. /package/lib/examples/{stores → utils}/agents/earthquake-detector.json +0 -0
  580. /package/lib/examples/{stores → utils}/agents/earthquake-detector.lexical.json +0 -0
  581. /package/lib/examples/{stores → utils}/agents/sales-forecaster.ipynb.json +0 -0
  582. /package/lib/examples/{stores → utils}/agents/sales-forecaster.json +0 -0
  583. /package/lib/examples/{stores → utils}/agents/sales-forecaster.lexical.json +0 -0
  584. /package/lib/examples/{stores → utils}/agents/social-post-generator.ipynb.json +0 -0
  585. /package/lib/examples/{stores → utils}/agents/social-post-generator.json +0 -0
  586. /package/lib/examples/{stores → utils}/agents/social-post-generator.lexical.json +0 -0
  587. /package/lib/examples/{stores → utils}/agents/stock-market.ipynb.json +0 -0
  588. /package/lib/examples/{stores → utils}/agents/stock-market.json +0 -0
  589. /package/lib/examples/{stores → utils}/agents/stock-market.lexical.json +0 -0
  590. /package/lib/examples/{stores → utils}/notebooks/IPyWidgetsExample.ipynb.json +0 -0
  591. /package/lib/examples/{stores → utils}/notebooks/IPyWidgetsExampleWithState.ipynb.json +0 -0
  592. /package/lib/examples/{stores → utils}/notebooks/Lite.ipynb.json +0 -0
  593. /package/lib/examples/{stores → utils}/notebooks/Matplotlib.ipynb.json +0 -0
  594. /package/lib/examples/{stores → utils}/notebooks/NotebookExample1.ipynb.json +0 -0
  595. /package/lib/examples/{stores → utils}/notebooks/NotebookOutputs.ipynb.json +0 -0
  596. /package/lib/examples/{stores → utils}/notebooks/NotebookToCExample.ipynb.json +0 -0
  597. /package/lib/examples/{stores → utils}/notebooks/OutputIPyWidgetsExample.d.ts +0 -0
  598. /package/lib/examples/{stores → utils}/notebooks/OutputIPyWidgetsExample.js +0 -0
  599. /package/lib/examples/{stores → utils}/notebooks/PyGWalker.ipynb.json +0 -0
  600. /package/lib/examples/{stores → utils}/themedProvider.d.ts +0 -0
  601. /package/lib/examples/{stores → utils}/themedProvider.js +0 -0
  602. /package/lib/{components/chat/inference → inference}/BaseInferenceProvider.js +0 -0
  603. /package/lib/{components → mcp}/McpServerManager.js +0 -0
  604. /package/lib/{components/chat/middleware → middleware}/MiddlewarePipeline.js +0 -0
  605. /package/lib/{components/chat/types/inference.js → types/a2a.js} +0 -0
  606. /package/lib/{components/chat/types/protocol.js → types/acp.js} +0 -0
  607. /package/lib/{components/sparklines/types.js → types/ag-ui.js} +0 -0
  608. /package/lib/{renderers/a2ui/types/index.js → types/agents-lifecycle.js} +0 -0
  609. /package/lib/types/{AIAgent.js → agentspecs.js} +0 -0
  610. /package/lib/types/{Types.js → chat.js} +0 -0
  611. /package/lib/{components/chat/types → types}/execution.js +0 -0
  612. /package/lib/{components/chat/types/extension.js → types/extensions.js} +0 -0
  613. /package/lib/{components/chat/types/message.js → types/messages.js} +0 -0
  614. /package/lib/{components/chat/types → types}/middleware.js +0 -0
  615. /package/lib/{components/chat/types/tool.js → types/tools.js} +0 -0
@@ -0,0 +1,1287 @@
1
+ import { jsx as _jsx, Fragment as _Fragment, jsxs as _jsxs } from "react/jsx-runtime";
2
+ /*
3
+ * Copyright (c) 2025-2026 Datalayer, Inc.
4
+ * Distributed under the terms of the Modified BSD License.
5
+ */
6
+ /**
7
+ * Main ChatBase component.
8
+ * Provides a full chat interface with messages and input.
9
+ * This is the base component used by all other chat container components.
10
+ *
11
+ * Supports multiple modes:
12
+ * 1. Store mode: Uses Zustand store for state management (default)
13
+ * 2. Protocol mode: Connects to backend via AG-UI, A2A, Vercel AI, or ACP protocols
14
+ * 3. Custom mode: Uses onSendMessage prop for custom message handling
15
+ *
16
+ * @module chat/base/ChatBase
17
+ */
18
+ import { useContext } from 'react';
19
+ import { useCallback, useEffect, useMemo, useRef, useState, } from 'react';
20
+ import { Text, Spinner } from '@primer/react';
21
+ import { Box, setupPrimerPortals } from '@datalayer/primer-addons';
22
+ import { AlertIcon, PersonIcon } from '@primer/octicons-react';
23
+ import { AiAgentIcon } from '@datalayer/icons-react';
24
+ import { QueryClientProvider, QueryClientContext } from '@tanstack/react-query';
25
+ import { useChatStore } from '../../stores/chatStore';
26
+ import { useConversationStore } from '../../stores/conversationStore';
27
+ import { generateMessageId, createUserMessage, createAssistantMessage, } from '../../types/messages';
28
+ import { internalQueryClient, isToolCallMessage, convertHistoryToDisplayItems, createProtocolAdapter, getApiBaseFromConfig, sanitizeAssistantContent, } from '../../utils';
29
+ import { useConfig, useSkills, useContextSnapshot, useSandbox, } from '../../hooks';
30
+ import { ChatBaseHeader } from '../header/ChatHeaderBase';
31
+ import { ChatEmptyState } from '../display/EmptyState';
32
+ import { PoweredByTag } from '../display/PoweredByTag';
33
+ import { ChatMessageList, } from '../messages/ChatMessageList';
34
+ import { InputToolbar } from '../prompt/InputFooter';
35
+ // Tracks pending prompts already auto-sent for a given conversation scope.
36
+ // This prevents layout-driven unmount/remount cycles from re-sending prompts.
37
+ const sentPendingPromptKeys = new Set();
38
+ function isToolCallOnlyPrompt(content) {
39
+ const normalized = content.toLowerCase();
40
+ return (/tool\s*call\s*only/.test(normalized) ||
41
+ /use\s+(?:a\s+)?tool\s+call\s+only/.test(normalized));
42
+ }
43
+ function formatToolResultFallback(result) {
44
+ if (typeof result === 'string') {
45
+ return result;
46
+ }
47
+ if (typeof result === 'number' ||
48
+ typeof result === 'boolean' ||
49
+ result === null) {
50
+ return String(result);
51
+ }
52
+ try {
53
+ const serialized = JSON.stringify(result, null, 2);
54
+ return serialized.length > 2000
55
+ ? `${serialized.slice(0, 2000)}\n...`
56
+ : serialized;
57
+ }
58
+ catch {
59
+ return 'Tool completed successfully.';
60
+ }
61
+ }
62
+ // ---------------------------------------------------------------------------
63
+ // ChatBase (outer wrapper — ensures QueryClient is available)
64
+ // ---------------------------------------------------------------------------
65
+ /**
66
+ * ChatBase component — Universal chat panel supporting store, protocol, and custom modes.
67
+ */
68
+ export function ChatBase(props) {
69
+ const { agentRuntimeConfig, protocol: protocolProp, useStore: useStoreMode = true, } = props;
70
+ // Resolve protocol: string Protocol overrides type in agentRuntimeConfig or
71
+ // is combined with a full ProtocolConfig object.
72
+ const protocolType = typeof protocolProp === 'string' ? protocolProp : undefined;
73
+ const protocolConfigProp = typeof protocolProp === 'object' ? protocolProp : undefined;
74
+ const protocol = agentRuntimeConfig
75
+ ? {
76
+ type: protocolType || agentRuntimeConfig.protocol || 'vercel-ai',
77
+ endpoint: agentRuntimeConfig.url,
78
+ authToken: agentRuntimeConfig.authToken,
79
+ agentId: agentRuntimeConfig.agentId,
80
+ enableConfigQuery: true,
81
+ configEndpoint: `${agentRuntimeConfig.url}/api/v1/config`,
82
+ }
83
+ : protocolConfigProp;
84
+ // If agentRuntimeConfig is provided, force protocol mode
85
+ const effectiveUseStoreMode = agentRuntimeConfig ? false : useStoreMode;
86
+ // Check if QueryClientProvider is already available
87
+ const existingQueryClient = useContext(QueryClientContext);
88
+ const innerProps = {
89
+ ...props,
90
+ // Protocol is resolved to ProtocolConfig | undefined by the outer wrapper.
91
+ // Force the type to satisfy ChatBaseProps (which accepts the union).
92
+ protocol: protocol,
93
+ useStore: effectiveUseStoreMode,
94
+ };
95
+ if (!existingQueryClient) {
96
+ return (_jsx(QueryClientProvider, { client: internalQueryClient, children: _jsx(ChatBaseInner, { ...innerProps }) }));
97
+ }
98
+ return _jsx(ChatBaseInner, { ...innerProps });
99
+ }
100
+ // ---------------------------------------------------------------------------
101
+ // ChatBaseInner — contains all actual logic
102
+ // ---------------------------------------------------------------------------
103
+ function ChatBaseInner({ title, showHeader = false, showTokenUsage = true, showLoadingIndicator = true, showErrors = true, showInput = true, showModelSelector = false, showToolsMenu = false, showSkillsMenu = false, codemodeEnabled = false, initialModel, availableModels, mcpServers, initialSkills, className, loadingState, headerActions, chatViewMode, onChatViewModeChange,
104
+ // Mode selection
105
+ useStore: useStoreMode = true, protocol: protocolRaw, onSendMessage, enableStreaming = false,
106
+ // Extended props
107
+ brandIcon, avatarConfig, headerButtons, showPoweredBy = false, poweredByProps, emptyState, renderToolResult, footerContent, showInformation = false, onInformationClick, headerContent, children, borderRadius, backgroundColor, border, boxShadow, compact = false, placeholder, description = 'Start a conversation with the AI agent.', onStateUpdate, onNewChat, onClear, onMessagesChange, autoFocus = false, suggestions, submitOnSuggestionClick = true, hideMessagesAfterToolUI = false, focusTrigger, frontendTools,
108
+ // Identity/Authorization props
109
+ onAuthorizationRequired, connectedIdentities,
110
+ // Conversation persistence
111
+ runtimeId, historyEndpoint, historyAuthToken,
112
+ // Pending prompt
113
+ pendingPrompt, }) {
114
+ useEffect(() => {
115
+ setupPrimerPortals();
116
+ }, []);
117
+ // The outer ChatBase wrapper always resolves a string Protocol to a full
118
+ // ProtocolConfig (or undefined). Narrow the type for internal use.
119
+ const protocol = typeof protocolRaw === 'object' ? protocolRaw : undefined;
120
+ // Stabilize the protocol reference so that the adapter-init effect only
121
+ // re-runs when the protocol *contents* actually change.
122
+ const protocolKey = protocol ? JSON.stringify(protocol) : '';
123
+ // Store (optional for message persistence)
124
+ const clearStoreMessages = useChatStore(state => state.clearMessages);
125
+ // Check if protocol is A2A (doesn't support per-request model override)
126
+ const isA2AProtocol = protocol?.type === 'a2a';
127
+ // ---- Component state ----
128
+ const [displayItems, setDisplayItems] = useState([]);
129
+ const [isLoading, setIsLoading] = useState(false);
130
+ const [isStreaming, setIsStreaming] = useState(false);
131
+ const [error, setError] = useState(null);
132
+ const [input, setInput] = useState('');
133
+ // History-loaded flag — true immediately when there is nothing to fetch
134
+ const [historyLoaded, setHistoryLoaded] = useState(!runtimeId);
135
+ // Adapter-ready flag — flipped to true once the protocol adapter is initialised
136
+ const [adapterReady, setAdapterReady] = useState(false);
137
+ // Guard so the pending prompt is sent at most once
138
+ const pendingPromptSentRef = useRef(false);
139
+ const pendingPromptKey = pendingPrompt &&
140
+ [
141
+ runtimeId || historyEndpoint || protocol?.endpoint || protocol?.agentId,
142
+ pendingPrompt,
143
+ ]
144
+ .filter(Boolean)
145
+ .join('::');
146
+ const [selectedModel, setSelectedModel] = useState('');
147
+ // enabledTools tracks which MCP server tools are enabled
148
+ // Format: Map<serverId, Set<toolName>>
149
+ const [enabledMcpTools, setEnabledMcpTools] = useState(new Map());
150
+ // Note: legacy _enabledTools for backend-defined tools from config query
151
+ const [_enabledTools, setEnabledTools] = useState([]);
152
+ // Skills state
153
+ const [enabledSkills, setEnabledSkills] = useState(new Set());
154
+ // ---- Data queries ----
155
+ const configQuery = useConfig(Boolean(protocol?.enableConfigQuery), protocol?.configEndpoint, protocol?.authToken);
156
+ const skillsQuery = useSkills(Boolean(protocol?.enableConfigQuery) && showSkillsMenu, protocol?.configEndpoint, protocol?.authToken);
157
+ const contextSnapshotQuery = useContextSnapshot(Boolean(protocol?.enableConfigQuery) && showTokenUsage, protocol?.configEndpoint, protocol?.agentId, protocol?.authToken);
158
+ const agentUsage = contextSnapshotQuery.data;
159
+ const sandboxStatusQuery = useSandbox(Boolean(protocol?.enableConfigQuery) && codemodeEnabled && showHeader, protocol?.configEndpoint, protocol?.authToken);
160
+ const sandboxStatus = sandboxStatusQuery.data;
161
+ // ---- Refs ----
162
+ const adapterRef = useRef(null);
163
+ const unsubscribeRef = useRef(null);
164
+ const toolCallsRef = useRef(new Map());
165
+ const pendingToolExecutionsRef = useRef(0);
166
+ const currentAssistantMessageRef = useRef(null);
167
+ const suppressAssistantTextForToolOnlyRef = useRef(false);
168
+ const hideMessagesAfterToolUIRef = useRef(hideMessagesAfterToolUI);
169
+ hideMessagesAfterToolUIRef.current = hideMessagesAfterToolUI;
170
+ const threadIdRef = useRef(generateMessageId());
171
+ const messagesEndRef = useRef(null);
172
+ const inputRef = useRef(null);
173
+ const abortControllerRef = useRef(null);
174
+ /** Set to true by handleStop so in-flight / about-to-run tool executions
175
+ * can bail out early. Reset to false at the start of each handleSend. */
176
+ const stoppedRef = useRef(false);
177
+ const connectedIdentitiesRef = useRef(connectedIdentities);
178
+ connectedIdentitiesRef.current = connectedIdentities;
179
+ // Keep a ref to frontendTools so the event listener closure (which is NOT
180
+ // re-created when frontendTools changes) always accesses the latest value.
181
+ const frontendToolsRef = useRef(frontendTools);
182
+ frontendToolsRef.current = frontendTools;
183
+ // ---- Helpers ----
184
+ const isServerSelected = useCallback((server) => {
185
+ if (!mcpServers)
186
+ return true;
187
+ const origin = server.isConfig === false ? 'catalog' : 'config';
188
+ return mcpServers.some(s => s.id === server.id && s.origin === origin);
189
+ }, [mcpServers]);
190
+ // ---- Focus management ----
191
+ useEffect(() => {
192
+ if (autoFocus && inputRef.current) {
193
+ const timeoutId = setTimeout(() => inputRef.current?.focus(), 100);
194
+ return () => clearTimeout(timeoutId);
195
+ }
196
+ }, [autoFocus]);
197
+ useEffect(() => {
198
+ if (focusTrigger !== undefined && focusTrigger > 0 && inputRef.current) {
199
+ const timeoutId = setTimeout(() => inputRef.current?.focus(), 150);
200
+ return () => clearTimeout(timeoutId);
201
+ }
202
+ }, [focusTrigger]);
203
+ const wasLoadingRef = useRef(false);
204
+ useEffect(() => {
205
+ if (wasLoadingRef.current && !isLoading && inputRef.current) {
206
+ const timeoutId = setTimeout(() => inputRef.current?.focus(), 50);
207
+ return () => clearTimeout(timeoutId);
208
+ }
209
+ wasLoadingRef.current = isLoading;
210
+ }, [isLoading]);
211
+ // ---- Auto-resize textarea ----
212
+ const adjustTextareaHeight = useCallback(() => {
213
+ const textarea = inputRef.current;
214
+ if (textarea) {
215
+ textarea.style.height = 'auto';
216
+ const maxHeight = 120;
217
+ const minHeight = 40;
218
+ const newHeight = Math.min(Math.max(textarea.scrollHeight, minHeight), maxHeight);
219
+ textarea.style.height = `${newHeight}px`;
220
+ textarea.style.overflowY =
221
+ textarea.scrollHeight > maxHeight ? 'auto' : 'hidden';
222
+ }
223
+ }, []);
224
+ useEffect(() => {
225
+ adjustTextareaHeight();
226
+ }, [input, adjustTextareaHeight]);
227
+ useEffect(() => {
228
+ const timer = setTimeout(adjustTextareaHeight, 0);
229
+ return () => clearTimeout(timer);
230
+ }, [adjustTextareaHeight]);
231
+ // ---- Initialize model and tools when config is available ----
232
+ useEffect(() => {
233
+ if ((configQuery.data || availableModels) && !selectedModel) {
234
+ const modelsList = availableModels || configQuery.data?.models || [];
235
+ const preferredModel = initialModel || configQuery.data?.defaultModel;
236
+ if (preferredModel) {
237
+ const modelExists = modelsList.some(m => m.id === preferredModel);
238
+ if (modelExists) {
239
+ setSelectedModel(preferredModel);
240
+ }
241
+ else {
242
+ const firstAvailableModel = modelsList.find(m => m.isAvailable !== false);
243
+ const firstModel = firstAvailableModel || modelsList[0];
244
+ if (firstModel)
245
+ setSelectedModel(firstModel.id);
246
+ }
247
+ }
248
+ else {
249
+ const firstAvailableModel = modelsList.find(m => m.isAvailable !== false);
250
+ const firstModel = firstAvailableModel || modelsList[0];
251
+ if (firstModel)
252
+ setSelectedModel(firstModel.id);
253
+ }
254
+ const allToolIds = configQuery.data?.builtinTools?.map(tool => tool.id) || [];
255
+ setEnabledTools(allToolIds);
256
+ if (configQuery.data?.mcpServers) {
257
+ const newEnabledMcpTools = new Map();
258
+ for (const server of configQuery.data.mcpServers) {
259
+ if (server.isAvailable && server.enabled) {
260
+ const shouldEnableServer = isServerSelected(server);
261
+ if (shouldEnableServer) {
262
+ const enabledToolNames = new Set(server.tools.filter(t => t.enabled).map(t => t.name));
263
+ newEnabledMcpTools.set(server.id, enabledToolNames);
264
+ }
265
+ }
266
+ }
267
+ setEnabledMcpTools(newEnabledMcpTools);
268
+ }
269
+ }
270
+ }, [
271
+ configQuery.data,
272
+ selectedModel,
273
+ initialModel,
274
+ availableModels,
275
+ mcpServers,
276
+ isServerSelected,
277
+ ]);
278
+ // Update enabled MCP servers when mcpServers prop changes
279
+ useEffect(() => {
280
+ if (!configQuery.data?.mcpServers || !mcpServers)
281
+ return;
282
+ setEnabledMcpTools(prev => {
283
+ const newMap = new Map();
284
+ for (const server of configQuery.data?.mcpServers ?? []) {
285
+ if (isServerSelected(server) && prev.has(server.id)) {
286
+ newMap.set(server.id, prev.get(server.id));
287
+ }
288
+ else if (isServerSelected(server) &&
289
+ server.isAvailable &&
290
+ server.enabled) {
291
+ const enabledToolNames = new Set(server.tools.filter(t => t.enabled).map(t => t.name));
292
+ newMap.set(server.id, enabledToolNames);
293
+ }
294
+ }
295
+ return newMap;
296
+ });
297
+ }, [mcpServers, configQuery.data?.mcpServers, isServerSelected]);
298
+ // Initialize enabled skills from initialSkills prop
299
+ useEffect(() => {
300
+ if (initialSkills && initialSkills.length > 0) {
301
+ setEnabledSkills(new Set(initialSkills));
302
+ }
303
+ }, [initialSkills]);
304
+ // ---- Toggle helpers ----
305
+ const toggleMcpTool = useCallback((serverId, toolName) => {
306
+ setEnabledMcpTools(prev => {
307
+ const newMap = new Map(prev);
308
+ const serverTools = new Set(prev.get(serverId) || []);
309
+ if (serverTools.has(toolName)) {
310
+ serverTools.delete(toolName);
311
+ }
312
+ else {
313
+ serverTools.add(toolName);
314
+ }
315
+ newMap.set(serverId, serverTools);
316
+ return newMap;
317
+ });
318
+ }, []);
319
+ const toggleAllMcpServerTools = useCallback((serverId, allToolNames, enable) => {
320
+ setEnabledMcpTools(prev => {
321
+ const newMap = new Map(prev);
322
+ if (enable) {
323
+ newMap.set(serverId, new Set(allToolNames));
324
+ }
325
+ else {
326
+ newMap.set(serverId, new Set());
327
+ }
328
+ return newMap;
329
+ });
330
+ }, []);
331
+ const toggleSkill = useCallback((skillId) => {
332
+ setEnabledSkills(prev => {
333
+ const newSet = new Set(prev);
334
+ if (newSet.has(skillId)) {
335
+ newSet.delete(skillId);
336
+ }
337
+ else {
338
+ newSet.add(skillId);
339
+ }
340
+ return newSet;
341
+ });
342
+ }, []);
343
+ const toggleAllSkills = useCallback((allSkillIds, enable) => {
344
+ setEnabledSkills(enable ? new Set(allSkillIds) : new Set());
345
+ }, []);
346
+ const getEnabledMcpToolNames = useCallback(() => {
347
+ const toolNames = [];
348
+ enabledMcpTools.forEach((tools, serverId) => {
349
+ if (!mcpServers || mcpServers.some(s => s.id === serverId)) {
350
+ tools.forEach(toolName => toolNames.push(toolName));
351
+ }
352
+ });
353
+ return toolNames;
354
+ }, [enabledMcpTools, mcpServers]);
355
+ const getEnabledSkillIds = useCallback(() => {
356
+ return Array.from(enabledSkills);
357
+ }, [enabledSkills]);
358
+ // ---- Load messages from store on mount ----
359
+ useEffect(() => {
360
+ if (useStoreMode) {
361
+ const storeMessages = useChatStore.getState().messages;
362
+ if (storeMessages.length > 0) {
363
+ setDisplayItems(storeMessages);
364
+ }
365
+ }
366
+ }, [useStoreMode]);
367
+ // ---- Conversation history loading ----
368
+ const prevRuntimeIdRef = useRef(undefined);
369
+ useEffect(() => {
370
+ if (runtimeId !== prevRuntimeIdRef.current) {
371
+ prevRuntimeIdRef.current = runtimeId;
372
+ setDisplayItems([]);
373
+ toolCallsRef.current.clear();
374
+ if (!runtimeId)
375
+ return;
376
+ }
377
+ else {
378
+ return;
379
+ }
380
+ const store = useConversationStore.getState();
381
+ if (!store.needsFetch(runtimeId)) {
382
+ const storedMessages = store.getMessages(runtimeId);
383
+ if (storedMessages.length > 0) {
384
+ setDisplayItems(storedMessages);
385
+ }
386
+ setHistoryLoaded(true);
387
+ return;
388
+ }
389
+ store.setFetching(runtimeId, true);
390
+ let endpoint = historyEndpoint ||
391
+ (protocol?.endpoint ? `${protocol.endpoint}/api/v1/history` : null);
392
+ if (!endpoint) {
393
+ console.warn('[ChatBase] No history endpoint available for runtimeId:', runtimeId);
394
+ store.markFetched(runtimeId);
395
+ setHistoryLoaded(true);
396
+ return;
397
+ }
398
+ if (protocol?.agentId && !endpoint.includes('agent_id=')) {
399
+ const separator = endpoint.includes('?') ? '&' : '?';
400
+ endpoint = `${endpoint}${separator}agent_id=${encodeURIComponent(protocol.agentId)}`;
401
+ }
402
+ const fetchHistory = async () => {
403
+ try {
404
+ const authToken = historyAuthToken || protocol?.authToken;
405
+ const headers = {
406
+ 'Content-Type': 'application/json',
407
+ };
408
+ if (authToken) {
409
+ headers['Authorization'] = `Bearer ${authToken}`;
410
+ }
411
+ const response = await fetch(endpoint, {
412
+ method: 'GET',
413
+ headers,
414
+ credentials: 'include',
415
+ });
416
+ if (!response.ok) {
417
+ throw new Error(`Failed to fetch history: ${response.status} ${response.statusText}`);
418
+ }
419
+ const data = await response.json();
420
+ const messages = (data.messages || []).map((msg) => {
421
+ if (msg.toolCalls && Array.isArray(msg.toolCalls)) {
422
+ msg.toolCalls = msg.toolCalls.map((tc) => {
423
+ if (tc.toolCallId && tc.toolName)
424
+ return tc;
425
+ let parsedArgs = tc.args ?? tc.arguments ?? {};
426
+ if (typeof parsedArgs === 'string') {
427
+ try {
428
+ parsedArgs = JSON.parse(parsedArgs);
429
+ }
430
+ catch {
431
+ parsedArgs = {};
432
+ }
433
+ }
434
+ return {
435
+ type: 'tool-call',
436
+ toolCallId: tc.toolCallId ?? tc.id ?? tc.tool_call_id ?? '',
437
+ toolName: tc.toolName ?? tc.name ?? tc.tool_name ?? '',
438
+ args: parsedArgs,
439
+ status: tc.status ?? 'completed',
440
+ };
441
+ });
442
+ }
443
+ return msg;
444
+ });
445
+ if (messages.length > 0) {
446
+ store.setMessages(runtimeId, messages);
447
+ const items = convertHistoryToDisplayItems(messages);
448
+ setDisplayItems(items);
449
+ }
450
+ store.markFetched(runtimeId);
451
+ setHistoryLoaded(true);
452
+ }
453
+ catch (err) {
454
+ console.error('[ChatBase] Failed to fetch conversation history:', err);
455
+ store.markFetched(runtimeId);
456
+ setHistoryLoaded(true);
457
+ }
458
+ };
459
+ fetchHistory();
460
+ }, [
461
+ runtimeId,
462
+ historyEndpoint,
463
+ historyAuthToken,
464
+ protocol?.endpoint,
465
+ protocol?.authToken,
466
+ ]);
467
+ // Keep in-memory store in sync with displayItems
468
+ useEffect(() => {
469
+ if (runtimeId && displayItems.length > 0) {
470
+ const messagesToSave = displayItems.filter((item) => !isToolCallMessage(item));
471
+ if (messagesToSave.length > 0) {
472
+ useConversationStore.getState().setMessages(runtimeId, messagesToSave);
473
+ }
474
+ }
475
+ }, [runtimeId, displayItems]);
476
+ // ---- Derived state ----
477
+ const messages = displayItems.filter((item) => !isToolCallMessage(item));
478
+ const ready = true;
479
+ const prevMessageCountRef = useRef(0);
480
+ useEffect(() => {
481
+ const currentCount = messages.length;
482
+ if (currentCount !== prevMessageCountRef.current) {
483
+ prevMessageCountRef.current = currentCount;
484
+ onMessagesChange?.(messages);
485
+ }
486
+ }, [displayItems, onMessagesChange]);
487
+ const padding = compact ? 2 : 3;
488
+ // Derive approval config from protocol for built-in tool approval support
489
+ const approvalConfig = useMemo(() => {
490
+ if (!protocol?.configEndpoint)
491
+ return undefined;
492
+ return {
493
+ apiBaseUrl: getApiBaseFromConfig(protocol.configEndpoint),
494
+ authToken: protocol.authToken,
495
+ };
496
+ }, [protocol?.configEndpoint, protocol?.authToken]);
497
+ const defaultAvatarConfig = {
498
+ userAvatar: _jsx(PersonIcon, { size: 16 }),
499
+ assistantAvatar: _jsx(AiAgentIcon, { size: 16 }),
500
+ showAvatars: true,
501
+ avatarSize: 32,
502
+ userAvatarBg: 'neutral.muted',
503
+ assistantAvatarBg: 'accent.emphasis',
504
+ ...avatarConfig,
505
+ };
506
+ // ========================================================================
507
+ // Protocol adapter subscription
508
+ // ========================================================================
509
+ useEffect(() => {
510
+ if (!protocol)
511
+ return;
512
+ const adapter = createProtocolAdapter(protocol);
513
+ if (!adapter)
514
+ return;
515
+ adapterRef.current = adapter;
516
+ setAdapterReady(true);
517
+ unsubscribeRef.current = adapter.subscribe((event) => {
518
+ switch (event.type) {
519
+ case 'message':
520
+ if (suppressAssistantTextForToolOnlyRef.current) {
521
+ const suppressedMessageId = currentAssistantMessageRef.current?.id;
522
+ if (suppressedMessageId) {
523
+ setDisplayItems(prev => prev.filter(item => isToolCallMessage(item) || item.id !== suppressedMessageId));
524
+ if (useStoreMode) {
525
+ useChatStore.getState().deleteMessage(suppressedMessageId);
526
+ }
527
+ currentAssistantMessageRef.current = null;
528
+ }
529
+ break;
530
+ }
531
+ if (event.message) {
532
+ const incomingId = event.message.id;
533
+ const currentId = currentAssistantMessageRef.current?.id;
534
+ const isNewMessage = !currentId || (incomingId && incomingId !== currentId);
535
+ if (currentAssistantMessageRef.current && !isNewMessage) {
536
+ setDisplayItems(prev => {
537
+ const newItems = [...prev];
538
+ const idx = newItems.findIndex(item => !isToolCallMessage(item) &&
539
+ item.id === currentAssistantMessageRef.current?.id);
540
+ if (idx >= 0 && !isToolCallMessage(newItems[idx])) {
541
+ const rawContent = event.message?.content;
542
+ const sanitizedContent = typeof rawContent === 'string'
543
+ ? sanitizeAssistantContent(rawContent)
544
+ : (rawContent ?? '');
545
+ newItems[idx] = {
546
+ ...newItems[idx],
547
+ content: sanitizedContent,
548
+ };
549
+ }
550
+ return newItems;
551
+ });
552
+ if (useStoreMode && currentAssistantMessageRef.current) {
553
+ const rawContent = event.message?.content;
554
+ const sanitizedContent = typeof rawContent === 'string'
555
+ ? sanitizeAssistantContent(rawContent)
556
+ : (rawContent ?? '');
557
+ useChatStore
558
+ .getState()
559
+ .updateMessage(currentAssistantMessageRef.current.id, {
560
+ content: sanitizedContent,
561
+ });
562
+ }
563
+ }
564
+ else {
565
+ const content = event.message.content;
566
+ const contentStr = typeof content === 'string' ? content : (content ?? '');
567
+ const sanitizedContent = typeof contentStr === 'string'
568
+ ? sanitizeAssistantContent(contentStr)
569
+ : '';
570
+ const newMessage = createAssistantMessage(sanitizedContent);
571
+ newMessage.id = event.message.id || newMessage.id;
572
+ currentAssistantMessageRef.current = newMessage;
573
+ setDisplayItems(prev => {
574
+ const existingIdx = prev.findIndex(item => !isToolCallMessage(item) && item.id === newMessage.id);
575
+ if (existingIdx >= 0) {
576
+ const newItems = [...prev];
577
+ newItems[existingIdx] = {
578
+ ...newItems[existingIdx],
579
+ content: sanitizedContent,
580
+ };
581
+ return newItems;
582
+ }
583
+ return [...prev, newMessage];
584
+ });
585
+ if (useStoreMode) {
586
+ const existingInStore = useChatStore
587
+ .getState()
588
+ .messages.find(m => m.id === newMessage.id);
589
+ if (existingInStore) {
590
+ useChatStore.getState().updateMessage(newMessage.id, {
591
+ content: sanitizedContent,
592
+ });
593
+ }
594
+ else {
595
+ useChatStore.getState().addMessage(newMessage);
596
+ }
597
+ }
598
+ }
599
+ }
600
+ break;
601
+ case 'tool-call':
602
+ if (event.toolCall && !stoppedRef.current) {
603
+ const toolCallId = event.toolCall.toolCallId || generateMessageId();
604
+ const toolName = event.toolCall.toolName;
605
+ const args = event.toolCall.args || {};
606
+ if (toolCallsRef.current.has(toolCallId)) {
607
+ const existingToolCall = toolCallsRef.current.get(toolCallId);
608
+ if (existingToolCall) {
609
+ const updatedToolCall = {
610
+ ...existingToolCall,
611
+ args: { ...existingToolCall.args, ...args },
612
+ };
613
+ toolCallsRef.current.set(toolCallId, updatedToolCall);
614
+ setDisplayItems(prev => prev.map(item => isToolCallMessage(item) && item.toolCallId === toolCallId
615
+ ? updatedToolCall
616
+ : item));
617
+ const frontendTool = frontendToolsRef.current?.find(t => t.name === toolName);
618
+ const toolHandler = frontendTool?.handler;
619
+ if (toolHandler &&
620
+ existingToolCall.status === 'executing' &&
621
+ Object.keys(args).length > 0) {
622
+ pendingToolExecutionsRef.current++;
623
+ executeFrontendTool(toolHandler, updatedToolCall, toolCallId);
624
+ }
625
+ }
626
+ }
627
+ else {
628
+ const toolCallMsg = {
629
+ id: `tool-${toolCallId}`,
630
+ type: 'tool-call',
631
+ toolCallId,
632
+ toolName,
633
+ args,
634
+ status: 'executing',
635
+ };
636
+ toolCallsRef.current.set(toolCallId, toolCallMsg);
637
+ setDisplayItems(prev => [...prev, toolCallMsg]);
638
+ const frontendTool = frontendToolsRef.current?.find(t => t.name === toolName);
639
+ const toolHandler = frontendTool?.handler;
640
+ // Only execute when we have actual args. AG-UI emits an
641
+ // initial tool-call with empty args on TOOL_CALL_START;
642
+ // the real args arrive on TOOL_CALL_END. Skip execution
643
+ // here and let the update branch (above) handle it once
644
+ // the full args are available.
645
+ if (toolHandler && Object.keys(args).length > 0) {
646
+ pendingToolExecutionsRef.current++;
647
+ executeFrontendTool(toolHandler, toolCallMsg, toolCallId);
648
+ }
649
+ }
650
+ }
651
+ break;
652
+ case 'tool-result':
653
+ if (event.toolResult) {
654
+ const toolCallId = event.toolResult.toolCallId;
655
+ if (toolCallId && toolCallsRef.current.has(toolCallId)) {
656
+ const existingToolCall = toolCallsRef.current.get(toolCallId);
657
+ if (existingToolCall) {
658
+ const isHumanInTheLoop = existingToolCall.args &&
659
+ 'steps' in existingToolCall.args &&
660
+ Array.isArray(existingToolCall.args.steps);
661
+ const resultData = event.toolResult.result;
662
+ let executionError;
663
+ let codeError;
664
+ let exitCode;
665
+ let isPendingApproval = false;
666
+ let hasError = !!event.toolResult.error;
667
+ if (resultData && typeof resultData === 'object') {
668
+ if ('pending_approval' in resultData &&
669
+ resultData.pending_approval === true) {
670
+ isPendingApproval = true;
671
+ }
672
+ if (resultData.execution_error &&
673
+ typeof resultData.execution_error === 'string') {
674
+ executionError = resultData.execution_error;
675
+ hasError = true;
676
+ }
677
+ if (resultData.code_error &&
678
+ typeof resultData.code_error === 'object') {
679
+ const ce = resultData.code_error;
680
+ codeError = {
681
+ name: ce.name || 'Error',
682
+ value: ce.value || 'Unknown error',
683
+ traceback: ce.traceback,
684
+ };
685
+ hasError = true;
686
+ }
687
+ if ('exit_code' in resultData) {
688
+ const ec = resultData.exit_code;
689
+ exitCode = typeof ec === 'number' ? ec : null;
690
+ if (exitCode != null && exitCode !== 0)
691
+ hasError = true;
692
+ }
693
+ if ('execution_ok' in resultData &&
694
+ resultData.execution_ok === false) {
695
+ hasError = true;
696
+ }
697
+ }
698
+ const updatedToolCall = {
699
+ ...existingToolCall,
700
+ result: event.toolResult.result,
701
+ status: hasError
702
+ ? 'error'
703
+ : isPendingApproval
704
+ ? 'inProgress'
705
+ : isHumanInTheLoop
706
+ ? 'executing'
707
+ : 'complete',
708
+ error: event.toolResult.error,
709
+ executionError,
710
+ codeError,
711
+ exitCode,
712
+ };
713
+ toolCallsRef.current.set(toolCallId, updatedToolCall);
714
+ setDisplayItems(prev => prev.map(item => isToolCallMessage(item) && item.toolCallId === toolCallId
715
+ ? updatedToolCall
716
+ : item));
717
+ }
718
+ }
719
+ }
720
+ break;
721
+ case 'state-update':
722
+ onStateUpdate?.(event.data);
723
+ if (event.data) {
724
+ const executingToolCalls = Array.from(toolCallsRef.current.entries()).filter(([_, tc]) => tc.status === 'executing');
725
+ if (executingToolCalls.length > 0) {
726
+ const [lastToolCallId, existingToolCall] = executingToolCalls[executingToolCalls.length - 1];
727
+ const isHumanInTheLoop = existingToolCall.args &&
728
+ 'steps' in existingToolCall.args &&
729
+ Array.isArray(existingToolCall.args.steps);
730
+ if (!isHumanInTheLoop) {
731
+ const stateData = event.data;
732
+ const result = stateData.weather ??
733
+ stateData.result ??
734
+ stateData.toolResult ??
735
+ stateData;
736
+ const updatedToolCall = {
737
+ ...existingToolCall,
738
+ result,
739
+ status: 'complete',
740
+ };
741
+ toolCallsRef.current.set(lastToolCallId, updatedToolCall);
742
+ setDisplayItems(prev => prev.map(item => isToolCallMessage(item) &&
743
+ item.toolCallId === lastToolCallId
744
+ ? updatedToolCall
745
+ : item));
746
+ }
747
+ }
748
+ }
749
+ break;
750
+ case 'done':
751
+ // The adapter signals the entire multi-turn conversation
752
+ // (including all continuations) has finished.
753
+ if (suppressAssistantTextForToolOnlyRef.current &&
754
+ hideMessagesAfterToolUIRef.current) {
755
+ setDisplayItems(prev => {
756
+ const hasAssistantContent = prev.some(item => !isToolCallMessage(item) &&
757
+ item.role === 'assistant' &&
758
+ String(item.content || '').trim().length > 0);
759
+ if (hasAssistantContent) {
760
+ return prev;
761
+ }
762
+ const latestCompletedTool = [...prev]
763
+ .reverse()
764
+ .find(item => isToolCallMessage(item) &&
765
+ item.status === 'complete' &&
766
+ item.result !== undefined);
767
+ if (!latestCompletedTool ||
768
+ !isToolCallMessage(latestCompletedTool)) {
769
+ return prev;
770
+ }
771
+ const fallbackMessage = createAssistantMessage(formatToolResultFallback(latestCompletedTool.result));
772
+ if (useStoreMode) {
773
+ useChatStore.getState().addMessage(fallbackMessage);
774
+ }
775
+ return [...prev, fallbackMessage];
776
+ });
777
+ }
778
+ suppressAssistantTextForToolOnlyRef.current = false;
779
+ pendingToolExecutionsRef.current = 0;
780
+ setIsLoading(false);
781
+ setIsStreaming(false);
782
+ break;
783
+ case 'error':
784
+ console.error('[ChatBase] Protocol error:', event.error);
785
+ if (event.error?.message &&
786
+ /exceeded maximum retries/i.test(event.error.message) &&
787
+ hideMessagesAfterToolUIRef.current) {
788
+ setDisplayItems(prev => {
789
+ const hasAssistantContent = prev.some(item => !isToolCallMessage(item) &&
790
+ item.role === 'assistant' &&
791
+ String(item.content || '').trim().length > 0);
792
+ if (hasAssistantContent) {
793
+ return prev;
794
+ }
795
+ const latestCompletedTool = [...prev]
796
+ .reverse()
797
+ .find(item => isToolCallMessage(item) &&
798
+ item.status === 'complete' &&
799
+ item.result !== undefined);
800
+ if (!latestCompletedTool ||
801
+ !isToolCallMessage(latestCompletedTool)) {
802
+ return prev;
803
+ }
804
+ const fallbackMessage = createAssistantMessage(formatToolResultFallback(latestCompletedTool.result));
805
+ if (useStoreMode) {
806
+ useChatStore.getState().addMessage(fallbackMessage);
807
+ }
808
+ return [...prev, fallbackMessage];
809
+ });
810
+ }
811
+ suppressAssistantTextForToolOnlyRef.current = false;
812
+ setError(event.error || new Error('Unknown error'));
813
+ pendingToolExecutionsRef.current = 0;
814
+ setIsLoading(false);
815
+ setIsStreaming(false);
816
+ break;
817
+ }
818
+ });
819
+ adapter.connect().catch(console.error);
820
+ return () => {
821
+ unsubscribeRef.current?.();
822
+ adapterRef.current?.disconnect();
823
+ };
824
+ // eslint-disable-next-line react-hooks/exhaustive-deps
825
+ }, [protocolKey, onStateUpdate, useStoreMode]);
826
+ // Helper to run a frontend tool and send result back via adapter
827
+ function executeFrontendTool(toolHandler, toolCallMsg, toolCallId) {
828
+ (async () => {
829
+ // If the user clicked Stop, skip executing this tool entirely.
830
+ if (stoppedRef.current) {
831
+ pendingToolExecutionsRef.current--;
832
+ if (pendingToolExecutionsRef.current < 0) {
833
+ pendingToolExecutionsRef.current = 0;
834
+ }
835
+ return;
836
+ }
837
+ try {
838
+ const result = await toolHandler(toolCallMsg.args);
839
+ if (adapterRef.current) {
840
+ await adapterRef.current.sendToolResult(toolCallId, {
841
+ toolCallId,
842
+ success: true,
843
+ result,
844
+ });
845
+ }
846
+ const completedToolCall = {
847
+ ...toolCallMsg,
848
+ result,
849
+ status: 'complete',
850
+ };
851
+ toolCallsRef.current.set(toolCallId, completedToolCall);
852
+ setDisplayItems(prev => prev.map(item => isToolCallMessage(item) && item.toolCallId === toolCallId
853
+ ? completedToolCall
854
+ : item));
855
+ }
856
+ catch (err) {
857
+ console.error('[ChatBase] Frontend tool execution error:', err);
858
+ const errorToolCall = {
859
+ ...toolCallMsg,
860
+ status: 'error',
861
+ error: err.message,
862
+ };
863
+ toolCallsRef.current.set(toolCallId, errorToolCall);
864
+ setDisplayItems(prev => prev.map(item => isToolCallMessage(item) && item.toolCallId === toolCallId
865
+ ? errorToolCall
866
+ : item));
867
+ }
868
+ finally {
869
+ pendingToolExecutionsRef.current--;
870
+ if (pendingToolExecutionsRef.current < 0) {
871
+ pendingToolExecutionsRef.current = 0;
872
+ }
873
+ // NOTE: Do NOT reset isLoading here. The adapter's 'done' event
874
+ // is the sole authority for ending the loading state — it fires
875
+ // only when RUN_FINISHED arrives with no pending tool calls,
876
+ // meaning the entire multi-turn conversation is truly complete.
877
+ }
878
+ })();
879
+ }
880
+ // ---- Auto-scroll to bottom ----
881
+ useEffect(() => {
882
+ messagesEndRef.current?.scrollIntoView({ behavior: 'smooth' });
883
+ }, [displayItems]);
884
+ // ========================================================================
885
+ // handleSend
886
+ // ========================================================================
887
+ const handleSend = useCallback(async (messageOverride) => {
888
+ const messageContent = (messageOverride ?? input).trim();
889
+ if (!messageContent || isLoading)
890
+ return;
891
+ if (!adapterRef.current && !onSendMessage)
892
+ return;
893
+ stoppedRef.current = false;
894
+ suppressAssistantTextForToolOnlyRef.current =
895
+ isToolCallOnlyPrompt(messageContent);
896
+ const userMessage = createUserMessage(messageContent);
897
+ const currentMessages = displayItems.filter((item) => !isToolCallMessage(item));
898
+ const allMessages = [...currentMessages, userMessage];
899
+ setDisplayItems(prev => [...prev, userMessage]);
900
+ setInput('');
901
+ setIsLoading(true);
902
+ setIsStreaming(true);
903
+ setError(null);
904
+ currentAssistantMessageRef.current = null;
905
+ if (useStoreMode) {
906
+ useChatStore.getState().addMessage(userMessage);
907
+ }
908
+ try {
909
+ if (onSendMessage) {
910
+ if (enableStreaming) {
911
+ const assistantMessageId = generateMessageId();
912
+ const assistantMessage = createAssistantMessage('');
913
+ assistantMessage.id = assistantMessageId;
914
+ setDisplayItems(prev => [...prev, assistantMessage]);
915
+ currentAssistantMessageRef.current = assistantMessage;
916
+ if (useStoreMode) {
917
+ useChatStore.getState().addMessage(assistantMessage);
918
+ useChatStore.getState().startStreaming(assistantMessageId);
919
+ }
920
+ abortControllerRef.current = new AbortController();
921
+ await onSendMessage(messageContent, allMessages, {
922
+ onChunk: (chunk) => {
923
+ setDisplayItems(prev => prev.map(item => item.id === assistantMessageId
924
+ ? {
925
+ ...item,
926
+ content: item.content + chunk,
927
+ }
928
+ : item));
929
+ if (useStoreMode) {
930
+ useChatStore
931
+ .getState()
932
+ .appendToStream(assistantMessageId, chunk);
933
+ }
934
+ },
935
+ onComplete: (fullResponse) => {
936
+ setDisplayItems(prev => prev.map(item => item.id === assistantMessageId
937
+ ? { ...item, content: fullResponse }
938
+ : item));
939
+ if (useStoreMode) {
940
+ useChatStore.getState().updateMessage(assistantMessageId, {
941
+ content: fullResponse,
942
+ });
943
+ useChatStore.getState().stopStreaming();
944
+ }
945
+ },
946
+ onError: (error) => {
947
+ const errorContent = `Error: ${error.message}`;
948
+ setDisplayItems(prev => prev.map(item => item.id === assistantMessageId
949
+ ? { ...item, content: errorContent }
950
+ : item));
951
+ if (useStoreMode) {
952
+ useChatStore.getState().updateMessage(assistantMessageId, {
953
+ content: errorContent,
954
+ });
955
+ useChatStore.getState().stopStreaming();
956
+ }
957
+ setError(error);
958
+ },
959
+ signal: abortControllerRef.current.signal,
960
+ });
961
+ }
962
+ else {
963
+ const response = await onSendMessage(messageContent, allMessages);
964
+ if (response) {
965
+ const assistantMessage = createAssistantMessage(response);
966
+ setDisplayItems(prev => [...prev, assistantMessage]);
967
+ if (useStoreMode) {
968
+ useChatStore.getState().addMessage(assistantMessage);
969
+ }
970
+ }
971
+ }
972
+ }
973
+ else if (adapterRef.current) {
974
+ const toolsForRequest = (frontendTools || []).map(tool => ({
975
+ name: tool.name,
976
+ description: tool.description,
977
+ parameters: tool.parameters || { type: 'object', properties: {} },
978
+ }));
979
+ console.log('[ChatBase] frontendTools count:', frontendTools?.length ?? 0, 'toolsForRequest:', toolsForRequest.map(t => t.name));
980
+ const enabledMcpToolNames = getEnabledMcpToolNames();
981
+ const enabledSkillIds = getEnabledSkillIds();
982
+ await adapterRef.current.sendMessage(userMessage, {
983
+ threadId: threadIdRef.current,
984
+ messages: allMessages,
985
+ ...(selectedModel && { model: selectedModel }),
986
+ tools: toolsForRequest,
987
+ builtinTools: enabledMcpToolNames,
988
+ skills: enabledSkillIds,
989
+ identities: connectedIdentitiesRef.current,
990
+ });
991
+ }
992
+ }
993
+ catch (err) {
994
+ if (err.name !== 'AbortError') {
995
+ console.error('[ChatBase] Send error:', err);
996
+ const errorMessage = createAssistantMessage(`Error: ${err.message}`);
997
+ setDisplayItems(prev => [...prev, errorMessage]);
998
+ setError(err);
999
+ }
1000
+ }
1001
+ finally {
1002
+ // NOTE: Do NOT reset isLoading here. The adapter's 'done' event
1003
+ // handles this — it fires only after the entire multi-turn
1004
+ // conversation (including all tool-call continuations) completes.
1005
+ // For the non-adapter path (onSendMessage), 'done' is never
1006
+ // emitted so we reset when no adapter is present.
1007
+ if (!adapterRef.current) {
1008
+ setIsLoading(false);
1009
+ setIsStreaming(false);
1010
+ }
1011
+ suppressAssistantTextForToolOnlyRef.current = false;
1012
+ currentAssistantMessageRef.current = null;
1013
+ abortControllerRef.current = null;
1014
+ }
1015
+ }, [
1016
+ input,
1017
+ isLoading,
1018
+ displayItems,
1019
+ selectedModel,
1020
+ frontendTools,
1021
+ useStoreMode,
1022
+ onSendMessage,
1023
+ enableStreaming,
1024
+ getEnabledMcpToolNames,
1025
+ getEnabledSkillIds,
1026
+ ]);
1027
+ // Send pending prompt once history loaded and adapter/handler available
1028
+ useEffect(() => {
1029
+ if (!pendingPrompt || pendingPromptSentRef.current)
1030
+ return;
1031
+ if (pendingPromptKey && sentPendingPromptKeys.has(pendingPromptKey)) {
1032
+ pendingPromptSentRef.current = true;
1033
+ return;
1034
+ }
1035
+ if (!historyLoaded)
1036
+ return;
1037
+ if (!adapterReady && !onSendMessage)
1038
+ return;
1039
+ pendingPromptSentRef.current = true;
1040
+ if (pendingPromptKey) {
1041
+ sentPendingPromptKeys.add(pendingPromptKey);
1042
+ }
1043
+ queueMicrotask(() => handleSend(pendingPrompt));
1044
+ }, [
1045
+ pendingPrompt,
1046
+ pendingPromptKey,
1047
+ historyLoaded,
1048
+ adapterReady,
1049
+ handleSend,
1050
+ onSendMessage,
1051
+ ]);
1052
+ // ---- handleStop ----
1053
+ const handleStop = useCallback(() => {
1054
+ stoppedRef.current = true;
1055
+ abortControllerRef.current?.abort();
1056
+ // Best-effort cancellation without tearing down adapter/session.
1057
+ const adapter = adapterRef.current;
1058
+ if (adapter) {
1059
+ // Abort the client-side SSE / fetch stream (if the adapter exposes it).
1060
+ if (typeof adapter.stopGeneration === 'function') {
1061
+ adapter.stopGeneration();
1062
+ }
1063
+ // Also tell the backend to stop (server-side cancellation).
1064
+ if (typeof adapter.terminateSession === 'function') {
1065
+ void adapter.terminateSession().catch(() => { });
1066
+ }
1067
+ else if (typeof adapter.terminateAgent === 'function') {
1068
+ void adapter.terminateAgent().catch(() => { });
1069
+ }
1070
+ else if (typeof adapter.terminateTask === 'function') {
1071
+ void adapter.terminateTask().catch(() => { });
1072
+ }
1073
+ else if (typeof adapter.terminateRequest === 'function') {
1074
+ void adapter.terminateRequest().catch(() => { });
1075
+ }
1076
+ }
1077
+ // Mark in-flight tool calls as interrupted so UI doesn't remain "Executing".
1078
+ for (const [toolCallId, toolCall] of toolCallsRef.current.entries()) {
1079
+ if (toolCall.status === 'executing' || toolCall.status === 'inProgress') {
1080
+ toolCallsRef.current.set(toolCallId, {
1081
+ ...toolCall,
1082
+ status: 'error',
1083
+ error: 'Interrupted by user',
1084
+ });
1085
+ }
1086
+ }
1087
+ setDisplayItems(prev => prev.map(item => {
1088
+ if (!isToolCallMessage(item))
1089
+ return item;
1090
+ if (item.status !== 'executing' && item.status !== 'inProgress') {
1091
+ return item;
1092
+ }
1093
+ return {
1094
+ ...item,
1095
+ status: 'error',
1096
+ error: 'Interrupted by user',
1097
+ };
1098
+ }));
1099
+ if (useStoreMode) {
1100
+ useChatStore.getState().stopStreaming();
1101
+ }
1102
+ pendingToolExecutionsRef.current = 0;
1103
+ setIsLoading(false);
1104
+ setIsStreaming(false);
1105
+ suppressAssistantTextForToolOnlyRef.current = false;
1106
+ currentAssistantMessageRef.current = null;
1107
+ // Also interrupt any code running in the sandbox (best-effort).
1108
+ if (protocol?.configEndpoint) {
1109
+ const query = protocol.agentId
1110
+ ? `?agent_id=${encodeURIComponent(protocol.agentId)}`
1111
+ : '';
1112
+ const interruptUrl = `${getApiBaseFromConfig(protocol.configEndpoint)}/configure/sandbox/interrupt${query}`;
1113
+ const headers = { 'Content-Type': 'application/json' };
1114
+ if (protocol.authToken) {
1115
+ headers['Authorization'] = `Bearer ${protocol.authToken}`;
1116
+ }
1117
+ fetch(interruptUrl, { method: 'POST', headers }).catch(() => { });
1118
+ }
1119
+ }, [
1120
+ useStoreMode,
1121
+ protocol?.configEndpoint,
1122
+ protocol?.authToken,
1123
+ protocol?.agentId,
1124
+ ]);
1125
+ // ---- handleNewChat ----
1126
+ const handleNewChat = useCallback(() => {
1127
+ setDisplayItems([]);
1128
+ toolCallsRef.current.clear();
1129
+ pendingToolExecutionsRef.current = 0;
1130
+ setInput('');
1131
+ threadIdRef.current = generateMessageId();
1132
+ if (useStoreMode)
1133
+ clearStoreMessages();
1134
+ if (runtimeId)
1135
+ useConversationStore.getState().clearMessages(runtimeId);
1136
+ onNewChat?.();
1137
+ headerButtons?.onNewChat?.();
1138
+ }, [clearStoreMessages, onNewChat, headerButtons, useStoreMode, runtimeId]);
1139
+ // ---- handleClear ----
1140
+ const handleClear = useCallback(() => {
1141
+ if (window.confirm('Clear all messages?')) {
1142
+ setDisplayItems([]);
1143
+ toolCallsRef.current.clear();
1144
+ if (useStoreMode)
1145
+ clearStoreMessages();
1146
+ if (runtimeId)
1147
+ useConversationStore.getState().clearMessages(runtimeId);
1148
+ onClear?.();
1149
+ headerButtons?.onClear?.();
1150
+ }
1151
+ }, [clearStoreMessages, onClear, headerButtons, useStoreMode, runtimeId]);
1152
+ // ---- handleSandboxInterrupt ----
1153
+ const handleSandboxInterrupt = useCallback(async () => {
1154
+ if (!protocol?.configEndpoint)
1155
+ return;
1156
+ const interruptUrl = `${getApiBaseFromConfig(protocol.configEndpoint)}/configure/sandbox/interrupt`;
1157
+ try {
1158
+ const headers = { 'Content-Type': 'application/json' };
1159
+ if (protocol.authToken) {
1160
+ headers['Authorization'] = `Bearer ${protocol.authToken}`;
1161
+ }
1162
+ await fetch(interruptUrl, { method: 'POST', headers });
1163
+ sandboxStatusQuery.refetch();
1164
+ }
1165
+ catch {
1166
+ // Interrupt is best-effort
1167
+ }
1168
+ }, [protocol?.configEndpoint, protocol?.authToken, sandboxStatusQuery]);
1169
+ // ---- HITL respond handler (passed to MessageList) ----
1170
+ const handleRespond = useCallback(async (toolCallId, result) => {
1171
+ const existingToolCall = toolCallsRef.current.get(toolCallId);
1172
+ if (existingToolCall && existingToolCall.status === 'executing') {
1173
+ const updatedToolCall = {
1174
+ ...existingToolCall,
1175
+ result,
1176
+ status: 'complete',
1177
+ };
1178
+ toolCallsRef.current.set(toolCallId, updatedToolCall);
1179
+ setDisplayItems(prev => prev.map(item => isToolCallMessage(item) && item.toolCallId === toolCallId
1180
+ ? updatedToolCall
1181
+ : item));
1182
+ if (adapterRef.current) {
1183
+ let responseText;
1184
+ if (typeof result === 'string') {
1185
+ responseText = result;
1186
+ }
1187
+ else if (result &&
1188
+ typeof result === 'object' &&
1189
+ 'accepted' in result) {
1190
+ const hitlResult = result;
1191
+ if (hitlResult.accepted) {
1192
+ const stepDescriptions = hitlResult.steps?.map(s => s.description).join(', ') || '';
1193
+ responseText = stepDescriptions
1194
+ ? `I confirm and approve the following steps: ${stepDescriptions}`
1195
+ : 'I confirm and approve the plan.';
1196
+ }
1197
+ else {
1198
+ responseText =
1199
+ 'I reject this plan. Please suggest something else.';
1200
+ }
1201
+ }
1202
+ else {
1203
+ responseText = JSON.stringify(result, null, 2);
1204
+ }
1205
+ const userMessage = {
1206
+ id: generateMessageId(),
1207
+ role: 'user',
1208
+ content: responseText,
1209
+ createdAt: new Date(),
1210
+ };
1211
+ setIsLoading(true);
1212
+ setIsStreaming(true);
1213
+ try {
1214
+ const allMessages = displayItems.filter((item) => !isToolCallMessage(item));
1215
+ await adapterRef.current.sendMessage(userMessage, {
1216
+ threadId: threadIdRef.current,
1217
+ messages: [...allMessages, userMessage],
1218
+ });
1219
+ }
1220
+ catch (err) {
1221
+ console.error('[ChatBase] HITL respond error:', err);
1222
+ }
1223
+ // NOTE: Do NOT reset isLoading here — the adapter's 'done'
1224
+ // event will handle it when the run truly completes.
1225
+ }
1226
+ }
1227
+ }, [displayItems]);
1228
+ // ---- Suggestion handlers (for EmptyState) ----
1229
+ const handleSuggestionSubmit = useCallback((suggestion) => {
1230
+ void handleSend(suggestion.message);
1231
+ }, [handleSend]);
1232
+ const handleSuggestionFill = useCallback((message) => {
1233
+ setInput(message);
1234
+ setTimeout(() => inputRef.current?.focus(), 0);
1235
+ }, []);
1236
+ // ---- Not ready ----
1237
+ if (!ready) {
1238
+ return (_jsx(Box, { className: className, sx: {
1239
+ display: 'flex',
1240
+ flexDirection: 'column',
1241
+ alignItems: 'center',
1242
+ justifyContent: 'center',
1243
+ height: '100%',
1244
+ p: 4,
1245
+ borderRadius,
1246
+ bg: backgroundColor || 'canvas.default',
1247
+ border,
1248
+ boxShadow,
1249
+ }, children: loadingState || (_jsxs(_Fragment, { children: [_jsx(Spinner, { size: "large" }), _jsx(Text, { sx: { mt: 3, color: 'fg.muted' }, children: "Initializing chat..." })] })) }));
1250
+ }
1251
+ // ---- apiBase for indicators (derived from configEndpoint) ----
1252
+ // Indicators (McpStatusIndicator, SandboxStatusIndicator) prepend
1253
+ // "/api/v1/configure/…" themselves, so we need the raw base URL
1254
+ // (without "/api/v1") rather than getApiBaseFromConfig() which keeps it.
1255
+ const indicatorApiBase = protocol?.configEndpoint
1256
+ ? protocol.configEndpoint.replace(/\/api\/v1\/(config|configure)\/?$/, '')
1257
+ : undefined;
1258
+ // ---- Compute data for InputToolbar ----
1259
+ const filteredMcpServers = (configQuery.data?.mcpServers || []).filter(server => !mcpServers || isServerSelected(server));
1260
+ // ========================================================================
1261
+ // Render
1262
+ // ========================================================================
1263
+ return (_jsxs(Box, { className: className, sx: {
1264
+ display: 'flex',
1265
+ flexDirection: 'column',
1266
+ height: '100%',
1267
+ bg: backgroundColor || 'canvas.default',
1268
+ borderRadius,
1269
+ border,
1270
+ boxShadow,
1271
+ overflow: 'hidden',
1272
+ }, children: [showHeader && (_jsx(ChatBaseHeader, { title: title, brandIcon: brandIcon, headerContent: headerContent, headerActions: headerActions, showInformation: showInformation, onInformationClick: onInformationClick, padding: padding, sandboxStatus: sandboxStatus, onSandboxInterrupt: handleSandboxInterrupt, headerButtons: headerButtons, messageCount: messages.length, onNewChat: handleNewChat, onClear: handleClear, chatViewMode: chatViewMode, onChatViewModeChange: onChatViewModeChange })), showErrors && error && (_jsxs(Box, { sx: {
1273
+ display: 'flex',
1274
+ alignItems: 'center',
1275
+ gap: 2,
1276
+ p: padding,
1277
+ bg: 'danger.subtle',
1278
+ borderBottom: '1px solid',
1279
+ borderColor: 'danger.muted',
1280
+ }, children: [_jsx(AlertIcon, { size: 16 }), _jsx(Text, { sx: { color: 'danger.fg', fontSize: 1 }, children: error.message })] })), _jsx(Box, { sx: { flex: 1, flexGrow: 1, overflow: 'auto', bg: 'canvas.default' }, children: children ? (children) : (_jsx(Box, { sx: {
1281
+ display: 'flex',
1282
+ flexDirection: 'column',
1283
+ minHeight: '100%',
1284
+ bg: 'canvas.default',
1285
+ }, children: _jsx(ChatMessageList, { displayItems: displayItems, isLoading: isLoading, isStreaming: isStreaming, showLoadingIndicator: showLoadingIndicator, hideMessagesAfterToolUI: hideMessagesAfterToolUI, avatarConfig: defaultAvatarConfig, padding: padding, renderToolResult: renderToolResult, approvalConfig: approvalConfig, messagesEndRef: messagesEndRef, onRespond: handleRespond, emptyContent: _jsx(ChatEmptyState, { emptyState: emptyState, brandIcon: brandIcon, description: description, suggestions: suggestions, submitOnSuggestionClick: submitOnSuggestionClick, onSuggestionSubmit: handleSuggestionSubmit, onSuggestionFill: handleSuggestionFill }) }) })) }), footerContent, showInput && (_jsx(InputToolbar, { input: input, setInput: setInput, isLoading: isLoading, placeholder: placeholder, autoFocus: autoFocus, focusTrigger: focusTrigger, padding: padding, onSend: () => handleSend(), onStop: handleStop, showTokenUsage: showTokenUsage, agentUsage: agentUsage, showModelSelector: showModelSelector, showToolsMenu: showToolsMenu, showSkillsMenu: showSkillsMenu, codemodeEnabled: codemodeEnabled, isA2AProtocol: isA2AProtocol, hasConfigData: !!configQuery.data, hasSkillsData: !!skillsQuery.data, models: availableModels || configQuery.data?.models || [], selectedModel: selectedModel, onModelSelect: setSelectedModel, availableTools: configQuery.data?.builtinTools || [], mcpServers: filteredMcpServers, enabledMcpTools: enabledMcpTools, enabledMcpToolCount: getEnabledMcpToolNames().length, onToggleMcpTool: toggleMcpTool, onToggleAllMcpServerTools: toggleAllMcpServerTools, skills: skillsQuery.data?.skills || [], skillsLoading: !!skillsQuery.isLoading, enabledSkills: enabledSkills, onToggleSkill: toggleSkill, onToggleAllSkills: toggleAllSkills, apiBase: indicatorApiBase, authToken: protocol?.authToken, agentId: protocol?.agentId })), showPoweredBy && _jsx(PoweredByTag, { ...poweredByProps })] }));
1286
+ }
1287
+ export default ChatBase;