@messenger-box/tailwind-ui-inbox 10.0.3-alpha.100

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 (373) hide show
  1. package/CHANGELOG.md +104 -0
  2. package/LICENSE +21 -0
  3. package/jest.config.js +9 -0
  4. package/lib/cdm-locales/en/translations.json +31 -0
  5. package/lib/cdm-locales/es/translations.json +31 -0
  6. package/lib/components/AIAgent/AIAgent.d.ts +21 -0
  7. package/lib/components/AIAgent/AIAgent.d.ts.map +1 -0
  8. package/lib/components/AIAgent/AIAgent.js +904 -0
  9. package/lib/components/AIAgent/AIAgent.js.map +1 -0
  10. package/lib/components/AIAgent/index.d.ts +2 -0
  11. package/lib/components/AIAgent/index.d.ts.map +1 -0
  12. package/lib/components/InboxMessage/CommonMessage.d.ts +8 -0
  13. package/lib/components/InboxMessage/CommonMessage.d.ts.map +1 -0
  14. package/lib/components/InboxMessage/CommonMessage.js +35 -0
  15. package/lib/components/InboxMessage/CommonMessage.js.map +1 -0
  16. package/lib/components/InboxMessage/ConversationItem.d.ts +14 -0
  17. package/lib/components/InboxMessage/ConversationItem.d.ts.map +1 -0
  18. package/lib/components/InboxMessage/ConversationItem.js +200 -0
  19. package/lib/components/InboxMessage/ConversationItem.js.map +1 -0
  20. package/lib/components/InboxMessage/InputComponent.d.ts +12 -0
  21. package/lib/components/InboxMessage/InputComponent.d.ts.map +1 -0
  22. package/lib/components/InboxMessage/InputComponent.js +359 -0
  23. package/lib/components/InboxMessage/InputComponent.js.map +1 -0
  24. package/lib/components/InboxMessage/LeftSidebar.d.ts +20 -0
  25. package/lib/components/InboxMessage/LeftSidebar.d.ts.map +1 -0
  26. package/lib/components/InboxMessage/LeftSidebar.js +102 -0
  27. package/lib/components/InboxMessage/LeftSidebar.js.map +1 -0
  28. package/lib/components/InboxMessage/MessageInput.d.ts +9 -0
  29. package/lib/components/InboxMessage/MessageInput.d.ts.map +1 -0
  30. package/lib/components/InboxMessage/MessageInput.js +154 -0
  31. package/lib/components/InboxMessage/MessageInput.js.map +1 -0
  32. package/lib/components/InboxMessage/MessageInputComponent.d.ts +9 -0
  33. package/lib/components/InboxMessage/MessageInputComponent.d.ts.map +1 -0
  34. package/lib/components/InboxMessage/Messages.d.ts +17 -0
  35. package/lib/components/InboxMessage/Messages.d.ts.map +1 -0
  36. package/lib/components/InboxMessage/Messages.js +99 -0
  37. package/lib/components/InboxMessage/Messages.js.map +1 -0
  38. package/lib/components/InboxMessage/MessagesBuilderUi.d.ts +17 -0
  39. package/lib/components/InboxMessage/MessagesBuilderUi.d.ts.map +1 -0
  40. package/lib/components/InboxMessage/Popover.d.ts +3 -0
  41. package/lib/components/InboxMessage/Popover.d.ts.map +1 -0
  42. package/lib/components/InboxMessage/Popover.js +31 -0
  43. package/lib/components/InboxMessage/Popover.js.map +1 -0
  44. package/lib/components/InboxMessage/RightSidebar.d.ts +9 -0
  45. package/lib/components/InboxMessage/RightSidebar.d.ts.map +1 -0
  46. package/lib/components/InboxMessage/RightSidebar.js +9 -0
  47. package/lib/components/InboxMessage/RightSidebar.js.map +1 -0
  48. package/lib/components/InboxMessage/RightSidebarAi.d.ts +23 -0
  49. package/lib/components/InboxMessage/RightSidebarAi.d.ts.map +1 -0
  50. package/lib/components/InboxMessage/RightSidebarAi.js +9 -0
  51. package/lib/components/InboxMessage/RightSidebarAi.js.map +1 -0
  52. package/lib/components/InboxMessage/ServiceConversationItem.d.ts +12 -0
  53. package/lib/components/InboxMessage/ServiceConversationItem.d.ts.map +1 -0
  54. package/lib/components/InboxMessage/ServiceConversationItem.js +185 -0
  55. package/lib/components/InboxMessage/ServiceConversationItem.js.map +1 -0
  56. package/lib/components/InboxMessage/ServiceInboxItem.d.ts +12 -0
  57. package/lib/components/InboxMessage/ServiceInboxItem.d.ts.map +1 -0
  58. package/lib/components/InboxMessage/ServiceInboxItem.js +182 -0
  59. package/lib/components/InboxMessage/ServiceInboxItem.js.map +1 -0
  60. package/lib/components/InboxMessage/SubscriptionHandler.d.ts +19 -0
  61. package/lib/components/InboxMessage/SubscriptionHandler.d.ts.map +1 -0
  62. package/lib/components/InboxMessage/SubscriptionHandler.js +41 -0
  63. package/lib/components/InboxMessage/SubscriptionHandler.js.map +1 -0
  64. package/lib/components/InboxMessage/UploadImageButton.d.ts +7 -0
  65. package/lib/components/InboxMessage/UploadImageButton.d.ts.map +1 -0
  66. package/lib/components/InboxMessage/UploadImageButton.js +34 -0
  67. package/lib/components/InboxMessage/UploadImageButton.js.map +1 -0
  68. package/lib/components/InboxMessage/UserModalContent.d.ts +3 -0
  69. package/lib/components/InboxMessage/UserModalContent.d.ts.map +1 -0
  70. package/lib/components/InboxMessage/UserModalContent.js +60 -0
  71. package/lib/components/InboxMessage/UserModalContent.js.map +1 -0
  72. package/lib/components/InboxMessage/index.d.ts +17 -0
  73. package/lib/components/InboxMessage/index.d.ts.map +1 -0
  74. package/lib/components/InboxMessage/message-widgets/CommonMessage.d.ts +11 -0
  75. package/lib/components/InboxMessage/message-widgets/CommonMessage.d.ts.map +1 -0
  76. package/lib/components/InboxMessage/message-widgets/CommonMessage.js +44 -0
  77. package/lib/components/InboxMessage/message-widgets/CommonMessage.js.map +1 -0
  78. package/lib/components/InboxMessage/message-widgets/ErrorFixCard.d.ts +11 -0
  79. package/lib/components/InboxMessage/message-widgets/ErrorFixCard.d.ts.map +1 -0
  80. package/lib/components/InboxMessage/message-widgets/ErrorFixCard.js +194 -0
  81. package/lib/components/InboxMessage/message-widgets/ErrorFixCard.js.map +1 -0
  82. package/lib/components/InboxMessage/message-widgets/MessageCard.d.ts +8 -0
  83. package/lib/components/InboxMessage/message-widgets/MessageCard.d.ts.map +1 -0
  84. package/lib/components/InboxMessage/message-widgets/MessageSliceRenderer.d.ts +12 -0
  85. package/lib/components/InboxMessage/message-widgets/MessageSliceRenderer.d.ts.map +1 -0
  86. package/lib/components/InboxMessage/message-widgets/MessageSliceRenderer.js +37 -0
  87. package/lib/components/InboxMessage/message-widgets/MessageSliceRenderer.js.map +1 -0
  88. package/lib/components/InboxMessage/message-widgets/ModernMessageGroup.d.ts +18 -0
  89. package/lib/components/InboxMessage/message-widgets/ModernMessageGroup.d.ts.map +1 -0
  90. package/lib/components/InboxMessage/message-widgets/ModernMessageGroup.js +1082 -0
  91. package/lib/components/InboxMessage/message-widgets/ModernMessageGroup.js.map +1 -0
  92. package/lib/components/InboxMessage/message-widgets/PlainMessage.d.ts +8 -0
  93. package/lib/components/InboxMessage/message-widgets/PlainMessage.d.ts.map +1 -0
  94. package/lib/components/InboxMessage/message-widgets/PlainMessage.js +14 -0
  95. package/lib/components/InboxMessage/message-widgets/PlainMessage.js.map +1 -0
  96. package/lib/components/InboxMessage/message-widgets/PropertyMessageWidget.d.ts +9 -0
  97. package/lib/components/InboxMessage/message-widgets/PropertyMessageWidget.d.ts.map +1 -0
  98. package/lib/components/InboxMessage/message-widgets/SlackLikeMessageGroup.d.ts +14 -0
  99. package/lib/components/InboxMessage/message-widgets/SlackLikeMessageGroup.d.ts.map +1 -0
  100. package/lib/components/InboxMessage/message-widgets/SlackLikeMessageGroup.js +333 -0
  101. package/lib/components/InboxMessage/message-widgets/SlackLikeMessageGroup.js.map +1 -0
  102. package/lib/components/InboxMessage/message-widgets/index.d.ts +4 -0
  103. package/lib/components/InboxMessage/message-widgets/index.d.ts.map +1 -0
  104. package/lib/components/ModelConfigPanel.d.ts +37 -0
  105. package/lib/components/ModelConfigPanel.d.ts.map +1 -0
  106. package/lib/components/ModelConfigPanel.js +317 -0
  107. package/lib/components/ModelConfigPanel.js.map +1 -0
  108. package/lib/components/filler-components/RightSiderBar.d.ts +24 -0
  109. package/lib/components/filler-components/RightSiderBar.d.ts.map +1 -0
  110. package/lib/components/filler-components/RightSiderBar.js +335 -0
  111. package/lib/components/filler-components/RightSiderBar.js.map +1 -0
  112. package/lib/components/inbox/FilesList.d.ts +20 -0
  113. package/lib/components/inbox/FilesList.d.ts.map +1 -0
  114. package/lib/components/inbox/FilesList.js +68 -0
  115. package/lib/components/inbox/FilesList.js.map +1 -0
  116. package/lib/components/inbox/MessageItem.d.ts +17 -0
  117. package/lib/components/inbox/MessageItem.d.ts.map +1 -0
  118. package/lib/components/inbox/MessageItem.js +50 -0
  119. package/lib/components/inbox/MessageItem.js.map +1 -0
  120. package/lib/components/inbox/ThreadItem.d.ts +11 -0
  121. package/lib/components/inbox/ThreadItem.d.ts.map +1 -0
  122. package/lib/components/inbox/ThreadItem.js +147 -0
  123. package/lib/components/inbox/ThreadItem.js.map +1 -0
  124. package/lib/components/inbox/index.d.ts +4 -0
  125. package/lib/components/inbox/index.d.ts.map +1 -0
  126. package/lib/components/index.d.ts +7 -0
  127. package/lib/components/index.d.ts.map +1 -0
  128. package/lib/components/live-code-editor/hybrid-live-editor.d.ts +20 -0
  129. package/lib/components/live-code-editor/hybrid-live-editor.d.ts.map +1 -0
  130. package/lib/components/live-code-editor/hybrid-live-editor.js +68 -0
  131. package/lib/components/live-code-editor/hybrid-live-editor.js.map +1 -0
  132. package/lib/components/live-code-editor/index.d.ts +4 -0
  133. package/lib/components/live-code-editor/index.d.ts.map +1 -0
  134. package/lib/components/live-code-editor/live-code-editor.d.ts +14 -0
  135. package/lib/components/live-code-editor/live-code-editor.d.ts.map +1 -0
  136. package/lib/components/live-code-editor/live-code-editor.js +207 -0
  137. package/lib/components/live-code-editor/live-code-editor.js.map +1 -0
  138. package/lib/components/slot-fill/chat-message-filler.d.ts +4 -0
  139. package/lib/components/slot-fill/chat-message-filler.d.ts.map +1 -0
  140. package/lib/components/slot-fill/chat-message-filler.js +5 -0
  141. package/lib/components/slot-fill/chat-message-filler.js.map +1 -0
  142. package/lib/components/slot-fill/chat-message-slot.d.ts +11 -0
  143. package/lib/components/slot-fill/chat-message-slot.d.ts.map +1 -0
  144. package/lib/components/slot-fill/chat-message-slot.js +6 -0
  145. package/lib/components/slot-fill/chat-message-slot.js.map +1 -0
  146. package/lib/components/slot-fill/index.d.ts +4 -0
  147. package/lib/components/slot-fill/index.d.ts.map +1 -0
  148. package/lib/components/slot-fill/right-sidebar-filler.d.ts +4 -0
  149. package/lib/components/slot-fill/right-sidebar-filler.d.ts.map +1 -0
  150. package/lib/components/slot-fill/right-sidebar-filler.js +13 -0
  151. package/lib/components/slot-fill/right-sidebar-filler.js.map +1 -0
  152. package/lib/components/ui/button.d.ts +9 -0
  153. package/lib/components/ui/button.d.ts.map +1 -0
  154. package/lib/compute.d.ts +8 -0
  155. package/lib/compute.d.ts.map +1 -0
  156. package/lib/compute.js +137 -0
  157. package/lib/compute.js.map +1 -0
  158. package/lib/config/env-config.d.ts +13 -0
  159. package/lib/config/env-config.d.ts.map +1 -0
  160. package/lib/config/env-config.js +34 -0
  161. package/lib/config/env-config.js.map +1 -0
  162. package/lib/config/index.d.ts +2 -0
  163. package/lib/config/index.d.ts.map +1 -0
  164. package/lib/constants/breakpoints.d.ts +8 -0
  165. package/lib/constants/breakpoints.d.ts.map +1 -0
  166. package/lib/constants/index.d.ts +3 -0
  167. package/lib/constants/index.d.ts.map +1 -0
  168. package/lib/container/AiInbox.d.ts +15 -0
  169. package/lib/container/AiInbox.d.ts.map +1 -0
  170. package/lib/container/AiInboxWithLoader.d.ts +36 -0
  171. package/lib/container/AiInboxWithLoader.d.ts.map +1 -0
  172. package/lib/container/AiLandingInput.d.ts +4 -0
  173. package/lib/container/AiLandingInput.d.ts.map +1 -0
  174. package/lib/container/AiLandingInput.js +101 -0
  175. package/lib/container/AiLandingInput.js.map +1 -0
  176. package/lib/container/Inbox.d.ts +15 -0
  177. package/lib/container/Inbox.d.ts.map +1 -0
  178. package/lib/container/Inbox.js +955 -0
  179. package/lib/container/Inbox.js.map +1 -0
  180. package/lib/container/InboxAiMessagesLoader.d.ts +15 -0
  181. package/lib/container/InboxAiMessagesLoader.d.ts.map +1 -0
  182. package/lib/container/InboxAiMessagesLoader.js +30 -0
  183. package/lib/container/InboxAiMessagesLoader.js.map +1 -0
  184. package/lib/container/InboxContainer.d.ts +12 -0
  185. package/lib/container/InboxContainer.d.ts.map +1 -0
  186. package/lib/container/InboxContainer.js +31 -0
  187. package/lib/container/InboxContainer.js.map +1 -0
  188. package/lib/container/InboxTemplate1.d.ts +15 -0
  189. package/lib/container/InboxTemplate1.d.ts.map +1 -0
  190. package/lib/container/InboxTemplate1WithLoader.d.ts +36 -0
  191. package/lib/container/InboxTemplate1WithLoader.d.ts.map +1 -0
  192. package/lib/container/InboxTemplate2.d.ts +15 -0
  193. package/lib/container/InboxTemplate2.d.ts.map +1 -0
  194. package/lib/container/InboxWithAiLoader.d.ts +15 -0
  195. package/lib/container/InboxWithAiLoader.d.ts.map +1 -0
  196. package/lib/container/InboxWithAiLoader.js +56 -0
  197. package/lib/container/InboxWithAiLoader.js.map +1 -0
  198. package/lib/container/InboxWithLoader.d.ts +36 -0
  199. package/lib/container/InboxWithLoader.d.ts.map +1 -0
  200. package/lib/container/InboxWithLoader.js +277 -0
  201. package/lib/container/InboxWithLoader.js.map +1 -0
  202. package/lib/container/ServiceInbox.d.ts +9 -0
  203. package/lib/container/ServiceInbox.d.ts.map +1 -0
  204. package/lib/container/ServiceInbox.js +144 -0
  205. package/lib/container/ServiceInbox.js.map +1 -0
  206. package/lib/container/ThreadMessages.d.ts +13 -0
  207. package/lib/container/ThreadMessages.d.ts.map +1 -0
  208. package/lib/container/ThreadMessages.js +314 -0
  209. package/lib/container/ThreadMessages.js.map +1 -0
  210. package/lib/container/ThreadMessagesInbox.d.ts +14 -0
  211. package/lib/container/ThreadMessagesInbox.d.ts.map +1 -0
  212. package/lib/container/ThreadMessagesInbox.js +341 -0
  213. package/lib/container/ThreadMessagesInbox.js.map +1 -0
  214. package/lib/container/Threads.d.ts +8 -0
  215. package/lib/container/Threads.d.ts.map +1 -0
  216. package/lib/container/Threads.js +231 -0
  217. package/lib/container/Threads.js.map +1 -0
  218. package/lib/container/ThreadsInbox.d.ts +21 -0
  219. package/lib/container/ThreadsInbox.d.ts.map +1 -0
  220. package/lib/container/ThreadsInbox.js +244 -0
  221. package/lib/container/ThreadsInbox.js.map +1 -0
  222. package/lib/container/apply-footer-styles.d.ts +2 -0
  223. package/lib/container/apply-footer-styles.d.ts.map +1 -0
  224. package/lib/container/apply-footer-styles.js +16 -0
  225. package/lib/container/apply-footer-styles.js.map +1 -0
  226. package/lib/container/index.d.ts +13 -0
  227. package/lib/container/index.d.ts.map +1 -0
  228. package/lib/enums/index.d.ts +2 -0
  229. package/lib/enums/index.d.ts.map +1 -0
  230. package/lib/enums/messenger-slot-fill-name-enum.d.ts +5 -0
  231. package/lib/enums/messenger-slot-fill-name-enum.d.ts.map +1 -0
  232. package/lib/enums/messenger-slot-fill-name-enum.js +5 -0
  233. package/lib/enums/messenger-slot-fill-name-enum.js.map +1 -0
  234. package/lib/hooks/index.d.ts +3 -0
  235. package/lib/hooks/index.d.ts.map +1 -0
  236. package/lib/hooks/use-file-sync.d.ts +16 -0
  237. package/lib/hooks/use-file-sync.d.ts.map +1 -0
  238. package/lib/hooks/use-file-sync.js +63 -0
  239. package/lib/hooks/use-file-sync.js.map +1 -0
  240. package/lib/hooks/usePersistentModelConfig.d.ts +15 -0
  241. package/lib/hooks/usePersistentModelConfig.d.ts.map +1 -0
  242. package/lib/hooks/usePersistentModelConfig.js +46 -0
  243. package/lib/hooks/usePersistentModelConfig.js.map +1 -0
  244. package/lib/index.d.ts +10 -0
  245. package/lib/index.d.ts.map +1 -0
  246. package/lib/index.js +1 -0
  247. package/lib/index.js.map +1 -0
  248. package/lib/interfaces/index.d.ts +2 -0
  249. package/lib/interfaces/index.d.ts.map +1 -0
  250. package/lib/interfaces/message-widgets.interface.d.ts +21 -0
  251. package/lib/interfaces/message-widgets.interface.d.ts.map +1 -0
  252. package/lib/machines/aiAgentMachine.d.ts +3 -0
  253. package/lib/machines/aiAgentMachine.d.ts.map +1 -0
  254. package/lib/machines/aiAgentMachine.js +1083 -0
  255. package/lib/machines/aiAgentMachine.js.map +1 -0
  256. package/lib/machines/aiAgentMachine.simple.d.ts +3 -0
  257. package/lib/machines/aiAgentMachine.simple.d.ts.map +1 -0
  258. package/lib/machines/aiAgentMachine.simple.js +108 -0
  259. package/lib/machines/aiAgentMachine.simple.js.map +1 -0
  260. package/lib/machines/index.d.ts +3 -0
  261. package/lib/machines/index.d.ts.map +1 -0
  262. package/lib/machines/types.d.ts +77 -0
  263. package/lib/machines/types.d.ts.map +1 -0
  264. package/lib/module.d.ts +7 -0
  265. package/lib/module.d.ts.map +1 -0
  266. package/lib/module.js +26 -0
  267. package/lib/module.js.map +1 -0
  268. package/lib/routes.json +98 -0
  269. package/lib/styles/responsive.css +76 -0
  270. package/lib/templates/InboxWithAi.d.ts +15 -0
  271. package/lib/templates/InboxWithAi.d.ts.map +1 -0
  272. package/lib/templates/InboxWithAi.js +440 -0
  273. package/lib/templates/InboxWithAi.js.map +1 -0
  274. package/lib/templates/InboxWithAi.tsx +533 -0
  275. package/lib/templates/index.d.ts +2 -0
  276. package/lib/templates/index.d.ts.map +1 -0
  277. package/lib/templates/index.ts +1 -0
  278. package/lib/utils/utils.d.ts +2 -0
  279. package/lib/utils/utils.d.ts.map +1 -0
  280. package/lib/utils/utils.js +3 -0
  281. package/lib/utils/utils.js.map +1 -0
  282. package/package.json +62 -0
  283. package/rollup.config.mjs +35 -0
  284. package/src/cdm-locales/en/translations.json +31 -0
  285. package/src/cdm-locales/es/translations.json +31 -0
  286. package/src/components/AIAgent/AIAgent.tsx +1103 -0
  287. package/src/components/AIAgent/AIAgent.tsx.bk +1365 -0
  288. package/src/components/AIAgent/README.md +82 -0
  289. package/src/components/AIAgent/index.ts +1 -0
  290. package/src/components/InboxMessage/CommonMessage.tsx +40 -0
  291. package/src/components/InboxMessage/ConversationItem.tsx +255 -0
  292. package/src/components/InboxMessage/InputComponent.tsx +462 -0
  293. package/src/components/InboxMessage/LeftSidebar.tsx +140 -0
  294. package/src/components/InboxMessage/MessageInput.tsx +209 -0
  295. package/src/components/InboxMessage/MessageInputComponent.tsx +245 -0
  296. package/src/components/InboxMessage/Messages.tsx +137 -0
  297. package/src/components/InboxMessage/MessagesBuilderUi.tsx +205 -0
  298. package/src/components/InboxMessage/Popover.tsx +42 -0
  299. package/src/components/InboxMessage/RightSidebar.tsx +22 -0
  300. package/src/components/InboxMessage/RightSidebarAi.tsx +37 -0
  301. package/src/components/InboxMessage/ServiceConversationItem.tsx +234 -0
  302. package/src/components/InboxMessage/ServiceInboxItem.tsx +223 -0
  303. package/src/components/InboxMessage/SubscriptionHandler.tsx +55 -0
  304. package/src/components/InboxMessage/UploadImageButton.tsx +46 -0
  305. package/src/components/InboxMessage/UserModalContent.tsx +60 -0
  306. package/src/components/InboxMessage/index.ts +16 -0
  307. package/src/components/InboxMessage/message-widgets/CommonMessage.tsx +69 -0
  308. package/src/components/InboxMessage/message-widgets/ErrorFixCard.tsx +240 -0
  309. package/src/components/InboxMessage/message-widgets/MessageCard.tsx +127 -0
  310. package/src/components/InboxMessage/message-widgets/MessageSliceRenderer.tsx +40 -0
  311. package/src/components/InboxMessage/message-widgets/ModernMessageGroup.tsx +1295 -0
  312. package/src/components/InboxMessage/message-widgets/PlainMessage.tsx +18 -0
  313. package/src/components/InboxMessage/message-widgets/PropertyMessageWidget.tsx +29 -0
  314. package/src/components/InboxMessage/message-widgets/SlackLikeMessageGroup.tsx +492 -0
  315. package/src/components/InboxMessage/message-widgets/index.ts +3 -0
  316. package/src/components/ModelConfigPanel.tsx +345 -0
  317. package/src/components/filler-components/RightSiderBar.tsx +408 -0
  318. package/src/components/inbox/FilesList.tsx +89 -0
  319. package/src/components/inbox/MessageItem.tsx +50 -0
  320. package/src/components/inbox/ThreadItem.tsx +295 -0
  321. package/src/components/inbox/index.ts +3 -0
  322. package/src/components/index.ts +22 -0
  323. package/src/components/live-code-editor/hybrid-live-editor.tsx +105 -0
  324. package/src/components/live-code-editor/index.ts +3 -0
  325. package/src/components/live-code-editor/live-code-editor.tsx +257 -0
  326. package/src/components/slot-fill/chat-message-filler.tsx +18 -0
  327. package/src/components/slot-fill/chat-message-slot.tsx +18 -0
  328. package/src/components/slot-fill/index.ts +3 -0
  329. package/src/components/slot-fill/right-sidebar-filler.tsx +39 -0
  330. package/src/components/ui/button.tsx +32 -0
  331. package/src/compute.ts +134 -0
  332. package/src/config/env-config.ts +17 -0
  333. package/src/config/index.ts +1 -0
  334. package/src/constants/breakpoints.ts +7 -0
  335. package/src/constants/index.ts +5 -0
  336. package/src/container/AiInbox.tsx +1819 -0
  337. package/src/container/AiInboxWithLoader.tsx +356 -0
  338. package/src/container/AiLandingInput.tsx +221 -0
  339. package/src/container/Inbox.tsx +1092 -0
  340. package/src/container/InboxAiMessagesLoader.tsx +44 -0
  341. package/src/container/InboxContainer.tsx +35 -0
  342. package/src/container/InboxTemplate1.tsx +1542 -0
  343. package/src/container/InboxTemplate1WithLoader.tsx +338 -0
  344. package/src/container/InboxTemplate2.tsx +1606 -0
  345. package/src/container/InboxWithAiLoader.tsx +76 -0
  346. package/src/container/InboxWithLoader.tsx +341 -0
  347. package/src/container/ServiceInbox.tsx +190 -0
  348. package/src/container/ThreadMessages.tsx +371 -0
  349. package/src/container/ThreadMessagesInbox.tsx +450 -0
  350. package/src/container/Threads.tsx +270 -0
  351. package/src/container/ThreadsInbox.tsx +354 -0
  352. package/src/container/apply-footer-styles.ts +17 -0
  353. package/src/container/index.ts +31 -0
  354. package/src/enums/index.ts +1 -0
  355. package/src/enums/messenger-slot-fill-name-enum.ts +4 -0
  356. package/src/hooks/index.ts +2 -0
  357. package/src/hooks/use-file-sync.ts +91 -0
  358. package/src/hooks/usePersistentModelConfig.ts +63 -0
  359. package/src/index.ts +37 -0
  360. package/src/interfaces/index.ts +1 -0
  361. package/src/interfaces/message-widgets.interface.ts +21 -0
  362. package/src/machines/aiAgentMachine.simple.ts +89 -0
  363. package/src/machines/aiAgentMachine.ts +1296 -0
  364. package/src/machines/aiAgentMachine.ts.bk +1296 -0
  365. package/src/machines/index.ts +2 -0
  366. package/src/machines/types.ts +59 -0
  367. package/src/module.tsx +32 -0
  368. package/src/styles/responsive.css +76 -0
  369. package/src/templates/InboxWithAi.tsx +533 -0
  370. package/src/templates/index.ts +1 -0
  371. package/src/utils/utils.ts +3 -0
  372. package/tsconfig.json +14 -0
  373. package/webpack.config.js +92 -0
