@parhelia/core 0.1.10745

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 (1012) hide show
  1. package/LICENSE +8 -0
  2. package/README.md +34 -0
  3. package/dev.css +3 -0
  4. package/dist/agents-view/AgentCard.d.ts +12 -0
  5. package/dist/agents-view/AgentCard.js +30 -0
  6. package/dist/agents-view/AgentCard.js.map +1 -0
  7. package/dist/agents-view/AgentsView.d.ts +5 -0
  8. package/dist/agents-view/AgentsView.js +255 -0
  9. package/dist/agents-view/AgentsView.js.map +1 -0
  10. package/dist/agents-view/ProfileAgentsGroup.d.ts +17 -0
  11. package/dist/agents-view/ProfileAgentsGroup.js +13 -0
  12. package/dist/agents-view/ProfileAgentsGroup.js.map +1 -0
  13. package/dist/client-components/api.d.ts +1 -0
  14. package/dist/client-components/api.js +4 -0
  15. package/dist/client-components/api.js.map +1 -0
  16. package/dist/client-components/index.d.ts +17 -0
  17. package/dist/client-components/index.js +18 -0
  18. package/dist/client-components/index.js.map +1 -0
  19. package/dist/components/ActionButton.d.ts +14 -0
  20. package/dist/components/ActionButton.js +6 -0
  21. package/dist/components/ActionButton.js.map +1 -0
  22. package/dist/components/Error.d.ts +9 -0
  23. package/dist/components/Error.js +24 -0
  24. package/dist/components/Error.js.map +1 -0
  25. package/dist/components/FilterInput.d.ts +22 -0
  26. package/dist/components/FilterInput.js +29 -0
  27. package/dist/components/FilterInput.js.map +1 -0
  28. package/dist/components/index.d.ts +7 -0
  29. package/dist/components/index.js +5 -0
  30. package/dist/components/index.js.map +1 -0
  31. package/dist/components/ui/CardConnector.d.ts +4 -0
  32. package/dist/components/ui/CardConnector.js +6 -0
  33. package/dist/components/ui/CardConnector.js.map +1 -0
  34. package/dist/components/ui/LanguageSelector.d.ts +8 -0
  35. package/dist/components/ui/LanguageSelector.js +47 -0
  36. package/dist/components/ui/LanguageSelector.js.map +1 -0
  37. package/dist/components/ui/PlaceholderInput.d.ts +41 -0
  38. package/dist/components/ui/PlaceholderInput.js +160 -0
  39. package/dist/components/ui/PlaceholderInput.js.map +1 -0
  40. package/dist/components/ui/PlaceholderInputTypes.d.ts +41 -0
  41. package/dist/components/ui/PlaceholderInputTypes.js +48 -0
  42. package/dist/components/ui/PlaceholderInputTypes.js.map +1 -0
  43. package/dist/components/ui/PlaceholderItemSelector.d.ts +7 -0
  44. package/dist/components/ui/PlaceholderItemSelector.js +154 -0
  45. package/dist/components/ui/PlaceholderItemSelector.js.map +1 -0
  46. package/dist/components/ui/alert.d.ts +7 -0
  47. package/dist/components/ui/alert.js +21 -0
  48. package/dist/components/ui/alert.js.map +1 -0
  49. package/dist/components/ui/badge.d.ts +9 -0
  50. package/dist/components/ui/badge.js +23 -0
  51. package/dist/components/ui/badge.js.map +1 -0
  52. package/dist/components/ui/button.d.ts +10 -0
  53. package/dist/components/ui/button.js +33 -0
  54. package/dist/components/ui/button.js.map +1 -0
  55. package/dist/components/ui/calendar.d.ts +7 -0
  56. package/dist/components/ui/calendar.js +58 -0
  57. package/dist/components/ui/calendar.js.map +1 -0
  58. package/dist/components/ui/card.d.ts +19 -0
  59. package/dist/components/ui/card.js +78 -0
  60. package/dist/components/ui/card.js.map +1 -0
  61. package/dist/components/ui/checkbox.d.ts +4 -0
  62. package/dist/components/ui/checkbox.js +10 -0
  63. package/dist/components/ui/checkbox.js.map +1 -0
  64. package/dist/components/ui/command.d.ts +18 -0
  65. package/dist/components/ui/command.js +35 -0
  66. package/dist/components/ui/command.js.map +1 -0
  67. package/dist/components/ui/context-menu.d.ts +53 -0
  68. package/dist/components/ui/context-menu.js +290 -0
  69. package/dist/components/ui/context-menu.js.map +1 -0
  70. package/dist/components/ui/copy-button.d.ts +10 -0
  71. package/dist/components/ui/copy-button.js +61 -0
  72. package/dist/components/ui/copy-button.js.map +1 -0
  73. package/dist/components/ui/dialog.d.ts +16 -0
  74. package/dist/components/ui/dialog.js +37 -0
  75. package/dist/components/ui/dialog.js.map +1 -0
  76. package/dist/components/ui/dropdown-menu.d.ts +25 -0
  77. package/dist/components/ui/dropdown-menu.js +52 -0
  78. package/dist/components/ui/dropdown-menu.js.map +1 -0
  79. package/dist/components/ui/input.d.ts +3 -0
  80. package/dist/components/ui/input.js +9 -0
  81. package/dist/components/ui/input.js.map +1 -0
  82. package/dist/components/ui/menubar.d.ts +26 -0
  83. package/dist/components/ui/menubar.js +55 -0
  84. package/dist/components/ui/menubar.js.map +1 -0
  85. package/dist/components/ui/paste-button.d.ts +14 -0
  86. package/dist/components/ui/paste-button.js +114 -0
  87. package/dist/components/ui/paste-button.js.map +1 -0
  88. package/dist/components/ui/popover.d.ts +11 -0
  89. package/dist/components/ui/popover.js +66 -0
  90. package/dist/components/ui/popover.js.map +1 -0
  91. package/dist/components/ui/progress.d.ts +7 -0
  92. package/dist/components/ui/progress.js +9 -0
  93. package/dist/components/ui/progress.js.map +1 -0
  94. package/dist/components/ui/select.d.ts +18 -0
  95. package/dist/components/ui/select.js +34 -0
  96. package/dist/components/ui/select.js.map +1 -0
  97. package/dist/components/ui/sonner.d.ts +3 -0
  98. package/dist/components/ui/sonner.js +16 -0
  99. package/dist/components/ui/sonner.js.map +1 -0
  100. package/dist/components/ui/switch.d.ts +4 -0
  101. package/dist/components/ui/switch.js +9 -0
  102. package/dist/components/ui/switch.js.map +1 -0
  103. package/dist/components/ui/tabs.d.ts +17 -0
  104. package/dist/components/ui/tabs.js +27 -0
  105. package/dist/components/ui/tabs.js.map +1 -0
  106. package/dist/components/ui/textarea.d.ts +3 -0
  107. package/dist/components/ui/textarea.js +11 -0
  108. package/dist/components/ui/textarea.js.map +1 -0
  109. package/dist/components/ui/tooltip.d.ts +9 -0
  110. package/dist/components/ui/tooltip.js +18 -0
  111. package/dist/components/ui/tooltip.js.map +1 -0
  112. package/dist/components/ui/upload-button.d.ts +15 -0
  113. package/dist/components/ui/upload-button.js +56 -0
  114. package/dist/components/ui/upload-button.js.map +1 -0
  115. package/dist/config/config.d.ts +24 -0
  116. package/dist/config/config.js +1087 -0
  117. package/dist/config/config.js.map +1 -0
  118. package/dist/config/types.d.ts +249 -0
  119. package/dist/config/types.js +2 -0
  120. package/dist/config/types.js.map +1 -0
  121. package/dist/editor/AspectRatioSelector.d.ts +13 -0
  122. package/dist/editor/AspectRatioSelector.js +71 -0
  123. package/dist/editor/AspectRatioSelector.js.map +1 -0
  124. package/dist/editor/ComponentInfo.d.ts +4 -0
  125. package/dist/editor/ComponentInfo.js +41 -0
  126. package/dist/editor/ComponentInfo.js.map +1 -0
  127. package/dist/editor/ConfirmationDialog.d.ts +19 -0
  128. package/dist/editor/ConfirmationDialog.js +31 -0
  129. package/dist/editor/ConfirmationDialog.js.map +1 -0
  130. package/dist/editor/ContentTree.d.ts +39 -0
  131. package/dist/editor/ContentTree.js +586 -0
  132. package/dist/editor/ContentTree.js.map +1 -0
  133. package/dist/editor/ContextMenu.d.ts +15 -0
  134. package/dist/editor/ContextMenu.js +239 -0
  135. package/dist/editor/ContextMenu.js.map +1 -0
  136. package/dist/editor/Editor.d.ts +12 -0
  137. package/dist/editor/Editor.js +59 -0
  138. package/dist/editor/Editor.js.map +1 -0
  139. package/dist/editor/EditorWarning.d.ts +5 -0
  140. package/dist/editor/EditorWarning.js +12 -0
  141. package/dist/editor/EditorWarning.js.map +1 -0
  142. package/dist/editor/EditorWarnings.d.ts +9 -0
  143. package/dist/editor/EditorWarnings.js +19 -0
  144. package/dist/editor/EditorWarnings.js.map +1 -0
  145. package/dist/editor/FieldActionsOverlay.d.ts +18 -0
  146. package/dist/editor/FieldActionsOverlay.js +201 -0
  147. package/dist/editor/FieldActionsOverlay.js.map +1 -0
  148. package/dist/editor/FieldEditorPopup.d.ts +10 -0
  149. package/dist/editor/FieldEditorPopup.js +23 -0
  150. package/dist/editor/FieldEditorPopup.js.map +1 -0
  151. package/dist/editor/FieldHistory.d.ts +7 -0
  152. package/dist/editor/FieldHistory.js +42 -0
  153. package/dist/editor/FieldHistory.js.map +1 -0
  154. package/dist/editor/FieldList.d.ts +19 -0
  155. package/dist/editor/FieldList.js +90 -0
  156. package/dist/editor/FieldList.js.map +1 -0
  157. package/dist/editor/FieldListField.d.ts +16 -0
  158. package/dist/editor/FieldListField.js +231 -0
  159. package/dist/editor/FieldListField.js.map +1 -0
  160. package/dist/editor/FieldListFieldWithFallbacks.d.ts +11 -0
  161. package/dist/editor/FieldListFieldWithFallbacks.js +120 -0
  162. package/dist/editor/FieldListFieldWithFallbacks.js.map +1 -0
  163. package/dist/editor/FloatingToolbar.d.ts +7 -0
  164. package/dist/editor/FloatingToolbar.js +91 -0
  165. package/dist/editor/FloatingToolbar.js.map +1 -0
  166. package/dist/editor/ImageEditButton.d.ts +27 -0
  167. package/dist/editor/ImageEditButton.js +22 -0
  168. package/dist/editor/ImageEditButton.js.map +1 -0
  169. package/dist/editor/ImageEditor.d.ts +5 -0
  170. package/dist/editor/ImageEditor.js +76 -0
  171. package/dist/editor/ImageEditor.js.map +1 -0
  172. package/dist/editor/ItemInfo.d.ts +4 -0
  173. package/dist/editor/ItemInfo.js +36 -0
  174. package/dist/editor/ItemInfo.js.map +1 -0
  175. package/dist/editor/LinkEditorDialog.d.ts +18 -0
  176. package/dist/editor/LinkEditorDialog.js +101 -0
  177. package/dist/editor/LinkEditorDialog.js.map +1 -0
  178. package/dist/editor/MainLayout.d.ts +12 -0
  179. package/dist/editor/MainLayout.js +55 -0
  180. package/dist/editor/MainLayout.js.map +1 -0
  181. package/dist/editor/MobileLayout.d.ts +2 -0
  182. package/dist/editor/MobileLayout.js +34 -0
  183. package/dist/editor/MobileLayout.js.map +1 -0
  184. package/dist/editor/NewEditorClient.d.ts +5 -0
  185. package/dist/editor/NewEditorClient.js +7 -0
  186. package/dist/editor/NewEditorClient.js.map +1 -0
  187. package/dist/editor/PictureCropper.d.ts +6 -0
  188. package/dist/editor/PictureCropper.js +722 -0
  189. package/dist/editor/PictureCropper.js.map +1 -0
  190. package/dist/editor/PictureEditor.d.ts +9 -0
  191. package/dist/editor/PictureEditor.js +180 -0
  192. package/dist/editor/PictureEditor.js.map +1 -0
  193. package/dist/editor/PictureEditorDialog.d.ts +8 -0
  194. package/dist/editor/PictureEditorDialog.js +195 -0
  195. package/dist/editor/PictureEditorDialog.js.map +1 -0
  196. package/dist/editor/QuickItemSwitcher.d.ts +9 -0
  197. package/dist/editor/QuickItemSwitcher.js +78 -0
  198. package/dist/editor/QuickItemSwitcher.js.map +1 -0
  199. package/dist/editor/ScrollingContentTree.d.ts +10 -0
  200. package/dist/editor/ScrollingContentTree.js +54 -0
  201. package/dist/editor/ScrollingContentTree.js.map +1 -0
  202. package/dist/editor/Titlebar.d.ts +1 -0
  203. package/dist/editor/Titlebar.js +46 -0
  204. package/dist/editor/Titlebar.js.map +1 -0
  205. package/dist/editor/ai/AgentCostDisplay.d.ts +32 -0
  206. package/dist/editor/ai/AgentCostDisplay.js +93 -0
  207. package/dist/editor/ai/AgentCostDisplay.js.map +1 -0
  208. package/dist/editor/ai/AgentHistory.d.ts +11 -0
  209. package/dist/editor/ai/AgentHistory.js +12 -0
  210. package/dist/editor/ai/AgentHistory.js.map +1 -0
  211. package/dist/editor/ai/AgentProfilesOverview.d.ts +9 -0
  212. package/dist/editor/ai/AgentProfilesOverview.js +16 -0
  213. package/dist/editor/ai/AgentProfilesOverview.js.map +1 -0
  214. package/dist/editor/ai/AgentStatusBadge.d.ts +26 -0
  215. package/dist/editor/ai/AgentStatusBadge.js +126 -0
  216. package/dist/editor/ai/AgentStatusBadge.js.map +1 -0
  217. package/dist/editor/ai/AgentTerminal.d.ts +14 -0
  218. package/dist/editor/ai/AgentTerminal.js +2634 -0
  219. package/dist/editor/ai/AgentTerminal.js.map +1 -0
  220. package/dist/editor/ai/Agents.d.ts +4 -0
  221. package/dist/editor/ai/Agents.js +813 -0
  222. package/dist/editor/ai/Agents.js.map +1 -0
  223. package/dist/editor/ai/AiResponseMessage.d.ts +18 -0
  224. package/dist/editor/ai/AiResponseMessage.js +684 -0
  225. package/dist/editor/ai/AiResponseMessage.js.map +1 -0
  226. package/dist/editor/ai/ContextInfoBar.d.ts +11 -0
  227. package/dist/editor/ai/ContextInfoBar.js +355 -0
  228. package/dist/editor/ai/ContextInfoBar.js.map +1 -0
  229. package/dist/editor/ai/DancingDots.d.ts +1 -0
  230. package/dist/editor/ai/DancingDots.js +6 -0
  231. package/dist/editor/ai/DancingDots.js.map +1 -0
  232. package/dist/editor/ai/MediaImage.d.ts +6 -0
  233. package/dist/editor/ai/MediaImage.js +38 -0
  234. package/dist/editor/ai/MediaImage.js.map +1 -0
  235. package/dist/editor/ai/ToolCallDisplay.d.ts +45 -0
  236. package/dist/editor/ai/ToolCallDisplay.js +292 -0
  237. package/dist/editor/ai/ToolCallDisplay.js.map +1 -0
  238. package/dist/editor/ai/aiPageModel.d.ts +24 -0
  239. package/dist/editor/ai/aiPageModel.js +97 -0
  240. package/dist/editor/ai/aiPageModel.js.map +1 -0
  241. package/dist/editor/ai/editorAiContext.d.ts +10 -0
  242. package/dist/editor/ai/editorAiContext.js +10 -0
  243. package/dist/editor/ai/editorAiContext.js.map +1 -0
  244. package/dist/editor/ai/types.d.ts +30 -0
  245. package/dist/editor/ai/types.js +2 -0
  246. package/dist/editor/ai/types.js.map +1 -0
  247. package/dist/editor/ai/useAgentStatus.d.ts +14 -0
  248. package/dist/editor/ai/useAgentStatus.js +203 -0
  249. package/dist/editor/ai/useAgentStatus.js.map +1 -0
  250. package/dist/editor/client/AboutDialog.d.ts +2 -0
  251. package/dist/editor/client/AboutDialog.js +23 -0
  252. package/dist/editor/client/AboutDialog.js.map +1 -0
  253. package/dist/editor/client/EditorShell.d.ts +37 -0
  254. package/dist/editor/client/EditorShell.js +2388 -0
  255. package/dist/editor/client/EditorShell.js.map +1 -0
  256. package/dist/editor/client/GenericDialog.d.ts +10 -0
  257. package/dist/editor/client/GenericDialog.js +25 -0
  258. package/dist/editor/client/GenericDialog.js.map +1 -0
  259. package/dist/editor/client/editContext.d.ts +260 -0
  260. package/dist/editor/client/editContext.js +29 -0
  261. package/dist/editor/client/editContext.js.map +1 -0
  262. package/dist/editor/client/fieldModificationStore.d.ts +25 -0
  263. package/dist/editor/client/fieldModificationStore.js +184 -0
  264. package/dist/editor/client/fieldModificationStore.js.map +1 -0
  265. package/dist/editor/client/helpers.d.ts +12 -0
  266. package/dist/editor/client/helpers.js +29 -0
  267. package/dist/editor/client/helpers.js.map +1 -0
  268. package/dist/editor/client/hooks/useEditorUrlSync.d.ts +18 -0
  269. package/dist/editor/client/hooks/useEditorUrlSync.js +56 -0
  270. package/dist/editor/client/hooks/useEditorUrlSync.js.map +1 -0
  271. package/dist/editor/client/hooks/useEditorWebSocket.d.ts +11 -0
  272. package/dist/editor/client/hooks/useEditorWebSocket.js +86 -0
  273. package/dist/editor/client/hooks/useEditorWebSocket.js.map +1 -0
  274. package/dist/editor/client/hooks/useGlobalEditorKeyDown.d.ts +1 -0
  275. package/dist/editor/client/hooks/useGlobalEditorKeyDown.js +12 -0
  276. package/dist/editor/client/hooks/useGlobalEditorKeyDown.js.map +1 -0
  277. package/dist/editor/client/hooks/useMediaQuery.d.ts +1 -0
  278. package/dist/editor/client/hooks/useMediaQuery.js +19 -0
  279. package/dist/editor/client/hooks/useMediaQuery.js.map +1 -0
  280. package/dist/editor/client/hooks/useMediaSelector.d.ts +12 -0
  281. package/dist/editor/client/hooks/useMediaSelector.js +30 -0
  282. package/dist/editor/client/hooks/useMediaSelector.js.map +1 -0
  283. package/dist/editor/client/hooks/useQuota.d.ts +29 -0
  284. package/dist/editor/client/hooks/useQuota.js +53 -0
  285. package/dist/editor/client/hooks/useQuota.js.map +1 -0
  286. package/dist/editor/client/hooks/useSocketMessageHandler.d.ts +35 -0
  287. package/dist/editor/client/hooks/useSocketMessageHandler.js +234 -0
  288. package/dist/editor/client/hooks/useSocketMessageHandler.js.map +1 -0
  289. package/dist/editor/client/hooks/useWorkbox.d.ts +9 -0
  290. package/dist/editor/client/hooks/useWorkbox.js +52 -0
  291. package/dist/editor/client/hooks/useWorkbox.js.map +1 -0
  292. package/dist/editor/client/itemsRepository.d.ts +38 -0
  293. package/dist/editor/client/itemsRepository.js +468 -0
  294. package/dist/editor/client/itemsRepository.js.map +1 -0
  295. package/dist/editor/client/operations.d.ts +69 -0
  296. package/dist/editor/client/operations.js +627 -0
  297. package/dist/editor/client/operations.js.map +1 -0
  298. package/dist/editor/client/pageModelBuilder.d.ts +6 -0
  299. package/dist/editor/client/pageModelBuilder.js +155 -0
  300. package/dist/editor/client/pageModelBuilder.js.map +1 -0
  301. package/dist/editor/client/ui/EditorChrome.d.ts +12 -0
  302. package/dist/editor/client/ui/EditorChrome.js +30 -0
  303. package/dist/editor/client/ui/EditorChrome.js.map +1 -0
  304. package/dist/editor/client/ui/FullscreenControls.d.ts +7 -0
  305. package/dist/editor/client/ui/FullscreenControls.js +21 -0
  306. package/dist/editor/client/ui/FullscreenControls.js.map +1 -0
  307. package/dist/editor/commands/agentCommands.d.ts +9 -0
  308. package/dist/editor/commands/agentCommands.js +30 -0
  309. package/dist/editor/commands/agentCommands.js.map +1 -0
  310. package/dist/editor/commands/commands.d.ts +19 -0
  311. package/dist/editor/commands/commands.js +2 -0
  312. package/dist/editor/commands/commands.js.map +1 -0
  313. package/dist/editor/commands/componentCommands.d.ts +12 -0
  314. package/dist/editor/commands/componentCommands.js +378 -0
  315. package/dist/editor/commands/componentCommands.js.map +1 -0
  316. package/dist/editor/commands/createVersionCommand.d.ts +4 -0
  317. package/dist/editor/commands/createVersionCommand.js +24 -0
  318. package/dist/editor/commands/createVersionCommand.js.map +1 -0
  319. package/dist/editor/commands/deleteVersionCommand.d.ts +4 -0
  320. package/dist/editor/commands/deleteVersionCommand.js +53 -0
  321. package/dist/editor/commands/deleteVersionCommand.js.map +1 -0
  322. package/dist/editor/commands/itemCommands.d.ts +29 -0
  323. package/dist/editor/commands/itemCommands.js +428 -0
  324. package/dist/editor/commands/itemCommands.js.map +1 -0
  325. package/dist/editor/commands/localizeItem/LocalizeItemDialog.d.ts +8 -0
  326. package/dist/editor/commands/localizeItem/LocalizeItemDialog.js +91 -0
  327. package/dist/editor/commands/localizeItem/LocalizeItemDialog.js.map +1 -0
  328. package/dist/editor/commands/undo.d.ts +15 -0
  329. package/dist/editor/commands/undo.js +29 -0
  330. package/dist/editor/commands/undo.js.map +1 -0
  331. package/dist/editor/componentTreeHelper.d.ts +18 -0
  332. package/dist/editor/componentTreeHelper.js +123 -0
  333. package/dist/editor/componentTreeHelper.js.map +1 -0
  334. package/dist/editor/context-menu/CopyMoveMenu.d.ts +7 -0
  335. package/dist/editor/context-menu/CopyMoveMenu.js +58 -0
  336. package/dist/editor/context-menu/CopyMoveMenu.js.map +1 -0
  337. package/dist/editor/context-menu/InsertMenu.d.ts +9 -0
  338. package/dist/editor/context-menu/InsertMenu.js +229 -0
  339. package/dist/editor/context-menu/InsertMenu.js.map +1 -0
  340. package/dist/editor/control-center/About.d.ts +1 -0
  341. package/dist/editor/control-center/About.js +8 -0
  342. package/dist/editor/control-center/About.js.map +1 -0
  343. package/dist/editor/control-center/AllAgentsPanel.d.ts +5 -0
  344. package/dist/editor/control-center/AllAgentsPanel.js +126 -0
  345. package/dist/editor/control-center/AllAgentsPanel.js.map +1 -0
  346. package/dist/editor/control-center/ControlCenterMenu.d.ts +1 -0
  347. package/dist/editor/control-center/ControlCenterMenu.js +66 -0
  348. package/dist/editor/control-center/ControlCenterMenu.js.map +1 -0
  349. package/dist/editor/control-center/IndexOverview.d.ts +1 -0
  350. package/dist/editor/control-center/IndexOverview.js +323 -0
  351. package/dist/editor/control-center/IndexOverview.js.map +1 -0
  352. package/dist/editor/control-center/Info.d.ts +1 -0
  353. package/dist/editor/control-center/Info.js +10 -0
  354. package/dist/editor/control-center/Info.js.map +1 -0
  355. package/dist/editor/control-center/LatestFeedback.d.ts +1 -0
  356. package/dist/editor/control-center/LatestFeedback.js +136 -0
  357. package/dist/editor/control-center/LatestFeedback.js.map +1 -0
  358. package/dist/editor/control-center/QuotaInfo.d.ts +1 -0
  359. package/dist/editor/control-center/QuotaInfo.js +102 -0
  360. package/dist/editor/control-center/QuotaInfo.js.map +1 -0
  361. package/dist/editor/control-center/Setup.d.ts +1 -0
  362. package/dist/editor/control-center/Setup.js +18 -0
  363. package/dist/editor/control-center/Setup.js.map +1 -0
  364. package/dist/editor/control-center/Status.d.ts +1 -0
  365. package/dist/editor/control-center/Status.js +79 -0
  366. package/dist/editor/control-center/Status.js.map +1 -0
  367. package/dist/editor/control-center/WebSocketMessages.d.ts +1 -0
  368. package/dist/editor/control-center/WebSocketMessages.js +71 -0
  369. package/dist/editor/control-center/WebSocketMessages.js.map +1 -0
  370. package/dist/editor/control-center/parhelia-setup/Overview.d.ts +1 -0
  371. package/dist/editor/control-center/parhelia-setup/Overview.js +91 -0
  372. package/dist/editor/control-center/parhelia-setup/Overview.js.map +1 -0
  373. package/dist/editor/control-center/setup-steps/AiSetupStep/EmbeddingsModelSection.d.ts +2 -0
  374. package/dist/editor/control-center/setup-steps/AiSetupStep/EmbeddingsModelSection.js +195 -0
  375. package/dist/editor/control-center/setup-steps/AiSetupStep/EmbeddingsModelSection.js.map +1 -0
  376. package/dist/editor/control-center/setup-steps/AiSetupStep/index.d.ts +2 -0
  377. package/dist/editor/control-center/setup-steps/AiSetupStep/index.js +22 -0
  378. package/dist/editor/control-center/setup-steps/AiSetupStep/index.js.map +1 -0
  379. package/dist/editor/control-center/setup-steps/AiSetupStep/provider/ProviderSection.d.ts +1 -0
  380. package/dist/editor/control-center/setup-steps/AiSetupStep/provider/ProviderSection.js +233 -0
  381. package/dist/editor/control-center/setup-steps/AiSetupStep/provider/ProviderSection.js.map +1 -0
  382. package/dist/editor/control-center/setup-steps/AiSetupStep/required-containers/RequiredContainersList.d.ts +15 -0
  383. package/dist/editor/control-center/setup-steps/AiSetupStep/required-containers/RequiredContainersList.js +14 -0
  384. package/dist/editor/control-center/setup-steps/AiSetupStep/required-containers/RequiredContainersList.js.map +1 -0
  385. package/dist/editor/control-center/setup-steps/AiSetupStep/required-containers/RequiredContainersSection.d.ts +1 -0
  386. package/dist/editor/control-center/setup-steps/AiSetupStep/required-containers/RequiredContainersSection.js +94 -0
  387. package/dist/editor/control-center/setup-steps/AiSetupStep/required-containers/RequiredContainersSection.js.map +1 -0
  388. package/dist/editor/control-center/setup-steps/AiSetupStep/tools/GenerateToolsSection.d.ts +1 -0
  389. package/dist/editor/control-center/setup-steps/AiSetupStep/tools/GenerateToolsSection.js +367 -0
  390. package/dist/editor/control-center/setup-steps/AiSetupStep/tools/GenerateToolsSection.js.map +1 -0
  391. package/dist/editor/control-center/setup-steps/AiSetupStep/types.d.ts +1 -0
  392. package/dist/editor/control-center/setup-steps/AiSetupStep/types.js +2 -0
  393. package/dist/editor/control-center/setup-steps/AiSetupStep/types.js.map +1 -0
  394. package/dist/editor/control-center/setup-steps/AiSetupStep/utils.d.ts +4 -0
  395. package/dist/editor/control-center/setup-steps/AiSetupStep/utils.js +25 -0
  396. package/dist/editor/control-center/setup-steps/AiSetupStep/utils.js.map +1 -0
  397. package/dist/editor/control-center/setup-steps/DbSetupStep.d.ts +2 -0
  398. package/dist/editor/control-center/setup-steps/DbSetupStep.js +46 -0
  399. package/dist/editor/control-center/setup-steps/DbSetupStep.js.map +1 -0
  400. package/dist/editor/control-center/setup-steps/IndexSetupStep.d.ts +2 -0
  401. package/dist/editor/control-center/setup-steps/IndexSetupStep.js +36 -0
  402. package/dist/editor/control-center/setup-steps/IndexSetupStep.js.map +1 -0
  403. package/dist/editor/control-center/setup-steps/SettingsSetupStep.d.ts +2 -0
  404. package/dist/editor/control-center/setup-steps/SettingsSetupStep.js +107 -0
  405. package/dist/editor/control-center/setup-steps/SettingsSetupStep.js.map +1 -0
  406. package/dist/editor/editor-warnings/ItemLocked.d.ts +2 -0
  407. package/dist/editor/editor-warnings/ItemLocked.js +38 -0
  408. package/dist/editor/editor-warnings/ItemLocked.js.map +1 -0
  409. package/dist/editor/editor-warnings/NoLanguageWriteAccess.d.ts +2 -0
  410. package/dist/editor/editor-warnings/NoLanguageWriteAccess.js +14 -0
  411. package/dist/editor/editor-warnings/NoLanguageWriteAccess.js.map +1 -0
  412. package/dist/editor/editor-warnings/NoWorkflowWriteAccess.d.ts +2 -0
  413. package/dist/editor/editor-warnings/NoWorkflowWriteAccess.js +14 -0
  414. package/dist/editor/editor-warnings/NoWorkflowWriteAccess.js.map +1 -0
  415. package/dist/editor/editor-warnings/NoWriteAccess.d.ts +2 -0
  416. package/dist/editor/editor-warnings/NoWriteAccess.js +14 -0
  417. package/dist/editor/editor-warnings/NoWriteAccess.js.map +1 -0
  418. package/dist/editor/editor-warnings/ValidationErrors.d.ts +2 -0
  419. package/dist/editor/editor-warnings/ValidationErrors.js +28 -0
  420. package/dist/editor/editor-warnings/ValidationErrors.js.map +1 -0
  421. package/dist/editor/field-types/AttachmentEditor.d.ts +9 -0
  422. package/dist/editor/field-types/AttachmentEditor.js +73 -0
  423. package/dist/editor/field-types/AttachmentEditor.js.map +1 -0
  424. package/dist/editor/field-types/CheckboxEditor.d.ts +5 -0
  425. package/dist/editor/field-types/CheckboxEditor.js +30 -0
  426. package/dist/editor/field-types/CheckboxEditor.js.map +1 -0
  427. package/dist/editor/field-types/DateFieldEditor.d.ts +5 -0
  428. package/dist/editor/field-types/DateFieldEditor.js +93 -0
  429. package/dist/editor/field-types/DateFieldEditor.js.map +1 -0
  430. package/dist/editor/field-types/DateTimeFieldEditor.d.ts +5 -0
  431. package/dist/editor/field-types/DateTimeFieldEditor.js +151 -0
  432. package/dist/editor/field-types/DateTimeFieldEditor.js.map +1 -0
  433. package/dist/editor/field-types/DropLinkEditor.d.ts +5 -0
  434. package/dist/editor/field-types/DropLinkEditor.js +42 -0
  435. package/dist/editor/field-types/DropLinkEditor.js.map +1 -0
  436. package/dist/editor/field-types/DropListEditor.d.ts +5 -0
  437. package/dist/editor/field-types/DropListEditor.js +46 -0
  438. package/dist/editor/field-types/DropListEditor.js.map +1 -0
  439. package/dist/editor/field-types/ImageFieldEditor.d.ts +5 -0
  440. package/dist/editor/field-types/ImageFieldEditor.js +34 -0
  441. package/dist/editor/field-types/ImageFieldEditor.js.map +1 -0
  442. package/dist/editor/field-types/InternalLinkFieldEditor.d.ts +5 -0
  443. package/dist/editor/field-types/InternalLinkFieldEditor.js +120 -0
  444. package/dist/editor/field-types/InternalLinkFieldEditor.js.map +1 -0
  445. package/dist/editor/field-types/LinkFieldEditor.d.ts +5 -0
  446. package/dist/editor/field-types/LinkFieldEditor.js +62 -0
  447. package/dist/editor/field-types/LinkFieldEditor.js.map +1 -0
  448. package/dist/editor/field-types/MultiLineText.d.ts +7 -0
  449. package/dist/editor/field-types/MultiLineText.js +48 -0
  450. package/dist/editor/field-types/MultiLineText.js.map +1 -0
  451. package/dist/editor/field-types/NameValueListEditor.d.ts +7 -0
  452. package/dist/editor/field-types/NameValueListEditor.js +101 -0
  453. package/dist/editor/field-types/NameValueListEditor.js.map +1 -0
  454. package/dist/editor/field-types/PictureFieldEditor.d.ts +5 -0
  455. package/dist/editor/field-types/PictureFieldEditor.js +58 -0
  456. package/dist/editor/field-types/PictureFieldEditor.js.map +1 -0
  457. package/dist/editor/field-types/RawEditor.d.ts +6 -0
  458. package/dist/editor/field-types/RawEditor.js +31 -0
  459. package/dist/editor/field-types/RawEditor.js.map +1 -0
  460. package/dist/editor/field-types/ReactQuill.d.ts +125 -0
  461. package/dist/editor/field-types/ReactQuill.js +385 -0
  462. package/dist/editor/field-types/ReactQuill.js.map +1 -0
  463. package/dist/editor/field-types/RichTextEditor.d.ts +7 -0
  464. package/dist/editor/field-types/RichTextEditor.js +21 -0
  465. package/dist/editor/field-types/RichTextEditor.js.map +1 -0
  466. package/dist/editor/field-types/RichTextEditorComponent.d.ts +8 -0
  467. package/dist/editor/field-types/RichTextEditorComponent.js +74 -0
  468. package/dist/editor/field-types/RichTextEditorComponent.js.map +1 -0
  469. package/dist/editor/field-types/SingleLineText.d.ts +7 -0
  470. package/dist/editor/field-types/SingleLineText.js +113 -0
  471. package/dist/editor/field-types/SingleLineText.js.map +1 -0
  472. package/dist/editor/field-types/TreeListEditor.d.ts +5 -0
  473. package/dist/editor/field-types/TreeListEditor.js +316 -0
  474. package/dist/editor/field-types/TreeListEditor.js.map +1 -0
  475. package/dist/editor/field-types/richtext/components/EditorDropdown.d.ts +11 -0
  476. package/dist/editor/field-types/richtext/components/EditorDropdown.js +83 -0
  477. package/dist/editor/field-types/richtext/components/EditorDropdown.js.map +1 -0
  478. package/dist/editor/field-types/richtext/components/ReactSlate.d.ts +5 -0
  479. package/dist/editor/field-types/richtext/components/ReactSlate.js +607 -0
  480. package/dist/editor/field-types/richtext/components/ReactSlate.js.map +1 -0
  481. package/dist/editor/field-types/richtext/components/SimpleDropdown.d.ts +18 -0
  482. package/dist/editor/field-types/richtext/components/SimpleDropdown.js +71 -0
  483. package/dist/editor/field-types/richtext/components/SimpleDropdown.js.map +1 -0
  484. package/dist/editor/field-types/richtext/components/SimpleRichTextEditor.d.ts +5 -0
  485. package/dist/editor/field-types/richtext/components/SimpleRichTextEditor.js +359 -0
  486. package/dist/editor/field-types/richtext/components/SimpleRichTextEditor.js.map +1 -0
  487. package/dist/editor/field-types/richtext/components/SimpleToolbar.d.ts +16 -0
  488. package/dist/editor/field-types/richtext/components/SimpleToolbar.js +181 -0
  489. package/dist/editor/field-types/richtext/components/SimpleToolbar.js.map +1 -0
  490. package/dist/editor/field-types/richtext/components/SimpleToolbarButton.d.ts +9 -0
  491. package/dist/editor/field-types/richtext/components/SimpleToolbarButton.js +14 -0
  492. package/dist/editor/field-types/richtext/components/SimpleToolbarButton.js.map +1 -0
  493. package/dist/editor/field-types/richtext/components/ToolbarButton.d.ts +3 -0
  494. package/dist/editor/field-types/richtext/components/ToolbarButton.js +6 -0
  495. package/dist/editor/field-types/richtext/components/ToolbarButton.js.map +1 -0
  496. package/dist/editor/field-types/richtext/config/pluginFactory.d.ts +19 -0
  497. package/dist/editor/field-types/richtext/config/pluginFactory.js +17 -0
  498. package/dist/editor/field-types/richtext/config/pluginFactory.js.map +1 -0
  499. package/dist/editor/field-types/richtext/contextMenuFactory.d.ts +4 -0
  500. package/dist/editor/field-types/richtext/contextMenuFactory.js +201 -0
  501. package/dist/editor/field-types/richtext/contextMenuFactory.js.map +1 -0
  502. package/dist/editor/field-types/richtext/hooks/useProfileCache.d.ts +68 -0
  503. package/dist/editor/field-types/richtext/hooks/useProfileCache.js +214 -0
  504. package/dist/editor/field-types/richtext/hooks/useProfileCache.js.map +1 -0
  505. package/dist/editor/field-types/richtext/hooks/useRichTextProfile.d.ts +25 -0
  506. package/dist/editor/field-types/richtext/hooks/useRichTextProfile.js +64 -0
  507. package/dist/editor/field-types/richtext/hooks/useRichTextProfile.js.map +1 -0
  508. package/dist/editor/field-types/richtext/index.d.ts +6 -0
  509. package/dist/editor/field-types/richtext/index.js +7 -0
  510. package/dist/editor/field-types/richtext/index.js.map +1 -0
  511. package/dist/editor/field-types/richtext/types.d.ts +288 -0
  512. package/dist/editor/field-types/richtext/types.js +107 -0
  513. package/dist/editor/field-types/richtext/types.js.map +1 -0
  514. package/dist/editor/field-types/richtext/utils/conversion.d.ts +7 -0
  515. package/dist/editor/field-types/richtext/utils/conversion.js +762 -0
  516. package/dist/editor/field-types/richtext/utils/conversion.js.map +1 -0
  517. package/dist/editor/field-types/richtext/utils/plugins.d.ts +170 -0
  518. package/dist/editor/field-types/richtext/utils/plugins.js +490 -0
  519. package/dist/editor/field-types/richtext/utils/plugins.js.map +1 -0
  520. package/dist/editor/field-types/richtext/utils/profileMapper.d.ts +38 -0
  521. package/dist/editor/field-types/richtext/utils/profileMapper.js +386 -0
  522. package/dist/editor/field-types/richtext/utils/profileMapper.js.map +1 -0
  523. package/dist/editor/field-types/richtext/utils/profileServiceCache.d.ts +37 -0
  524. package/dist/editor/field-types/richtext/utils/profileServiceCache.js +119 -0
  525. package/dist/editor/field-types/richtext/utils/profileServiceCache.js.map +1 -0
  526. package/dist/editor/fieldTypes.d.ts +129 -0
  527. package/dist/editor/fieldTypes.js +2 -0
  528. package/dist/editor/fieldTypes.js.map +1 -0
  529. package/dist/editor/hooks/useEditorSettings.d.ts +17 -0
  530. package/dist/editor/hooks/useEditorSettings.js +61 -0
  531. package/dist/editor/hooks/useEditorSettings.js.map +1 -0
  532. package/dist/editor/media-selector/AiImageSearch.d.ts +4 -0
  533. package/dist/editor/media-selector/AiImageSearch.js +164 -0
  534. package/dist/editor/media-selector/AiImageSearch.js.map +1 -0
  535. package/dist/editor/media-selector/AiImageSearchPrompt.d.ts +3 -0
  536. package/dist/editor/media-selector/AiImageSearchPrompt.js +57 -0
  537. package/dist/editor/media-selector/AiImageSearchPrompt.js.map +1 -0
  538. package/dist/editor/media-selector/MediaFolderBrowser.d.ts +5 -0
  539. package/dist/editor/media-selector/MediaFolderBrowser.js +182 -0
  540. package/dist/editor/media-selector/MediaFolderBrowser.js.map +1 -0
  541. package/dist/editor/media-selector/MediaSelector.d.ts +9 -0
  542. package/dist/editor/media-selector/MediaSelector.js +8 -0
  543. package/dist/editor/media-selector/MediaSelector.js.map +1 -0
  544. package/dist/editor/media-selector/Preview.d.ts +4 -0
  545. package/dist/editor/media-selector/Preview.js +19 -0
  546. package/dist/editor/media-selector/Preview.js.map +1 -0
  547. package/dist/editor/media-selector/Thumbnails.d.ts +8 -0
  548. package/dist/editor/media-selector/Thumbnails.js +10 -0
  549. package/dist/editor/media-selector/Thumbnails.js.map +1 -0
  550. package/dist/editor/media-selector/TreeSelector.d.ts +7 -0
  551. package/dist/editor/media-selector/TreeSelector.js +183 -0
  552. package/dist/editor/media-selector/TreeSelector.js.map +1 -0
  553. package/dist/editor/media-selector/UploadZone.d.ts +4 -0
  554. package/dist/editor/media-selector/UploadZone.js +81 -0
  555. package/dist/editor/media-selector/UploadZone.js.map +1 -0
  556. package/dist/editor/media-selector/index.d.ts +8 -0
  557. package/dist/editor/media-selector/index.js +9 -0
  558. package/dist/editor/media-selector/index.js.map +1 -0
  559. package/dist/editor/menubar/ActiveUsers.d.ts +1 -0
  560. package/dist/editor/menubar/ActiveUsers.js +120 -0
  561. package/dist/editor/menubar/ActiveUsers.js.map +1 -0
  562. package/dist/editor/menubar/ApproveAndPublish.d.ts +1 -0
  563. package/dist/editor/menubar/ApproveAndPublish.js +13 -0
  564. package/dist/editor/menubar/ApproveAndPublish.js.map +1 -0
  565. package/dist/editor/menubar/FavoritesControls.d.ts +8 -0
  566. package/dist/editor/menubar/FavoritesControls.js +124 -0
  567. package/dist/editor/menubar/FavoritesControls.js.map +1 -0
  568. package/dist/editor/menubar/GenericToolbar.d.ts +11 -0
  569. package/dist/editor/menubar/GenericToolbar.js +10 -0
  570. package/dist/editor/menubar/GenericToolbar.js.map +1 -0
  571. package/dist/editor/menubar/ItemActionsMenu.d.ts +3 -0
  572. package/dist/editor/menubar/ItemActionsMenu.js +23 -0
  573. package/dist/editor/menubar/ItemActionsMenu.js.map +1 -0
  574. package/dist/editor/menubar/ItemLanguageVersion.d.ts +1 -0
  575. package/dist/editor/menubar/ItemLanguageVersion.js +54 -0
  576. package/dist/editor/menubar/ItemLanguageVersion.js.map +1 -0
  577. package/dist/editor/menubar/ItemToolbar.d.ts +1 -0
  578. package/dist/editor/menubar/ItemToolbar.js +11 -0
  579. package/dist/editor/menubar/ItemToolbar.js.map +1 -0
  580. package/dist/editor/menubar/NavButtons.d.ts +1 -0
  581. package/dist/editor/menubar/NavButtons.js +40 -0
  582. package/dist/editor/menubar/NavButtons.js.map +1 -0
  583. package/dist/editor/menubar/PageSelector.d.ts +4 -0
  584. package/dist/editor/menubar/PageSelector.js +149 -0
  585. package/dist/editor/menubar/PageSelector.js.map +1 -0
  586. package/dist/editor/menubar/Separator.d.ts +3 -0
  587. package/dist/editor/menubar/Separator.js +6 -0
  588. package/dist/editor/menubar/Separator.js.map +1 -0
  589. package/dist/editor/menubar/SiteInfo.d.ts +1 -0
  590. package/dist/editor/menubar/SiteInfo.js +24 -0
  591. package/dist/editor/menubar/SiteInfo.js.map +1 -0
  592. package/dist/editor/menubar/ToolbarFactory.d.ts +2 -0
  593. package/dist/editor/menubar/ToolbarFactory.js +55 -0
  594. package/dist/editor/menubar/ToolbarFactory.js.map +1 -0
  595. package/dist/editor/menubar/User.d.ts +4 -0
  596. package/dist/editor/menubar/User.js +18 -0
  597. package/dist/editor/menubar/User.js.map +1 -0
  598. package/dist/editor/menubar/VersionSelector.d.ts +10 -0
  599. package/dist/editor/menubar/VersionSelector.js +53 -0
  600. package/dist/editor/menubar/VersionSelector.js.map +1 -0
  601. package/dist/editor/menubar/WorkflowButton.d.ts +1 -0
  602. package/dist/editor/menubar/WorkflowButton.js +93 -0
  603. package/dist/editor/menubar/WorkflowButton.js.map +1 -0
  604. package/dist/editor/menubar/toolbar-sections/CompareControls.d.ts +1 -0
  605. package/dist/editor/menubar/toolbar-sections/CompareControls.js +11 -0
  606. package/dist/editor/menubar/toolbar-sections/CompareControls.js.map +1 -0
  607. package/dist/editor/menubar/toolbar-sections/EditControls.d.ts +7 -0
  608. package/dist/editor/menubar/toolbar-sections/EditControls.js +15 -0
  609. package/dist/editor/menubar/toolbar-sections/EditControls.js.map +1 -0
  610. package/dist/editor/menubar/toolbar-sections/InsertControls.d.ts +1 -0
  611. package/dist/editor/menubar/toolbar-sections/InsertControls.js +15 -0
  612. package/dist/editor/menubar/toolbar-sections/InsertControls.js.map +1 -0
  613. package/dist/editor/menubar/toolbar-sections/ReviewCommands.d.ts +1 -0
  614. package/dist/editor/menubar/toolbar-sections/ReviewCommands.js +41 -0
  615. package/dist/editor/menubar/toolbar-sections/ReviewCommands.js.map +1 -0
  616. package/dist/editor/menubar/toolbar-sections/UtilityControls.d.ts +1 -0
  617. package/dist/editor/menubar/toolbar-sections/UtilityControls.js +17 -0
  618. package/dist/editor/menubar/toolbar-sections/UtilityControls.js.map +1 -0
  619. package/dist/editor/menubar/toolbar-sections/ViewportControls.d.ts +1 -0
  620. package/dist/editor/menubar/toolbar-sections/ViewportControls.js +21 -0
  621. package/dist/editor/menubar/toolbar-sections/ViewportControls.js.map +1 -0
  622. package/dist/editor/menubar/toolbar-sections/index.d.ts +6 -0
  623. package/dist/editor/menubar/toolbar-sections/index.js +7 -0
  624. package/dist/editor/menubar/toolbar-sections/index.js.map +1 -0
  625. package/dist/editor/page-editor-chrome/CommentHighlighting.d.ts +6 -0
  626. package/dist/editor/page-editor-chrome/CommentHighlighting.js +270 -0
  627. package/dist/editor/page-editor-chrome/CommentHighlighting.js.map +1 -0
  628. package/dist/editor/page-editor-chrome/CommentHighlightings.d.ts +4 -0
  629. package/dist/editor/page-editor-chrome/CommentHighlightings.js +15 -0
  630. package/dist/editor/page-editor-chrome/CommentHighlightings.js.map +1 -0
  631. package/dist/editor/page-editor-chrome/FieldActionIndicator.d.ts +4 -0
  632. package/dist/editor/page-editor-chrome/FieldActionIndicator.js +35 -0
  633. package/dist/editor/page-editor-chrome/FieldActionIndicator.js.map +1 -0
  634. package/dist/editor/page-editor-chrome/FieldActionIndicators.d.ts +1 -0
  635. package/dist/editor/page-editor-chrome/FieldActionIndicators.js +13 -0
  636. package/dist/editor/page-editor-chrome/FieldActionIndicators.js.map +1 -0
  637. package/dist/editor/page-editor-chrome/FieldEditedIndicator.d.ts +8 -0
  638. package/dist/editor/page-editor-chrome/FieldEditedIndicator.js +26 -0
  639. package/dist/editor/page-editor-chrome/FieldEditedIndicator.js.map +1 -0
  640. package/dist/editor/page-editor-chrome/FieldEditedIndicators.d.ts +6 -0
  641. package/dist/editor/page-editor-chrome/FieldEditedIndicators.js +14 -0
  642. package/dist/editor/page-editor-chrome/FieldEditedIndicators.js.map +1 -0
  643. package/dist/editor/page-editor-chrome/FrameMenu.d.ts +7 -0
  644. package/dist/editor/page-editor-chrome/FrameMenu.js +346 -0
  645. package/dist/editor/page-editor-chrome/FrameMenu.js.map +1 -0
  646. package/dist/editor/page-editor-chrome/FrameMenus.d.ts +5 -0
  647. package/dist/editor/page-editor-chrome/FrameMenus.js +22 -0
  648. package/dist/editor/page-editor-chrome/FrameMenus.js.map +1 -0
  649. package/dist/editor/page-editor-chrome/InlineEditor.d.ts +5 -0
  650. package/dist/editor/page-editor-chrome/InlineEditor.js +704 -0
  651. package/dist/editor/page-editor-chrome/InlineEditor.js.map +1 -0
  652. package/dist/editor/page-editor-chrome/LockedFieldIndicator.d.ts +1 -0
  653. package/dist/editor/page-editor-chrome/LockedFieldIndicator.js +33 -0
  654. package/dist/editor/page-editor-chrome/LockedFieldIndicator.js.map +1 -0
  655. package/dist/editor/page-editor-chrome/NoLayout.d.ts +1 -0
  656. package/dist/editor/page-editor-chrome/NoLayout.js +19 -0
  657. package/dist/editor/page-editor-chrome/NoLayout.js.map +1 -0
  658. package/dist/editor/page-editor-chrome/PageEditorChrome.d.ts +6 -0
  659. package/dist/editor/page-editor-chrome/PageEditorChrome.js +64 -0
  660. package/dist/editor/page-editor-chrome/PageEditorChrome.js.map +1 -0
  661. package/dist/editor/page-editor-chrome/PictureEditorOverlay.d.ts +1 -0
  662. package/dist/editor/page-editor-chrome/PictureEditorOverlay.js +152 -0
  663. package/dist/editor/page-editor-chrome/PictureEditorOverlay.js.map +1 -0
  664. package/dist/editor/page-editor-chrome/PlaceholderDropZone.d.ts +18 -0
  665. package/dist/editor/page-editor-chrome/PlaceholderDropZone.js +122 -0
  666. package/dist/editor/page-editor-chrome/PlaceholderDropZone.js.map +1 -0
  667. package/dist/editor/page-editor-chrome/PlaceholderDropZones.d.ts +5 -0
  668. package/dist/editor/page-editor-chrome/PlaceholderDropZones.js +289 -0
  669. package/dist/editor/page-editor-chrome/PlaceholderDropZones.js.map +1 -0
  670. package/dist/editor/page-editor-chrome/SuggestionHighlighting.d.ts +6 -0
  671. package/dist/editor/page-editor-chrome/SuggestionHighlighting.js +224 -0
  672. package/dist/editor/page-editor-chrome/SuggestionHighlighting.js.map +1 -0
  673. package/dist/editor/page-editor-chrome/SuggestionHighlightings.d.ts +4 -0
  674. package/dist/editor/page-editor-chrome/SuggestionHighlightings.js +16 -0
  675. package/dist/editor/page-editor-chrome/SuggestionHighlightings.js.map +1 -0
  676. package/dist/editor/page-editor-chrome/useInlineAICompletion.d.ts +7 -0
  677. package/dist/editor/page-editor-chrome/useInlineAICompletion.js +699 -0
  678. package/dist/editor/page-editor-chrome/useInlineAICompletion.js.map +1 -0
  679. package/dist/editor/page-viewer/DeviceToolbar.d.ts +6 -0
  680. package/dist/editor/page-viewer/DeviceToolbar.js +21 -0
  681. package/dist/editor/page-viewer/DeviceToolbar.js.map +1 -0
  682. package/dist/editor/page-viewer/EditorForm.d.ts +8 -0
  683. package/dist/editor/page-viewer/EditorForm.js +257 -0
  684. package/dist/editor/page-viewer/EditorForm.js.map +1 -0
  685. package/dist/editor/page-viewer/EditorFormPopup.d.ts +11 -0
  686. package/dist/editor/page-viewer/EditorFormPopup.js +41 -0
  687. package/dist/editor/page-viewer/EditorFormPopup.js.map +1 -0
  688. package/dist/editor/page-viewer/MiniMap.d.ts +9 -0
  689. package/dist/editor/page-viewer/MiniMap.js +233 -0
  690. package/dist/editor/page-viewer/MiniMap.js.map +1 -0
  691. package/dist/editor/page-viewer/PageViewer.d.ts +10 -0
  692. package/dist/editor/page-viewer/PageViewer.js +67 -0
  693. package/dist/editor/page-viewer/PageViewer.js.map +1 -0
  694. package/dist/editor/page-viewer/PageViewerFrame.d.ts +11 -0
  695. package/dist/editor/page-viewer/PageViewerFrame.js +857 -0
  696. package/dist/editor/page-viewer/PageViewerFrame.js.map +1 -0
  697. package/dist/editor/page-viewer/pageModelSkeletonBuilder.d.ts +3 -0
  698. package/dist/editor/page-viewer/pageModelSkeletonBuilder.js +339 -0
  699. package/dist/editor/page-viewer/pageModelSkeletonBuilder.js.map +1 -0
  700. package/dist/editor/page-viewer/pageViewContext.d.ts +40 -0
  701. package/dist/editor/page-viewer/pageViewContext.js +156 -0
  702. package/dist/editor/page-viewer/pageViewContext.js.map +1 -0
  703. package/dist/editor/pageModel.d.ts +222 -0
  704. package/dist/editor/pageModel.js +2 -0
  705. package/dist/editor/pageModel.js.map +1 -0
  706. package/dist/editor/picture-shared.d.ts +16 -0
  707. package/dist/editor/picture-shared.js +25 -0
  708. package/dist/editor/picture-shared.js.map +1 -0
  709. package/dist/editor/reviews/Comment.d.ts +8 -0
  710. package/dist/editor/reviews/Comment.js +162 -0
  711. package/dist/editor/reviews/Comment.js.map +1 -0
  712. package/dist/editor/reviews/CommentDisplayPopover.d.ts +9 -0
  713. package/dist/editor/reviews/CommentDisplayPopover.js +104 -0
  714. package/dist/editor/reviews/CommentDisplayPopover.js.map +1 -0
  715. package/dist/editor/reviews/CommentEditor.d.ts +20 -0
  716. package/dist/editor/reviews/CommentEditor.js +57 -0
  717. package/dist/editor/reviews/CommentEditor.js.map +1 -0
  718. package/dist/editor/reviews/CommentPopover.d.ts +22 -0
  719. package/dist/editor/reviews/CommentPopover.js +145 -0
  720. package/dist/editor/reviews/CommentPopover.js.map +1 -0
  721. package/dist/editor/reviews/CommentView.d.ts +21 -0
  722. package/dist/editor/reviews/CommentView.js +52 -0
  723. package/dist/editor/reviews/CommentView.js.map +1 -0
  724. package/dist/editor/reviews/Comments.d.ts +3 -0
  725. package/dist/editor/reviews/Comments.js +118 -0
  726. package/dist/editor/reviews/Comments.js.map +1 -0
  727. package/dist/editor/reviews/DiffView.d.ts +17 -0
  728. package/dist/editor/reviews/DiffView.js +57 -0
  729. package/dist/editor/reviews/DiffView.js.map +1 -0
  730. package/dist/editor/reviews/PreviewInfo.d.ts +1 -0
  731. package/dist/editor/reviews/PreviewInfo.js +12 -0
  732. package/dist/editor/reviews/PreviewInfo.js.map +1 -0
  733. package/dist/editor/reviews/Reviews.d.ts +1 -0
  734. package/dist/editor/reviews/Reviews.js +186 -0
  735. package/dist/editor/reviews/Reviews.js.map +1 -0
  736. package/dist/editor/reviews/SuggestedEdit.d.ts +4 -0
  737. package/dist/editor/reviews/SuggestedEdit.js +200 -0
  738. package/dist/editor/reviews/SuggestedEdit.js.map +1 -0
  739. package/dist/editor/reviews/SuggestionDisplayPopover.d.ts +9 -0
  740. package/dist/editor/reviews/SuggestionDisplayPopover.js +204 -0
  741. package/dist/editor/reviews/SuggestionDisplayPopover.js.map +1 -0
  742. package/dist/editor/reviews/commentAi.d.ts +7 -0
  743. package/dist/editor/reviews/commentAi.js +100 -0
  744. package/dist/editor/reviews/commentAi.js.map +1 -0
  745. package/dist/editor/reviews/reviewCommands.d.ts +3 -0
  746. package/dist/editor/reviews/reviewCommands.js +38 -0
  747. package/dist/editor/reviews/reviewCommands.js.map +1 -0
  748. package/dist/editor/reviews/useReviews.d.ts +12 -0
  749. package/dist/editor/reviews/useReviews.js +43 -0
  750. package/dist/editor/reviews/useReviews.js.map +1 -0
  751. package/dist/editor/services/agentService.d.ts +306 -0
  752. package/dist/editor/services/agentService.js +627 -0
  753. package/dist/editor/services/agentService.js.map +1 -0
  754. package/dist/editor/services/aiService.d.ts +106 -0
  755. package/dist/editor/services/aiService.js +294 -0
  756. package/dist/editor/services/aiService.js.map +1 -0
  757. package/dist/editor/services/componentDesignerService.d.ts +46 -0
  758. package/dist/editor/services/componentDesignerService.js +72 -0
  759. package/dist/editor/services/componentDesignerService.js.map +1 -0
  760. package/dist/editor/services/contentService.d.ts +79 -0
  761. package/dist/editor/services/contentService.js +119 -0
  762. package/dist/editor/services/contentService.js.map +1 -0
  763. package/dist/editor/services/contextService.d.ts +26 -0
  764. package/dist/editor/services/contextService.js +103 -0
  765. package/dist/editor/services/contextService.js.map +1 -0
  766. package/dist/editor/services/editService.d.ts +66 -0
  767. package/dist/editor/services/editService.js +325 -0
  768. package/dist/editor/services/editService.js.map +1 -0
  769. package/dist/editor/services/favouritesService.d.ts +33 -0
  770. package/dist/editor/services/favouritesService.js +22 -0
  771. package/dist/editor/services/favouritesService.js.map +1 -0
  772. package/dist/editor/services/indexService.d.ts +13 -0
  773. package/dist/editor/services/indexService.js +45 -0
  774. package/dist/editor/services/indexService.js.map +1 -0
  775. package/dist/editor/services/reviewsService.d.ts +18 -0
  776. package/dist/editor/services/reviewsService.js +60 -0
  777. package/dist/editor/services/reviewsService.js.map +1 -0
  778. package/dist/editor/services/searchService.d.ts +17 -0
  779. package/dist/editor/services/searchService.js +25 -0
  780. package/dist/editor/services/searchService.js.map +1 -0
  781. package/dist/editor/services/serviceHelper.d.ts +10 -0
  782. package/dist/editor/services/serviceHelper.js +118 -0
  783. package/dist/editor/services/serviceHelper.js.map +1 -0
  784. package/dist/editor/services/setupService.d.ts +21 -0
  785. package/dist/editor/services/setupService.js +10 -0
  786. package/dist/editor/services/setupService.js.map +1 -0
  787. package/dist/editor/services/suggestedEditsService.d.ts +18 -0
  788. package/dist/editor/services/suggestedEditsService.js +36 -0
  789. package/dist/editor/services/suggestedEditsService.js.map +1 -0
  790. package/dist/editor/services/systemService.d.ts +4 -0
  791. package/dist/editor/services/systemService.js +11 -0
  792. package/dist/editor/services/systemService.js.map +1 -0
  793. package/dist/editor/services-server/api.d.ts +19 -0
  794. package/dist/editor/services-server/api.js +111 -0
  795. package/dist/editor/services-server/api.js.map +1 -0
  796. package/dist/editor/services-server/graphQL.d.ts +29 -0
  797. package/dist/editor/services-server/graphQL.js +53 -0
  798. package/dist/editor/services-server/graphQL.js.map +1 -0
  799. package/dist/editor/sidebar/Completions.d.ts +1 -0
  800. package/dist/editor/sidebar/Completions.js +55 -0
  801. package/dist/editor/sidebar/Completions.js.map +1 -0
  802. package/dist/editor/sidebar/ComponentPalette.d.ts +1 -0
  803. package/dist/editor/sidebar/ComponentPalette.js +86 -0
  804. package/dist/editor/sidebar/ComponentPalette.js.map +1 -0
  805. package/dist/editor/sidebar/ComponentTree.d.ts +1 -0
  806. package/dist/editor/sidebar/ComponentTree.js +691 -0
  807. package/dist/editor/sidebar/ComponentTree.js.map +1 -0
  808. package/dist/editor/sidebar/Debug.d.ts +1 -0
  809. package/dist/editor/sidebar/Debug.js +71 -0
  810. package/dist/editor/sidebar/Debug.js.map +1 -0
  811. package/dist/editor/sidebar/DictionaryEditor.d.ts +1 -0
  812. package/dist/editor/sidebar/DictionaryEditor.js +158 -0
  813. package/dist/editor/sidebar/DictionaryEditor.js.map +1 -0
  814. package/dist/editor/sidebar/Divider.d.ts +6 -0
  815. package/dist/editor/sidebar/Divider.js +6 -0
  816. package/dist/editor/sidebar/Divider.js.map +1 -0
  817. package/dist/editor/sidebar/EditHistory.d.ts +1 -0
  818. package/dist/editor/sidebar/EditHistory.js +78 -0
  819. package/dist/editor/sidebar/EditHistory.js.map +1 -0
  820. package/dist/editor/sidebar/GraphQL.d.ts +2 -0
  821. package/dist/editor/sidebar/GraphQL.js +234 -0
  822. package/dist/editor/sidebar/GraphQL.js.map +1 -0
  823. package/dist/editor/sidebar/Insert.d.ts +1 -0
  824. package/dist/editor/sidebar/Insert.js +22 -0
  825. package/dist/editor/sidebar/Insert.js.map +1 -0
  826. package/dist/editor/sidebar/LeftToolbar.d.ts +1 -0
  827. package/dist/editor/sidebar/LeftToolbar.js +16 -0
  828. package/dist/editor/sidebar/LeftToolbar.js.map +1 -0
  829. package/dist/editor/sidebar/MainContentTree.d.ts +5 -0
  830. package/dist/editor/sidebar/MainContentTree.js +70 -0
  831. package/dist/editor/sidebar/MainContentTree.js.map +1 -0
  832. package/dist/editor/sidebar/Performance.d.ts +1 -0
  833. package/dist/editor/sidebar/Performance.js +32 -0
  834. package/dist/editor/sidebar/Performance.js.map +1 -0
  835. package/dist/editor/sidebar/SEOInfo.d.ts +1 -0
  836. package/dist/editor/sidebar/SEOInfo.js +158 -0
  837. package/dist/editor/sidebar/SEOInfo.js.map +1 -0
  838. package/dist/editor/sidebar/Sessions.d.ts +1 -0
  839. package/dist/editor/sidebar/Sessions.js +29 -0
  840. package/dist/editor/sidebar/Sessions.js.map +1 -0
  841. package/dist/editor/sidebar/Sidebar.d.ts +1 -0
  842. package/dist/editor/sidebar/Sidebar.js +13 -0
  843. package/dist/editor/sidebar/Sidebar.js.map +1 -0
  844. package/dist/editor/sidebar/SidebarView.d.ts +10 -0
  845. package/dist/editor/sidebar/SidebarView.js +40 -0
  846. package/dist/editor/sidebar/SidebarView.js.map +1 -0
  847. package/dist/editor/sidebar/Validation.d.ts +1 -0
  848. package/dist/editor/sidebar/Validation.js +51 -0
  849. package/dist/editor/sidebar/Validation.js.map +1 -0
  850. package/dist/editor/sidebar/ViewSelector.d.ts +4 -0
  851. package/dist/editor/sidebar/ViewSelector.js +191 -0
  852. package/dist/editor/sidebar/ViewSelector.js.map +1 -0
  853. package/dist/editor/sidebar/Workbox.d.ts +1 -0
  854. package/dist/editor/sidebar/Workbox.js +79 -0
  855. package/dist/editor/sidebar/Workbox.js.map +1 -0
  856. package/dist/editor/ui/CenteredMessage.d.ts +3 -0
  857. package/dist/editor/ui/CenteredMessage.js +5 -0
  858. package/dist/editor/ui/CenteredMessage.js.map +1 -0
  859. package/dist/editor/ui/CopyMoveTargetSelectorDialog.d.ts +10 -0
  860. package/dist/editor/ui/CopyMoveTargetSelectorDialog.js +38 -0
  861. package/dist/editor/ui/CopyMoveTargetSelectorDialog.js.map +1 -0
  862. package/dist/editor/ui/DialogButtons.d.ts +3 -0
  863. package/dist/editor/ui/DialogButtons.js +5 -0
  864. package/dist/editor/ui/DialogButtons.js.map +1 -0
  865. package/dist/editor/ui/DragPreview.d.ts +14 -0
  866. package/dist/editor/ui/DragPreview.js +33 -0
  867. package/dist/editor/ui/DragPreview.js.map +1 -0
  868. package/dist/editor/ui/Icons.d.ts +74 -0
  869. package/dist/editor/ui/Icons.js +106 -0
  870. package/dist/editor/ui/Icons.js.map +1 -0
  871. package/dist/editor/ui/ItemList.d.ts +16 -0
  872. package/dist/editor/ui/ItemList.js +19 -0
  873. package/dist/editor/ui/ItemList.js.map +1 -0
  874. package/dist/editor/ui/ItemNameDialogNew.d.ts +10 -0
  875. package/dist/editor/ui/ItemNameDialogNew.js +68 -0
  876. package/dist/editor/ui/ItemNameDialogNew.js.map +1 -0
  877. package/dist/editor/ui/ItemSearch.d.ts +25 -0
  878. package/dist/editor/ui/ItemSearch.js +92 -0
  879. package/dist/editor/ui/ItemSearch.js.map +1 -0
  880. package/dist/editor/ui/PerfectTree.d.ts +78 -0
  881. package/dist/editor/ui/PerfectTree.js +858 -0
  882. package/dist/editor/ui/PerfectTree.js.map +1 -0
  883. package/dist/editor/ui/Section.d.ts +4 -0
  884. package/dist/editor/ui/Section.js +12 -0
  885. package/dist/editor/ui/Section.js.map +1 -0
  886. package/dist/editor/ui/SimpleIconButton.d.ts +14 -0
  887. package/dist/editor/ui/SimpleIconButton.js +15 -0
  888. package/dist/editor/ui/SimpleIconButton.js.map +1 -0
  889. package/dist/editor/ui/SimpleMenu.d.ts +6 -0
  890. package/dist/editor/ui/SimpleMenu.js +7 -0
  891. package/dist/editor/ui/SimpleMenu.js.map +1 -0
  892. package/dist/editor/ui/SimpleTable.d.ts +14 -0
  893. package/dist/editor/ui/SimpleTable.js +9 -0
  894. package/dist/editor/ui/SimpleTable.js.map +1 -0
  895. package/dist/editor/ui/SimpleTabs.d.ts +15 -0
  896. package/dist/editor/ui/SimpleTabs.js +20 -0
  897. package/dist/editor/ui/SimpleTabs.js.map +1 -0
  898. package/dist/editor/ui/SimpleToolbar.d.ts +3 -0
  899. package/dist/editor/ui/SimpleToolbar.js +5 -0
  900. package/dist/editor/ui/SimpleToolbar.js.map +1 -0
  901. package/dist/editor/ui/Spinner.d.ts +4 -0
  902. package/dist/editor/ui/Spinner.js +18 -0
  903. package/dist/editor/ui/Spinner.js.map +1 -0
  904. package/dist/editor/ui/Splitter.d.ts +22 -0
  905. package/dist/editor/ui/Splitter.js +443 -0
  906. package/dist/editor/ui/Splitter.js.map +1 -0
  907. package/dist/editor/ui/TemplateSelectorDialog.d.ts +8 -0
  908. package/dist/editor/ui/TemplateSelectorDialog.js +61 -0
  909. package/dist/editor/ui/TemplateSelectorDialog.js.map +1 -0
  910. package/dist/editor/ui/Toolbar.d.ts +3 -0
  911. package/dist/editor/ui/Toolbar.js +5 -0
  912. package/dist/editor/ui/Toolbar.js.map +1 -0
  913. package/dist/editor/utils/id-helper.d.ts +1 -0
  914. package/dist/editor/utils/id-helper.js +5 -0
  915. package/dist/editor/utils/id-helper.js.map +1 -0
  916. package/dist/editor/utils/insertOptions.d.ts +3 -0
  917. package/dist/editor/utils/insertOptions.js +43 -0
  918. package/dist/editor/utils/insertOptions.js.map +1 -0
  919. package/dist/editor/utils/itemConverters.d.ts +3 -0
  920. package/dist/editor/utils/itemConverters.js +53 -0
  921. package/dist/editor/utils/itemConverters.js.map +1 -0
  922. package/dist/editor/utils/itemutils.d.ts +3 -0
  923. package/dist/editor/utils/itemutils.js +24 -0
  924. package/dist/editor/utils/itemutils.js.map +1 -0
  925. package/dist/editor/utils/jsonCleaner.d.ts +8 -0
  926. package/dist/editor/utils/jsonCleaner.js +76 -0
  927. package/dist/editor/utils/jsonCleaner.js.map +1 -0
  928. package/dist/editor/utils/keyboardNavigation.d.ts +34 -0
  929. package/dist/editor/utils/keyboardNavigation.js +237 -0
  930. package/dist/editor/utils/keyboardNavigation.js.map +1 -0
  931. package/dist/editor/utils/urlUtils.d.ts +9 -0
  932. package/dist/editor/utils/urlUtils.js +25 -0
  933. package/dist/editor/utils/urlUtils.js.map +1 -0
  934. package/dist/editor/utils/useMemoDebug.d.ts +1 -0
  935. package/dist/editor/utils/useMemoDebug.js +18 -0
  936. package/dist/editor/utils/useMemoDebug.js.map +1 -0
  937. package/dist/editor/utils.d.ts +65 -0
  938. package/dist/editor/utils.js +468 -0
  939. package/dist/editor/utils.js.map +1 -0
  940. package/dist/editor/views/CompareView.d.ts +1 -0
  941. package/dist/editor/views/CompareView.js +148 -0
  942. package/dist/editor/views/CompareView.js.map +1 -0
  943. package/dist/editor/views/EditView.d.ts +1 -0
  944. package/dist/editor/views/EditView.js +15 -0
  945. package/dist/editor/views/EditView.js.map +1 -0
  946. package/dist/editor/views/ItemEditor.d.ts +7 -0
  947. package/dist/editor/views/ItemEditor.js +29 -0
  948. package/dist/editor/views/ItemEditor.js.map +1 -0
  949. package/dist/editor/views/MediaFolderEditView.d.ts +4 -0
  950. package/dist/editor/views/MediaFolderEditView.js +40 -0
  951. package/dist/editor/views/MediaFolderEditView.js.map +1 -0
  952. package/dist/editor/views/ParheliaView.d.ts +5 -0
  953. package/dist/editor/views/ParheliaView.js +136 -0
  954. package/dist/editor/views/ParheliaView.js.map +1 -0
  955. package/dist/editor/views/SingleEditView.d.ts +9 -0
  956. package/dist/editor/views/SingleEditView.js +33 -0
  957. package/dist/editor/views/SingleEditView.js.map +1 -0
  958. package/dist/images/bg-shape-black.webp +0 -0
  959. package/dist/images/wizard-bg.png +0 -0
  960. package/dist/images/wizard-tour.png +0 -0
  961. package/dist/images/wizard.png +0 -0
  962. package/dist/index.d.ts +62 -0
  963. package/dist/index.js +53 -0
  964. package/dist/index.js.map +1 -0
  965. package/dist/lib/safelist.d.ts +1 -0
  966. package/dist/lib/safelist.js +5 -0
  967. package/dist/lib/safelist.js.map +1 -0
  968. package/dist/lib/utils.d.ts +2 -0
  969. package/dist/lib/utils.js +6 -0
  970. package/dist/lib/utils.js.map +1 -0
  971. package/dist/revision.d.ts +2 -0
  972. package/dist/revision.js +3 -0
  973. package/dist/revision.js.map +1 -0
  974. package/dist/splash-screen/ModernSplashScreen.d.ts +8 -0
  975. package/dist/splash-screen/ModernSplashScreen.js +92 -0
  976. package/dist/splash-screen/ModernSplashScreen.js.map +1 -0
  977. package/dist/splash-screen/NewPage.d.ts +3 -0
  978. package/dist/splash-screen/NewPage.js +145 -0
  979. package/dist/splash-screen/NewPage.js.map +1 -0
  980. package/dist/splash-screen/OpenPage.d.ts +1 -0
  981. package/dist/splash-screen/OpenPage.js +56 -0
  982. package/dist/splash-screen/OpenPage.js.map +1 -0
  983. package/dist/splash-screen/ParheliaAssistantChat.d.ts +8 -0
  984. package/dist/splash-screen/ParheliaAssistantChat.js +155 -0
  985. package/dist/splash-screen/ParheliaAssistantChat.js.map +1 -0
  986. package/dist/splash-screen/RecentAgents.d.ts +7 -0
  987. package/dist/splash-screen/RecentAgents.js +76 -0
  988. package/dist/splash-screen/RecentAgents.js.map +1 -0
  989. package/dist/splash-screen/RecentPages.d.ts +1 -0
  990. package/dist/splash-screen/RecentPages.js +47 -0
  991. package/dist/splash-screen/RecentPages.js.map +1 -0
  992. package/dist/splash-screen/SectionHeadline.d.ts +4 -0
  993. package/dist/splash-screen/SectionHeadline.js +7 -0
  994. package/dist/splash-screen/SectionHeadline.js.map +1 -0
  995. package/dist/styles.css +5914 -0
  996. package/dist/tour/Tour.d.ts +3 -0
  997. package/dist/tour/Tour.js +426 -0
  998. package/dist/tour/Tour.js.map +1 -0
  999. package/dist/tour/default-tour.d.ts +9 -0
  1000. package/dist/tour/default-tour.js +302 -0
  1001. package/dist/tour/default-tour.js.map +1 -0
  1002. package/dist/tour/preview-tour.d.ts +2 -0
  1003. package/dist/tour/preview-tour.js +93 -0
  1004. package/dist/tour/preview-tour.js.map +1 -0
  1005. package/dist/types.d.ts +396 -0
  1006. package/dist/types.js +2 -0
  1007. package/dist/types.js.map +1 -0
  1008. package/images/bg-shape-black.webp +0 -0
  1009. package/images/wizard-bg.png +0 -0
  1010. package/images/wizard-tour.png +0 -0
  1011. package/images/wizard.png +0 -0
  1012. package/package.json +93 -0
@@ -0,0 +1,2634 @@
1
+ import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
2
+ import React, { useEffect, useState, useRef, useCallback, useLayoutEffect, useMemo, ViewTransition, } from "react";
3
+ import { Send, AlertCircle, Loader2, User, Wand2, Square, Mic, MicOff, ChevronDown, ChevronUp, ListTodo, } from "lucide-react";
4
+ import { DancingDots } from "./DancingDots";
5
+ import { getAgent, startAgent, updateAgentSettings, updateAgentCostLimit, cancelAgent, canonicalizeAgentMetadata, } from "../services/agentService";
6
+ import { useEditContext, useFieldsEditContext } from "../client/editContext";
7
+ import { Textarea } from "../../components/ui/textarea";
8
+ import { Button } from "../../components/ui/button";
9
+ import { PlaceholderInput } from "../../components/ui/PlaceholderInput";
10
+ import { AiResponseMessage } from "./AiResponseMessage";
11
+ import { AgentCostDisplay } from "./AgentCostDisplay";
12
+ import { ContextInfoBar } from "./ContextInfoBar";
13
+ import { getComponentById } from "../componentTreeHelper";
14
+ import { Popover, PopoverContent, PopoverTrigger, } from "../../components/ui/popover";
15
+ import { SecretAgentIcon } from "../ui/Icons";
16
+ import { formatTime } from "../utils";
17
+ import { Tooltip, TooltipTrigger, TooltipContent, } from "../../components/ui/tooltip";
18
+ // Simple user message component
19
+ const UserMessage = ({ message }) => {
20
+ return (_jsxs("div", { className: "flex gap-3 p-4", children: [_jsx("div", { className: "flex-shrink-0", children: _jsx(User, { className: "h-6 w-6 text-blue-600", strokeWidth: 1 }) }), _jsxs("div", { className: "min-w-0 flex-1 select-text", children: [_jsxs("div", { className: "mb-1 flex items-center gap-2", children: [_jsx("span", { className: "text-xs font-medium text-gray-900", children: "You" }), message.createdDate && (_jsx("span", { className: "text-xs text-gray-400", "data-testid": "user-message-timestamp", "data-timestamp": message.createdDate, children: formatTime(new Date(message.createdDate)) }))] }), _jsx("div", { className: "prose prose-sm max-w-none text-xs text-gray-700 select-text", children: message.content })] })] }));
21
+ };
22
+ // Helper to extract todos from potentially incomplete JSON during streaming
23
+ const extractPartialTodos = (jsonText) => {
24
+ // First try to parse complete JSON
25
+ try {
26
+ const parsed = JSON.parse(jsonText);
27
+ return Array.isArray(parsed) ? parsed : parsed?.items || [];
28
+ }
29
+ catch (e) {
30
+ // If JSON is incomplete, try to extract whatever todo items we can find
31
+ const items = [];
32
+ // Look for individual todo objects in the partial JSON
33
+ // Match patterns like: { "text": "...", "done": false, "note": "..." }
34
+ // Handle various field orderings (text can be anywhere in the object)
35
+ const textPattern = /"text"\s*:\s*"([^"]+)"/g;
36
+ const textMatches = [];
37
+ let textMatch;
38
+ while ((textMatch = textPattern.exec(jsonText)) !== null) {
39
+ if (textMatch[1]) {
40
+ textMatches.push({
41
+ text: textMatch[1],
42
+ startIdx: textMatch.index,
43
+ });
44
+ }
45
+ }
46
+ // For each text field found, try to find the enclosing object
47
+ for (const { text, startIdx } of textMatches) {
48
+ // Find the opening brace before this text field
49
+ let openBrace = -1;
50
+ for (let i = startIdx - 1; i >= 0; i--) {
51
+ if (jsonText[i] === "{") {
52
+ openBrace = i;
53
+ break;
54
+ }
55
+ if (jsonText[i] === "}")
56
+ break; // Hit another object's end
57
+ }
58
+ if (openBrace === -1)
59
+ continue;
60
+ // Find the closing brace after this text field
61
+ let closeBrace = -1;
62
+ let depth = 0;
63
+ for (let i = openBrace; i < jsonText.length; i++) {
64
+ if (jsonText[i] === "{")
65
+ depth++;
66
+ if (jsonText[i] === "}") {
67
+ depth--;
68
+ if (depth === 0) {
69
+ closeBrace = i;
70
+ break;
71
+ }
72
+ }
73
+ }
74
+ // Extract the object and try to parse it
75
+ const objStr = closeBrace !== -1
76
+ ? jsonText.substring(openBrace, closeBrace + 1)
77
+ : jsonText.substring(openBrace) + "}"; // Try to close incomplete object
78
+ try {
79
+ const obj = JSON.parse(objStr);
80
+ if (obj.text) {
81
+ items.push({
82
+ text: obj.text,
83
+ done: obj.done === true,
84
+ note: obj.note || undefined,
85
+ });
86
+ }
87
+ }
88
+ catch (e) {
89
+ // Skip malformed objects
90
+ }
91
+ }
92
+ // Also try to extract from partial objects at the end
93
+ // Look for the last opening brace and try to parse up to where we have valid content
94
+ const lines = jsonText.split("\n");
95
+ for (let i = lines.length - 1; i >= 0; i--) {
96
+ const partialJson = lines.slice(0, i + 1).join("\n");
97
+ // Try to close any open braces/brackets
98
+ let testJson = partialJson;
99
+ const openBraces = (testJson.match(/\{/g) || []).length;
100
+ const closeBraces = (testJson.match(/\}/g) || []).length;
101
+ const openBrackets = (testJson.match(/\[/g) || []).length;
102
+ const closeBrackets = (testJson.match(/\]/g) || []).length;
103
+ // Add missing closing characters
104
+ testJson += "]".repeat(openBrackets - closeBrackets);
105
+ testJson += "}".repeat(openBraces - closeBraces);
106
+ try {
107
+ const parsed = JSON.parse(testJson);
108
+ const partialItems = Array.isArray(parsed)
109
+ ? parsed
110
+ : parsed?.items || [];
111
+ if (partialItems.length > items.length) {
112
+ return partialItems;
113
+ }
114
+ }
115
+ catch (e) {
116
+ continue;
117
+ }
118
+ }
119
+ return items;
120
+ }
121
+ };
122
+ const extractTodosFromMessages = (messages) => {
123
+ const todos = [];
124
+ const fencedTodoToken = "```todo_list";
125
+ const plainTodoToken = "todo_list";
126
+ for (const message of messages) {
127
+ if (message.role !== "assistant" || !message.content)
128
+ continue;
129
+ const content = message.content;
130
+ let cursor = 0;
131
+ while (cursor < content.length) {
132
+ const nextFenced = content.indexOf(fencedTodoToken, cursor);
133
+ const nextPlain = content.indexOf(plainTodoToken, cursor);
134
+ let todoStart = -1;
135
+ let isFenced = false;
136
+ if (nextFenced !== -1 && (nextPlain === -1 || nextFenced < nextPlain)) {
137
+ todoStart = nextFenced;
138
+ isFenced = true;
139
+ }
140
+ else if (nextPlain !== -1) {
141
+ // Check if it's at line start
142
+ const before = nextPlain > 0 ? content[nextPlain - 1] : "\n";
143
+ if (before === "\n" || before === "\r" || nextPlain === 0) {
144
+ todoStart = nextPlain;
145
+ isFenced = false;
146
+ }
147
+ }
148
+ if (todoStart === -1)
149
+ break;
150
+ try {
151
+ let jsonText = "";
152
+ let isComplete = true;
153
+ if (isFenced) {
154
+ const afterToken = todoStart + fencedTodoToken.length;
155
+ const closePos = content.indexOf("```", afterToken);
156
+ if (closePos === -1) {
157
+ // Incomplete fenced block - extract what we have so far
158
+ jsonText = content.slice(afterToken).trim();
159
+ isComplete = false;
160
+ cursor = content.length; // Process till end
161
+ }
162
+ else {
163
+ jsonText = content.slice(afterToken, closePos).trim();
164
+ cursor = closePos + 3;
165
+ }
166
+ }
167
+ else {
168
+ const afterToken = todoStart + plainTodoToken.length;
169
+ const braceStart = content.indexOf("{", afterToken);
170
+ if (braceStart === -1)
171
+ break;
172
+ let depth = 0;
173
+ let braceEnd = -1;
174
+ for (let i = braceStart; i < content.length; i++) {
175
+ if (content[i] === "{")
176
+ depth++;
177
+ if (content[i] === "}") {
178
+ depth--;
179
+ if (depth === 0) {
180
+ braceEnd = i;
181
+ break;
182
+ }
183
+ }
184
+ }
185
+ if (braceEnd === -1) {
186
+ // Incomplete JSON - extract what we have
187
+ jsonText = content.slice(braceStart).trim();
188
+ isComplete = false;
189
+ cursor = content.length;
190
+ }
191
+ else {
192
+ jsonText = content.slice(braceStart, braceEnd + 1).trim();
193
+ cursor = braceEnd + 1;
194
+ }
195
+ }
196
+ // Use the partial extraction helper for incomplete JSON
197
+ const todoItems = isComplete
198
+ ? (() => {
199
+ try {
200
+ const parsed = JSON.parse(jsonText);
201
+ return Array.isArray(parsed) ? parsed : parsed?.items || [];
202
+ }
203
+ catch (e) {
204
+ return [];
205
+ }
206
+ })()
207
+ : extractPartialTodos(jsonText);
208
+ const title = (() => {
209
+ try {
210
+ const parsed = JSON.parse(jsonText);
211
+ return Array.isArray(parsed) ? undefined : parsed?.title;
212
+ }
213
+ catch (e) {
214
+ return undefined;
215
+ }
216
+ })();
217
+ todoItems.forEach((item) => {
218
+ if (!item)
219
+ return;
220
+ const text = item.text ||
221
+ item.content ||
222
+ item.label ||
223
+ String(item.task || item.title || "");
224
+ if (!text)
225
+ return;
226
+ todos.push({
227
+ id: item.id,
228
+ text,
229
+ done: !!(item.done ??
230
+ item.completed ??
231
+ item.checked ??
232
+ item.status === "completed"),
233
+ note: item.note || item.description,
234
+ messageId: message.id,
235
+ sourceTitle: title,
236
+ });
237
+ });
238
+ }
239
+ catch (e) {
240
+ cursor++;
241
+ continue;
242
+ }
243
+ }
244
+ }
245
+ return todos;
246
+ };
247
+ // TodoListPanel component
248
+ const TodoListPanel = ({ messages, agentMetadata, }) => {
249
+ const [isExpanded, setIsExpanded] = useState(true);
250
+ const todos = useMemo(() => {
251
+ // First try to get todos from agent metadata (real-time updates)
252
+ const metadataTodos = (() => {
253
+ try {
254
+ const todoList = agentMetadata?.additionalData?.todoList;
255
+ if (todoList?.items && Array.isArray(todoList.items)) {
256
+ return todoList.items
257
+ .map((item, idx) => ({
258
+ id: item.id || `metadata-${idx}`,
259
+ text: item.text ||
260
+ item.label ||
261
+ String(item.task || item.title || ""),
262
+ done: !!(item.done ?? item.completed ?? item.checked),
263
+ note: item.note || item.description,
264
+ messageId: undefined,
265
+ sourceTitle: todoList.title,
266
+ }))
267
+ .filter((item) => item.text);
268
+ }
269
+ }
270
+ catch (e) {
271
+ console.error("📋 Error extracting todos from metadata:", e);
272
+ }
273
+ return null;
274
+ })();
275
+ // If we have metadata todos, use them; otherwise extract from messages
276
+ if (metadataTodos && metadataTodos.length > 0) {
277
+ return metadataTodos;
278
+ }
279
+ return extractTodosFromMessages(messages);
280
+ }, [messages, agentMetadata]);
281
+ // Check if there's an active streaming message with incomplete todo content
282
+ const isUpdating = useMemo(() => {
283
+ return messages.some((msg) => {
284
+ if (msg.role !== "assistant" || msg.isCompleted)
285
+ return false;
286
+ const content = msg.content || "";
287
+ // Check for incomplete fenced todo blocks
288
+ const fencedStart = content.indexOf("```todo_list");
289
+ if (fencedStart !== -1) {
290
+ const afterStart = fencedStart + "```todo_list".length;
291
+ const closePos = content.indexOf("```", afterStart);
292
+ if (closePos === -1) {
293
+ // Incomplete fenced block
294
+ return true;
295
+ }
296
+ }
297
+ // Check for incomplete plain todo blocks
298
+ const plainStart = content.indexOf("todo_list");
299
+ if (plainStart !== -1 && plainStart !== fencedStart) {
300
+ const before = plainStart > 0 ? content[plainStart - 1] : "\n";
301
+ if (before === "\n" || before === "\r" || plainStart === 0) {
302
+ const braceStart = content.indexOf("{", plainStart);
303
+ if (braceStart !== -1) {
304
+ let depth = 0;
305
+ let braceEnd = -1;
306
+ for (let i = braceStart; i < content.length; i++) {
307
+ if (content[i] === "{")
308
+ depth++;
309
+ if (content[i] === "}") {
310
+ depth--;
311
+ if (depth === 0) {
312
+ braceEnd = i;
313
+ break;
314
+ }
315
+ }
316
+ }
317
+ if (braceEnd === -1) {
318
+ // Incomplete plain block
319
+ return true;
320
+ }
321
+ }
322
+ }
323
+ }
324
+ return false;
325
+ });
326
+ }, [messages]);
327
+ if (todos.length === 0 && !isUpdating)
328
+ return null;
329
+ const completedCount = todos.filter((t) => t.done).length;
330
+ const totalCount = todos.length;
331
+ return (_jsxs("div", { className: "border-t border-gray-200 bg-gray-50", children: [_jsxs("button", { onClick: () => setIsExpanded(!isExpanded), className: "flex w-full cursor-pointer items-center justify-between px-4 py-2 text-left transition-colors hover:bg-gray-100", children: [_jsxs("div", { className: "flex items-center gap-2", children: [_jsx(ListTodo, { className: "h-4 w-4 text-gray-500", strokeWidth: 1 }), _jsx("span", { className: "text-xs font-medium text-gray-700", children: "Todo List" }), isUpdating ? (_jsxs("span", { className: "flex items-center gap-1 text-xs text-blue-600", children: [_jsx(Loader2, { className: "h-3 w-3 animate-spin", strokeWidth: 1 }), "Updating..."] })) : (_jsxs("span", { className: "text-xs text-gray-500", children: [completedCount, "/", totalCount, " completed"] }))] }), isExpanded ? (_jsx(ChevronUp, { className: "h-4 w-4 text-gray-500", strokeWidth: 1 })) : (_jsx(ChevronDown, { className: "h-4 w-4 text-gray-500", strokeWidth: 1 }))] }), isExpanded && (_jsxs("div", { className: "max-h-64 overflow-y-auto px-4 pb-3", children: [todos.length > 0 && (_jsx("div", { className: "space-y-1.5", children: todos.map((todo, idx) => (_jsxs("div", { className: "flex items-start gap-2 rounded bg-white p-2 text-xs", children: [_jsx("div", { className: "flex-shrink-0 pt-0.5", children: todo.done ? (_jsx("div", { className: "flex h-4 w-4 items-center justify-center rounded border-2 border-green-500 bg-green-500", children: _jsx("svg", { className: "h-3 w-3 text-white", fill: "none", strokeWidth: 2, stroke: "currentColor", viewBox: "0 0 24 24", children: _jsx("path", { strokeLinecap: "round", strokeLinejoin: "round", d: "M5 13l4 4L19 7" }) }) })) : (_jsx("div", { className: "h-4 w-4 rounded border-2 border-gray-300" })) }), _jsxs("div", { className: "min-w-0 flex-1", children: [_jsx("div", { className: `${todo.done
332
+ ? "text-gray-500 line-through"
333
+ : "text-gray-900"}`, children: todo.text }), todo.note && (_jsx("div", { className: "mt-0.5 text-xs text-gray-500", children: todo.note }))] })] }, todo.id || `${todo.messageId}-${idx}`))) })), isUpdating && (_jsxs("div", { className: `flex items-center gap-2 rounded px-3 py-2 text-xs ${todos.length > 0
334
+ ? "mt-2 bg-blue-50 text-blue-700"
335
+ : "justify-center bg-white text-gray-500"}`, children: [_jsx(Loader2, { className: "h-3 w-3 animate-spin", strokeWidth: 1 }), _jsx("span", { children: todos.length > 0
336
+ ? "Updating todo list..."
337
+ : "Loading todo list..." })] }))] }))] }));
338
+ };
339
+ const groupConsecutiveMessages = (agentMessages) => {
340
+ // Work directly with the messages array - streaming messages are identified by their properties
341
+ const allMessages = agentMessages;
342
+ const groups = [];
343
+ let currentAssistantGroup = [];
344
+ for (const message of allMessages) {
345
+ if (message.role === "user") {
346
+ // Finish any current assistant group
347
+ if (currentAssistantGroup.length > 0) {
348
+ groups.push({
349
+ type: "assistant-group",
350
+ messages: currentAssistantGroup,
351
+ });
352
+ currentAssistantGroup = [];
353
+ }
354
+ // Add user message
355
+ groups.push({ type: "user", messages: [message] });
356
+ }
357
+ else if (message.role === "assistant") {
358
+ // Add to current assistant group
359
+ currentAssistantGroup.push(message);
360
+ }
361
+ // Skip tool messages as they're handled within assistant messages
362
+ }
363
+ // Add any remaining assistant group
364
+ if (currentAssistantGroup.length > 0) {
365
+ groups.push({ type: "assistant-group", messages: currentAssistantGroup });
366
+ }
367
+ return groups;
368
+ };
369
+ // Merge messages from DB and local state with ID-based deduplication
370
+ const mergeMessagesById = (dbMessages, localMessages) => {
371
+ const messageMap = new Map();
372
+ // Normalize ID key (lowercase) to avoid duplicates caused by casing differences
373
+ const keyOf = (id) => (id ? id.toLowerCase() : "");
374
+ // First, add all DB messages (source of truth for completed messages)
375
+ dbMessages.forEach((msg) => {
376
+ if (msg.id)
377
+ messageMap.set(keyOf(msg.id), msg);
378
+ });
379
+ // Then merge local messages (preserve streaming state, prefer longer content)
380
+ localMessages.forEach((localMsg) => {
381
+ if (!localMsg.id)
382
+ return;
383
+ const key = keyOf(localMsg.id);
384
+ const existingMsg = messageMap.get(key);
385
+ if (!existingMsg) {
386
+ // New message only in local state (e.g., streaming)
387
+ messageMap.set(key, localMsg);
388
+ }
389
+ else if (!localMsg.isCompleted && localMsg.messageType === "streaming") {
390
+ // Keep streaming version if more recent/longer
391
+ if (localMsg.content.length > existingMsg.content.length) {
392
+ messageMap.set(key, localMsg);
393
+ }
394
+ }
395
+ // Otherwise, keep the DB version (completed messages from DB are authoritative)
396
+ });
397
+ // Sort by messageIndex or createdDate to maintain order
398
+ // Ignore messageIndex if it's -1 (unassigned/streaming)
399
+ return Array.from(messageMap.values()).sort((a, b) => {
400
+ const aIndex = a.messageIndex === -1 ? Infinity : a.messageIndex;
401
+ const bIndex = b.messageIndex === -1 ? Infinity : b.messageIndex;
402
+ if (aIndex !== bIndex) {
403
+ return aIndex - bIndex;
404
+ }
405
+ return (new Date(a.createdDate || 0).getTime() -
406
+ new Date(b.createdDate || 0).getTime());
407
+ });
408
+ };
409
+ // Calculate total token usage and cost data from agent messages
410
+ const calculateTotalTokens = (messages) => {
411
+ const totals = messages.reduce((acc, message) => {
412
+ return {
413
+ input: acc.input + (message.inputTokens || 0),
414
+ output: acc.output + (message.outputTokens || 0),
415
+ cached: acc.cached + (message.cachedInputTokens || 0),
416
+ cacheWrite: acc.cacheWrite,
417
+ inputCost: acc.inputCost + (message.inputTokenCost || 0),
418
+ outputCost: acc.outputCost + (message.outputTokenCost || 0),
419
+ cachedCost: acc.cachedCost + (message.cachedInputTokenCost || 0),
420
+ cacheWriteCost: acc.cacheWriteCost,
421
+ totalCost: acc.totalCost + (message.totalCost || 0),
422
+ };
423
+ }, {
424
+ input: 0,
425
+ output: 0,
426
+ cached: 0,
427
+ cacheWrite: 0,
428
+ inputCost: 0,
429
+ outputCost: 0,
430
+ cachedCost: 0,
431
+ cacheWriteCost: 0,
432
+ totalCost: 0,
433
+ });
434
+ return totals;
435
+ };
436
+ // Convert agent messages to AI terminal format for a response group
437
+ const convertAgentMessagesToAiFormat = (agentMessages) => {
438
+ return agentMessages.map((agentMessage) => {
439
+ const message = {
440
+ id: agentMessage.id,
441
+ content: agentMessage.content,
442
+ formattedContent: agentMessage.content
443
+ ?.replace(/^######\s+(.+)$/gm, "<h6>$1</h6>")
444
+ ?.replace(/^#####\s+(.+)$/gm, "<h5>$1</h5>")
445
+ ?.replace(/^####\s+(.+)$/gm, "<h4>$1</h4>")
446
+ ?.replace(/^###\s+(.+)$/gm, "<h3>$1</h3>")
447
+ ?.replace(/^##\s+(.+)$/gm, "<h2>$1</h2>")
448
+ ?.replace(/^#\s+(.+)$/gm, "<h1>$1</h1>")
449
+ ?.replace(/\*\*(.*?)\*\*/g, "<strong>$1</strong>")
450
+ ?.replace(/\n/g, "<br/>"),
451
+ name: agentMessage.name,
452
+ role: agentMessage.role,
453
+ createdDate: agentMessage.createdDate,
454
+ tool_calls: agentMessage.toolCalls
455
+ ? agentMessage.toolCalls.map((toolCall) => ({
456
+ id: toolCall.toolCallId,
457
+ displayName: toolCall.functionName,
458
+ function: {
459
+ name: toolCall.functionName,
460
+ arguments: toolCall.functionArguments,
461
+ result: toolCall.functionResult,
462
+ error: toolCall.functionError,
463
+ },
464
+ // Pass through approval info if present on the tool call
465
+ requiresApproval: toolCall.requiresApproval,
466
+ }))
467
+ : [],
468
+ };
469
+ if (agentMessage.toolCallId) {
470
+ message.tool_call_id = agentMessage.toolCallId;
471
+ }
472
+ return message;
473
+ });
474
+ };
475
+ // interface AgentTerminalProps {
476
+ // agentStub: Agent;
477
+ // }
478
+ export function AgentTerminal({ agentStub, initialMetadata, profiles, isActive = true, compact = false, hideContext = false, hideBottomControls = false, hideGreeting = false, className, initialPrompt, }) {
479
+ const editContext = useEditContext();
480
+ const fieldsContext = useFieldsEditContext();
481
+ const [agent, setAgent] = useState(undefined);
482
+ const [messages, setMessages] = useState([]);
483
+ const [prompt, setPrompt] = useState("");
484
+ const [inputPlaceholder, setInputPlaceholder] = useState("Type your message... (Enter to send, Shift+Enter or Ctrl+Enter for new line)");
485
+ const [isLoading, setIsLoading] = useState(false);
486
+ const [isConnecting, setIsConnecting] = useState(false);
487
+ const [isSubmitting, setIsSubmitting] = useState(false);
488
+ const [activePlaceholderInput, setActivePlaceholderInput] = useState(null);
489
+ const [agentMetadata, setAgentMetadata] = useState(null);
490
+ // Generate a stable clientSessionId per component instance for stream deduplication
491
+ const clientSessionIdRef = useRef(null);
492
+ if (!clientSessionIdRef.current) {
493
+ clientSessionIdRef.current = crypto.randomUUID();
494
+ }
495
+ // Voice input state
496
+ const [isVoiceSupported, setIsVoiceSupported] = useState(false);
497
+ const [isListening, setIsListening] = useState(false);
498
+ const recognitionRef = useRef(null);
499
+ const prevPlaceholderRef = useRef(null);
500
+ const [isWaitingForResponse, setIsWaitingForResponse] = useState(false);
501
+ const isWaitingRef = useRef(false);
502
+ useEffect(() => {
503
+ isWaitingRef.current = isWaitingForResponse;
504
+ }, [isWaitingForResponse]);
505
+ // Dots visibility controlled by 1s idle timer since last incremental update
506
+ const [showDots, setShowDots] = useState(false);
507
+ const dotsTimeoutRef = useRef(null);
508
+ const hasActiveStreaming = useCallback(() => {
509
+ const current = messagesRef.current || [];
510
+ return current.some((m) => !m.isCompleted && m.messageType === "streaming");
511
+ }, []);
512
+ const hasPendingApprovals = useCallback(() => {
513
+ const current = messagesRef.current || [];
514
+ return current.some((m) => (m.toolCalls || []).some((tc) => (tc.functionName || "").includes("(pending approval)")));
515
+ }, []);
516
+ const resetDotsTimer = useCallback(() => {
517
+ if (dotsTimeoutRef.current) {
518
+ clearTimeout(dotsTimeoutRef.current);
519
+ dotsTimeoutRef.current = null;
520
+ }
521
+ const waiting = isWaitingRef.current;
522
+ const streaming = hasActiveStreaming();
523
+ const pendingApprovals = hasPendingApprovals();
524
+ // Don't show dots if there are pending approvals (waiting for user action)
525
+ if (!waiting && !streaming) {
526
+ setShowDots(false);
527
+ return;
528
+ }
529
+ if (pendingApprovals) {
530
+ setShowDots(false);
531
+ return;
532
+ }
533
+ // Show dots immediately when waiting or streaming
534
+ setShowDots(true);
535
+ dotsTimeoutRef.current = setTimeout(() => {
536
+ // Re-check conditions after a brief delay to avoid flicker
537
+ const stillWaiting = isWaitingRef.current;
538
+ const stillStreaming = hasActiveStreaming();
539
+ const stillPendingApprovals = hasPendingApprovals();
540
+ setShowDots((stillWaiting || stillStreaming) && !stillPendingApprovals);
541
+ }, 100);
542
+ }, [hasActiveStreaming, hasPendingApprovals]);
543
+ const [resolvedPageName, setResolvedPageName] = useState(undefined);
544
+ const [resolvedComponentName, setResolvedComponentName] = useState(undefined);
545
+ const [resolvedFieldName, setResolvedFieldName] = useState(undefined);
546
+ const [isContextCollapsed, setIsContextCollapsed] = useState(true);
547
+ const [isContextDragOver, setIsContextDragOver] = useState(false);
548
+ const [promptHistory, setPromptHistory] = useState(() => {
549
+ if (typeof window !== "undefined") {
550
+ return JSON.parse(localStorage.getItem("editor.agent.promptHistory") || "[]");
551
+ }
552
+ return [];
553
+ });
554
+ const [currentHistoryIndex, setCurrentHistoryIndex] = useState(-1);
555
+ const [showPredefined, setShowPredefined] = useState(false);
556
+ const [activeProfile, setActiveProfile] = useState(undefined);
557
+ const [selectedModelId, setSelectedModelId] = useState(undefined);
558
+ const [mode, setMode] = useState("supervised");
559
+ // Remove deprecated cost limit fields from metadata to avoid confusion with agent/profile settings
560
+ const sanitizeAgentMetadata = useCallback((meta) => {
561
+ try {
562
+ if (!meta)
563
+ return meta;
564
+ const clean = { ...meta };
565
+ delete clean.costLimit;
566
+ delete clean.CostLimit;
567
+ delete clean.initialCostLimit;
568
+ delete clean.InitialCostLimit;
569
+ if (clean.additionalData && typeof clean.additionalData === "object") {
570
+ const ad = { ...clean.additionalData };
571
+ delete ad.costLimit;
572
+ delete ad.CostLimit;
573
+ delete ad.initialCostLimit;
574
+ delete ad.InitialCostLimit;
575
+ clean.additionalData = ad;
576
+ }
577
+ return clean;
578
+ }
579
+ catch {
580
+ return meta;
581
+ }
582
+ }, []);
583
+ // Read deterministic flags from query string once
584
+ const deterministicFlags = React.useMemo(() => {
585
+ try {
586
+ const params = new URLSearchParams(window.location.search);
587
+ const detParam = params.get("deterministic");
588
+ const deterministic = detParam === "true" ||
589
+ (detParam === null ? params.has("deterministic") : false);
590
+ const seedStr = params.get("seed");
591
+ const seed = seedStr ? Number(seedStr) : undefined;
592
+ return {
593
+ deterministic,
594
+ seed: Number.isFinite(seed) ? seed : undefined,
595
+ };
596
+ }
597
+ catch {
598
+ return { deterministic: false, seed: undefined };
599
+ }
600
+ }, []);
601
+ useEffect(() => {
602
+ localStorage.setItem("editor.agent.promptHistory", JSON.stringify(promptHistory));
603
+ }, [promptHistory]);
604
+ // Clear idle timer on unmount
605
+ useEffect(() => {
606
+ return () => {
607
+ if (dotsTimeoutRef.current) {
608
+ clearTimeout(dotsTimeoutRef.current);
609
+ dotsTimeoutRef.current = null;
610
+ }
611
+ };
612
+ }, []);
613
+ // Whenever waiting state changes, restart idle timer logic
614
+ useEffect(() => {
615
+ resetDotsTimer();
616
+ }, [isWaitingForResponse, resetDotsTimer]);
617
+ useEffect(() => {
618
+ // Keep messagesRef synchronized with messages state
619
+ messagesRef.current = messages;
620
+ }, [messages]);
621
+ const [error, setError] = useState(null);
622
+ const [costLimitExceeded, setCostLimitExceeded] = useState(null);
623
+ // Live running totals from backend status updates (tokenUsage)
624
+ const [liveTotals, setLiveTotals] = useState(null);
625
+ // Flag to track when we should create a new message
626
+ const shouldCreateNewMessage = useRef(false);
627
+ // Keep a ref to the current messages for immediate access
628
+ const messagesRef = useRef([]);
629
+ const abortControllerRef = useRef(null);
630
+ const messagesEndRef = useRef(null);
631
+ const textareaRef = useRef(null);
632
+ const messagesContainerRef = useRef(null);
633
+ const [shouldAutoScroll, setShouldAutoScroll] = useState(true);
634
+ // WebSocket subscription state for agent streaming
635
+ const seenMessageIdsRef = useRef(new Set());
636
+ const lastSeqRef = useRef(0);
637
+ const subscribedAgentIdRef = useRef(null);
638
+ // Cache mode/model changes made while the agent is still "new" (not yet persisted)
639
+ const pendingSettingsRef = useRef(null);
640
+ // Auto-scroll to bottom when new messages arrive
641
+ const scrollToBottom = useCallback(() => {
642
+ const container = messagesContainerRef.current;
643
+ if (!container)
644
+ return;
645
+ // Jump precisely to the bottom to avoid ending slightly above due to smooth scrolling animations
646
+ container.scrollTop = container.scrollHeight;
647
+ }, []);
648
+ // Detect speech recognition support (client-only)
649
+ useEffect(() => {
650
+ try {
651
+ if (typeof window === "undefined")
652
+ return;
653
+ const SR = window.SpeechRecognition ||
654
+ window.webkitSpeechRecognition;
655
+ setIsVoiceSupported(!!SR);
656
+ }
657
+ catch {
658
+ setIsVoiceSupported(false);
659
+ }
660
+ }, []);
661
+ // Auto-focus terminal input on mount
662
+ useEffect(() => {
663
+ if (textareaRef.current) {
664
+ textareaRef.current.focus();
665
+ }
666
+ }, []);
667
+ // Start voice recognition
668
+ const startVoice = useCallback(() => {
669
+ try {
670
+ if (isListening)
671
+ return;
672
+ if (typeof window === "undefined")
673
+ return;
674
+ const SR = window.SpeechRecognition ||
675
+ window.webkitSpeechRecognition;
676
+ if (!SR) {
677
+ return;
678
+ }
679
+ const r = new SR();
680
+ r.lang = editContext?.currentItemDescriptor?.language || "en-US";
681
+ r.continuous = true;
682
+ r.interimResults = true;
683
+ r.onstart = () => {
684
+ setIsListening(true);
685
+ prevPlaceholderRef.current = inputPlaceholder;
686
+ setInputPlaceholder("Listening...");
687
+ };
688
+ r.onresult = (event) => {
689
+ let finalText = "";
690
+ let interimText = "";
691
+ for (let i = event.resultIndex; i < event.results.length; i++) {
692
+ const res = event.results[i];
693
+ if (res.isFinal)
694
+ finalText += res[0]?.transcript || "";
695
+ else
696
+ interimText += res[0]?.transcript || "";
697
+ }
698
+ if (interimText) {
699
+ setInputPlaceholder(`Listening... ${interimText.trim()}`);
700
+ }
701
+ else {
702
+ setInputPlaceholder("Listening...");
703
+ }
704
+ if (finalText && finalText.trim()) {
705
+ setPrompt((prev) => {
706
+ const prefix = prev && !prev.endsWith(" ") ? prev + " " : prev;
707
+ return (prefix || "") + finalText.trim() + " ";
708
+ });
709
+ if (textareaRef.current) {
710
+ try {
711
+ const v = textareaRef.current.value || "";
712
+ textareaRef.current.selectionStart = v.length;
713
+ textareaRef.current.selectionEnd = v.length;
714
+ }
715
+ catch { }
716
+ }
717
+ }
718
+ };
719
+ r.onerror = (e) => {
720
+ console.warn("Speech recognition error", e);
721
+ };
722
+ r.onend = () => {
723
+ setIsListening(false);
724
+ if (prevPlaceholderRef.current !== null) {
725
+ setInputPlaceholder(prevPlaceholderRef.current);
726
+ prevPlaceholderRef.current = null;
727
+ }
728
+ recognitionRef.current = null;
729
+ };
730
+ recognitionRef.current = r;
731
+ r.start();
732
+ }
733
+ catch (e) {
734
+ console.error("Failed to start voice input", e);
735
+ }
736
+ }, [
737
+ editContext?.currentItemDescriptor?.language,
738
+ inputPlaceholder,
739
+ isListening,
740
+ ]);
741
+ const stopVoice = useCallback(() => {
742
+ try {
743
+ const r = recognitionRef.current;
744
+ if (r)
745
+ r.stop();
746
+ }
747
+ catch { }
748
+ }, []);
749
+ const toggleVoice = useCallback(() => {
750
+ if (isListening)
751
+ stopVoice();
752
+ else
753
+ startVoice();
754
+ }, [isListening, startVoice, stopVoice]);
755
+ // Cleanup any active recognition on unmount
756
+ useEffect(() => {
757
+ return () => {
758
+ try {
759
+ const r = recognitionRef.current;
760
+ if (r) {
761
+ r.onresult = null;
762
+ r.onerror = null;
763
+ r.onend = null;
764
+ r.stop();
765
+ }
766
+ }
767
+ catch { }
768
+ recognitionRef.current = null;
769
+ };
770
+ }, []);
771
+ // Check if user is at the bottom of the scroll container
772
+ const isAtBottom = useCallback(() => {
773
+ const container = messagesContainerRef.current;
774
+ if (!container)
775
+ return true;
776
+ const threshold = 100; // pixels from bottom to consider "at bottom"
777
+ return (container.scrollHeight - container.scrollTop - container.clientHeight <
778
+ threshold);
779
+ }, []);
780
+ // Handle scroll events to detect manual scrolling
781
+ const handleScroll = useCallback(() => {
782
+ const atBottom = isAtBottom();
783
+ if (atBottom !== shouldAutoScroll) {
784
+ setShouldAutoScroll(atBottom);
785
+ }
786
+ }, [isAtBottom, shouldAutoScroll]);
787
+ // Shared stream message handlers with messageId support
788
+ const createNewStreamMessage = useCallback((messageId, agentData) => {
789
+ const currentAgent = agentData || agent;
790
+ if (!currentAgent) {
791
+ console.error("❌ createNewStreamMessage: No agent available", {
792
+ messageId,
793
+ agentData: !!agentData,
794
+ agent: !!agent,
795
+ });
796
+ throw new Error("No agent available");
797
+ }
798
+ // Reduced: avoid verbose logging during streaming
799
+ return {
800
+ id: messageId,
801
+ agentId: currentAgent.id,
802
+ messageIndex: -1,
803
+ role: "assistant",
804
+ content: "",
805
+ name: "agent",
806
+ messageType: "streaming",
807
+ isCompleted: false,
808
+ model: currentAgent.model || "",
809
+ tokensUsed: 0,
810
+ inputTokens: 0,
811
+ outputTokens: 0,
812
+ cachedInputTokens: 0,
813
+ inputTokenCost: 0,
814
+ outputTokenCost: 0,
815
+ cachedInputTokenCost: 0,
816
+ totalCost: 0,
817
+ currency: currentAgent.currency || "USD",
818
+ createdDate: new Date().toISOString(),
819
+ toolCalls: [],
820
+ };
821
+ }, [agent]);
822
+ const handleContentChunk = useCallback((message, agentData) => {
823
+ // Get messageId from data, or generate one from agent ID (for backward compatibility)
824
+ // If no messageId is provided, we'll use the last assistant message or create a new one
825
+ let messageId = message.data?.messageId;
826
+ if (!messageId && agentData?.id) {
827
+ // For backward compatibility: if no messageId, find or create the current streaming message
828
+ // This handles cases where the backend doesn't send messageId
829
+ const currentMessages = messagesRef.current;
830
+ const lastStreamingMessage = [...currentMessages]
831
+ .reverse()
832
+ .find((m) => m.role === "assistant" && !m.isCompleted);
833
+ if (lastStreamingMessage) {
834
+ messageId = lastStreamingMessage.id;
835
+ }
836
+ else {
837
+ // Create a new message ID based on timestamp
838
+ messageId = crypto.randomUUID();
839
+ }
840
+ }
841
+ if (!messageId) {
842
+ console.error("Unable to determine messageId for content chunk!");
843
+ return;
844
+ }
845
+ // Clear waiting state when first content chunk arrives
846
+ setIsWaitingForResponse(false);
847
+ isWaitingRef.current = false;
848
+ // Any content chunk is an incremental update -> reset idle timer
849
+ resetDotsTimer();
850
+ // Extract cost/token data from message.cost (new structure)
851
+ const cost = message.cost;
852
+ if (cost &&
853
+ (cost.total !== undefined || cost.tokens?.total !== undefined)) {
854
+ const nextTotals = {
855
+ input: Number(cost.tokens?.input) || 0,
856
+ output: Number(cost.tokens?.output) || 0,
857
+ cached: Number(cost.tokens?.cached) || 0,
858
+ cacheWrite: Number(cost.tokens?.cacheWrite) || 0,
859
+ inputCost: Number(cost.input) || 0,
860
+ outputCost: Number(cost.output) || 0,
861
+ cachedCost: Number(cost.cached) || 0,
862
+ cacheWriteCost: Number(cost.cacheWrite) || 0,
863
+ totalCost: Number(cost.total) || 0,
864
+ currency: "USD",
865
+ };
866
+ const anyNonZero = (nextTotals.totalCost || 0) > 0 ||
867
+ (nextTotals.input || 0) > 0 ||
868
+ (nextTotals.output || 0) > 0 ||
869
+ (nextTotals.cached || 0) > 0 ||
870
+ (nextTotals.cacheWrite || 0) > 0;
871
+ if (anyNonZero) {
872
+ setLiveTotals(nextTotals);
873
+ }
874
+ // Check cost limit if available
875
+ if (cost.limit &&
876
+ cost.total &&
877
+ Number(cost.total) > Number(cost.limit)) {
878
+ setCostLimitExceeded({
879
+ totalCost: Number(cost.total),
880
+ costLimit: Number(cost.limit),
881
+ initialCostLimit: Number(cost.limit),
882
+ });
883
+ setIsWaitingForResponse(false);
884
+ shouldCreateNewMessage.current = false;
885
+ }
886
+ }
887
+ // Always call setMessages and handle all logic in the callback with latest messages
888
+ setMessages((prev) => {
889
+ // Find existing message by messageId in the latest messages
890
+ const existingMessageIndex = prev.findIndex((msg) => msg.id === messageId);
891
+ if (existingMessageIndex === -1) {
892
+ // Message doesn't exist - create new streaming message
893
+ const newStreamMessage = createNewStreamMessage(messageId, agentData);
894
+ // Set the content for the new message
895
+ const updatedNewMessage = { ...newStreamMessage };
896
+ if (!message.data.isIncremental) {
897
+ updatedNewMessage.content = message.data?.deltaContent || "";
898
+ }
899
+ else {
900
+ updatedNewMessage.content = message.data?.deltaContent || "";
901
+ }
902
+ const updated = [...prev, updatedNewMessage];
903
+ messagesRef.current = updated;
904
+ return updated;
905
+ }
906
+ else {
907
+ // Message exists - update it
908
+ const existingMessage = prev[existingMessageIndex];
909
+ if (!existingMessage)
910
+ return prev;
911
+ // Check if existing content is already longer than what we're trying to stream
912
+ const currentContentLength = existingMessage.content?.length || 0;
913
+ const totalContentLength = message.data?.totalContentLength || 0;
914
+ if (currentContentLength >= totalContentLength &&
915
+ totalContentLength > 0) {
916
+ return prev;
917
+ }
918
+ const updatedMessage = { ...existingMessage };
919
+ if (!message.data.isIncremental) {
920
+ updatedMessage.content = message.data?.deltaContent || "";
921
+ }
922
+ else {
923
+ updatedMessage.content =
924
+ existingMessage.content + (message.data?.deltaContent || "");
925
+ }
926
+ const updated = prev.map((msg, index) => index === existingMessageIndex ? updatedMessage : msg);
927
+ messagesRef.current = updated;
928
+ return updated;
929
+ }
930
+ });
931
+ }, [createNewStreamMessage]);
932
+ const handleToolCall = useCallback((message, agentData) => {
933
+ const toolCallId = message.data?.toolCallId || message.data?.id || crypto.randomUUID();
934
+ // Prefer provided messageId, otherwise fall back to the last streaming assistant message
935
+ let toolCallMessageId = message.data?.messageId;
936
+ if (!toolCallMessageId) {
937
+ const current = messagesRef.current;
938
+ const lastStreaming = [...current]
939
+ .reverse()
940
+ .find((m) => m.role === "assistant" && !m.isCompleted);
941
+ if (lastStreaming?.id) {
942
+ toolCallMessageId = lastStreaming.id;
943
+ }
944
+ }
945
+ // Find or create the target message for this tool call
946
+ if (toolCallMessageId) {
947
+ const currentMessages = messagesRef.current;
948
+ const existingMessageIndex = currentMessages.findIndex((msg) => msg.id === toolCallMessageId);
949
+ if (existingMessageIndex === -1) {
950
+ // Double-check with current ref to prevent race conditions
951
+ const currentMessages = messagesRef.current;
952
+ const existsInRef = currentMessages.find((msg) => msg.id === toolCallMessageId);
953
+ if (!existsInRef) {
954
+ // Create new message for this tool call
955
+ const newStreamMessage = createNewStreamMessage(toolCallMessageId, agentData);
956
+ setMessages((prev) => {
957
+ // Final check before adding to prevent duplicates
958
+ const finalCheck = prev.find((msg) => msg.id === toolCallMessageId);
959
+ if (finalCheck) {
960
+ return prev;
961
+ }
962
+ const updated = [...prev, newStreamMessage];
963
+ messagesRef.current = updated;
964
+ return updated;
965
+ });
966
+ }
967
+ }
968
+ }
969
+ // Add tool call to the message in the array
970
+ if (toolCallMessageId && message.data && toolCallId) {
971
+ const functionName = message.data.functionName ||
972
+ message.data.name ||
973
+ message.data.function?.name ||
974
+ "unknown";
975
+ const toolCall = {
976
+ id: toolCallId,
977
+ messageId: toolCallMessageId,
978
+ dbMessageId: message.data.messageId, // Database message ID for approval/rejection
979
+ toolCallId: toolCallId,
980
+ functionName: functionName,
981
+ functionArguments: message.data.functionArguments ||
982
+ message.data.arguments ||
983
+ JSON.stringify(message.data.function?.arguments || {}),
984
+ functionResult: message.data.functionResult || message.data.result || "",
985
+ functionError: message.data.functionError || message.data.error || "",
986
+ isCompleted: false,
987
+ responseTimeMs: message.data.responseTimeMs,
988
+ createdDate: new Date().toISOString(),
989
+ requiresApproval: message.data?.requiresApproval,
990
+ };
991
+ // Check for duplicates using the current messages ref
992
+ const currentMessages = messagesRef.current;
993
+ const targetMessage = currentMessages.find((msg) => msg.id === toolCallMessageId);
994
+ if (targetMessage) {
995
+ const existingToolCalls = targetMessage.toolCalls || [];
996
+ const existingToolCallIndex = existingToolCalls.findIndex((tc) => tc.toolCallId === toolCallId);
997
+ if (existingToolCallIndex !== -1) {
998
+ return; // Skip adding duplicate
999
+ }
1000
+ }
1001
+ setMessages((prev) => {
1002
+ const updated = prev.map((msg) => {
1003
+ if (msg.id !== toolCallMessageId)
1004
+ return msg;
1005
+ const existingToolCalls = msg.toolCalls || [];
1006
+ return { ...msg, toolCalls: [...existingToolCalls, toolCall] };
1007
+ });
1008
+ messagesRef.current = updated;
1009
+ return updated;
1010
+ });
1011
+ // Tool call activity counts as activity; keep dots hidden for 1s
1012
+ resetDotsTimer();
1013
+ }
1014
+ }, [createNewStreamMessage]);
1015
+ const handleToolResult = useCallback((message, agentData) => {
1016
+ const resultToolCallId = message.data?.toolCallId || message.data?.id || crypto.randomUUID();
1017
+ // Prefer provided messageId, otherwise fall back to the last streaming assistant message
1018
+ let resultMessageId = message.data?.messageId;
1019
+ if (!resultMessageId) {
1020
+ const current = messagesRef.current;
1021
+ const lastStreaming = [...current]
1022
+ .reverse()
1023
+ .find((m) => m.role === "assistant" && !m.isCompleted);
1024
+ if (lastStreaming?.id) {
1025
+ resultMessageId = lastStreaming.id;
1026
+ }
1027
+ }
1028
+ // Extract cost/token data from tool result if present
1029
+ const cost = message.cost;
1030
+ if (cost &&
1031
+ (cost.total !== undefined || cost.tokens?.total !== undefined)) {
1032
+ const nextTotals = {
1033
+ input: Number(cost.tokens?.input) || 0,
1034
+ output: Number(cost.tokens?.output) || 0,
1035
+ cached: Number(cost.tokens?.cached) || 0,
1036
+ cacheWrite: Number(cost.tokens?.cacheWrite) || 0,
1037
+ inputCost: Number(cost.input) || 0,
1038
+ outputCost: Number(cost.output) || 0,
1039
+ cachedCost: Number(cost.cached) || 0,
1040
+ cacheWriteCost: Number(cost.cacheWrite) || 0,
1041
+ totalCost: Number(cost.total) || 0,
1042
+ currency: "USD",
1043
+ };
1044
+ const anyNonZero = (nextTotals.totalCost || 0) > 0 ||
1045
+ (nextTotals.input || 0) > 0 ||
1046
+ (nextTotals.output || 0) > 0 ||
1047
+ (nextTotals.cached || 0) > 0 ||
1048
+ (nextTotals.cacheWrite || 0) > 0;
1049
+ if (anyNonZero) {
1050
+ setLiveTotals(nextTotals);
1051
+ }
1052
+ }
1053
+ else {
1054
+ // Fallback: legacy aggregated totals included in the tool result data
1055
+ const data = message.data;
1056
+ if (data &&
1057
+ (data.totalCost !== undefined || data.totalTokens !== undefined)) {
1058
+ const nextTotals = {
1059
+ input: Number(data.totalInputTokens) || 0,
1060
+ output: Number(data.totalOutputTokens) || 0,
1061
+ cached: Number(data.totalCachedTokens) || 0,
1062
+ cacheWrite: Number(data.totalCacheWriteTokens) || 0,
1063
+ inputCost: Number(data.totalInputTokenCost) || 0,
1064
+ outputCost: Number(data.totalOutputTokenCost) || 0,
1065
+ cachedCost: Number(data.totalCachedTokenCost) || 0,
1066
+ cacheWriteCost: Number(data.totalCacheWriteTokenCost) || 0,
1067
+ totalCost: Number(data.totalCost) || 0,
1068
+ currency: data.currency || "USD",
1069
+ };
1070
+ const anyNonZero = (nextTotals.totalCost || 0) > 0 ||
1071
+ (nextTotals.input || 0) > 0 ||
1072
+ (nextTotals.output || 0) > 0 ||
1073
+ (nextTotals.cached || 0) > 0 ||
1074
+ (nextTotals.cacheWrite || 0) > 0;
1075
+ if (anyNonZero) {
1076
+ setLiveTotals(nextTotals);
1077
+ }
1078
+ }
1079
+ }
1080
+ // Update tool result directly in the messages array
1081
+ if (!resultMessageId) {
1082
+ return;
1083
+ }
1084
+ // Update the message with tool result
1085
+ setMessages((prev) => {
1086
+ const updated = prev.map((msg) => {
1087
+ if (msg.id !== resultMessageId)
1088
+ return msg;
1089
+ const updatedMessage = { ...msg };
1090
+ if (!updatedMessage.toolCalls) {
1091
+ updatedMessage.toolCalls = [];
1092
+ }
1093
+ // Find and update the tool call with the result
1094
+ const toolCallIndex = updatedMessage.toolCalls.findIndex((tc) => tc.toolCallId === resultToolCallId);
1095
+ if (toolCallIndex >= 0) {
1096
+ const existingToolCall = updatedMessage.toolCalls[toolCallIndex];
1097
+ if (existingToolCall && message.data) {
1098
+ const updatedToolCalls = [...updatedMessage.toolCalls];
1099
+ const toolCall = {
1100
+ id: existingToolCall.id,
1101
+ messageId: existingToolCall.messageId,
1102
+ toolCallId: existingToolCall.toolCallId,
1103
+ functionName: existingToolCall.functionName,
1104
+ functionArguments: existingToolCall.functionArguments,
1105
+ functionResult: message.data.functionResult || message.data.result || "",
1106
+ functionError: message.data.functionError || message.data.error || "",
1107
+ isCompleted: true,
1108
+ responseTimeMs: message.data.responseTimeMs,
1109
+ createdDate: existingToolCall.createdDate,
1110
+ };
1111
+ updatedToolCalls[toolCallIndex] = toolCall;
1112
+ updatedMessage.toolCalls = updatedToolCalls;
1113
+ }
1114
+ // Check if all tool calls in message are completed
1115
+ const allToolCallsCompleted = updatedMessage.toolCalls.every((tc) => tc.isCompleted);
1116
+ if (allToolCallsCompleted) {
1117
+ shouldCreateNewMessage.current = true;
1118
+ }
1119
+ }
1120
+ else if (message.data && resultToolCallId && resultMessageId) {
1121
+ // Create new tool call if it doesn't exist
1122
+ const functionName = message.data.functionName ||
1123
+ message.data.name ||
1124
+ message.data.function?.name ||
1125
+ "unknown";
1126
+ const toolCall = {
1127
+ id: resultToolCallId,
1128
+ messageId: resultMessageId,
1129
+ toolCallId: resultToolCallId,
1130
+ functionName: functionName,
1131
+ functionArguments: message.data.functionArguments ||
1132
+ message.data.arguments ||
1133
+ JSON.stringify(message.data.function?.arguments || {}),
1134
+ functionResult: message.data.functionResult || message.data.result || "",
1135
+ functionError: message.data.functionError || message.data.error || "",
1136
+ isCompleted: true,
1137
+ responseTimeMs: message.data.responseTimeMs,
1138
+ createdDate: new Date().toISOString(),
1139
+ };
1140
+ updatedMessage.toolCalls = [...updatedMessage.toolCalls, toolCall];
1141
+ }
1142
+ // Updated tool calls count
1143
+ return updatedMessage;
1144
+ });
1145
+ messagesRef.current = updated;
1146
+ return updated;
1147
+ });
1148
+ // Tool result activity; reset idle timer
1149
+ resetDotsTimer();
1150
+ }, [resetDotsTimer]);
1151
+ // Listen for local approval resolution to update UI
1152
+ useEffect(() => {
1153
+ const onApprovalResolved = (ev) => {
1154
+ try {
1155
+ const detail = ev?.detail || {};
1156
+ const messageId = detail.messageId;
1157
+ const toolCallId = detail.toolCallId;
1158
+ const approved = !!detail.approved;
1159
+ if (!messageId || !toolCallId)
1160
+ return;
1161
+ // Update local state to reflect approval status
1162
+ setMessages((prev) => {
1163
+ const updated = prev.map((m) => {
1164
+ if (m.id !== messageId)
1165
+ return m;
1166
+ const updatedToolCalls = (m.toolCalls || []).map((tc) => {
1167
+ if (tc.toolCallId !== toolCallId)
1168
+ return tc;
1169
+ const base = (tc.functionName || "")
1170
+ .replace(" (pending approval)", "")
1171
+ .replace(" (approved)", "")
1172
+ .replace(" (rejected)", "");
1173
+ return {
1174
+ ...tc,
1175
+ functionName: base + (approved ? " (approved)" : " (rejected)"),
1176
+ };
1177
+ });
1178
+ return { ...m, toolCalls: updatedToolCalls };
1179
+ });
1180
+ messagesRef.current = updated;
1181
+ return updated;
1182
+ });
1183
+ }
1184
+ catch (err) {
1185
+ console.error("❌ Error handling approval resolution:", err);
1186
+ }
1187
+ };
1188
+ window.addEventListener("agent:toolApprovalResolved", onApprovalResolved);
1189
+ return () => window.removeEventListener("agent:toolApprovalResolved", onApprovalResolved);
1190
+ }, []);
1191
+ // Load agent data and messages
1192
+ const loadAgent = useCallback(async () => {
1193
+ try {
1194
+ if (agentStub.status === "new") {
1195
+ // Derive initial profile from provided metadata if present
1196
+ const initialProfileIdFromMeta = (() => {
1197
+ try {
1198
+ return initialMetadata?.additionalData?.profileId;
1199
+ }
1200
+ catch {
1201
+ return undefined;
1202
+ }
1203
+ })();
1204
+ const initialProfileNameFromMeta = (() => {
1205
+ try {
1206
+ return (initialMetadata?.additionalData?.profileName ||
1207
+ initialMetadata?.profile ||
1208
+ undefined);
1209
+ }
1210
+ catch {
1211
+ return undefined;
1212
+ }
1213
+ })();
1214
+ setAgent({
1215
+ ...agentStub,
1216
+ messages: [],
1217
+ status: "new",
1218
+ updatedDate: new Date().toISOString(),
1219
+ createdDate: new Date().toISOString(),
1220
+ id: agentStub.id,
1221
+ name: agentStub.name,
1222
+ model: "",
1223
+ currency: "USD",
1224
+ profileId: initialProfileIdFromMeta || "",
1225
+ profileName: initialProfileNameFromMeta || "",
1226
+ totalTokensUsed: 0,
1227
+ totalInputTokens: 0,
1228
+ totalOutputTokens: 0,
1229
+ totalCachedInputTokens: 0,
1230
+ totalInputTokenCost: 0,
1231
+ totalOutputTokenCost: 0,
1232
+ totalCachedInputTokenCost: 0,
1233
+ totalCost: 0,
1234
+ messageCount: 0,
1235
+ });
1236
+ setMessages([]);
1237
+ setError(null);
1238
+ setIsLoading(false);
1239
+ // Initialize local context for a brand-new agent (not yet persisted)
1240
+ // Optionally seed with current page/selection/focused field based on profile setting
1241
+ const item = editContext?.currentItemDescriptor;
1242
+ const profileForSeeding = (() => {
1243
+ try {
1244
+ if (initialProfileIdFromMeta) {
1245
+ const byId = (profiles || []).find((p) => p.id === initialProfileIdFromMeta);
1246
+ if (byId)
1247
+ return byId;
1248
+ }
1249
+ if (initialProfileNameFromMeta) {
1250
+ const byName = (profiles || []).find((p) => p.name === initialProfileNameFromMeta);
1251
+ if (byName)
1252
+ return byName;
1253
+ }
1254
+ return (profiles || [])[0];
1255
+ }
1256
+ catch {
1257
+ return undefined;
1258
+ }
1259
+ })();
1260
+ const shouldSeedContext = (() => {
1261
+ try {
1262
+ // Prefer profile flag if available; default to true when unspecified
1263
+ return profileForSeeding?.includeEditorContextOnCreate !== undefined
1264
+ ? !!profileForSeeding.includeEditorContextOnCreate
1265
+ : true;
1266
+ }
1267
+ catch {
1268
+ return true;
1269
+ }
1270
+ })();
1271
+ // Create context with top-level properties (what ContextInfoBar expects)
1272
+ const localCtx = item && shouldSeedContext
1273
+ ? {
1274
+ items: [
1275
+ {
1276
+ id: item.id,
1277
+ language: item.language,
1278
+ version: item.version,
1279
+ name: editContext?.contentEditorItem?.name,
1280
+ },
1281
+ ],
1282
+ components: editContext?.selection?.length && item
1283
+ ? editContext.selection.map((componentId) => ({
1284
+ componentId,
1285
+ pageItem: {
1286
+ id: item.id,
1287
+ language: item.language,
1288
+ version: item.version,
1289
+ name: editContext?.contentEditorItem?.name,
1290
+ },
1291
+ }))
1292
+ : undefined,
1293
+ field: fieldsContext?.focusedField?.fieldId &&
1294
+ fieldsContext.focusedField?.item?.id
1295
+ ? {
1296
+ fieldId: fieldsContext.focusedField.fieldId,
1297
+ fieldName: fieldsContext.focusedField
1298
+ .fieldName,
1299
+ item: {
1300
+ id: fieldsContext.focusedField.item.id,
1301
+ language: fieldsContext.focusedField.item.language ||
1302
+ editContext?.currentItemDescriptor?.language ||
1303
+ "en",
1304
+ version: fieldsContext.focusedField.item.version ??
1305
+ editContext?.currentItemDescriptor?.version ??
1306
+ 0,
1307
+ name: editContext?.contentEditorItem?.name,
1308
+ },
1309
+ }
1310
+ : undefined,
1311
+ }
1312
+ : null;
1313
+ let nextMetadata = null;
1314
+ if (initialMetadata) {
1315
+ // Merge initial metadata with local context (using top-level structure)
1316
+ const base = { ...initialMetadata };
1317
+ if (localCtx) {
1318
+ // Merge items (avoid duplicates)
1319
+ if (localCtx.items && localCtx.items.length) {
1320
+ const targetPages = Array.isArray(base.items)
1321
+ ? [...base.items]
1322
+ : [];
1323
+ const existingKeys = new Set(targetPages.map((p) => `${p.id}-${p.language || ""}-${p.version || ""}`));
1324
+ const additions = localCtx.items.filter((p) => !existingKeys.has(`${p.id}-${p.language || ""}-${p.version || ""}`));
1325
+ if (additions.length)
1326
+ base.items = [...targetPages, ...additions];
1327
+ }
1328
+ // Merge components (avoid duplicates)
1329
+ if (localCtx.components && localCtx.components.length) {
1330
+ const currentComponents = Array.isArray(base.components)
1331
+ ? base.components
1332
+ : [];
1333
+ const existingIds = new Set(currentComponents.map((c) => c.componentId));
1334
+ const additions = localCtx.components.filter((c) => !!c?.componentId && !existingIds.has(c.componentId));
1335
+ if (additions.length)
1336
+ base.components = [...currentComponents, ...additions];
1337
+ }
1338
+ // Set field if missing
1339
+ if (!base.field && localCtx.field) {
1340
+ base.field = localCtx.field;
1341
+ }
1342
+ }
1343
+ nextMetadata = base;
1344
+ }
1345
+ else {
1346
+ nextMetadata = localCtx;
1347
+ }
1348
+ if (nextMetadata) {
1349
+ setAgentMetadata(sanitizeAgentMetadata(nextMetadata));
1350
+ // If an initial prompt is provided via metadata, seed the input once
1351
+ try {
1352
+ const maybePrompt = nextMetadata?.additionalData
1353
+ ?.initialPrompt;
1354
+ if (typeof maybePrompt === "string" && maybePrompt.trim()) {
1355
+ setPrompt(maybePrompt);
1356
+ }
1357
+ }
1358
+ catch { }
1359
+ }
1360
+ return;
1361
+ }
1362
+ setIsLoading(true);
1363
+ setError(null);
1364
+ const agentData = await getAgent(agentStub.id);
1365
+ setAgent(agentData);
1366
+ // Merge database messages with any existing local messages using ID-based deduplication
1367
+ // This prevents both missing messages and duplicates
1368
+ setMessages((prevMessages) => {
1369
+ const dbMessages = agentData.messages || [];
1370
+ // Track all DB message IDs as "seen" to prevent WebSocket duplicates
1371
+ dbMessages.forEach((msg) => {
1372
+ if (msg.id) {
1373
+ seenMessageIdsRef.current.add(msg.id.toLowerCase());
1374
+ }
1375
+ });
1376
+ const merged = mergeMessagesById(dbMessages, prevMessages);
1377
+ return merged;
1378
+ });
1379
+ // Check if cost limit was exceeded (detect from existing messages)
1380
+ try {
1381
+ const costLimitMessage = (agentData.messages || []).find((msg) => msg.role === "assistant" &&
1382
+ msg.content &&
1383
+ msg.content.startsWith("⚠️") &&
1384
+ msg.content.includes("Cost limit"));
1385
+ if (costLimitMessage &&
1386
+ costLimitMessage.content &&
1387
+ agentData.costLimit) {
1388
+ // Extract cost from the message if possible
1389
+ const match = costLimitMessage.content.match(/Current cost: \$([0-9.]+)/);
1390
+ const totalCost = match && match[1] ? parseFloat(match[1]) : agentData.totalCost || 0;
1391
+ setCostLimitExceeded({
1392
+ totalCost: totalCost,
1393
+ costLimit: agentData.costLimit,
1394
+ initialCostLimit: agentData.costLimit,
1395
+ });
1396
+ }
1397
+ else if (agentData.costLimit &&
1398
+ agentData.totalCost &&
1399
+ agentData.totalCost > agentData.costLimit) {
1400
+ setCostLimitExceeded({
1401
+ totalCost: agentData.totalCost,
1402
+ costLimit: agentData.costLimit,
1403
+ initialCostLimit: agentData.costLimit,
1404
+ });
1405
+ }
1406
+ }
1407
+ catch (e) {
1408
+ console.error("Failed to check cost limit on load:", e);
1409
+ }
1410
+ // Parse metadata from DB if present (do not seed for existing agents)
1411
+ const parsedMeta = (() => {
1412
+ try {
1413
+ const contextJson = agentData.agentContext;
1414
+ if (!contextJson)
1415
+ return null;
1416
+ const parsedContext = JSON.parse(contextJson);
1417
+ // Context is stored as flat structure with top-level properties
1418
+ if (parsedContext && typeof parsedContext === "object") {
1419
+ return parsedContext;
1420
+ }
1421
+ return null;
1422
+ }
1423
+ catch {
1424
+ return null;
1425
+ }
1426
+ })();
1427
+ // For existing agents, use database metadata or none
1428
+ setAgentMetadata(sanitizeAgentMetadata(parsedMeta));
1429
+ }
1430
+ catch (err) {
1431
+ console.error("❌ Failed to load agent:", err);
1432
+ // For new agents that don't exist yet, this is expected
1433
+ if (err?.message?.includes("404") ||
1434
+ err?.message?.includes("not found")) {
1435
+ // Agent does not exist, treat as new
1436
+ setAgent(undefined);
1437
+ setMessages([]);
1438
+ setError(null);
1439
+ }
1440
+ else {
1441
+ console.error("❌ Load error:", err.message);
1442
+ setError("Failed to load agent data");
1443
+ }
1444
+ }
1445
+ finally {
1446
+ setIsLoading(false);
1447
+ }
1448
+ }, [agentStub.id]);
1449
+ // Initial load
1450
+ useEffect(() => {
1451
+ loadAgent();
1452
+ }, [loadAgent]);
1453
+ // Reload agent when tab becomes active to get latest messages
1454
+ const previousIsActiveRef = useRef(isActive);
1455
+ useEffect(() => {
1456
+ const wasInactive = !previousIsActiveRef.current;
1457
+ const isNowActive = isActive;
1458
+ previousIsActiveRef.current = isActive;
1459
+ if (wasInactive && isNowActive && agent) {
1460
+ loadAgent();
1461
+ }
1462
+ }, [isActive, agent?.id, loadAgent]);
1463
+ // Watch for cost limit exceeded based on agent status or cost values
1464
+ useEffect(() => {
1465
+ if (!agent) {
1466
+ setCostLimitExceeded(null);
1467
+ return;
1468
+ }
1469
+ // Check if cost limit exceeded based on status or cost values
1470
+ const statusIndicatesLimit = agent.status === "costLimitReached" || agent.status === 7;
1471
+ const costExceedsLimit = agent.costLimit && agent.totalCost && agent.totalCost > agent.costLimit;
1472
+ if (statusIndicatesLimit || costExceedsLimit) {
1473
+ // Only set if not already set to avoid unnecessary re-renders
1474
+ setCostLimitExceeded((prev) => {
1475
+ const totalCost = agent.totalCost || 0;
1476
+ const costLimit = agent.costLimit || 0;
1477
+ // Check if values actually changed
1478
+ if (prev?.totalCost === totalCost && prev?.costLimit === costLimit) {
1479
+ return prev;
1480
+ }
1481
+ return {
1482
+ totalCost,
1483
+ costLimit,
1484
+ initialCostLimit: costLimit,
1485
+ };
1486
+ });
1487
+ }
1488
+ else {
1489
+ // Clear cost limit exceeded if status changed back
1490
+ setCostLimitExceeded((prev) => (prev ? null : prev));
1491
+ }
1492
+ }, [agent?.status, agent?.totalCost, agent?.costLimit]);
1493
+ // WebSocket message handler for agent streaming
1494
+ const handleAgentWebSocketMessage = useCallback((message) => {
1495
+ if (!agent)
1496
+ return;
1497
+ const messageType = message.type;
1498
+ // Handle agent:name:updated (payload structure is different)
1499
+ if (messageType === "agent:name:updated") {
1500
+ const { agentId: updatedAgentId, agentName } = message.payload;
1501
+ if (updatedAgentId === agent.id && agentName) {
1502
+ setAgent((prev) => (prev ? { ...prev, name: agentName } : prev));
1503
+ }
1504
+ return;
1505
+ }
1506
+ // For other agent messages, check if this is for our agent
1507
+ const agentId = message.payload?.agentId;
1508
+ if (agentId !== agent.id)
1509
+ return;
1510
+ // Handle agent:run:start
1511
+ if (messageType === "agent:run:start") {
1512
+ // Reset run-scoped deduplication so new run seq values (starting at 1)
1513
+ // are not discarded due to previous run's lastSeqRef
1514
+ lastSeqRef.current = 0;
1515
+ // Prep streaming UI state for the new run
1516
+ setIsConnecting(true);
1517
+ setIsWaitingForResponse(true);
1518
+ isWaitingRef.current = true;
1519
+ shouldCreateNewMessage.current = false;
1520
+ resetDotsTimer();
1521
+ return;
1522
+ }
1523
+ // Handle agent:user:message
1524
+ if (messageType === "agent:user:message") {
1525
+ const { messageId, content, timestamp } = message.payload;
1526
+ // Track in seenMessageIds for deduplication
1527
+ const normalizedId = messageId.toLowerCase();
1528
+ if (seenMessageIdsRef.current.has(normalizedId)) {
1529
+ return;
1530
+ }
1531
+ seenMessageIdsRef.current.add(normalizedId);
1532
+ // Add user message to the messages list
1533
+ setMessages((prev) => {
1534
+ // Double-check if message already exists (deduplication)
1535
+ if (prev.some((m) => m.id && m.id.toLowerCase() === normalizedId)) {
1536
+ return prev;
1537
+ }
1538
+ const userMessage = {
1539
+ id: messageId,
1540
+ agentId: agent.id,
1541
+ messageIndex: prev.length,
1542
+ role: "user",
1543
+ content: content,
1544
+ name: "user",
1545
+ messageType: "user",
1546
+ isCompleted: true,
1547
+ model: "",
1548
+ tokensUsed: 0,
1549
+ inputTokens: 0,
1550
+ outputTokens: 0,
1551
+ cachedInputTokens: 0,
1552
+ inputTokenCost: 0,
1553
+ outputTokenCost: 0,
1554
+ cachedInputTokenCost: 0,
1555
+ totalCost: 0,
1556
+ currency: "USD",
1557
+ createdDate: timestamp || new Date().toISOString(),
1558
+ toolCalls: [],
1559
+ };
1560
+ const updated = [...prev, userMessage];
1561
+ messagesRef.current = updated;
1562
+ return updated;
1563
+ });
1564
+ return;
1565
+ }
1566
+ // Handle agent:run:delta (content, tools, etc.)
1567
+ if (messageType === "agent:run:delta") {
1568
+ const { seq, type, data, cost } = message.payload;
1569
+ // Deduplicate by sequence
1570
+ if (seq && seq <= lastSeqRef.current) {
1571
+ return; // Already processed
1572
+ }
1573
+ if (seq) {
1574
+ lastSeqRef.current = seq;
1575
+ }
1576
+ // Route based on delta type
1577
+ const agentStreamMessage = {
1578
+ type,
1579
+ data,
1580
+ cost,
1581
+ timestamp: new Date().toISOString(),
1582
+ };
1583
+ if (type === "ContentChunk" || type === "contentChunk") {
1584
+ handleContentChunk(agentStreamMessage, agent);
1585
+ }
1586
+ else if (type === "ToolCall" || type === "toolCall") {
1587
+ handleToolCall(agentStreamMessage, agent);
1588
+ }
1589
+ else if (type === "ToolResult" || type === "toolResult") {
1590
+ handleToolResult(agentStreamMessage, agent);
1591
+ }
1592
+ return;
1593
+ }
1594
+ // Unified: agent:run:status (state only)
1595
+ if (messageType === "agent:run:status") {
1596
+ const { seq, data: statusData } = message.payload;
1597
+ // Deduplicate by sequence
1598
+ if (seq && seq <= lastSeqRef.current) {
1599
+ return;
1600
+ }
1601
+ if (seq) {
1602
+ lastSeqRef.current = seq;
1603
+ }
1604
+ // Route based on statusData.state
1605
+ try {
1606
+ if (statusData?.state === "streamOpen") {
1607
+ setIsConnecting(false);
1608
+ return;
1609
+ }
1610
+ if (statusData?.state === "tokenUsage") {
1611
+ const totals = statusData?.totals;
1612
+ if (totals) {
1613
+ const totalCost = Number(totals.totalCost) || 0;
1614
+ const statusCostLimit = (() => {
1615
+ try {
1616
+ const v = statusData?.costLimit;
1617
+ const n = v != null ? Number(v) : undefined;
1618
+ return Number.isFinite(n) && n > 0
1619
+ ? n
1620
+ : undefined;
1621
+ }
1622
+ catch {
1623
+ return undefined;
1624
+ }
1625
+ })();
1626
+ const nextTotals = {
1627
+ input: Number(totals.totalInputTokens) || 0,
1628
+ output: Number(totals.totalOutputTokens) || 0,
1629
+ cached: Number(totals.totalCachedInputTokens) || 0,
1630
+ cacheWrite: Number(totals.totalCacheWriteTokens) || 0,
1631
+ inputCost: Number(totals.totalInputTokenCost) || 0,
1632
+ outputCost: Number(totals.totalOutputTokenCost) || 0,
1633
+ cachedCost: Number(totals.totalCachedInputTokenCost) || 0,
1634
+ cacheWriteCost: Number(totals.totalCacheWriteTokenCost) || 0,
1635
+ totalCost: totalCost,
1636
+ currency: totals.currency,
1637
+ };
1638
+ const anyNonZero = (nextTotals.totalCost || 0) > 0 ||
1639
+ (nextTotals.input || 0) > 0 ||
1640
+ (nextTotals.output || 0) > 0 ||
1641
+ (nextTotals.cached || 0) > 0 ||
1642
+ (nextTotals.cacheWrite || 0) > 0;
1643
+ if (anyNonZero) {
1644
+ setLiveTotals(nextTotals);
1645
+ }
1646
+ // If server provides costLimit along with totals, persist it locally
1647
+ if (statusCostLimit) {
1648
+ setAgent((prev) => prev &&
1649
+ (!prev.costLimit || prev.costLimit !== statusCostLimit)
1650
+ ? { ...prev, costLimit: statusCostLimit }
1651
+ : prev);
1652
+ }
1653
+ if (agent?.costLimit && totalCost > agent.costLimit) {
1654
+ setCostLimitExceeded({
1655
+ totalCost: totalCost,
1656
+ costLimit: agent.costLimit,
1657
+ initialCostLimit: agent.costLimit,
1658
+ });
1659
+ setIsWaitingForResponse(false);
1660
+ shouldCreateNewMessage.current = false;
1661
+ }
1662
+ setMessages((prev) => [...prev]);
1663
+ }
1664
+ return;
1665
+ }
1666
+ if (statusData?.state === "ToolApprovalsRequired") {
1667
+ const msgId = statusData.messageId;
1668
+ const ids = statusData.toolCallIds || [];
1669
+ if (msgId && Array.isArray(ids) && ids.length > 0) {
1670
+ setMessages((prev) => {
1671
+ const updated = prev.map((m) => {
1672
+ if (m.id !== msgId)
1673
+ return m;
1674
+ const existingToolCalls = m.toolCalls || [];
1675
+ const updatedToolCalls = existingToolCalls.map((tc) => {
1676
+ if (!ids.includes(tc.toolCallId))
1677
+ return tc;
1678
+ const fn = tc.functionName || "";
1679
+ return {
1680
+ ...tc,
1681
+ functionName: fn.includes("(pending approval)")
1682
+ ? fn
1683
+ : fn + " (pending approval)",
1684
+ };
1685
+ });
1686
+ return { ...m, toolCalls: updatedToolCalls };
1687
+ });
1688
+ messagesRef.current = updated;
1689
+ return updated;
1690
+ });
1691
+ }
1692
+ setIsConnecting(false);
1693
+ setIsWaitingForResponse(false);
1694
+ return;
1695
+ }
1696
+ if (statusData?.state === "CostLimitReached") {
1697
+ const totalCost = Number(statusData.totalCost) || 0;
1698
+ const costLimit = Number(statusData.costLimit) || agent?.costLimit || 0;
1699
+ setCostLimitExceeded({
1700
+ totalCost: totalCost,
1701
+ costLimit: costLimit,
1702
+ initialCostLimit: costLimit,
1703
+ });
1704
+ setIsWaitingForResponse(false);
1705
+ setIsConnecting(false);
1706
+ return;
1707
+ }
1708
+ if (statusData?.state === "contextWindow") {
1709
+ window.__agentContextWindowStatus = {
1710
+ model: statusData.model,
1711
+ normalizedModel: statusData.normalizedModel,
1712
+ contextWindowTokens: statusData.contextWindowTokens,
1713
+ maxCompletionTokens: statusData.maxCompletionTokens,
1714
+ estimatedInputTokens: statusData.estimatedInputTokens,
1715
+ messageCount: statusData.messageCount,
1716
+ contextUsedPercent: statusData.contextUsedPercent,
1717
+ };
1718
+ setMessages((prev) => [...prev]);
1719
+ return;
1720
+ }
1721
+ if (statusData?.state === "contextChanged") {
1722
+ const nextContext = statusData.context || {};
1723
+ setAgentMetadata((prev) => {
1724
+ const current = (prev || {});
1725
+ const currentWithoutContext = { ...current };
1726
+ delete currentWithoutContext.context;
1727
+ const next = {
1728
+ ...currentWithoutContext,
1729
+ additionalData: {
1730
+ ...(current.additionalData || {}),
1731
+ context: nextContext,
1732
+ },
1733
+ };
1734
+ return next;
1735
+ });
1736
+ return;
1737
+ }
1738
+ }
1739
+ catch (err) {
1740
+ console.error("[AgentTerminal] Error handling status update:", err);
1741
+ }
1742
+ return;
1743
+ }
1744
+ // Lifecycle: agent:run:complete
1745
+ if (messageType === "agent:run:complete") {
1746
+ // Reset deduplication for the next run
1747
+ lastSeqRef.current = 0;
1748
+ // Mark the last assistant message as completed
1749
+ setMessages((prev) => {
1750
+ const updated = prev.map((msg) => msg.role === "assistant" && !msg.isCompleted
1751
+ ? {
1752
+ ...msg,
1753
+ isCompleted: true,
1754
+ messageType: "completed",
1755
+ }
1756
+ : msg);
1757
+ messagesRef.current = updated;
1758
+ return updated;
1759
+ });
1760
+ setIsWaitingForResponse(false);
1761
+ isWaitingRef.current = false;
1762
+ setIsConnecting(false);
1763
+ shouldCreateNewMessage.current = false;
1764
+ resetDotsTimer();
1765
+ return;
1766
+ }
1767
+ // Lifecycle: agent:run:error
1768
+ if (messageType === "agent:run:error") {
1769
+ const errorMsg = message.payload?.error || "Unknown error";
1770
+ // Reset deduplication for the next run after an error
1771
+ lastSeqRef.current = 0;
1772
+ setError(errorMsg);
1773
+ setIsWaitingForResponse(false);
1774
+ isWaitingRef.current = false;
1775
+ setIsConnecting(false);
1776
+ resetDotsTimer();
1777
+ return;
1778
+ }
1779
+ }, [
1780
+ agent,
1781
+ handleContentChunk,
1782
+ handleToolCall,
1783
+ handleToolResult,
1784
+ resetDotsTimer,
1785
+ ]);
1786
+ // Keep refs for latest agent and resetDotsTimer to avoid adding them to effect deps
1787
+ const agentRef = useRef(agent);
1788
+ const resetDotsTimerRef = useRef(resetDotsTimer);
1789
+ const handleAgentWebSocketMessageRef = useRef(handleAgentWebSocketMessage);
1790
+ useEffect(() => {
1791
+ agentRef.current = agent;
1792
+ }, [agent]);
1793
+ useEffect(() => {
1794
+ resetDotsTimerRef.current = resetDotsTimer;
1795
+ }, [resetDotsTimer]);
1796
+ useEffect(() => {
1797
+ handleAgentWebSocketMessageRef.current = handleAgentWebSocketMessage;
1798
+ }, [handleAgentWebSocketMessage]);
1799
+ // Subscribe to agent WebSocket messages when active
1800
+ useEffect(() => {
1801
+ const addListener = editContext?.addSocketMessageListener;
1802
+ if (!isActive || !addListener) {
1803
+ // Unsubscribe if we were previously subscribed
1804
+ if (subscribedAgentIdRef.current) {
1805
+ const socket = globalThis.editorSocket;
1806
+ if (socket && socket.readyState === WebSocket.OPEN) {
1807
+ socket.send(JSON.stringify({
1808
+ type: "agent:unsubscribe",
1809
+ agentId: subscribedAgentIdRef.current,
1810
+ }));
1811
+ }
1812
+ subscribedAgentIdRef.current = null;
1813
+ }
1814
+ return;
1815
+ }
1816
+ // Send subscription message to server
1817
+ const socket = globalThis.editorSocket;
1818
+ if (socket && socket.readyState === WebSocket.OPEN) {
1819
+ socket.send(JSON.stringify({
1820
+ type: "agent:subscribe",
1821
+ agentId: agentStub.id,
1822
+ }));
1823
+ }
1824
+ // Use the addSocketMessageListener helper from editContext
1825
+ // Wrap the handler in a stable function that uses the ref
1826
+ const stableHandler = (message) => {
1827
+ handleAgentWebSocketMessageRef.current(message);
1828
+ };
1829
+ const unsubscribe = addListener(stableHandler);
1830
+ subscribedAgentIdRef.current = agentStub.id;
1831
+ // Reset deduplication state when switching agents
1832
+ seenMessageIdsRef.current.clear();
1833
+ lastSeqRef.current = 0;
1834
+ // Set up streaming state based on agent status (uses latest values via refs)
1835
+ const currentAgent = agentRef.current;
1836
+ if (currentAgent) {
1837
+ const isRunning = currentAgent.status === "running" || currentAgent.status === 1;
1838
+ const isWaitingForApproval = currentAgent.status === "waitingForApproval" ||
1839
+ currentAgent.status === 2;
1840
+ if (isRunning) {
1841
+ setIsWaitingForResponse(true);
1842
+ isWaitingRef.current = true;
1843
+ shouldCreateNewMessage.current = false;
1844
+ resetDotsTimerRef.current();
1845
+ }
1846
+ else if (isWaitingForApproval) {
1847
+ setIsWaitingForResponse(false);
1848
+ isWaitingRef.current = false;
1849
+ resetDotsTimerRef.current();
1850
+ }
1851
+ else {
1852
+ setIsWaitingForResponse(false);
1853
+ isWaitingRef.current = false;
1854
+ resetDotsTimerRef.current();
1855
+ }
1856
+ }
1857
+ return () => {
1858
+ // Send unsubscribe message to server
1859
+ const socket = globalThis.editorSocket;
1860
+ if (socket &&
1861
+ socket.readyState === WebSocket.OPEN &&
1862
+ subscribedAgentIdRef.current) {
1863
+ socket.send(JSON.stringify({
1864
+ type: "agent:unsubscribe",
1865
+ agentId: subscribedAgentIdRef.current,
1866
+ }));
1867
+ }
1868
+ unsubscribe();
1869
+ subscribedAgentIdRef.current = null;
1870
+ };
1871
+ }, [isActive, agentStub.id, editContext?.addSocketMessageListener]);
1872
+ // Focus prompt when requested globally (from AI command)
1873
+ useEffect(() => {
1874
+ const focusHandler = () => {
1875
+ try {
1876
+ if (textareaRef.current) {
1877
+ textareaRef.current.focus();
1878
+ // Move caret to end
1879
+ const value = textareaRef.current.value || "";
1880
+ textareaRef.current.selectionStart = value.length;
1881
+ textareaRef.current.selectionEnd = value.length;
1882
+ }
1883
+ }
1884
+ catch { }
1885
+ };
1886
+ window.addEventListener("editor:focusAgentPrompt", focusHandler);
1887
+ return () => window.removeEventListener("editor:focusAgentPrompt", focusHandler);
1888
+ }, []);
1889
+ // Profiles are provided by parent component (Agents). No local loading here.
1890
+ // Select active profile based on agent.profileId or agentStub.profileId
1891
+ useEffect(() => {
1892
+ if (!profiles || profiles.length === 0)
1893
+ return;
1894
+ // For new agents, use agentStub.profileId; for loaded agents, use agent.profileId
1895
+ const profileIdToUse = agent?.profileId || agentStub.profileId;
1896
+ const candidate = profileIdToUse
1897
+ ? (profiles.find((p) => p.id === profileIdToUse) ?? profiles[0])
1898
+ : profiles[0];
1899
+ if (candidate && (!activeProfile || activeProfile.id !== candidate.id)) {
1900
+ setActiveProfile(candidate);
1901
+ }
1902
+ }, [profiles, agent?.profileId, agentStub.profileId]);
1903
+ // Update selected model when the active profile or agent model changes
1904
+ useEffect(() => {
1905
+ if (!activeProfile)
1906
+ return;
1907
+ const agentModelName = agent?.model; // persisted as model NAME on server
1908
+ const models = activeProfile.models || [];
1909
+ let nextModelId = undefined;
1910
+ if (agentModelName) {
1911
+ const match = models.find((m) => (m.name || "").toLowerCase() === agentModelName.toLowerCase());
1912
+ if (match)
1913
+ nextModelId = match.id;
1914
+ }
1915
+ if (!nextModelId) {
1916
+ nextModelId = activeProfile.defaultModelId || models[0]?.id;
1917
+ }
1918
+ setSelectedModelId(nextModelId || undefined);
1919
+ }, [activeProfile?.id, agent?.model]);
1920
+ // Cleanup stream connection when component unmounts or agent changes
1921
+ useEffect(() => {
1922
+ return () => {
1923
+ if (abortControllerRef.current) {
1924
+ abortControllerRef.current.abort();
1925
+ }
1926
+ };
1927
+ }, [agent?.id]);
1928
+ // Initialize mode from metadata; fall back to agent.Mode from server
1929
+ useEffect(() => {
1930
+ try {
1931
+ const metaMode = agentMetadata?.mode;
1932
+ if (metaMode === "autonomous" ||
1933
+ metaMode === "read-only" ||
1934
+ metaMode === "supervised") {
1935
+ setMode(metaMode);
1936
+ return;
1937
+ }
1938
+ }
1939
+ catch { }
1940
+ try {
1941
+ const serverMode = agent?.mode;
1942
+ if (serverMode === "autonomous" ||
1943
+ serverMode === "read-only" ||
1944
+ serverMode === "supervised") {
1945
+ setMode(serverMode);
1946
+ }
1947
+ }
1948
+ catch { }
1949
+ }, [agentMetadata, agent?.mode]);
1950
+ // Auto-scroll when messages change (only if user hasn't manually scrolled up)
1951
+ useLayoutEffect(() => {
1952
+ if (shouldAutoScroll) {
1953
+ scrollToBottom();
1954
+ }
1955
+ }, [messages, scrollToBottom, shouldAutoScroll]);
1956
+ // Persist any pending settings (mode/model) once an agent exists server-side
1957
+ const persistPendingSettingsIfNeeded = useCallback(async () => {
1958
+ try {
1959
+ if (!agent?.id)
1960
+ return;
1961
+ const pending = pendingSettingsRef.current;
1962
+ if (!pending)
1963
+ return;
1964
+ const payload = {};
1965
+ if (pending.modelName)
1966
+ payload.model = pending.modelName;
1967
+ if (pending.mode)
1968
+ payload.mode = pending.mode;
1969
+ if (Object.keys(payload).length === 0)
1970
+ return;
1971
+ await updateAgentSettings(agent.id, payload);
1972
+ pendingSettingsRef.current = null;
1973
+ }
1974
+ catch (e) {
1975
+ console.error("Failed to persist pending settings", e);
1976
+ }
1977
+ }, [agent?.id]);
1978
+ const handleSubmit = async () => {
1979
+ if (isSubmitting || !editContext)
1980
+ return;
1981
+ try {
1982
+ setIsSubmitting(true);
1983
+ setError(null);
1984
+ // For new agents, use agentStub.id; for existing agents, use agent.id
1985
+ const agentId = agent?.id || agentStub.id;
1986
+ if (!agentId)
1987
+ return;
1988
+ // Optional context factory: invoke if configured and available, otherwise continue
1989
+ const factoryName = agentMetadata?.additionalData
1990
+ ?.contextFactory;
1991
+ if (factoryName) {
1992
+ const factory = editContext.getContextFactory?.(factoryName);
1993
+ if (factory) {
1994
+ try {
1995
+ await Promise.resolve(factory());
1996
+ }
1997
+ catch (e) {
1998
+ console.warn(`Context factory '${factoryName}' failed: ${e?.message || String(e)}`);
1999
+ }
2000
+ }
2001
+ else {
2002
+ console.warn(`Context factory not found: ${factoryName}. Proceeding without it.`);
2003
+ }
2004
+ }
2005
+ // NOTE: User message is no longer added optimistically here
2006
+ // It will be added when we receive the agent:user:message broadcast from the server
2007
+ // This ensures all tabs (including the sending tab) have the same messageId from the database
2008
+ const request = {
2009
+ agentId: agentId,
2010
+ message: prompt.trim(),
2011
+ sessionId: editContext.sessionId,
2012
+ profileId: activeProfile?.id || profiles[0]?.id || "",
2013
+ profile: activeProfile?.name || profiles[0]?.name || "",
2014
+ model: selectedModelId,
2015
+ mode: mode,
2016
+ context: canonicalizeAgentMetadata(agentMetadata), // Canonicalize to ensure complete field structure
2017
+ deterministic: deterministicFlags.deterministic,
2018
+ seed: deterministicFlags.seed,
2019
+ };
2020
+ // Starting agent
2021
+ // Set waiting state to show dancing dots immediately
2022
+ setIsWaitingForResponse(true);
2023
+ // Update the ref immediately so resetDotsTimer sees the new state
2024
+ isWaitingRef.current = true;
2025
+ // Start idle timer; dots appear only if no chunks for >1s
2026
+ resetDotsTimer();
2027
+ // Re-enable auto-scroll when user submits a new message
2028
+ setShouldAutoScroll(true);
2029
+ // No need to create a temporary message - the stream will create messages as needed
2030
+ await startAgent(request);
2031
+ // If user changed mode/model while the agent was new, persist them now
2032
+ await persistPendingSettingsIfNeeded();
2033
+ // Save prompt to history
2034
+ if (prompt.trim()) {
2035
+ setPromptHistory((prev) => [
2036
+ prompt.trim(),
2037
+ ...prev.filter((p) => p !== prompt.trim()).slice(0, 9),
2038
+ ]);
2039
+ setCurrentHistoryIndex(-1);
2040
+ }
2041
+ setPrompt("");
2042
+ // WebSocket connection is already active via subscription - no need for SSE
2043
+ }
2044
+ catch (err) {
2045
+ console.error("Failed to submit prompt:", err);
2046
+ setError("Failed to submit prompt");
2047
+ setIsWaitingForResponse(false);
2048
+ // Remove the optimistically added user message on error
2049
+ setMessages((prev) => prev.slice(0, -1));
2050
+ }
2051
+ finally {
2052
+ setIsSubmitting(false);
2053
+ }
2054
+ };
2055
+ const handleKeyPress = (e) => {
2056
+ // Submit only on plain Enter (no Ctrl/Meta/Shift/Alt)
2057
+ if (e.key === "Enter" &&
2058
+ !e.ctrlKey &&
2059
+ !e.metaKey &&
2060
+ !e.shiftKey &&
2061
+ !e.altKey) {
2062
+ e.preventDefault();
2063
+ handleSubmit();
2064
+ }
2065
+ if (e.key === "ArrowUp") {
2066
+ // Only navigate history if prompt is empty or we're already navigating history
2067
+ const canNavigateHistory = prompt.trim().length === 0 || currentHistoryIndex !== -1;
2068
+ if (canNavigateHistory) {
2069
+ e.preventDefault();
2070
+ if (promptHistory.length > 0) {
2071
+ const newIndex = currentHistoryIndex < promptHistory.length - 1
2072
+ ? currentHistoryIndex + 1
2073
+ : currentHistoryIndex;
2074
+ setCurrentHistoryIndex(newIndex);
2075
+ const historicalPrompt = promptHistory[newIndex];
2076
+ if (textareaRef.current && historicalPrompt) {
2077
+ setPrompt(historicalPrompt);
2078
+ setTimeout(() => {
2079
+ if (textareaRef.current) {
2080
+ textareaRef.current.selectionStart = historicalPrompt.length;
2081
+ textareaRef.current.selectionEnd = historicalPrompt.length;
2082
+ }
2083
+ }, 0);
2084
+ }
2085
+ }
2086
+ }
2087
+ }
2088
+ if (e.key === "ArrowDown" && currentHistoryIndex >= 0) {
2089
+ e.preventDefault();
2090
+ const newIndex = currentHistoryIndex - 1;
2091
+ setCurrentHistoryIndex(newIndex);
2092
+ const historicalPrompt = newIndex >= 0 ? promptHistory[newIndex] || "" : "";
2093
+ setPrompt(historicalPrompt);
2094
+ if (textareaRef.current) {
2095
+ setTimeout(() => {
2096
+ if (textareaRef.current) {
2097
+ textareaRef.current.selectionStart = historicalPrompt.length;
2098
+ textareaRef.current.selectionEnd = historicalPrompt.length;
2099
+ }
2100
+ }, 0);
2101
+ }
2102
+ }
2103
+ };
2104
+ // Send a message programmatically (used by quick-action buttons)
2105
+ const sendQuickMessage = async (text) => {
2106
+ if (!text.trim() || isSubmitting || !editContext)
2107
+ return;
2108
+ try {
2109
+ setIsSubmitting(true);
2110
+ setError(null);
2111
+ const agentId = agent?.id;
2112
+ if (!agentId)
2113
+ return;
2114
+ // Optional context factory: invoke if configured and available, otherwise continue
2115
+ const factoryName = agentMetadata?.additionalData
2116
+ ?.contextFactory;
2117
+ if (factoryName) {
2118
+ const factory = editContext.getContextFactory?.(factoryName);
2119
+ if (factory) {
2120
+ try {
2121
+ await Promise.resolve(factory());
2122
+ }
2123
+ catch (e) {
2124
+ console.warn(`Context factory '${factoryName}' failed: ${e?.message || String(e)}`);
2125
+ }
2126
+ }
2127
+ else {
2128
+ console.warn(`Context factory not found: ${factoryName}. Proceeding without it.`);
2129
+ }
2130
+ }
2131
+ // NOTE: User message is no longer added optimistically here
2132
+ // It will be added when we receive the agent:user:message broadcast from the server
2133
+ // This ensures all tabs (including the sending tab) have the same messageId from the database
2134
+ const request = {
2135
+ agentId: agent.id,
2136
+ message: text.trim(),
2137
+ sessionId: editContext.sessionId,
2138
+ profileId: activeProfile?.id || profiles[0]?.id || "",
2139
+ profile: activeProfile?.name || profiles[0]?.name || "",
2140
+ model: selectedModelId,
2141
+ mode: mode,
2142
+ context: canonicalizeAgentMetadata(agentMetadata), // Canonicalize to ensure complete field structure
2143
+ deterministic: deterministicFlags.deterministic,
2144
+ seed: deterministicFlags.seed,
2145
+ };
2146
+ setIsWaitingForResponse(true);
2147
+ // Update the ref immediately so resetDotsTimer sees the new state
2148
+ isWaitingRef.current = true;
2149
+ resetDotsTimer();
2150
+ setShouldAutoScroll(true);
2151
+ await startAgent(request);
2152
+ // If user changed mode/model while the agent was new, persist them now
2153
+ await persistPendingSettingsIfNeeded();
2154
+ // WebSocket connection is already active via subscription - no need for SSE
2155
+ }
2156
+ catch (err) {
2157
+ console.error("Failed to submit quick message:", err);
2158
+ setError("Failed to submit prompt");
2159
+ setIsWaitingForResponse(false);
2160
+ setMessages((prev) => prev.slice(0, -1));
2161
+ }
2162
+ finally {
2163
+ setIsSubmitting(false);
2164
+ }
2165
+ };
2166
+ // Auto-send initial prompt if provided and agent has no messages yet
2167
+ const initialPromptSentRef = useRef(false);
2168
+ useEffect(() => {
2169
+ if (initialPrompt !== undefined &&
2170
+ !isLoading &&
2171
+ !initialPromptSentRef.current &&
2172
+ messages.length === 0 &&
2173
+ agentStub.id &&
2174
+ editContext &&
2175
+ activeProfile && // MUST have activeProfile set, not just profiles.length
2176
+ profiles.length > 0) {
2177
+ initialPromptSentRef.current = true;
2178
+ // Delay slightly to ensure all state is ready
2179
+ setTimeout(() => {
2180
+ setPrompt(initialPrompt);
2181
+ // Trigger submit programmatically
2182
+ handleSubmit();
2183
+ }, 200);
2184
+ }
2185
+ }, [
2186
+ initialPrompt,
2187
+ isLoading,
2188
+ messages.length,
2189
+ agentStub.id,
2190
+ editContext,
2191
+ activeProfile,
2192
+ profiles.length,
2193
+ handleSubmit,
2194
+ ]);
2195
+ // Resolve display names when metadata or editor state changes
2196
+ useEffect(() => {
2197
+ const metaCtx = agentMetadata;
2198
+ if (!metaCtx) {
2199
+ setResolvedPageName(undefined);
2200
+ setResolvedComponentName(undefined);
2201
+ setResolvedFieldName(undefined);
2202
+ return;
2203
+ }
2204
+ // Page names (for now, just resolve the first page)
2205
+ if (metaCtx.items?.length) {
2206
+ const firstPage = metaCtx.items[0];
2207
+ if (firstPage) {
2208
+ let name = firstPage.name;
2209
+ if (!name &&
2210
+ editContext?.contentEditorItem?.descriptor.id === firstPage.id &&
2211
+ editContext?.contentEditorItem?.name) {
2212
+ name = editContext.contentEditorItem.name;
2213
+ }
2214
+ else if (!name) {
2215
+ name = undefined;
2216
+ }
2217
+ setResolvedPageName(name);
2218
+ }
2219
+ else {
2220
+ setResolvedPageName(undefined);
2221
+ }
2222
+ }
2223
+ else
2224
+ setResolvedPageName(undefined);
2225
+ // Component names (for now, just resolve the first component)
2226
+ if (metaCtx.components?.length && editContext?.page) {
2227
+ const firstComponent = metaCtx.components[0];
2228
+ if (firstComponent?.componentId) {
2229
+ try {
2230
+ const comp = getComponentById(firstComponent.componentId, editContext.page);
2231
+ setResolvedComponentName(comp?.name);
2232
+ }
2233
+ catch {
2234
+ setResolvedComponentName(undefined);
2235
+ }
2236
+ }
2237
+ else {
2238
+ setResolvedComponentName(undefined);
2239
+ }
2240
+ }
2241
+ else
2242
+ setResolvedComponentName(undefined);
2243
+ // Field name (async)
2244
+ (async () => {
2245
+ if (metaCtx.field && editContext?.itemsRepository) {
2246
+ try {
2247
+ // Use the item descriptor from field context if available, otherwise fallback to current item
2248
+ const itemDescriptor = metaCtx.field.item || {
2249
+ id: editContext.currentItemDescriptor?.id || "",
2250
+ language: editContext.currentItemDescriptor?.language || "en",
2251
+ version: editContext.currentItemDescriptor?.version || 0,
2252
+ };
2253
+ const field = await editContext.itemsRepository.getField({
2254
+ item: itemDescriptor,
2255
+ fieldId: metaCtx.field.fieldId,
2256
+ });
2257
+ setResolvedFieldName(field?.name || metaCtx.field.fieldName);
2258
+ }
2259
+ catch {
2260
+ setResolvedFieldName(metaCtx.field.fieldName);
2261
+ }
2262
+ }
2263
+ else
2264
+ setResolvedFieldName(undefined);
2265
+ })();
2266
+ }, [
2267
+ agentMetadata,
2268
+ editContext?.page,
2269
+ editContext?.contentEditorItem,
2270
+ editContext?.currentItemDescriptor,
2271
+ editContext?.itemsRepository,
2272
+ ]);
2273
+ // Stop current execution/stream safely
2274
+ const handleStop = useCallback(async () => {
2275
+ try {
2276
+ setIsWaitingForResponse(false);
2277
+ // **CRITICAL FIX**: Actually cancel the agent execution on the backend
2278
+ // Before we were only disconnecting from the stream, letting the agent run
2279
+ if (agentStub?.id) {
2280
+ try {
2281
+ await cancelAgent(agentStub.id);
2282
+ console.log(`Agent ${agentStub.id} cancellation requested`);
2283
+ }
2284
+ catch (err) {
2285
+ console.error("Failed to cancel agent on backend:", err);
2286
+ // Continue with UI cleanup even if backend call fails
2287
+ }
2288
+ }
2289
+ // Disconnect from the stream
2290
+ if (abortControllerRef.current) {
2291
+ abortControllerRef.current.abort();
2292
+ abortControllerRef.current = null;
2293
+ }
2294
+ setIsConnecting(false);
2295
+ setIsSubmitting(false);
2296
+ // Mark any in-progress streaming messages as completed in UI
2297
+ setMessages((prev) => {
2298
+ const updated = prev.map((msg) => !msg.isCompleted && msg.messageType === "streaming"
2299
+ ? { ...msg, isCompleted: true, messageType: "completed" }
2300
+ : msg);
2301
+ messagesRef.current = updated;
2302
+ return updated;
2303
+ });
2304
+ // Update indicator state
2305
+ resetDotsTimer();
2306
+ }
2307
+ catch (e) {
2308
+ console.error("Failed to stop agent execution", e);
2309
+ }
2310
+ }, [agentStub?.id, resetDotsTimer]);
2311
+ // Determine effective cost limit from agent, profile, or metadata so the cost display
2312
+ // is visible immediately even before any messages or server-side persistence.
2313
+ const effectiveCostLimit = useMemo(() => {
2314
+ try {
2315
+ const candidates = [
2316
+ agent?.costLimit,
2317
+ activeProfile?.costLimit,
2318
+ ];
2319
+ for (const c of candidates) {
2320
+ const n = c != null ? Number(c) : 0;
2321
+ if (Number.isFinite(n) && n > 0)
2322
+ return n;
2323
+ }
2324
+ }
2325
+ catch { }
2326
+ return undefined;
2327
+ }, [agent?.costLimit, activeProfile?.costLimit]);
2328
+ if (isLoading) {
2329
+ return (_jsx("div", { className: "flex h-full items-center justify-center", children: _jsxs("div", { className: "flex items-center gap-2 text-xs text-gray-500", children: [_jsx(Loader2, { className: "h-4 w-4 animate-spin", strokeWidth: 1 }), "Loading agent..."] }) }));
2330
+ }
2331
+ // Calculate total token usage for cost display
2332
+ const totalTokens = calculateTotalTokens(messages);
2333
+ // Determine if the agent is actively executing (submitting, connecting, waiting, or streaming)
2334
+ const isExecuting = isSubmitting ||
2335
+ isConnecting ||
2336
+ isWaitingForResponse ||
2337
+ hasActiveStreaming();
2338
+ const renderContextInfoBar = () => (_jsx(ContextInfoBar, { agent: agent, agentMetadata: agentMetadata, setAgentMetadata: setAgentMetadata, setAgent: setAgent, resolvedPageName: resolvedPageName, resolvedComponentName: resolvedComponentName, resolvedFieldName: resolvedFieldName }));
2339
+ const renderCostLimitBanner = () => {
2340
+ if (!costLimitExceeded)
2341
+ return null;
2342
+ const { totalCost, costLimit, initialCostLimit } = costLimitExceeded;
2343
+ return (_jsxs("div", { className: "m-3 rounded border border-amber-300 bg-amber-50 p-3 text-xs text-amber-900", children: [_jsxs("div", { className: "mb-2 flex items-center gap-2", children: [_jsx(AlertCircle, { className: "h-4 w-4 text-amber-500", strokeWidth: 1 }), _jsxs("span", { children: ["Cost limit exceeded. Spent $", totalCost.toFixed(2), " / $", costLimit.toFixed(2), "."] })] }), _jsx("div", { className: "flex gap-2", children: _jsx("button", { className: "rounded border border-amber-300 bg-white px-2 py-1 hover:bg-amber-100", onClick: async () => {
2344
+ if (!agent?.id)
2345
+ return;
2346
+ try {
2347
+ // Extend cost limit - backend will automatically resume the agent
2348
+ const result = await updateAgentCostLimit(agent.id, "extend");
2349
+ // Update the agent's cost limit in local state
2350
+ if (result.success && result.costLimit !== undefined) {
2351
+ setAgent((prev) => prev ? { ...prev, costLimit: result.costLimit } : prev);
2352
+ }
2353
+ // Clear the banner and set waiting state
2354
+ // Agent will resume automatically via backend's ResumeAgentAsync
2355
+ setCostLimitExceeded(null);
2356
+ setIsWaitingForResponse(true);
2357
+ isWaitingRef.current = true;
2358
+ setShouldAutoScroll(true);
2359
+ }
2360
+ catch (e) {
2361
+ console.error("Failed to extend cost limit:", e);
2362
+ setError(e instanceof Error
2363
+ ? e.message
2364
+ : "Failed to extend cost limit");
2365
+ }
2366
+ }, children: "Extend limit and continue" }) })] }));
2367
+ };
2368
+ return (_jsxs("div", { className: `flex h-full flex-col ${className || ""}`, children: [_jsxs("div", { ref: messagesContainerRef, className: "flex-1 overflow-y-auto", onScroll: handleScroll, children: [error && (_jsx("div", { className: "m-4 rounded-lg border-l-4 border-red-500 bg-red-50 p-3 select-text", children: _jsxs("div", { className: "flex items-start", children: [_jsx(AlertCircle, { className: "mt-0.5 h-5 w-5 text-red-400", strokeWidth: 1 }), _jsxs("div", { className: "ml-3", children: [_jsx("p", { className: "text-sm font-medium text-red-800", children: "Error" }), _jsx("p", { className: "mt-1 text-sm text-red-700", children: error })] })] }) })), messages.length === 0 && !error && !hideGreeting && (_jsx("div", { className: "flex h-full items-center justify-center p-8", children: _jsx("div", { className: "max-w-prose text-center", children: !activeProfile ? (_jsx(Loader2, { className: "h-8 w-8 animate-spin text-gray-400 mx-auto" })) : (_jsxs(_Fragment, { children: [activeProfile.svgIcon ? (_jsx("div", { className: "mx-auto mb-4 flex h-24 w-24 items-center justify-center text-gray-400 [&>svg]:h-full [&>svg]:w-full", dangerouslySetInnerHTML: {
2369
+ __html: activeProfile.svgIcon,
2370
+ } })) : (_jsx(SecretAgentIcon, { size: 96, strokeWidth: 1, className: "mx-auto mb-4 text-gray-400" })), activeProfile.greetingMessage ? (_jsx(ViewTransition, { children: _jsx("div", { className: "prose prose-sm mx-auto text-center", dangerouslySetInnerHTML: {
2371
+ __html: activeProfile.greetingMessage,
2372
+ } }) })) : (_jsxs(_Fragment, { children: [_jsx("h3", { className: "mb-2 text-lg font-medium text-gray-900", children: "Start a conversation" }), _jsx("p", { className: "mb-4 text-sm text-gray-500", children: "Send a message to begin working with your AI agent." }), _jsx("div", { className: "text-xs text-gray-400", children: "Your agent can help with content editing, research, and automation tasks." })] }))] })) }) })), _jsx("div", { className: "space-y-0 divide-y divide-gray-100 select-text", children: groupConsecutiveMessages(messages).map((group, groupIndex) => {
2373
+ if (group.type === "user" && group.messages[0]) {
2374
+ // Render user message
2375
+ return (_jsx(UserMessage, { message: group.messages[0] }, groupIndex));
2376
+ }
2377
+ else {
2378
+ // Render bundled assistant messages
2379
+ // Check if this group contains any streaming message
2380
+ const hasStreamingMessage = group.messages.some((msg) => !msg.isCompleted && msg.messageType === "streaming");
2381
+ // Filter out cost limit error messages (they're shown in the banner instead)
2382
+ const filteredMessages = group.messages.filter((msg) => {
2383
+ const content = msg.content || "";
2384
+ // Skip messages that are cost limit errors (shown in banner instead)
2385
+ return (!content.startsWith("⚠️") || !content.includes("Cost limit"));
2386
+ });
2387
+ // If all messages were filtered out, don't render this group
2388
+ if (filteredMessages.length === 0) {
2389
+ return null;
2390
+ }
2391
+ const convertedMessages = convertAgentMessagesToAiFormat(filteredMessages);
2392
+ return (_jsx(AiResponseMessage, { messages: convertedMessages, finished: !isSubmitting && !isConnecting, editOperations: [], error: error || undefined, profileSvgIcon: activeProfile?.svgIcon, agentId: agent?.id || agentStub.id, agentName: activeProfile?.name, onQuickAction: (action) => {
2393
+ const text = (action.prompt ||
2394
+ action.value ||
2395
+ action.label ||
2396
+ "").trim();
2397
+ if (!text)
2398
+ return;
2399
+ // Check if text contains placeholders ({placeholder} or <placeholder>)
2400
+ const hasPlaceholders = /\{([^}]+)\}|<([^>]+)>/.test(text);
2401
+ if (hasPlaceholders) {
2402
+ // Show placeholder input
2403
+ setActivePlaceholderInput({
2404
+ text,
2405
+ behavior: action.behavior,
2406
+ });
2407
+ return;
2408
+ }
2409
+ if (action.behavior === "compose") {
2410
+ setPrompt(text);
2411
+ setInputPlaceholder(action.placeholder ||
2412
+ "Review and edit, then press Enter to send");
2413
+ if (textareaRef.current) {
2414
+ try {
2415
+ textareaRef.current.focus();
2416
+ const v = textareaRef.current.value || "";
2417
+ textareaRef.current.selectionStart = v.length;
2418
+ textareaRef.current.selectionEnd = v.length;
2419
+ }
2420
+ catch { }
2421
+ }
2422
+ return;
2423
+ }
2424
+ // Stop any current execution before sending the next message
2425
+ if (isExecuting) {
2426
+ try {
2427
+ handleStop();
2428
+ }
2429
+ catch { }
2430
+ }
2431
+ sendQuickMessage(text);
2432
+ } }, groupIndex));
2433
+ }
2434
+ }) }), _jsx("div", { className: showDots ? "visible" : "invisible", children: _jsx(DancingDots, {}) }), renderCostLimitBanner(), _jsx("div", { ref: messagesEndRef })] }), !hideContext && renderContextInfoBar(), !hideContext && (_jsx(TodoListPanel, { messages: messages, agentMetadata: agentMetadata })), _jsxs("div", { className: "border-t border-gray-200 p-4", children: [activePlaceholderInput ? (
2435
+ // Placeholder Input (from quick actions)
2436
+ _jsx(PlaceholderInput, { text: activePlaceholderInput.text, showButtons: false, onComplete: (filledText) => {
2437
+ setActivePlaceholderInput(null);
2438
+ if (activePlaceholderInput.behavior === "compose") {
2439
+ setPrompt(filledText);
2440
+ setInputPlaceholder("Review and edit, then press Enter to send");
2441
+ if (textareaRef.current) {
2442
+ try {
2443
+ textareaRef.current.focus();
2444
+ const v = textareaRef.current.value || "";
2445
+ textareaRef.current.selectionStart = v.length;
2446
+ textareaRef.current.selectionEnd = v.length;
2447
+ }
2448
+ catch { }
2449
+ }
2450
+ }
2451
+ else {
2452
+ // Submit behavior or default
2453
+ if (isExecuting) {
2454
+ try {
2455
+ handleStop();
2456
+ }
2457
+ catch { }
2458
+ }
2459
+ sendQuickMessage(filledText);
2460
+ }
2461
+ }, onCancel: () => {
2462
+ setActivePlaceholderInput(null);
2463
+ } })) : prompt && /\{([^}]+)\}|<([^>]+)>/.test(prompt) ? (
2464
+ // Template mode: show PlaceholderInput when prompt contains placeholders
2465
+ _jsx(PlaceholderInput, { text: prompt, showButtons: false, onComplete: (filledText) => {
2466
+ setPrompt(filledText);
2467
+ // Auto-submit after filling placeholders
2468
+ if (filledText.trim()) {
2469
+ if (isExecuting) {
2470
+ try {
2471
+ handleStop();
2472
+ }
2473
+ catch { }
2474
+ }
2475
+ sendQuickMessage(filledText);
2476
+ }
2477
+ }, onCancel: () => {
2478
+ setPrompt("");
2479
+ setInputPlaceholder("Type your message... (Enter to send, Shift+Enter or Ctrl+Enter for new line)");
2480
+ } })) : (_jsx("div", { className: "flex items-stretch gap-2", children: _jsx(Textarea, { ref: textareaRef, value: prompt, onChange: (e) => {
2481
+ setPrompt(e.target.value);
2482
+ // Reset history index when user starts typing
2483
+ if (currentHistoryIndex !== -1) {
2484
+ setCurrentHistoryIndex(-1);
2485
+ }
2486
+ }, onKeyDown: handleKeyPress, placeholder: inputPlaceholder, className: "h-[80px] flex-1 resize-none overflow-y-auto text-xs", "data-testid": "agent-terminal-prompt", disabled: isSubmitting }) })), !hideBottomControls && (_jsxs(_Fragment, { children: [_jsxs("div", { className: "flex items-stretch justify-between gap-2", children: [_jsxs("div", { className: "mt-2 flex flex-wrap items-center justify-start gap-2", children: [_jsxs(Tooltip, { delayDuration: 400, children: [_jsx(TooltipTrigger, { asChild: true, children: _jsxs("select", { className: `h-5 rounded border px-1.5 text-[10px] ${mode === "read-only"
2487
+ ? "border-green-300 bg-green-50 text-green-700"
2488
+ : mode === "supervised"
2489
+ ? "border-amber-300 bg-amber-50 text-amber-700"
2490
+ : "border-red-300 bg-red-50 text-red-700"}`, value: mode, onChange: async (e) => {
2491
+ const nextMode = e.target.value || "supervised";
2492
+ // Optimistic UI update
2493
+ setMode(nextMode);
2494
+ const current = agentMetadata || {};
2495
+ const nextMeta = {
2496
+ ...current,
2497
+ mode: nextMode,
2498
+ };
2499
+ try {
2500
+ if (!agent?.id || agent.status === "new") {
2501
+ setAgentMetadata(nextMeta);
2502
+ // Cache until first start when agent is persisted
2503
+ pendingSettingsRef.current = {
2504
+ ...(pendingSettingsRef.current || {}),
2505
+ mode: nextMode,
2506
+ };
2507
+ return;
2508
+ }
2509
+ await updateAgentSettings(agent.id, {
2510
+ mode: nextMode,
2511
+ });
2512
+ setAgentMetadata(nextMeta);
2513
+ setAgent((prev) => prev
2514
+ ? { ...prev, metadata: JSON.stringify(nextMeta) }
2515
+ : prev);
2516
+ }
2517
+ catch (e2) {
2518
+ console.error("Failed to persist mode change", e2);
2519
+ }
2520
+ }, title: "Mode", "aria-label": "Mode", "data-testid": "agent-mode-select", children: [_jsx("option", { value: "supervised", children: "Supervised" }), _jsx("option", { value: "autonomous", children: "Autonomous" }), _jsx("option", { value: "read-only", children: "Read-Only" })] }) }), _jsx(TooltipContent, { side: "top", sideOffset: 6, children: _jsxs("div", { className: "max-w-[320px] space-y-1", children: [_jsxs("div", { children: [_jsx("span", { className: "font-semibold text-green-500", children: "Read-Only" }), ": Limited tool access as configured by the profile (Ask Mode Tools)."] }), _jsxs("div", { children: [_jsx("span", { className: "font-semibold text-amber-500", children: "Supervised" }), ": Full tool access, but writes are limited to pages/items in the current context. Creating new items or updating existing items outside the current context requires explicit approval."] }), _jsxs("div", { children: [_jsx("span", { className: "font-semibold text-red-500", children: "Autonomous" }), ": Full tool access; can write across the site/project only limited by user permissions."] })] }) })] }), profiles?.length > 0 && (_jsx("select", { className: "h-5 rounded border px-1.5 text-[10px] text-gray-500", value: activeProfile?.id || "", onChange: async (e) => {
2521
+ const nextProfile = profiles.find((x) => x.id === e.target.value);
2522
+ if (!nextProfile)
2523
+ return;
2524
+ setActiveProfile(nextProfile);
2525
+ try {
2526
+ if (agent?.id && agent.status !== "new") {
2527
+ await updateAgentSettings(agent.id, {
2528
+ profileId: nextProfile.id,
2529
+ profileName: nextProfile.name,
2530
+ });
2531
+ }
2532
+ else {
2533
+ // cache until first start
2534
+ pendingSettingsRef.current = {
2535
+ ...(pendingSettingsRef.current || {}),
2536
+ // we cache profile by updating local metadata
2537
+ };
2538
+ setAgentMetadata((current) => {
2539
+ const next = { ...(current || {}) };
2540
+ next.profile = nextProfile.name;
2541
+ next.additionalData = {
2542
+ ...(next.additionalData || {}),
2543
+ profileId: nextProfile.id,
2544
+ profileName: nextProfile.name,
2545
+ };
2546
+ return next;
2547
+ });
2548
+ }
2549
+ // reflect in local agent stub so tabs and titles can use it if needed
2550
+ setAgent((prev) => prev
2551
+ ? {
2552
+ ...prev,
2553
+ metadata: JSON.stringify({
2554
+ ...(agentMetadata || {}),
2555
+ profile: nextProfile.name,
2556
+ additionalData: {
2557
+ ...(agentMetadata
2558
+ ?.additionalData || {}),
2559
+ profileId: nextProfile.id,
2560
+ profileName: nextProfile.name,
2561
+ },
2562
+ }),
2563
+ }
2564
+ : prev);
2565
+ }
2566
+ catch (err) {
2567
+ console.error("Failed to persist agent profile", err);
2568
+ }
2569
+ }, title: "Profile", "aria-label": "Profile", "data-testid": "agent-profile-select", children: profiles.map((p) => (_jsx("option", { value: p.id, children: p.name }, p.id))) })), activeProfile?.models?.length ? (_jsx("select", { className: "h-5 rounded border px-1.5 text-[10px] text-gray-500", value: selectedModelId || "", onChange: async (e) => {
2570
+ const nextId = e.target.value;
2571
+ setSelectedModelId(nextId);
2572
+ const modelName = activeProfile?.models?.find((m) => m.id === nextId)
2573
+ ?.name || "";
2574
+ // Update local agent state immediately for UX and to reflect in streaming stub
2575
+ setAgent((prev) => prev ? { ...prev, model: modelName } : prev);
2576
+ // Persist only for existing agents; otherwise cache until first start
2577
+ try {
2578
+ if (agent?.id && agent.status !== "new") {
2579
+ await updateAgentSettings(agent.id, {
2580
+ model: modelName,
2581
+ });
2582
+ }
2583
+ else {
2584
+ pendingSettingsRef.current = {
2585
+ ...(pendingSettingsRef.current || {}),
2586
+ modelName,
2587
+ };
2588
+ }
2589
+ }
2590
+ catch (err) {
2591
+ console.error("Failed to persist agent model", err);
2592
+ }
2593
+ }, title: "Model", "aria-label": "Model", "data-testid": "agent-model-select", children: activeProfile.models.map((m) => (_jsx("option", { value: m.id, children: m.name }, m.id))) })) : null, activeProfile?.prompts?.length ? (_jsxs(Popover, { open: showPredefined, onOpenChange: setShowPredefined, children: [_jsx(PopoverTrigger, { asChild: true, children: _jsx("button", { className: "rounded p-1 hover:bg-gray-100", onClick: () => { }, title: "Predefined prompts", "aria-label": "Predefined prompts", children: _jsx(Wand2, { className: "h-3 w-3", strokeWidth: 1 }) }) }), _jsx(PopoverContent, { className: "w-64 p-0", align: "start", children: _jsx("div", { className: "max-h-56 overflow-y-auto p-2", children: activeProfile.prompts.map((p, index) => (_jsx("div", { className: "cursor-pointer rounded p-1.5 text-xs text-gray-700 hover:bg-gray-100", onClick: () => {
2594
+ setPrompt(p.prompt);
2595
+ setShowPredefined(false);
2596
+ if (textareaRef.current)
2597
+ textareaRef.current.focus();
2598
+ }, children: p.title }, index))) }) })] })) : null] }), _jsxs("div", { className: "flex items-center gap-1 self-end", children: [isVoiceSupported ? (_jsx(Button, { onClick: toggleVoice, size: "sm", className: "h-5.5 w-5.5 cursor-pointer rounded-full", title: isListening ? "Stop voice input" : "Start voice input", "aria-label": isListening ? "Stop voice input" : "Start voice input", "aria-pressed": isListening, children: isListening ? (_jsx(MicOff, { className: "size-3", strokeWidth: 1 })) : (_jsx(Mic, { className: "size-3", strokeWidth: 1 })) })) : null, _jsx(Button, { onClick: isExecuting ? handleStop : handleSubmit, disabled: !isExecuting && !prompt.trim(), size: "sm", className: "h-5.5 w-5.5 cursor-pointer rounded-full", title: isExecuting ? "Stop" : "Send", "aria-label": isExecuting ? "Stop" : "Send", "data-testid": "agent-send-stop-button", "data-executing": isExecuting ? "true" : "false", children: isExecuting ? (_jsx(Square, { className: "size-3", strokeWidth: 1 })) : (_jsx(Send, { className: "size-3", strokeWidth: 1 })) })] })] }), _jsxs("div", { className: "mt-1 flex items-center gap-2 text-[10px] text-gray-500", children: [_jsx(AgentCostDisplay, { totalTokens: liveTotals
2599
+ ? {
2600
+ input: liveTotals.input,
2601
+ output: liveTotals.output,
2602
+ cached: liveTotals.cached,
2603
+ cacheWrite: liveTotals.cacheWrite ?? 0,
2604
+ inputCost: liveTotals.inputCost,
2605
+ outputCost: liveTotals.outputCost,
2606
+ cachedCost: liveTotals.cachedCost,
2607
+ cacheWriteCost: liveTotals.cacheWriteCost ?? 0,
2608
+ totalCost: liveTotals.totalCost,
2609
+ }
2610
+ : totalTokens, costLimit: effectiveCostLimit }), (() => {
2611
+ try {
2612
+ const s = window.__agentContextWindowStatus;
2613
+ if (!s || !s.contextWindowTokens)
2614
+ return null;
2615
+ const pct = typeof s.contextUsedPercent === "number"
2616
+ ? `${s.contextUsedPercent.toFixed(1)}%`
2617
+ : undefined;
2618
+ // Helper function to format tokens as "k"
2619
+ const formatTokens = (tokens) => {
2620
+ if (tokens >= 1000) {
2621
+ return `${(tokens / 1000).toFixed(1)}k`;
2622
+ }
2623
+ return tokens.toString();
2624
+ };
2625
+ if (!pct)
2626
+ return null;
2627
+ return (_jsxs(Tooltip, { children: [_jsx(TooltipTrigger, { asChild: true, children: _jsxs("div", { className: "cursor-help rounded border border-gray-200 bg-gray-50 px-2 py-0.5", children: ["Context: ", pct] }) }), _jsx(TooltipContent, { side: "top", sideOffset: 6, children: _jsxs("div", { className: "max-w-[320px] space-y-1 text-xs", children: [_jsxs("div", { children: [_jsx("span", { className: "font-semibold", children: "Model:" }), " ", s.model, s.normalizedModel && ` (${s.normalizedModel})`] }), _jsxs("div", { children: [_jsx("span", { className: "font-semibold", children: "Context window:" }), " ", formatTokens(s.estimatedInputTokens || 0), " /", " ", formatTokens(s.contextWindowTokens), " tokens"] }), typeof s.maxCompletionTokens === "number" && (_jsxs("div", { children: [_jsx("span", { className: "font-semibold", children: "Max completion:" }), " ", formatTokens(s.maxCompletionTokens), " tokens"] })), _jsxs("div", { children: [_jsx("span", { className: "font-semibold", children: "Used:" }), " ", pct] })] }) })] }));
2628
+ }
2629
+ catch {
2630
+ return null;
2631
+ }
2632
+ })()] })] }))] })] }));
2633
+ }
2634
+ //# sourceMappingURL=AgentTerminal.js.map