@@ -0,0 +1,1103 @@
1
+ import React, { useCallback, useMemo, useRef, useState, useEffect } from 'react';
2
+ import { useActor, useMachine } from '@xstate/react';
3
+ import { aiAgentMachine } from '../../machines/aiAgentMachine.simple';
4
+ import { InputComponent } from '../InboxMessage/InputComponent';
5
+ import { format, isToday, isYesterday, formatDistanceToNow } from 'date-fns';
6
+ import { useTranslation } from 'react-i18next';
7
+ import { ModernMessageGroupComponent } from '../InboxMessage/message-widgets/ModernMessageGroup';
8
+ import { useUploadFiles } from '@messenger-box/platform-client';
9
+ import { IFileInfo, PostTypeEnum, ISandboxError } from 'common';
10
+ import { useSelector, shallowEqual } from 'react-redux';
11
+ import { Store, userSelector } from '@adminide-stack/user-auth0-client';
12
+ import { IUserState } from '@adminide-stack/core';
13
+ import { objectId } from '@messenger-box/core';
14
+ import { useApolloClient } from '@apollo/client';
15
+ import {
16
+ useSendMessagesMutation,
17
+ MessagesDocument,
18
+ useMessagesQuery,
19
+ OnChatMessageAddedDocument as CHAT_MESSAGE_ADDED,
20
+ useGenerateAiCodeMutation,
21
+ useOnChatMessageAddedSubscription,
22
+ useSandboxErrorSubscription,
23
+ useRecreateSandboxMutation,
24
+ } from 'common/graphql';
25
+ import { config } from '../../config';
26
+ import { orderBy, uniqBy } from 'lodash-es';
27
+ import { useParams, useNavigate } from '@remix-run/react';
28
+ import { RoomType } from 'common';
29
+ import { SubscriptionHandler } from '../InboxMessage/SubscriptionHandler';
30
+ import { usePersistentModelConfig } from '../../hooks/usePersistentModelConfig';
31
+
32
+ const { MESSAGES_PER_PAGE } = config;
33
+
34
+ interface AIAgentProps {
35
+ channelId?: string;
36
+ onSendMessage?: (message: string, files?: File[]) => Promise<void>;
37
+ placeholder?: string;
38
+ className?: string;
39
+ currentUser?: any;
40
+ channelName?: string;
41
+ isDesktopView?: boolean;
42
+ isSmallScreen?: boolean;
43
+ messages?: any[];
44
+ setMessages?: (messages: any[]) => void;
45
+ selectedPost?: any;
46
+ setSelectedPost?: (selectedPost: any) => void;
47
+ setIsLoading?: (isLoading: boolean) => void;
48
+ isLoading?: boolean;
49
+ [key: string]: any; // Allow other props to be passed through to Inbox
50
+ }
51
+
52
+ export const AIAgent: React.FC<AIAgentProps> = ({
53
+ channelId,
54
+ onSendMessage,
55
+ placeholder = 'Ask me anything...',
56
+ className = '',
57
+ currentUser,
58
+ isDesktopView = false,
59
+ isSmallScreen = false,
60
+ setMessages,
61
+ setSelectedPost,
62
+ messages,
63
+ selectedPost,
64
+ setIsLoading,
65
+ isLoading,
66
+ }) => {
67
+ const [state, send] = useMachine(aiAgentMachine);
68
+ const apolloClient = useApolloClient();
69
+ const { startUpload } = useUploadFiles();
70
+ const [sendMsg] = useSendMessagesMutation();
71
+ const auth: any = useSelector<Store.Auth, IUserState>(userSelector, shallowEqual);
72
+ const { id: pathChannelId } = useParams();
73
+ const navigate = useNavigate();
74
+ const { modelConfig, updateModelConfig, getValidatedConfig, hasApiKey } = usePersistentModelConfig();
75
+ // const [isLoading, setIsLoading] = useState(false);
76
+ const [errorData, setError] = useState<string | null>(null);
77
+ // Get channelId from props or path params
78
+ const actualChannelId = channelId || pathChannelId;
79
+ const [generateAiCode] = useGenerateAiCodeMutation();
80
+ const [recreateSandbox] = useRecreateSandboxMutation();
81
+ const { data: chatMessageAddedData } = useOnChatMessageAddedSubscription({
82
+ variables: { channelId: actualChannelId?.toString() || '' },
83
+ skip: !actualChannelId,
84
+ });
85
+
86
+ // Subscribe to sandbox errors if projectId is provided
87
+ const { data: sandboxErrorData } = useSandboxErrorSubscription({
88
+ variables: { projectId: actualChannelId?.toString() || '' },
89
+ skip: !actualChannelId,
90
+ });
91
+
92
+ // Direct message query from InboxWithAiLoader.tsx
93
+ const messagesQuery = useMessagesQuery({
94
+ variables: {
95
+ props: {
96
+ projectId: actualChannelId?.toString(),
97
+ },
98
+ parentId: null,
99
+ limit: MESSAGES_PER_PAGE,
100
+ },
101
+ skip: !actualChannelId,
102
+ fetchPolicy: 'cache-and-network',
103
+ errorPolicy: 'all',
104
+ notifyOnNetworkStatusChange: true,
105
+ returnPartialData: true,
106
+ pollInterval: 0,
107
+ context: {
108
+ cacheKey: 'messages-list',
109
+ },
110
+ });
111
+
112
+ const { messages: aiMessages, error, isTyping } = state.context;
113
+ const { t } = useTranslation('translations');
114
+
115
+ const [isOpen, setIsOpen] = useState(false);
116
+ const [selectedElement, setSelectedElement] = useState<any>(null);
117
+ const [activeTab, setActiveTab] = useState<'chat' | 'history'>('chat');
118
+ const bottomRef = useRef<HTMLDivElement | null>(null);
119
+ const [sandboxErrors, setSandboxErrors] = useState<ISandboxError[]>([]);
120
+ const [currentFiles, setCurrentFiles] = useState<Record<string, string>>({});
121
+ const [canvasLayers, setCanvasLayers] = useState<any[]>([]);
122
+ // New state variables for message display control
123
+ const [isSuccessThinking, setIsSuccessThinking] = useState(false);
124
+ const successThinkingTimeoutRef = useRef<any>(null);
125
+
126
+ // Get regular messages from direct query
127
+ const {
128
+ data: messagesData,
129
+ loading: messageLoading,
130
+ refetch: refetchMessages,
131
+ fetchMore: fetchMoreMessages,
132
+ subscribeToMore,
133
+ } = messagesQuery;
134
+
135
+ useEffect(() => {
136
+ if (actualChannelId) {
137
+ refetchMessages({
138
+ limit: MESSAGES_PER_PAGE,
139
+ props: {
140
+ projectId: actualChannelId?.toString(),
141
+ },
142
+ });
143
+ }
144
+ }, [actualChannelId, refetchMessages]);
145
+
146
+ useEffect(() => {
147
+ if (chatMessageAddedData?.chatMessageAdded) {
148
+ console.log(
149
+ 'chatMessageAddedData?.chatMessageAdded',
150
+ JSON.stringify(chatMessageAddedData?.chatMessageAdded, null, 2),
151
+ );
152
+ // handleGenerateAiCode(chatMessageAddedData.chatMessageAdded.id);
153
+ // Stop the success thinking loader once a new message arrives
154
+ if (isSuccessThinking) {
155
+ setIsSuccessThinking(false);
156
+ if (successThinkingTimeoutRef.current) {
157
+ clearTimeout(successThinkingTimeoutRef.current);
158
+ successThinkingTimeoutRef.current = null;
159
+ }
160
+ }
161
+ }
162
+ }, [chatMessageAddedData?.chatMessageAdded]);
163
+
164
+ useEffect(() => {
165
+ if (messagesData?.messages?.data?.length == 1) {
166
+ handleGenerateAiCode(messagesData.messages.data[0].id);
167
+ }
168
+ // console.log('messagesData?.messages?.data',JSON.stringify(messagesData?.messages?.data,null,2))
169
+ }, [messagesData?.messages?.data]);
170
+
171
+ // Handle sandbox error subscription updates
172
+ useEffect(() => {
173
+ if (sandboxErrorData?.sandboxError) {
174
+ const errorData = sandboxErrorData.sandboxError;
175
+ console.log('Sandbox error received:', errorData);
176
+ setSandboxErrors((prev) => [...prev, errorData.error]);
177
+ }
178
+ }, [sandboxErrorData]);
179
+
180
+ const regularMessages = useMemo(() => {
181
+ if (!messagesData?.messages?.data) return [];
182
+ return orderBy(uniqBy(messagesData.messages.data || [], 'id'), ['createdAt'], ['asc']);
183
+ }, [messagesData?.messages?.data]);
184
+
185
+ // Send regular messages to AI agent machine for context
186
+ useEffect(() => {
187
+ if (regularMessages && regularMessages.length > 0) {
188
+ send({ type: 'UPDATE_REGULAR_MESSAGES', messages: regularMessages });
189
+ setMessages(regularMessages);
190
+ const currentMessage = regularMessages?.[regularMessages.length - 1];
191
+ setSelectedPost(regularMessages[regularMessages.length - 1]);
192
+ setCurrentFiles(currentMessage?.propsConfiguration?.contents?.fragment?.files ?? {});
193
+ let canvasLayers = currentMessage?.propsConfiguration?.contents?.fragment?.canvasLayers ?? [];
194
+ const summary = currentMessage?.propsConfiguration?.contents?.fragment?.summary ?? null;
195
+ // If not in direct field, try to extract from summary
196
+ if (!canvasLayers && summary) {
197
+ const canvasLayersMatch = summary?.match(/<canvas_layers>([\s\S]*?)<\/canvas_layers>/);
198
+ if (canvasLayersMatch) {
199
+ try {
200
+ canvasLayers = JSON.parse(canvasLayersMatch[1]);
201
+ } catch (error) {
202
+ console.error('Failed to parse canvas layers from summary:', error);
203
+ }
204
+ }
205
+ }
206
+ // Update canvas layers if available
207
+ if (canvasLayers && Array.isArray(canvasLayers)) {
208
+ setCanvasLayers(canvasLayers);
209
+ }
210
+
211
+ console.log('currenmessage', currentMessage);
212
+ if (currentMessage?.propsConfiguration?.contents?.role === 'ASSISTANT') {
213
+ //setIsLoading(false);
214
+ }
215
+
216
+ scrollToBottom('smooth', 0);
217
+ }
218
+ }, [regularMessages, send]);
219
+
220
+ const handleGenerateAiCode = useCallback(
221
+ (messageId: string) => {
222
+ generateAiCode({
223
+ variables: {
224
+ messageId: messageId,
225
+ modelConfig: modelConfig,
226
+ },
227
+ onCompleted: (res) => {
228
+ if (res.generateAiCode.success) {
229
+ console.log('generated_result', res);
230
+ // Show AI is thinking loader on success
231
+ if (successThinkingTimeoutRef.current) {
232
+ clearTimeout(successThinkingTimeoutRef.current);
233
+ successThinkingTimeoutRef.current = null;
234
+ }
235
+ setIsSuccessThinking(true);
236
+ // Fallback auto-hide after 15s in case no subsequent event arrives
237
+ successThinkingTimeoutRef.current = setTimeout(() => {
238
+ setIsSuccessThinking(false);
239
+ // setIsLoading(false);
240
+ successThinkingTimeoutRef.current = null;
241
+ }, 15000);
242
+ }
243
+ },
244
+ onError: (err) => {
245
+ console.log('err', JSON.stringify(err, null, 2));
246
+ // Also ensure loader is hidden on error
247
+ if (successThinkingTimeoutRef.current) {
248
+ clearTimeout(successThinkingTimeoutRef.current);
249
+ successThinkingTimeoutRef.current = null;
250
+ }
251
+ setIsSuccessThinking(false);
252
+ },
253
+ });
254
+ },
255
+ [generateAiCode, modelConfig],
256
+ );
257
+
258
+ const onOpen = (element?: any) => {
259
+ setSelectedElement(element);
260
+ setIsOpen(true);
261
+ };
262
+
263
+ const onClose = () => {
264
+ setIsOpen(false);
265
+ setSelectedElement(null);
266
+ };
267
+
268
+ // Enhanced scroll to bottom function
269
+ const scrollToBottom = useCallback((behavior: ScrollBehavior = 'smooth', delay: number = 0) => {
270
+ setTimeout(() => {
271
+ if (bottomRef.current) {
272
+ bottomRef.current.scrollIntoView({
273
+ behavior,
274
+ block: 'end',
275
+ inline: 'nearest',
276
+ });
277
+ }
278
+ }, delay);
279
+ }, []);
280
+
281
+ const recreateSandboxForFragment = useCallback(
282
+ async (messageId: string) => {
283
+ if (!actualChannelId) {
284
+ console.error('No project ID available for sandbox recreation');
285
+ return;
286
+ }
287
+
288
+ try {
289
+ setIsLoading(true);
290
+ setError(null);
291
+
292
+ const response = await recreateSandbox({
293
+ variables: {
294
+ projectId: actualChannelId,
295
+ messageId,
296
+ },
297
+ });
298
+
299
+ if (response.data?.recreateSandbox?.success) {
300
+ console.log('Sandbox recreation initiated successfully');
301
+ // The subscription will handle updating the UI with the new sandbox URL
302
+ } else {
303
+ const errorMsg = response.data?.recreateSandbox?.message || 'Failed to recreate sandbox';
304
+ throw new Error(errorMsg);
305
+ }
306
+ } catch (err) {
307
+ console.error('Error recreating sandbox:', err);
308
+ setError(err instanceof Error ? err.message : 'Failed to recreate sandbox');
309
+ setIsLoading(false);
310
+ }
311
+ },
312
+ [recreateSandbox, actualChannelId],
313
+ );
314
+
315
+ // Updated handleSend function from InboxWithAi.tsx
316
+ const handleSend = useCallback(
317
+ async (message: string, files: any[] = []) => {
318
+ // Allow sending if there's either a message or files
319
+ if ((!message || !message.trim()) && (!files || files.length === 0)) return;
320
+
321
+ const validated = getValidatedConfig();
322
+ if (!validated && !hasApiKey) {
323
+ // No API key/config; do nothing (AiLandingInput would prompt config UI)
324
+ return;
325
+ }
326
+
327
+ // Start the AI thinking loader immediately on send
328
+ if (successThinkingTimeoutRef.current) {
329
+ clearTimeout(successThinkingTimeoutRef.current);
330
+ successThinkingTimeoutRef.current = null;
331
+ }
332
+ setIsSuccessThinking(true);
333
+ setIsLoading(true);
334
+ // Safety auto-stop in case no event arrives
335
+ successThinkingTimeoutRef.current = setTimeout(() => {
336
+ setIsSuccessThinking(false);
337
+ successThinkingTimeoutRef.current = null;
338
+ }, 15000);
339
+
340
+ // If we already have a channel, send message (with optional file upload) similar to Inbox
341
+ if (actualChannelId) {
342
+ try {
343
+ const postId = objectId();
344
+ const channelId = objectId();
345
+ const currentDate = new Date();
346
+
347
+ const createOptimisticMessage = (uploadedFiles?: any[]) => ({
348
+ __typename: 'Post' as const,
349
+ id: postId,
350
+ message,
351
+ createdAt: currentDate.toISOString(),
352
+ updatedAt: currentDate.toISOString(),
353
+ author: {
354
+ __typename: 'UserAccount' as const,
355
+ id: auth?.id,
356
+ givenName: auth?.profile?.given_name || '',
357
+ familyName: auth?.profile?.family_name || '',
358
+ email: auth?.profile?.email || '',
359
+ username: auth?.profile?.nickname || '',
360
+ fullName: auth?.profile?.name || '',
361
+ picture: auth?.profile?.picture || '',
362
+ alias: [auth?.authUserId ?? ''],
363
+ tokens: [],
364
+ },
365
+ isDelivered: false,
366
+ isRead: false,
367
+ type: 'TEXT' as PostTypeEnum,
368
+ parentId: null,
369
+ fromServer: false,
370
+ channel: {
371
+ __typename: 'Channel' as const,
372
+ id: actualChannelId,
373
+ },
374
+ propsConfiguration: {
375
+ __typename: 'MachineConfiguration' as const,
376
+ id: null,
377
+ resource: '' as any,
378
+ contents: null,
379
+ keys: null,
380
+ target: null,
381
+ overrides: null,
382
+ },
383
+ props: {},
384
+ files: {
385
+ __typename: 'FilesInfo' as const,
386
+ data: uploadedFiles || [],
387
+ totalCount: uploadedFiles?.length || 0,
388
+ },
389
+ replies: {
390
+ __typename: 'Messages' as const,
391
+ data: [],
392
+ totalCount: 0,
393
+ },
394
+ });
395
+
396
+ const cacheMessagesQuery = {
397
+ query: MessagesDocument,
398
+ variables: {
399
+ // Match variables used in useMessagesQuery above
400
+ props: { projectId: actualChannelId.toString() },
401
+ parentId: null,
402
+ limit: MESSAGES_PER_PAGE,
403
+ },
404
+ } as const;
405
+
406
+ const extraProps = {
407
+ projectId: actualChannelId,
408
+ template: modelConfig?.template || 'vite-react',
409
+ role: 'USER',
410
+ sendNotificationWithProjectId: true,
411
+ } as any;
412
+
413
+ if (files?.length > 0) {
414
+ const uploadResponse = await startUpload({
415
+ file: files,
416
+ saveUploadedFile: { variables: { postId } },
417
+ createUploadLink: { variables: { postId } },
418
+ });
419
+
420
+ const uploadedFiles = uploadResponse.data as unknown as IFileInfo[];
421
+ const fileIds = (uploadedFiles || []).map((f: any) => f.id);
422
+
423
+ await sendMsg({
424
+ variables: {
425
+ postId,
426
+ channelId: actualChannelId,
427
+ content: message,
428
+ files: fileIds,
429
+ extraProps,
430
+ },
431
+ optimisticResponse: {
432
+ __typename: 'Mutation',
433
+ sendMessage: createOptimisticMessage(uploadedFiles),
434
+ },
435
+ update: (cache, { data: mutationData }) => {
436
+ if (!mutationData?.sendMessage) return;
437
+ if (mutationData?.sendMessage?.id) {
438
+ handleGenerateAiCode(mutationData.sendMessage.id);
439
+ }
440
+ },
441
+ });
442
+ } else {
443
+ await sendMsg({
444
+ variables: { channelId: actualChannelId, content: message, extraProps },
445
+ optimisticResponse: {
446
+ __typename: 'Mutation',
447
+ sendMessage: createOptimisticMessage(),
448
+ },
449
+ update: (cache, { data: mutationData }) => {
450
+ if (!mutationData?.sendMessage) return;
451
+ console.log('mutationData', JSON.stringify(mutationData, null, 2));
452
+ if (mutationData?.sendMessage?.id) {
453
+ handleGenerateAiCode(mutationData.sendMessage.id);
454
+ }
455
+ },
456
+ });
457
+ }
458
+
459
+ // Scroll to bottom after send
460
+ scrollToBottom('smooth', 0);
461
+ } catch (error) {
462
+ console.error('Error sending message from AIAgent:', error);
463
+ setIsLoading(false);
464
+ }
465
+
466
+ return;
467
+ }
468
+ // If no channelId, we skip sending here.
469
+ },
470
+ [actualChannelId, auth, startUpload, sendMsg, scrollToBottom, getValidatedConfig, hasApiKey, modelConfig],
471
+ );
472
+
473
+ const fixError = useCallback(
474
+ (errorMessage: string) => {
475
+ // Use sendMessage to fix the error, which will use createProject flow
476
+ return handleSend(errorMessage);
477
+ },
478
+ [handleSend],
479
+ );
480
+
481
+ const handleRetry = useCallback(() => {
482
+ send({ type: 'RETRY' });
483
+ }, [send]);
484
+
485
+ const handleClearError = useCallback(() => {
486
+ send({ type: 'CLEAR_ERROR' });
487
+ }, [send]);
488
+
489
+ // Use only default/regular messages and ignore AI messages
490
+ const allMessages = useMemo(() => {
491
+ if (!regularMessages) return [] as any[];
492
+
493
+ const regularMessagesFormatted = (regularMessages || []).map((m, idx) => ({
494
+ id: m.id || `regular-${idx}`,
495
+ message: (m as any).message || (m as any).content || '',
496
+ createdAt: new Date((m as any).createdAt || Date.now()),
497
+ propsConfiguration: (m as any).propsConfiguration,
498
+ props: (m as any).props,
499
+ files: (m as any).files,
500
+ sender: 'user',
501
+ author: (m as any).author,
502
+ isUserMessage: true,
503
+ }));
504
+
505
+ return regularMessagesFormatted;
506
+ }, [regularMessages, currentUser]);
507
+
508
+ // Build list with date separators similar to MessagesBuilderUi
509
+ const messageListWithDates = useMemo(() => {
510
+ let currentDate = '';
511
+ const res: any[] = [];
512
+
513
+ allMessages?.forEach((msg: any) => {
514
+ const date = new Date(msg.createdAt);
515
+ let msgDate: string;
516
+ if (isToday(date)) msgDate = t('tailwind_ui_inbox.today');
517
+ else if (isYesterday(date)) msgDate = t('tailwind_ui_inbox.yesterday');
518
+ else msgDate = format(date, 'eee, do MMMM');
519
+
520
+ if (msgDate !== currentDate) {
521
+ res.push({ type: 'date', content: msgDate });
522
+ currentDate = msgDate;
523
+ }
524
+ res.push(msg);
525
+ });
526
+
527
+ if (allMessages && allMessages.length > 0) {
528
+ const todayLabel = t('tailwind_ui_inbox.today');
529
+ if (currentDate !== todayLabel) {
530
+ res.push({ type: 'date', content: todayLabel });
531
+ }
532
+ }
533
+
534
+ return res;
535
+ }, [allMessages, t]);
536
+
537
+ // Group messages by date sections for Slack-like rendering
538
+ const messagesByDate = useMemo(() => {
539
+ const sections: { date: string | null; messages: any[] }[] = [];
540
+ let currentSection: { date: string | null; messages: any[] } = { date: null, messages: [] };
541
+
542
+ messageListWithDates.forEach((item: any) => {
543
+ if (item?.type === 'date') {
544
+ if (currentSection.messages.length > 0) {
545
+ sections.push(currentSection);
546
+ }
547
+ currentSection = { date: item.content, messages: [] };
548
+ } else {
549
+ currentSection.messages.push(item);
550
+ }
551
+ });
552
+
553
+ if (currentSection.messages.length > 0) {
554
+ sections.push(currentSection);
555
+ }
556
+
557
+ return sections;
558
+ }, [messageListWithDates]);
559
+
560
+ // Show all messages without limiting
561
+ const limitedMessagesByDate = useMemo(() => {
562
+ if (!messagesByDate || messagesByDate.length === 0) return [];
563
+ return messagesByDate;
564
+ }, [messagesByDate]);
565
+
566
+ // Ensure we show complete conversation pairs (user message + AI response)
567
+ const completeConversationMessages = useMemo(() => {
568
+ if (!limitedMessagesByDate || limitedMessagesByDate.length === 0) return [];
569
+
570
+ const completeSections: { date: string | null; messages: any[] }[] = [];
571
+
572
+ limitedMessagesByDate.forEach((section) => {
573
+ const completeMessages: any[] = [];
574
+ const sectionMessages = [...section.messages];
575
+
576
+ console.log('🔄 Processing section for complete conversations:', {
577
+ sectionDate: section.date,
578
+ totalMessages: sectionMessages.length,
579
+ messages: sectionMessages.map((m) => ({
580
+ sender: m.sender,
581
+ isUserMessage: m.isUserMessage,
582
+ message: m.message?.substring(0, 30) + '...',
583
+ })),
584
+ });
585
+
586
+ // Group messages into conversation pairs
587
+ for (let i = 0; i < sectionMessages.length; i++) {
588
+ const currentMsg = sectionMessages[i];
589
+
590
+ // If this is a user message, look for its AI response
591
+ if (currentMsg.sender === 'user' || currentMsg.isUserMessage) {
592
+ completeMessages.push(currentMsg);
593
+
594
+ // Look for the corresponding AI response (next message should be AI)
595
+ if (i + 1 < sectionMessages.length) {
596
+ const nextMsg = sectionMessages[i + 1];
597
+ if (nextMsg.sender === 'ai' || !nextMsg.isUserMessage) {
598
+ completeMessages.push(nextMsg);
599
+ i++; // Skip the next message since we've already added it
600
+ }
601
+ }
602
+ } else if (currentMsg.sender === 'ai' || !currentMsg.isUserMessage) {
603
+ // If this is an AI message without a preceding user message, still show it
604
+ completeMessages.push(currentMsg);
605
+ }
606
+ }
607
+
608
+ console.log('🔄 Complete messages for section:', {
609
+ sectionDate: section.date,
610
+ completeMessages: completeMessages.map((m) => ({
611
+ sender: m.sender,
612
+ isUserMessage: m.isUserMessage,
613
+ message: m.message?.substring(0, 30) + '...',
614
+ })),
615
+ });
616
+
617
+ if (completeMessages.length > 0) {
618
+ completeSections.push({ ...section, messages: completeMessages });
619
+ }
620
+ });
621
+
622
+ return completeSections;
623
+ }, [limitedMessagesByDate]);
624
+
625
+ // Auto scroll to bottom when messages, typing status, or AI responses change
626
+ useEffect(() => {
627
+ // scrollToBottom('smooth', 100);
628
+ }, [completeConversationMessages?.length, isTyping, aiMessages.length, scrollToBottom]);
629
+
630
+ // Cleanup any pending timeout on unmount
631
+ useEffect(() => {
632
+ return () => {
633
+ if (successThinkingTimeoutRef.current) {
634
+ clearTimeout(successThinkingTimeoutRef.current);
635
+ }
636
+ };
637
+ }, []);
638
+
639
+ const extractCleanContent = useCallback((summary: string): string => {
640
+ console.log('summary...........', summary);
641
+ if (!summary) return 'Project generated successfully!';
642
+
643
+ const summeryData = summary
644
+ .replace(/<canvas_layers>[\s\S]*?<\/canvas_layers>/g, '')
645
+ .replace(/<task_summary>([\s\S]*?)<\/task_summary>/g, '');
646
+ if (summeryData && summeryData.trim() !== '' && summeryData.trim()?.length > 0) {
647
+ return summeryData || 'Project generated successfully!';
648
+ }
649
+ // Extract content from <task_summary> tags
650
+ const taskSummaryMatch = summary.match(/<task_summary>([\s\S]*?)<\/task_summary>/);
651
+ if (taskSummaryMatch) {
652
+ // const removedCanvasLayers = summary.replace(/<canvas_layers>[\s\S]*?<\/canvas_layers>/g, '').replace(/<task_summary>([\s\S]*?)<\/task_summary>/g, '');
653
+ return taskSummaryMatch?.[1]?.trim() ?? 'Project generated successfully!';
654
+ }
655
+
656
+ // If no task_summary tags, remove canvas_layers and return the rest
657
+ const withoutCanvasLayers = summary.replace(/<canvas_layers>[\s\S]*?<\/canvas_layers>/g, '').trim();
658
+ return withoutCanvasLayers || 'Project generated successfully!';
659
+ }, []);
660
+
661
+ return (
662
+ <div className={`flex flex-col h-full ${className}`}>
663
+ {/* Header with Tabs */}
664
+ <div className="border-b border-gray-200 bg-white">
665
+ <div className="flex items-center justify-between px-4 py-3">
666
+ {/* Tabs */}
667
+ <div className="flex space-x-6">
668
+ <button
669
+ onClick={() => setActiveTab('chat')}
670
+ className={`relative ${
671
+ activeTab === 'chat' ? 'text-blue-600 font-medium' : 'text-gray-500 hover:text-gray-700'
672
+ } text-sm transition-colors`}
673
+ >
674
+ <span>Chat</span>
675
+ {activeTab === 'chat' && (
676
+ <div className="absolute bottom-0 left-0 w-full h-0.5 bg-blue-600"></div>
677
+ )}
678
+ </button>
679
+ <button
680
+ onClick={() => setActiveTab('history')}
681
+ className={`relative ${
682
+ activeTab === 'history'
683
+ ? 'text-blue-600 font-medium'
684
+ : 'text-gray-500 hover:text-gray-700'
685
+ } text-sm transition-colors`}
686
+ >
687
+ <span>History</span>
688
+ {activeTab === 'history' && (
689
+ <div className="absolute bottom-0 left-0 w-full h-0.5 bg-blue-600"></div>
690
+ )}
691
+ </button>
692
+ </div>
693
+
694
+ {/* New Chat Button */}
695
+ {/* <button
696
+ onClick={() => {
697
+ // Clear AI messages by sending update event to the machine
698
+ send({ type: 'UPDATE', value: { messages: [] } });
699
+ }}
700
+ className="px-4 py-2 text-sm text-gray-700 border border-gray-300 rounded-lg hover:bg-gray-200 transition-colors"
701
+ style={{ borderRadius: '10px' }}
702
+ >
703
+ New Chat
704
+ </button> */}
705
+ </div>
706
+ </div>
707
+
708
+ {/* Tab Content */}
709
+ {activeTab === 'history' ? (
710
+ /* History Tab Content */
711
+ <div className="flex-1 overflow-y-auto bg-white">
712
+ {/* Search Bar */}
713
+ <div className="px-4 py-3 border-b border-gray-200">
714
+ <div className="relative">
715
+ <div className="absolute inset-y-0 left-0 pl-3 flex items-center pointer-events-none">
716
+ <svg
717
+ className="h-5 w-5 text-gray-400"
718
+ fill="none"
719
+ viewBox="0 0 24 24"
720
+ stroke="currentColor"
721
+ >
722
+ <path
723
+ strokeLinecap="round"
724
+ strokeLinejoin="round"
725
+ strokeWidth={2}
726
+ d="M21 21l-6-6m2-5a7 7 0 11-14 0 7 7 0 0114 0z"
727
+ />
728
+ </svg>
729
+ </div>
730
+ <input
731
+ type="text"
732
+ placeholder="Search messages..."
733
+ className="block w-full pl-10 pr-12 py-2 border border-gray-300 rounded-lg focus:ring-2 focus:ring-blue-500 focus:border-blue-500 text-sm"
734
+ />
735
+ <div className="absolute inset-y-0 right-0 pr-3 flex items-center">
736
+ <button className="text-gray-400 hover:text-gray-600">
737
+ <svg className="h-5 w-5" fill="none" viewBox="0 0 24 24" stroke="currentColor">
738
+ <path
739
+ strokeLinecap="round"
740
+ strokeLinejoin="round"
741
+ strokeWidth={2}
742
+ d="M5 5a2 2 0 012-2h10a2 2 0 012 2v16l-7-3.5L5 21V5z"
743
+ />
744
+ </svg>
745
+ </button>
746
+ </div>
747
+ </div>
748
+ </div>
749
+
750
+ {/* Message History List */}
751
+ <div className="px-4 py-2">
752
+ {regularMessages && regularMessages.length > 0 ? (
753
+ regularMessages
754
+ .filter((msg: any) => (msg as any)?.propsConfiguration?.contents?.role === 'USER')
755
+ .map((msg: any, index: number) => {
756
+ const messageTime = new Date(msg.createdAt);
757
+
758
+ return (
759
+ <div key={msg.id || index} className="mb-4">
760
+ {/* Restore to this point button */}
761
+ <div className="flex items-center justify-end mb-2">
762
+ <button className="text-blue-600 text-sm underline hover:text-blue-800 flex items-center">
763
+ <svg
764
+ className="w-4 h-4 mr-1"
765
+ fill="none"
766
+ viewBox="0 0 24 24"
767
+ stroke="currentColor"
768
+ >
769
+ <path
770
+ strokeLinecap="round"
771
+ strokeLinejoin="round"
772
+ strokeWidth={2}
773
+ d="M15 19l-7-7 7-7"
774
+ />
775
+ </svg>
776
+ Restore to this point
777
+ </button>
778
+ </div>
779
+
780
+ {/* Message using same container as Chat tab */}
781
+ <ModernMessageGroupComponent
782
+ messages={[
783
+ {
784
+ id: msg.id,
785
+ //message: msg.message || msg.content || 'No message content',
786
+ message:
787
+ (msg as any)?.propsConfiguration?.contents?.role ===
788
+ 'ASSISTANT'
789
+ ? msg.propsConfiguration?.contents?.fragment?.summary
790
+ ? extractCleanContent(
791
+ msg.propsConfiguration?.contents?.fragment
792
+ ?.summary,
793
+ )
794
+ : msg.message
795
+ : msg.message,
796
+ author: msg.author || {
797
+ id: 'user',
798
+ givenName: 'User',
799
+ familyName: '',
800
+ fullName: 'User',
801
+ username: 'user',
802
+ email: '',
803
+ picture: null,
804
+ alias: [],
805
+ tokens: [],
806
+ },
807
+ createdAt: msg.createdAt,
808
+ type: 'Simple' as any,
809
+ isDelivered: false,
810
+ isRead: false,
811
+ parentId: null,
812
+ fromServer: null,
813
+ updatedAt: msg.createdAt,
814
+ propsConfiguration: msg.propsConfiguration,
815
+ props: msg.props,
816
+ files: msg.files,
817
+ replies: null,
818
+ channel: null,
819
+ isPinned: false,
820
+ },
821
+ ]}
822
+ currentUser={currentUser as any}
823
+ onOpen={onOpen}
824
+ onMessageClick={(msg) => setSelectedPost(msg)}
825
+ isDesktopView={isDesktopView}
826
+ isSmallScreen={isSmallScreen}
827
+ />
828
+ </div>
829
+ );
830
+ })
831
+ ) : (
832
+ // Fallback entries when no messages
833
+ <>
834
+ {/* History Entry 1 */}
835
+ <div className="mb-4">
836
+ <div className="flex items-center justify-end mb-2">
837
+ <button className="text-blue-600 text-sm underline hover:text-blue-800 flex items-center">
838
+ <svg
839
+ className="w-4 h-4 mr-1"
840
+ fill="none"
841
+ viewBox="0 0 24 24"
842
+ stroke="currentColor"
843
+ >
844
+ <path
845
+ strokeLinecap="round"
846
+ strokeLinejoin="round"
847
+ strokeWidth={2}
848
+ d="M15 19l-7-7 7-7"
849
+ />
850
+ </svg>
851
+ Restore to this point
852
+ </button>
853
+ </div>
854
+ <div className="bg-gray-100 rounded-lg p-3">
855
+ <p className="text-sm text-gray-900">Sample message for demonstration</p>
856
+ </div>
857
+ </div>
858
+ </>
859
+ )}
860
+ </div>
861
+ </div>
862
+ ) : (
863
+ /* Chat Tab Content */
864
+ <div className="flex-1 overflow-y-auto bg-white">
865
+ {/* Messages Display - Styled like MessagesBuilderUi */}
866
+ <div
867
+ className={`w-full pb-4 pt-2 ${
868
+ isDesktopView ? 'space-y-3 max-w-full mx-auto' : isSmallScreen ? 'space-y-2' : 'space-y-2'
869
+ }`}
870
+ >
871
+ {/* Load Past Messages Button */}
872
+ {/* Load Past Messages disabled to show all messages */}
873
+
874
+ {/* Show placeholder when no messages */}
875
+ {(!completeConversationMessages || completeConversationMessages.length === 0) && (
876
+ <div className="px-4 py-8 text-center">
877
+ <div className="text-gray-500 text-lg font-medium mb-2">
878
+ Describe your idea and I'll help you create it step by step
879
+ </div>
880
+ <div className="text-gray-400 text-sm">
881
+ Start a new conversation by typing your message below
882
+ </div>
883
+ </div>
884
+ )}
885
+
886
+ {completeConversationMessages?.map((section, sectionIndex) => (
887
+ <div key={`section-${sectionIndex}`} className="w-full px-4">
888
+ {section.date && (
889
+ <div className="flex items-center justify-center my-3">
890
+ <div className="flex-grow border-t border-gray-200"></div>
891
+ <div className="mx-4 px-3 py-1 bg-white border border-gray-200 rounded-full text-xs font-medium text-gray-600">
892
+ {section.date}
893
+ </div>
894
+ <div className="flex-grow border-t border-gray-200"></div>
895
+ </div>
896
+ )}
897
+
898
+ <div className={`${isDesktopView ? 'mb-2' : 'mb-1'}`}>
899
+ {section.messages.map((msg: any, msgIndex: number) => (
900
+ <div key={msg.id || msgIndex} className="mb-3">
901
+ {/* AI Message Indicator */}
902
+ {msg.isAIMessage && (
903
+ <div className="flex items-center mb-2">
904
+ <div className="w-2 h-2 bg-blue-500 rounded-full mr-2"></div>
905
+ <span className="text-xs text-blue-600 font-medium">
906
+ AI Assistant
907
+ </span>
908
+ </div>
909
+ )}
910
+
911
+ {msg.isLoading ? (
912
+ // Show loader for loading messages
913
+ <div className="flex items-center space-x-2 bg-gray-50 border border-gray-200 px-4 py-3 rounded-lg">
914
+ <div className="w-4 h-4 border-2 border-gray-300 border-t-gray-500 rounded-full animate-spin"></div>
915
+ <span className="text-sm text-gray-600">
916
+ {msg.isProcessing ? 'Thinking...' : 'Thinking...'}
917
+ </span>
918
+ </div>
919
+ ) : (
920
+ // Show normal message for non-loading messages
921
+ <ModernMessageGroupComponent
922
+ messages={[
923
+ {
924
+ id: msg.id,
925
+ // message: msg.message,
926
+ message:
927
+ (msg as any)?.propsConfiguration?.contents?.role ===
928
+ 'ASSISTANT'
929
+ ? msg.propsConfiguration?.contents?.fragment
930
+ ?.summary
931
+ ? extractCleanContent(
932
+ msg.propsConfiguration?.contents?.fragment
933
+ ?.summary,
934
+ )
935
+ : msg.message
936
+ : msg.message,
937
+ author:
938
+ msg.sender === 'user'
939
+ ? msg.author
940
+ : {
941
+ id: 'ai-assistant',
942
+ givenName: 'AI',
943
+ familyName: 'Assistant',
944
+ fullName: 'AI Assistant',
945
+ username: 'ai-assistant',
946
+ email: 'ai@assistant.com',
947
+ picture: null,
948
+ alias: [],
949
+ tokens: [],
950
+ },
951
+ createdAt: msg.createdAt,
952
+ type: 'Simple' as any,
953
+ isDelivered: false,
954
+ isRead: false,
955
+ parentId: null,
956
+ fromServer: null,
957
+ updatedAt: msg.createdAt,
958
+ propsConfiguration: msg.propsConfiguration,
959
+ props: msg.props,
960
+ files: msg.files,
961
+ replies: null,
962
+ channel: null,
963
+ isPinned: false,
964
+ },
965
+ ]}
966
+ currentUser={currentUser as any}
967
+ onOpen={onOpen}
968
+ onMessageClick={(msg) => setSelectedPost(msg)}
969
+ isDesktopView={isDesktopView}
970
+ isSmallScreen={isSmallScreen}
971
+ sandboxErrors={sandboxErrors}
972
+ currentFiles={currentFiles}
973
+ onFixError={fixError}
974
+ onRecreateSandbox={recreateSandboxForFragment}
975
+ />
976
+ )}
977
+ </div>
978
+ ))}
979
+ </div>
980
+ </div>
981
+ ))}
982
+
983
+ {/* Typing indicator */}
984
+ {(isTyping || isSuccessThinking || isLoading) && (
985
+ <div className="px-4">
986
+ <div className="flex justify-start">
987
+ <div className="bg-gray-50 border border-gray-200 px-4 py-3 rounded-lg">
988
+ <div className="flex items-center space-x-2">
989
+ <div className="w-4 h-4 border-2 border-gray-300 border-t-gray-500 rounded-full animate-spin"></div>
990
+ <span className="text-sm text-gray-600">Thinking...</span>
991
+ </div>
992
+ </div>
993
+ </div>
994
+ </div>
995
+ )}
996
+
997
+ <div ref={bottomRef} />
998
+ </div>
999
+
1000
+ {/* Subscription Handler for real-time message updates */}
1001
+ <SubscriptionHandler
1002
+ subscribeToMore={subscribeToMore}
1003
+ document={CHAT_MESSAGE_ADDED}
1004
+ variables={{ channelId: actualChannelId?.toString() }}
1005
+ enabled={!!actualChannelId && !!subscribeToMore}
1006
+ updateQuery={(prev: any, { subscriptionData }: any) => {
1007
+ console.log('Subscription updateQuery called:', { prev, subscriptionData });
1008
+ if (!subscriptionData.data) {
1009
+ console.log('No subscription data, returning prev');
1010
+ return prev;
1011
+ }
1012
+ const newMessage = subscriptionData.data.chatMessageAdded;
1013
+
1014
+ console.log('New message received via subscription:', newMessage);
1015
+
1016
+ return {
1017
+ ...prev,
1018
+ messages: {
1019
+ ...prev?.messages,
1020
+ data: uniqBy([...(prev?.messages?.data || []), newMessage], 'id'),
1021
+ totalCount: (prev?.messages?.totalCount || 0) + 1,
1022
+ },
1023
+ };
1024
+ }}
1025
+ onError={(error) => {
1026
+ console.error('Subscription error:', error);
1027
+ }}
1028
+ />
1029
+ </div>
1030
+ )}
1031
+
1032
+ {/* Error Display */}
1033
+ {error && (
1034
+ <div className="mx-4 mb-4 p-3 bg-red-50 border border-red-200 rounded-lg">
1035
+ <div className="flex items-center justify-between">
1036
+ <div className="text-red-800 text-sm">{error}</div>
1037
+ <div className="flex space-x-2">
1038
+ <button
1039
+ onClick={handleRetry}
1040
+ className="px-2 py-1 text-xs bg-red-100 text-red-700 rounded hover:bg-red-200 transition-colors"
1041
+ >
1042
+ Retry
1043
+ </button>
1044
+ <button
1045
+ onClick={handleClearError}
1046
+ className="px-2 py-1 text-xs bg-gray-100 text-gray-700 rounded hover:bg-gray-200 transition-colors"
1047
+ >
1048
+ Dismiss
1049
+ </button>
1050
+ </div>
1051
+ </div>
1052
+ </div>
1053
+ )}
1054
+
1055
+ {/* Input Area - Only show for Chat tab */}
1056
+ {activeTab === 'chat' && (
1057
+ <div className="border-t border-gray-200 bg-white">
1058
+ {/* Removed temporary test button */}
1059
+ <InputComponent
1060
+ channelId={actualChannelId}
1061
+ handleSend={handleSend}
1062
+ placeholder={placeholder}
1063
+ modelConfig={modelConfig}
1064
+ onModelConfigChange={updateModelConfig}
1065
+ />
1066
+ </div>
1067
+ )}
1068
+
1069
+ {/* Optional Modal for user content like MessagesBuilderUi */}
1070
+ {isOpen ? (
1071
+ <div>
1072
+ <div className="fixed inset-0 bg-black bg-opacity-50 z-40" onClick={onClose} />
1073
+ <div className="fixed z-50 left-1/2 top-1/2 transform -translate-x-1/2 -translate-y-1/2">
1074
+ <div
1075
+ className="bg-white w-[1036px] h-[700px] rounded-lg shadow-xl"
1076
+ style={{ boxShadow: '0 10px 20px rgba(0,0,0,0.19), 0 6px 6px rgba(0,0,0,0.23)' }}
1077
+ >
1078
+ <div className="flex justify-between border-b border-gray-300 pb-4 pt-4">
1079
+ <button
1080
+ onClick={onClose}
1081
+ className="w-8 ml-3 text-black hover:text-black focus:outline-none"
1082
+ >
1083
+ <svg className="w-6 h-6" fill="none" stroke="currentColor" viewBox="0 0 24 24">
1084
+ <path
1085
+ strokeLinecap="round"
1086
+ strokeLinejoin="round"
1087
+ strokeWidth={2}
1088
+ d="M6 18L18 6M6 6l12 12"
1089
+ />
1090
+ </svg>
1091
+ </button>
1092
+ </div>
1093
+ <div className="p-4">
1094
+ {/* Keep minimal until full UserModalContent is needed */}
1095
+ <div className="text-sm text-gray-700">{selectedElement?.author?.username}</div>
1096
+ </div>
1097
+ </div>
1098
+ </div>
1099
+ </div>
1100
+ ) : null}
1101
+ </div>
1102
+ );
1103
+ };