@copilotkit/react-ui 0.0.0-0.0.0-max-changeset-10101010101010-20260109191632

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 (395) hide show
  1. package/CHANGELOG.md +17415 -0
  2. package/LICENSE +21 -0
  3. package/README.md +141 -0
  4. package/dist/chunk-3W6J75HS.mjs +126 -0
  5. package/dist/chunk-3W6J75HS.mjs.map +1 -0
  6. package/dist/chunk-54JAUBUJ.mjs +26 -0
  7. package/dist/chunk-54JAUBUJ.mjs.map +1 -0
  8. package/dist/chunk-7OURDQZJ.mjs +133 -0
  9. package/dist/chunk-7OURDQZJ.mjs.map +1 -0
  10. package/dist/chunk-7PR2KJDO.mjs +222 -0
  11. package/dist/chunk-7PR2KJDO.mjs.map +1 -0
  12. package/dist/chunk-BH6PCAAL.mjs +81 -0
  13. package/dist/chunk-BH6PCAAL.mjs.map +1 -0
  14. package/dist/chunk-C3GSYRC3.mjs +118 -0
  15. package/dist/chunk-C3GSYRC3.mjs.map +1 -0
  16. package/dist/chunk-DBKRAOH7.mjs +34 -0
  17. package/dist/chunk-DBKRAOH7.mjs.map +1 -0
  18. package/dist/chunk-EFZPSZWO.mjs +1 -0
  19. package/dist/chunk-EFZPSZWO.mjs.map +1 -0
  20. package/dist/chunk-ELGRNEAO.mjs +32 -0
  21. package/dist/chunk-ELGRNEAO.mjs.map +1 -0
  22. package/dist/chunk-ELUJRANC.mjs +21 -0
  23. package/dist/chunk-ELUJRANC.mjs.map +1 -0
  24. package/dist/chunk-FFJHOZX6.mjs +202 -0
  25. package/dist/chunk-FFJHOZX6.mjs.map +1 -0
  26. package/dist/chunk-GDSZGYCE.mjs +32 -0
  27. package/dist/chunk-GDSZGYCE.mjs.map +1 -0
  28. package/dist/chunk-HIW7RXCD.mjs +184 -0
  29. package/dist/chunk-HIW7RXCD.mjs.map +1 -0
  30. package/dist/chunk-IEMQ2SQW.mjs +93 -0
  31. package/dist/chunk-IEMQ2SQW.mjs.map +1 -0
  32. package/dist/chunk-IHFR6PYG.mjs +116 -0
  33. package/dist/chunk-IHFR6PYG.mjs.map +1 -0
  34. package/dist/chunk-IK2BPURM.mjs +400 -0
  35. package/dist/chunk-IK2BPURM.mjs.map +1 -0
  36. package/dist/chunk-IU3WTXLQ.mjs +1 -0
  37. package/dist/chunk-IU3WTXLQ.mjs.map +1 -0
  38. package/dist/chunk-JGMFJZMG.mjs +11 -0
  39. package/dist/chunk-JGMFJZMG.mjs.map +1 -0
  40. package/dist/chunk-JY2CSDKN.mjs +135 -0
  41. package/dist/chunk-JY2CSDKN.mjs.map +1 -0
  42. package/dist/chunk-JZ3RFQQ6.mjs +128 -0
  43. package/dist/chunk-JZ3RFQQ6.mjs.map +1 -0
  44. package/dist/chunk-KXE2JCUH.mjs +1 -0
  45. package/dist/chunk-KXE2JCUH.mjs.map +1 -0
  46. package/dist/chunk-LQEFRHRT.mjs +30 -0
  47. package/dist/chunk-LQEFRHRT.mjs.map +1 -0
  48. package/dist/chunk-MMVDU6DF.mjs +1 -0
  49. package/dist/chunk-MMVDU6DF.mjs.map +1 -0
  50. package/dist/chunk-MRXNTQOX.mjs +59 -0
  51. package/dist/chunk-MRXNTQOX.mjs.map +1 -0
  52. package/dist/chunk-NCIAFFQ2.mjs +82 -0
  53. package/dist/chunk-NCIAFFQ2.mjs.map +1 -0
  54. package/dist/chunk-NGJ32FAP.mjs +30 -0
  55. package/dist/chunk-NGJ32FAP.mjs.map +1 -0
  56. package/dist/chunk-NRA3CFEE.mjs +97 -0
  57. package/dist/chunk-NRA3CFEE.mjs.map +1 -0
  58. package/dist/chunk-O72ZB5V3.mjs +140 -0
  59. package/dist/chunk-O72ZB5V3.mjs.map +1 -0
  60. package/dist/chunk-PLHTVHUW.mjs +82 -0
  61. package/dist/chunk-PLHTVHUW.mjs.map +1 -0
  62. package/dist/chunk-Q5V6S67N.mjs +103 -0
  63. package/dist/chunk-Q5V6S67N.mjs.map +1 -0
  64. package/dist/chunk-QB3GUN2N.mjs +31 -0
  65. package/dist/chunk-QB3GUN2N.mjs.map +1 -0
  66. package/dist/chunk-QIOJXTIQ.mjs +64 -0
  67. package/dist/chunk-QIOJXTIQ.mjs.map +1 -0
  68. package/dist/chunk-QPQRLXN3.mjs +435 -0
  69. package/dist/chunk-QPQRLXN3.mjs.map +1 -0
  70. package/dist/chunk-RYUCX3ZK.mjs +32 -0
  71. package/dist/chunk-RYUCX3ZK.mjs.map +1 -0
  72. package/dist/chunk-SC6JRFAJ.mjs +1 -0
  73. package/dist/chunk-SC6JRFAJ.mjs.map +1 -0
  74. package/dist/chunk-T26KLXLH.mjs +1 -0
  75. package/dist/chunk-T26KLXLH.mjs.map +1 -0
  76. package/dist/chunk-UFN2VWSR.mjs +25 -0
  77. package/dist/chunk-UFN2VWSR.mjs.map +1 -0
  78. package/dist/chunk-V7W6IM2V.mjs +1 -0
  79. package/dist/chunk-V7W6IM2V.mjs.map +1 -0
  80. package/dist/chunk-WB3YULQ4.mjs +1 -0
  81. package/dist/chunk-WB3YULQ4.mjs.map +1 -0
  82. package/dist/chunk-XWG3L6QC.mjs +258 -0
  83. package/dist/chunk-XWG3L6QC.mjs.map +1 -0
  84. package/dist/chunk-Y4FKRAKJ.mjs +12 -0
  85. package/dist/chunk-Y4FKRAKJ.mjs.map +1 -0
  86. package/dist/components/chat/Button.d.ts +9 -0
  87. package/dist/components/chat/Button.js +71 -0
  88. package/dist/components/chat/Button.js.map +1 -0
  89. package/dist/components/chat/Button.mjs +10 -0
  90. package/dist/components/chat/Button.mjs.map +1 -0
  91. package/dist/components/chat/Chat.d.ts +204 -0
  92. package/dist/components/chat/Chat.js +2270 -0
  93. package/dist/components/chat/Chat.js.map +1 -0
  94. package/dist/components/chat/Chat.mjs +29 -0
  95. package/dist/components/chat/Chat.mjs.map +1 -0
  96. package/dist/components/chat/ChatContext.d.ts +145 -0
  97. package/dist/components/chat/ChatContext.js +329 -0
  98. package/dist/components/chat/ChatContext.js.map +1 -0
  99. package/dist/components/chat/ChatContext.mjs +13 -0
  100. package/dist/components/chat/ChatContext.mjs.map +1 -0
  101. package/dist/components/chat/CodeBlock.d.ts +14 -0
  102. package/dist/components/chat/CodeBlock.js +510 -0
  103. package/dist/components/chat/CodeBlock.js.map +1 -0
  104. package/dist/components/chat/CodeBlock.mjs +14 -0
  105. package/dist/components/chat/CodeBlock.mjs.map +1 -0
  106. package/dist/components/chat/Header.d.ts +9 -0
  107. package/dist/components/chat/Header.js +582 -0
  108. package/dist/components/chat/Header.js.map +1 -0
  109. package/dist/components/chat/Header.mjs +17 -0
  110. package/dist/components/chat/Header.mjs.map +1 -0
  111. package/dist/components/chat/Icons.d.ts +20 -0
  112. package/dist/components/chat/Icons.js +297 -0
  113. package/dist/components/chat/Icons.js.map +1 -0
  114. package/dist/components/chat/Icons.mjs +38 -0
  115. package/dist/components/chat/Icons.mjs.map +1 -0
  116. package/dist/components/chat/ImageUploadQueue.d.ts +13 -0
  117. package/dist/components/chat/ImageUploadQueue.js +106 -0
  118. package/dist/components/chat/ImageUploadQueue.js.map +1 -0
  119. package/dist/components/chat/ImageUploadQueue.mjs +8 -0
  120. package/dist/components/chat/ImageUploadQueue.mjs.map +1 -0
  121. package/dist/components/chat/Input.d.ts +9 -0
  122. package/dist/components/chat/Input.js +396 -0
  123. package/dist/components/chat/Input.js.map +1 -0
  124. package/dist/components/chat/Input.mjs +14 -0
  125. package/dist/components/chat/Input.mjs.map +1 -0
  126. package/dist/components/chat/Markdown.d.ts +10 -0
  127. package/dist/components/chat/Markdown.js +652 -0
  128. package/dist/components/chat/Markdown.js.map +1 -0
  129. package/dist/components/chat/Markdown.mjs +11 -0
  130. package/dist/components/chat/Markdown.mjs.map +1 -0
  131. package/dist/components/chat/Messages.d.ts +13 -0
  132. package/dist/components/chat/Messages.js +1195 -0
  133. package/dist/components/chat/Messages.js.map +1 -0
  134. package/dist/components/chat/Messages.mjs +20 -0
  135. package/dist/components/chat/Messages.mjs.map +1 -0
  136. package/dist/components/chat/Modal.d.ts +51 -0
  137. package/dist/components/chat/Modal.js +3075 -0
  138. package/dist/components/chat/Modal.js.map +1 -0
  139. package/dist/components/chat/Modal.mjs +38 -0
  140. package/dist/components/chat/Modal.mjs.map +1 -0
  141. package/dist/components/chat/Popup.d.ts +13 -0
  142. package/dist/components/chat/Popup.js +3086 -0
  143. package/dist/components/chat/Popup.js.map +1 -0
  144. package/dist/components/chat/Popup.mjs +39 -0
  145. package/dist/components/chat/Popup.mjs.map +1 -0
  146. package/dist/components/chat/PoweredByTag.d.ts +7 -0
  147. package/dist/components/chat/PoweredByTag.js +61 -0
  148. package/dist/components/chat/PoweredByTag.js.map +1 -0
  149. package/dist/components/chat/PoweredByTag.mjs +9 -0
  150. package/dist/components/chat/PoweredByTag.mjs.map +1 -0
  151. package/dist/components/chat/Sidebar.d.ts +13 -0
  152. package/dist/components/chat/Sidebar.js +3095 -0
  153. package/dist/components/chat/Sidebar.js.map +1 -0
  154. package/dist/components/chat/Sidebar.mjs +39 -0
  155. package/dist/components/chat/Sidebar.mjs.map +1 -0
  156. package/dist/components/chat/Suggestion.d.ts +12 -0
  157. package/dist/components/chat/Suggestion.js +56 -0
  158. package/dist/components/chat/Suggestion.js.map +1 -0
  159. package/dist/components/chat/Suggestion.mjs +9 -0
  160. package/dist/components/chat/Suggestion.mjs.map +1 -0
  161. package/dist/components/chat/Suggestions.d.ts +9 -0
  162. package/dist/components/chat/Suggestions.js +81 -0
  163. package/dist/components/chat/Suggestions.js.map +1 -0
  164. package/dist/components/chat/Suggestions.mjs +10 -0
  165. package/dist/components/chat/Suggestions.mjs.map +1 -0
  166. package/dist/components/chat/Textarea.d.ts +15 -0
  167. package/dist/components/chat/Textarea.js +84 -0
  168. package/dist/components/chat/Textarea.js.map +1 -0
  169. package/dist/components/chat/Textarea.mjs +8 -0
  170. package/dist/components/chat/Textarea.mjs.map +1 -0
  171. package/dist/components/chat/Window.d.ts +9 -0
  172. package/dist/components/chat/Window.js +164 -0
  173. package/dist/components/chat/Window.js.map +1 -0
  174. package/dist/components/chat/Window.mjs +10 -0
  175. package/dist/components/chat/Window.mjs.map +1 -0
  176. package/dist/components/chat/index.d.ts +18 -0
  177. package/dist/components/chat/index.js +3122 -0
  178. package/dist/components/chat/index.js.map +1 -0
  179. package/dist/components/chat/index.mjs +69 -0
  180. package/dist/components/chat/index.mjs.map +1 -0
  181. package/dist/components/chat/messages/AssistantMessage.d.ts +9 -0
  182. package/dist/components/chat/messages/AssistantMessage.js +775 -0
  183. package/dist/components/chat/messages/AssistantMessage.js.map +1 -0
  184. package/dist/components/chat/messages/AssistantMessage.mjs +13 -0
  185. package/dist/components/chat/messages/AssistantMessage.mjs.map +1 -0
  186. package/dist/components/chat/messages/ErrorMessage.d.ts +9 -0
  187. package/dist/components/chat/messages/ErrorMessage.js +722 -0
  188. package/dist/components/chat/messages/ErrorMessage.js.map +1 -0
  189. package/dist/components/chat/messages/ErrorMessage.mjs +66 -0
  190. package/dist/components/chat/messages/ErrorMessage.mjs.map +1 -0
  191. package/dist/components/chat/messages/ImageRenderer.d.ts +12 -0
  192. package/dist/components/chat/messages/ImageRenderer.js +58 -0
  193. package/dist/components/chat/messages/ImageRenderer.js.map +1 -0
  194. package/dist/components/chat/messages/ImageRenderer.mjs +8 -0
  195. package/dist/components/chat/messages/ImageRenderer.mjs.map +1 -0
  196. package/dist/components/chat/messages/LegacyRenderMessage.d.ts +28 -0
  197. package/dist/components/chat/messages/LegacyRenderMessage.js +1023 -0
  198. package/dist/components/chat/messages/LegacyRenderMessage.js.map +1 -0
  199. package/dist/components/chat/messages/LegacyRenderMessage.mjs +17 -0
  200. package/dist/components/chat/messages/LegacyRenderMessage.mjs.map +1 -0
  201. package/dist/components/chat/messages/RenderMessage.d.ts +9 -0
  202. package/dist/components/chat/messages/RenderMessage.js +898 -0
  203. package/dist/components/chat/messages/RenderMessage.js.map +1 -0
  204. package/dist/components/chat/messages/RenderMessage.mjs +16 -0
  205. package/dist/components/chat/messages/RenderMessage.mjs.map +1 -0
  206. package/dist/components/chat/messages/UserMessage.d.ts +9 -0
  207. package/dist/components/chat/messages/UserMessage.js +56 -0
  208. package/dist/components/chat/messages/UserMessage.js.map +1 -0
  209. package/dist/components/chat/messages/UserMessage.mjs +8 -0
  210. package/dist/components/chat/messages/UserMessage.mjs.map +1 -0
  211. package/dist/components/chat/props.d.ts +298 -0
  212. package/dist/components/chat/props.js +19 -0
  213. package/dist/components/chat/props.js.map +1 -0
  214. package/dist/components/chat/props.mjs +2 -0
  215. package/dist/components/chat/props.mjs.map +1 -0
  216. package/dist/components/dev-console/console.d.ts +11 -0
  217. package/dist/components/dev-console/console.js +537 -0
  218. package/dist/components/dev-console/console.js.map +1 -0
  219. package/dist/components/dev-console/console.mjs +17 -0
  220. package/dist/components/dev-console/console.mjs.map +1 -0
  221. package/dist/components/dev-console/icons.d.ts +9 -0
  222. package/dist/components/dev-console/icons.js +131 -0
  223. package/dist/components/dev-console/icons.js.map +1 -0
  224. package/dist/components/dev-console/icons.mjs +16 -0
  225. package/dist/components/dev-console/icons.mjs.map +1 -0
  226. package/dist/components/dev-console/index.d.ts +3 -0
  227. package/dist/components/dev-console/index.js +537 -0
  228. package/dist/components/dev-console/index.js.map +1 -0
  229. package/dist/components/dev-console/index.mjs +18 -0
  230. package/dist/components/dev-console/index.mjs.map +1 -0
  231. package/dist/components/dev-console/types.d.ts +9 -0
  232. package/dist/components/dev-console/types.js +19 -0
  233. package/dist/components/dev-console/types.js.map +1 -0
  234. package/dist/components/dev-console/types.mjs +1 -0
  235. package/dist/components/dev-console/types.mjs.map +1 -0
  236. package/dist/components/dev-console/utils.d.ts +10 -0
  237. package/dist/components/dev-console/utils.js +177 -0
  238. package/dist/components/dev-console/utils.js.map +1 -0
  239. package/dist/components/dev-console/utils.mjs +16 -0
  240. package/dist/components/dev-console/utils.mjs.map +1 -0
  241. package/dist/components/help-modal/icons.d.ts +9 -0
  242. package/dist/components/help-modal/icons.js +107 -0
  243. package/dist/components/help-modal/icons.js.map +1 -0
  244. package/dist/components/help-modal/icons.mjs +12 -0
  245. package/dist/components/help-modal/icons.mjs.map +1 -0
  246. package/dist/components/help-modal/index.d.ts +2 -0
  247. package/dist/components/help-modal/index.js +137 -0
  248. package/dist/components/help-modal/index.js.map +1 -0
  249. package/dist/components/help-modal/index.mjs +10 -0
  250. package/dist/components/help-modal/index.mjs.map +1 -0
  251. package/dist/components/help-modal/modal.d.ts +5 -0
  252. package/dist/components/help-modal/modal.js +135 -0
  253. package/dist/components/help-modal/modal.js.map +1 -0
  254. package/dist/components/help-modal/modal.mjs +9 -0
  255. package/dist/components/help-modal/modal.mjs.map +1 -0
  256. package/dist/components/index.d.ts +19 -0
  257. package/dist/components/index.js +3126 -0
  258. package/dist/components/index.js.map +1 -0
  259. package/dist/components/index.mjs +76 -0
  260. package/dist/components/index.mjs.map +1 -0
  261. package/dist/context/index.d.ts +2 -0
  262. package/dist/context/index.js +19 -0
  263. package/dist/context/index.js.map +1 -0
  264. package/dist/context/index.mjs +2 -0
  265. package/dist/context/index.mjs.map +1 -0
  266. package/dist/hooks/index.d.ts +2 -0
  267. package/dist/hooks/index.js +36 -0
  268. package/dist/hooks/index.js.map +1 -0
  269. package/dist/hooks/index.mjs +9 -0
  270. package/dist/hooks/index.mjs.map +1 -0
  271. package/dist/hooks/use-copilot-chat-suggestions.d.ts +66 -0
  272. package/dist/hooks/use-copilot-chat-suggestions.js +34 -0
  273. package/dist/hooks/use-copilot-chat-suggestions.js.map +1 -0
  274. package/dist/hooks/use-copilot-chat-suggestions.mjs +8 -0
  275. package/dist/hooks/use-copilot-chat-suggestions.mjs.map +1 -0
  276. package/dist/hooks/use-copy-to-clipboard.d.ts +9 -0
  277. package/dist/hooks/use-copy-to-clipboard.js +60 -0
  278. package/dist/hooks/use-copy-to-clipboard.js.map +1 -0
  279. package/dist/hooks/use-copy-to-clipboard.mjs +8 -0
  280. package/dist/hooks/use-copy-to-clipboard.mjs.map +1 -0
  281. package/dist/hooks/use-dark-mode.d.ts +3 -0
  282. package/dist/hooks/use-dark-mode.js +35 -0
  283. package/dist/hooks/use-dark-mode.js.map +1 -0
  284. package/dist/hooks/use-dark-mode.mjs +8 -0
  285. package/dist/hooks/use-dark-mode.mjs.map +1 -0
  286. package/dist/hooks/use-push-to-talk.d.ts +19 -0
  287. package/dist/hooks/use-push-to-talk.js +195 -0
  288. package/dist/hooks/use-push-to-talk.js.map +1 -0
  289. package/dist/hooks/use-push-to-talk.mjs +12 -0
  290. package/dist/hooks/use-push-to-talk.mjs.map +1 -0
  291. package/dist/index.css +1258 -0
  292. package/dist/index.css.map +1 -0
  293. package/dist/index.d.ts +21 -0
  294. package/dist/index.js +3135 -0
  295. package/dist/index.js.map +1 -0
  296. package/dist/index.mjs +84 -0
  297. package/dist/index.mjs.map +1 -0
  298. package/dist/lib/utils.d.ts +4 -0
  299. package/dist/lib/utils.js +76 -0
  300. package/dist/lib/utils.js.map +1 -0
  301. package/dist/lib/utils.mjs +34 -0
  302. package/dist/lib/utils.mjs.map +1 -0
  303. package/dist/types/css.d.ts +22 -0
  304. package/dist/types/css.js +19 -0
  305. package/dist/types/css.js.map +1 -0
  306. package/dist/types/css.mjs +1 -0
  307. package/dist/types/css.mjs.map +1 -0
  308. package/dist/types/index.d.ts +3 -0
  309. package/dist/types/index.js +19 -0
  310. package/dist/types/index.js.map +1 -0
  311. package/dist/types/index.mjs +2 -0
  312. package/dist/types/index.mjs.map +1 -0
  313. package/dist/types/suggestions.d.ts +9 -0
  314. package/dist/types/suggestions.js +19 -0
  315. package/dist/types/suggestions.js.map +1 -0
  316. package/dist/types/suggestions.mjs +1 -0
  317. package/dist/types/suggestions.mjs.map +1 -0
  318. package/dist/v2/index.css +4 -0
  319. package/dist/v2/index.css.map +1 -0
  320. package/dist/v2/index.d.ts +2 -0
  321. package/dist/v2/index.js +2 -0
  322. package/dist/v2/index.js.map +1 -0
  323. package/dist/v2/index.mjs +2 -0
  324. package/dist/v2/index.mjs.map +1 -0
  325. package/jest.config.js +5 -0
  326. package/package.json +83 -0
  327. package/postcss.config.js +60 -0
  328. package/src/components/chat/Button.tsx +18 -0
  329. package/src/components/chat/Chat.tsx +795 -0
  330. package/src/components/chat/ChatContext.tsx +248 -0
  331. package/src/components/chat/CodeBlock.tsx +418 -0
  332. package/src/components/chat/Header.tsx +24 -0
  333. package/src/components/chat/Icons.tsx +237 -0
  334. package/src/components/chat/ImageUploadQueue.tsx +77 -0
  335. package/src/components/chat/Input.tsx +156 -0
  336. package/src/components/chat/Markdown.tsx +144 -0
  337. package/src/components/chat/Messages.tsx +206 -0
  338. package/src/components/chat/Modal.tsx +220 -0
  339. package/src/components/chat/Popup.tsx +77 -0
  340. package/src/components/chat/PoweredByTag.tsx +42 -0
  341. package/src/components/chat/Sidebar.tsx +96 -0
  342. package/src/components/chat/Suggestion.tsx +29 -0
  343. package/src/components/chat/Suggestions.tsx +23 -0
  344. package/src/components/chat/Textarea.tsx +77 -0
  345. package/src/components/chat/Window.tsx +152 -0
  346. package/src/components/chat/index.tsx +11 -0
  347. package/src/components/chat/messages/AssistantMessage.tsx +118 -0
  348. package/src/components/chat/messages/ErrorMessage.tsx +59 -0
  349. package/src/components/chat/messages/ImageRenderer.tsx +37 -0
  350. package/src/components/chat/messages/LegacyRenderMessage.tsx +150 -0
  351. package/src/components/chat/messages/RenderMessage.tsx +61 -0
  352. package/src/components/chat/messages/UserMessage.tsx +46 -0
  353. package/src/components/chat/props.ts +353 -0
  354. package/src/components/dev-console/console.tsx +242 -0
  355. package/src/components/dev-console/icons.tsx +99 -0
  356. package/src/components/dev-console/index.tsx +2 -0
  357. package/src/components/dev-console/types.ts +7 -0
  358. package/src/components/dev-console/utils.ts +142 -0
  359. package/src/components/help-modal/icons.tsx +68 -0
  360. package/src/components/help-modal/index.tsx +1 -0
  361. package/src/components/help-modal/modal.tsx +101 -0
  362. package/src/components/index.ts +2 -0
  363. package/src/context/index.ts +1 -0
  364. package/src/css/animations.css +35 -0
  365. package/src/css/button.css +67 -0
  366. package/src/css/colors.css +78 -0
  367. package/src/css/console.css +166 -0
  368. package/src/css/crew.css +277 -0
  369. package/src/css/header.css +65 -0
  370. package/src/css/input.css +152 -0
  371. package/src/css/markdown.css +150 -0
  372. package/src/css/messages.css +244 -0
  373. package/src/css/panel.css +39 -0
  374. package/src/css/popup.css +22 -0
  375. package/src/css/sidebar.css +34 -0
  376. package/src/css/suggestions.css +43 -0
  377. package/src/css/window.css +60 -0
  378. package/src/hooks/index.ts +1 -0
  379. package/src/hooks/use-copilot-chat-suggestions.tsx +71 -0
  380. package/src/hooks/use-copy-to-clipboard.tsx +29 -0
  381. package/src/hooks/use-dark-mode.ts +10 -0
  382. package/src/hooks/use-push-to-talk.tsx +167 -0
  383. package/src/index.tsx +7 -0
  384. package/src/lib/utils.test.ts +7 -0
  385. package/src/lib/utils.ts +27 -0
  386. package/src/styles.css +14 -0
  387. package/src/types/css.ts +21 -0
  388. package/src/types/index.ts +2 -0
  389. package/src/types/suggestions.ts +7 -0
  390. package/src/v2/index.ts +1 -0
  391. package/src/v2/styles.css +1 -0
  392. package/tailwind.config.js +7 -0
  393. package/tsconfig.json +12 -0
  394. package/tsup.config.ts +11 -0
  395. package/typedoc.json +4 -0
@@ -0,0 +1,795 @@
1
+ /**
2
+ * <br/>
3
+ * <img src="https://cdn.copilotkit.ai/docs/copilotkit/images/CopilotChat.gif" width="500" />
4
+ *
5
+ * A chatbot panel component for the CopilotKit framework. The component allows for a high degree
6
+ * of customization through various props and custom CSS.
7
+ *
8
+ * ## Install Dependencies
9
+ *
10
+ * This component is part of the [@copilotkit/react-ui](https://npmjs.com/package/@copilotkit/react-ui) package.
11
+ *
12
+ * ```shell npm2yarn \"@copilotkit/react-ui"\
13
+ * npm install @copilotkit/react-core @copilotkit/react-ui
14
+ * ```
15
+ *
16
+ * ## Usage
17
+ *
18
+ * ```tsx
19
+ * import { CopilotChat } from "@copilotkit/react-ui";
20
+ * import "@copilotkit/react-ui/styles.css";
21
+ *
22
+ * <CopilotChat
23
+ * labels={{
24
+ * title: "Your Assistant",
25
+ * initial: "Hi! 👋 How can I assist you today?",
26
+ * }}
27
+ * />
28
+ * ```
29
+ *
30
+ * ### With Observability Hooks
31
+ *
32
+ * To monitor user interactions, provide the `observabilityHooks` prop.
33
+ * **Note:** This requires a `publicApiKey` in the `<CopilotKit>` provider.
34
+ *
35
+ * ```tsx
36
+ * <CopilotKit publicApiKey="YOUR_PUBLIC_API_KEY">
37
+ * <CopilotChat
38
+ * observabilityHooks={{
39
+ * onMessageSent: (message) => {
40
+ * console.log("Message sent:", message);
41
+ * },
42
+ * }}
43
+ * />
44
+ * </CopilotKit>
45
+ * ```
46
+ *
47
+ * ### Look & Feel
48
+ *
49
+ * By default, CopilotKit components do not have any styles. You can import CopilotKit's stylesheet at the root of your project:
50
+ * ```tsx title="YourRootComponent.tsx"
51
+ * ...
52
+ * import "@copilotkit/react-ui/styles.css"; // [!code highlight]
53
+ *
54
+ * export function YourRootComponent() {
55
+ * return (
56
+ * <CopilotKit>
57
+ * ...
58
+ * </CopilotKit>
59
+ * );
60
+ * }
61
+ * ```
62
+ * For more information about how to customize the styles, check out the [Customize Look & Feel](/guides/custom-look-and-feel/customize-built-in-ui-components) guide.
63
+ */
64
+
65
+ import {
66
+ ChatContext,
67
+ ChatContextProvider,
68
+ CopilotChatIcons,
69
+ CopilotChatLabels,
70
+ } from "./ChatContext";
71
+ import { Messages as DefaultMessages } from "./Messages";
72
+ import { Input as DefaultInput } from "./Input";
73
+ import { RenderMessage as DefaultRenderMessage } from "./messages/RenderMessage";
74
+ import { AssistantMessage as DefaultAssistantMessage } from "./messages/AssistantMessage";
75
+ import { UserMessage as DefaultUserMessage } from "./messages/UserMessage";
76
+ import { ImageRenderer as DefaultImageRenderer } from "./messages/ImageRenderer";
77
+ import React, { useEffect, useRef, useState, useCallback } from "react";
78
+ import {
79
+ SystemMessageFunction,
80
+ useCopilotContext,
81
+ useCopilotChatInternal,
82
+ type OnStopGeneration,
83
+ type OnReloadMessages,
84
+ type ChatSuggestions,
85
+ } from "@copilotkit/react-core";
86
+ import {
87
+ CopilotKitError,
88
+ CopilotKitErrorCode,
89
+ CopilotErrorEvent,
90
+ Message,
91
+ Severity,
92
+ ErrorVisibility,
93
+ styledConsole,
94
+ CopilotErrorHandler,
95
+ randomUUID,
96
+ } from "@copilotkit/shared";
97
+ import {
98
+ AssistantMessageProps,
99
+ ChatError,
100
+ ComponentsMap,
101
+ CopilotObservabilityHooks,
102
+ ErrorMessageProps,
103
+ ImageRendererProps,
104
+ InputProps,
105
+ MessagesProps,
106
+ RenderMessageProps,
107
+ RenderSuggestionsListProps,
108
+ UserMessageProps,
109
+ } from "./props";
110
+
111
+ import { ImageUploadQueue } from "./ImageUploadQueue";
112
+ import { Suggestions as DefaultRenderSuggestionsList } from "./Suggestions";
113
+
114
+ /**
115
+ * Props for CopilotChat component.
116
+ */
117
+ export interface CopilotChatProps {
118
+ /**
119
+ * Custom instructions to be added to the system message. Use this property to
120
+ * provide additional context or guidance to the language model, influencing
121
+ * its responses. These instructions can include specific directions,
122
+ * preferences, or criteria that the model should consider when generating
123
+ * its output, thereby tailoring the conversation more precisely to the
124
+ * user's needs or the application's requirements.
125
+ */
126
+ instructions?: string;
127
+
128
+ /**
129
+ * Controls the behavior of suggestions in the chat interface.
130
+ *
131
+ * `auto` (default) - Suggestions are generated automatically:
132
+ * - When the chat is first opened (empty state)
133
+ * - After each message exchange completes
134
+ * - Uses configuration from `useCopilotChatSuggestions` hooks
135
+ *
136
+ * `manual` - Suggestions are controlled programmatically:
137
+ * - Use `setSuggestions()` to set custom suggestions
138
+ * - Use `generateSuggestions()` to trigger AI generation
139
+ * - Access via `useCopilotChat` hook
140
+ *
141
+ * `SuggestionItem[]` - Static suggestions array:
142
+ * - Always shows the same suggestions
143
+ * - No AI generation involved
144
+ */
145
+ suggestions?: ChatSuggestions;
146
+
147
+ /**
148
+ * A callback that gets called when the in progress state changes.
149
+ */
150
+ onInProgress?: (inProgress: boolean) => void;
151
+
152
+ /**
153
+ * A callback that gets called when a new message it submitted.
154
+ */
155
+ onSubmitMessage?: (message: string) => void | Promise<void>;
156
+
157
+ /**
158
+ * A custom stop generation function.
159
+ */
160
+ onStopGeneration?: OnStopGeneration;
161
+
162
+ /**
163
+ * A custom reload messages function.
164
+ */
165
+ onReloadMessages?: OnReloadMessages;
166
+
167
+ /**
168
+ * A callback function to regenerate the assistant's response
169
+ */
170
+ onRegenerate?: (messageId: string) => void;
171
+
172
+ /**
173
+ * A callback function when the message is copied
174
+ */
175
+ onCopy?: (message: string) => void;
176
+
177
+ /**
178
+ * A callback function for thumbs up feedback
179
+ */
180
+ onThumbsUp?: (message: Message) => void;
181
+
182
+ /**
183
+ * A callback function for thumbs down feedback
184
+ */
185
+ onThumbsDown?: (message: Message) => void;
186
+
187
+ /**
188
+ * A list of markdown components to render in assistant message.
189
+ * Useful when you want to render custom elements in the message (e.g a reference tag element)
190
+ */
191
+ markdownTagRenderers?: ComponentsMap;
192
+
193
+ /**
194
+ * Icons can be used to set custom icons for the chat window.
195
+ */
196
+ icons?: CopilotChatIcons;
197
+
198
+ /**
199
+ * Labels can be used to set custom labels for the chat window.
200
+ */
201
+ labels?: CopilotChatLabels;
202
+
203
+ /**
204
+ * Enable image upload button (image inputs only supported on some models)
205
+ */
206
+ imageUploadsEnabled?: boolean;
207
+
208
+ /**
209
+ * The 'accept' attribute for the file input used for image uploads.
210
+ * Defaults to "image/*".
211
+ */
212
+ inputFileAccept?: string;
213
+
214
+ /**
215
+ * A function that takes in context string and instructions and returns
216
+ * the system message to include in the chat request.
217
+ * Use this to completely override the system message, when providing
218
+ * instructions is not enough.
219
+ */
220
+ makeSystemMessage?: SystemMessageFunction;
221
+
222
+ /**
223
+ * Disables inclusion of CopilotKit’s default system message. When true, no system message is sent (this also suppresses any custom message from <code>makeSystemMessage</code>).
224
+ */
225
+ disableSystemMessage?: boolean;
226
+
227
+ /**
228
+ * A custom assistant message component to use instead of the default.
229
+ */
230
+ AssistantMessage?: React.ComponentType<AssistantMessageProps>;
231
+
232
+ /**
233
+ * A custom user message component to use instead of the default.
234
+ */
235
+ UserMessage?: React.ComponentType<UserMessageProps>;
236
+
237
+ /**
238
+ * A custom error message component to use instead of the default.
239
+ */
240
+ ErrorMessage?: React.ComponentType<ErrorMessageProps>;
241
+
242
+ /**
243
+ * A custom Messages component to use instead of the default.
244
+ */
245
+ Messages?: React.ComponentType<MessagesProps>;
246
+
247
+ /**
248
+ * @deprecated - use RenderMessage instead
249
+ */
250
+ RenderTextMessage?: React.ComponentType<RenderMessageProps>;
251
+
252
+ /**
253
+ * @deprecated - use RenderMessage instead
254
+ */
255
+ RenderActionExecutionMessage?: React.ComponentType<RenderMessageProps>;
256
+
257
+ /**
258
+ * @deprecated - use RenderMessage instead
259
+ */
260
+ RenderAgentStateMessage?: React.ComponentType<RenderMessageProps>;
261
+
262
+ /**
263
+ * @deprecated - use RenderMessage instead
264
+ */
265
+ RenderResultMessage?: React.ComponentType<RenderMessageProps>;
266
+
267
+ /**
268
+ * @deprecated - use RenderMessage instead
269
+ */
270
+ RenderImageMessage?: React.ComponentType<RenderMessageProps>;
271
+
272
+ /**
273
+ * A custom RenderMessage component to use instead of the default.
274
+ *
275
+ * **Warning**: This is a break-glass solution to allow for custom
276
+ * rendering of messages. You are most likely looking to swap out
277
+ * the AssistantMessage and UserMessage components instead which
278
+ * are also props.
279
+ */
280
+ RenderMessage?: React.ComponentType<RenderMessageProps>;
281
+
282
+ /**
283
+ * A custom suggestions list component to use instead of the default.
284
+ */
285
+ RenderSuggestionsList?: React.ComponentType<RenderSuggestionsListProps>;
286
+
287
+ /**
288
+ * A custom Input component to use instead of the default.
289
+ */
290
+ Input?: React.ComponentType<InputProps>;
291
+
292
+ /**
293
+ * A custom image rendering component to use instead of the default.
294
+ */
295
+ ImageRenderer?: React.ComponentType<ImageRendererProps>;
296
+
297
+ /**
298
+ * A class name to apply to the root element.
299
+ */
300
+ className?: string;
301
+
302
+ /**
303
+ * Children to render.
304
+ */
305
+ children?: React.ReactNode;
306
+
307
+ hideStopButton?: boolean;
308
+
309
+ /**
310
+ * Event hooks for CopilotKit chat events.
311
+ * These hooks only work when publicApiKey is provided.
312
+ */
313
+ observabilityHooks?: CopilotObservabilityHooks;
314
+
315
+ /**
316
+ * Custom error renderer for chat-specific errors.
317
+ * When provided, errors will be displayed inline within the chat interface.
318
+ */
319
+ renderError?: (error: {
320
+ message: string;
321
+ operation?: string;
322
+ timestamp: number;
323
+ onDismiss: () => void;
324
+ onRetry?: () => void;
325
+ }) => React.ReactNode;
326
+
327
+ /**
328
+ * Optional handler for comprehensive debugging and observability.
329
+ */
330
+ onError?: CopilotErrorHandler;
331
+ }
332
+
333
+ export type ImageUpload = {
334
+ contentType: string;
335
+ bytes: string;
336
+ };
337
+
338
+ export function CopilotChat({
339
+ instructions,
340
+ suggestions = "auto",
341
+ onSubmitMessage,
342
+ makeSystemMessage,
343
+ disableSystemMessage,
344
+ onInProgress,
345
+ onStopGeneration,
346
+ onReloadMessages,
347
+ onRegenerate,
348
+ onCopy,
349
+ onThumbsUp,
350
+ onThumbsDown,
351
+ markdownTagRenderers,
352
+ Messages = DefaultMessages,
353
+ RenderMessage = DefaultRenderMessage,
354
+ RenderSuggestionsList = DefaultRenderSuggestionsList,
355
+ Input = DefaultInput,
356
+ className,
357
+ icons,
358
+ labels,
359
+ AssistantMessage = DefaultAssistantMessage,
360
+ UserMessage = DefaultUserMessage,
361
+ ImageRenderer = DefaultImageRenderer,
362
+ ErrorMessage,
363
+ imageUploadsEnabled,
364
+ inputFileAccept = "image/*",
365
+ hideStopButton,
366
+ observabilityHooks,
367
+ renderError,
368
+ onError,
369
+ // Legacy props - deprecated
370
+ RenderTextMessage,
371
+ RenderActionExecutionMessage,
372
+ RenderAgentStateMessage,
373
+ RenderResultMessage,
374
+ RenderImageMessage,
375
+ }: CopilotChatProps) {
376
+ const {
377
+ additionalInstructions,
378
+ setChatInstructions,
379
+ copilotApiConfig,
380
+ setBannerError,
381
+ setInternalErrorHandler,
382
+ removeInternalErrorHandler,
383
+ } = useCopilotContext();
384
+
385
+ // Destructure stable values to avoid object reference changes
386
+ const { publicApiKey, chatApiEndpoint } = copilotApiConfig;
387
+ const [selectedImages, setSelectedImages] = useState<Array<ImageUpload>>([]);
388
+ const [chatError, setChatError] = useState<ChatError | null>(null);
389
+ const [messageFeedback, setMessageFeedback] = useState<Record<string, "thumbsUp" | "thumbsDown">>(
390
+ {},
391
+ );
392
+ const fileInputRef = useRef<HTMLInputElement>(null);
393
+
394
+ // Helper function to trigger event hooks only if publicApiKey is provided
395
+ const triggerObservabilityHook = useCallback(
396
+ (hookName: keyof CopilotObservabilityHooks, ...args: any[]) => {
397
+ if (publicApiKey && observabilityHooks?.[hookName]) {
398
+ (observabilityHooks[hookName] as any)(...args);
399
+ }
400
+ if (observabilityHooks?.[hookName] && !publicApiKey) {
401
+ setBannerError(
402
+ new CopilotKitError({
403
+ message: "observabilityHooks requires a publicApiKey to function.",
404
+ code: CopilotKitErrorCode.MISSING_PUBLIC_API_KEY_ERROR,
405
+ severity: Severity.CRITICAL,
406
+ visibility: ErrorVisibility.BANNER,
407
+ }),
408
+ );
409
+ styledConsole.publicApiKeyRequired("observabilityHooks");
410
+ }
411
+ },
412
+ [publicApiKey, observabilityHooks, setBannerError],
413
+ );
414
+
415
+ // Helper function to trigger chat error and render error UI
416
+ const triggerChatError = useCallback(
417
+ (error: any, operation: string, originalError?: any) => {
418
+ const errorMessage = error?.message || error?.toString() || "An error occurred";
419
+
420
+ // Set chat error state for rendering
421
+ setChatError({
422
+ message: errorMessage,
423
+ operation,
424
+ timestamp: Date.now(),
425
+ });
426
+
427
+ const errorEvent: CopilotErrorEvent = {
428
+ type: "error",
429
+ timestamp: Date.now(),
430
+ context: {
431
+ source: "ui",
432
+ request: {
433
+ operation,
434
+ url: chatApiEndpoint,
435
+ startTime: Date.now(),
436
+ },
437
+ technical: {
438
+ environment: "browser",
439
+ userAgent: typeof navigator !== "undefined" ? navigator.userAgent : undefined,
440
+ stackTrace: originalError instanceof Error ? originalError.stack : undefined,
441
+ },
442
+ },
443
+ error,
444
+ };
445
+
446
+ if (onError) {
447
+ onError(errorEvent);
448
+ }
449
+
450
+ // Also trigger observability hook if available
451
+ if (publicApiKey && observabilityHooks?.onError) {
452
+ observabilityHooks.onError(errorEvent);
453
+ }
454
+
455
+ // Show banner error if onError hook is used without publicApiKey
456
+ if (observabilityHooks?.onError && !publicApiKey) {
457
+ setBannerError(
458
+ new CopilotKitError({
459
+ message: "observabilityHooks.onError requires a publicApiKey to function.",
460
+ code: CopilotKitErrorCode.MISSING_PUBLIC_API_KEY_ERROR,
461
+ severity: Severity.CRITICAL,
462
+ visibility: ErrorVisibility.BANNER,
463
+ }),
464
+ );
465
+ styledConsole.publicApiKeyRequired("observabilityHooks.onError");
466
+ }
467
+ },
468
+ [publicApiKey, chatApiEndpoint, observabilityHooks, setBannerError],
469
+ );
470
+
471
+ useEffect(() => {
472
+ const id = "chat-component";
473
+ setInternalErrorHandler({
474
+ [id]: (error: CopilotErrorEvent) => {
475
+ if (!error) return;
476
+ triggerChatError(error.error, "sendMessage");
477
+ },
478
+ });
479
+ return () => {
480
+ // unregister when this instance unmounts
481
+ removeInternalErrorHandler?.(id);
482
+ };
483
+ }, [triggerChatError, setInternalErrorHandler, removeInternalErrorHandler]);
484
+
485
+ // Clipboard paste handler
486
+ useEffect(() => {
487
+ if (!imageUploadsEnabled) return;
488
+
489
+ const handlePaste = async (e: ClipboardEvent) => {
490
+ const target = e.target as HTMLElement;
491
+ if (!target.parentElement?.classList.contains("copilotKitInput")) return;
492
+
493
+ const items = Array.from(e.clipboardData?.items || []);
494
+ const imageItems = items.filter((item) => item.type.startsWith("image/"));
495
+
496
+ if (imageItems.length === 0) return;
497
+
498
+ e.preventDefault(); // Prevent default paste behavior for images
499
+
500
+ const imagePromises: Promise<ImageUpload | null>[] = imageItems.map((item) => {
501
+ const file = item.getAsFile();
502
+ if (!file) return Promise.resolve(null);
503
+
504
+ return new Promise<ImageUpload | null>((resolve, reject) => {
505
+ const reader = new FileReader();
506
+ reader.onload = (e) => {
507
+ const base64String = (e.target?.result as string)?.split(",")[1];
508
+ if (base64String) {
509
+ resolve({
510
+ contentType: file.type,
511
+ bytes: base64String,
512
+ });
513
+ } else {
514
+ resolve(null);
515
+ }
516
+ };
517
+ reader.onerror = reject;
518
+ reader.readAsDataURL(file);
519
+ });
520
+ });
521
+
522
+ try {
523
+ const loadedImages = (await Promise.all(imagePromises)).filter((img) => img !== null);
524
+ setSelectedImages((prev) => [...prev, ...loadedImages]);
525
+ } catch (error) {
526
+ // Trigger chat-level error handler
527
+ triggerChatError(error, "processClipboardImages", error);
528
+ console.error("Error processing pasted images:", error);
529
+ }
530
+ };
531
+
532
+ document.addEventListener("paste", handlePaste);
533
+ return () => document.removeEventListener("paste", handlePaste);
534
+ }, [imageUploadsEnabled, triggerChatError]);
535
+
536
+ useEffect(() => {
537
+ if (!additionalInstructions?.length) {
538
+ setChatInstructions(instructions || "");
539
+ return;
540
+ }
541
+
542
+ /*
543
+ Will result in a prompt like:
544
+
545
+ You are a helpful assistant.
546
+ Additionally, follow these instructions:
547
+ - Do not answer questions about the weather.
548
+ - Do not answer questions about the stock market."
549
+ */
550
+ const combinedAdditionalInstructions = [
551
+ instructions,
552
+ "Additionally, follow these instructions:",
553
+ ...additionalInstructions.map((instruction) => `- ${instruction}`),
554
+ ];
555
+
556
+ setChatInstructions(combinedAdditionalInstructions.join("\n") || "");
557
+ }, [instructions, additionalInstructions]);
558
+
559
+ const {
560
+ messages,
561
+ isLoading,
562
+ sendMessage,
563
+ stopGeneration,
564
+ reloadMessages,
565
+ suggestions: currentSuggestions,
566
+ isLoadingSuggestions,
567
+ agent,
568
+ } = useCopilotChatInternal({
569
+ suggestions,
570
+ onInProgress,
571
+ onSubmitMessage,
572
+ onStopGeneration,
573
+ onReloadMessages,
574
+ });
575
+ // makeSystemMessage,
576
+ // disableSystemMessage,
577
+
578
+ // Track loading state changes for chat start/stop events
579
+ const prevIsLoading = useRef(isLoading);
580
+ useEffect(() => {
581
+ if (prevIsLoading.current !== isLoading) {
582
+ if (isLoading) {
583
+ triggerObservabilityHook("onChatStarted");
584
+ } else {
585
+ triggerObservabilityHook("onChatStopped");
586
+ }
587
+ prevIsLoading.current = isLoading;
588
+ }
589
+ }, [isLoading, triggerObservabilityHook]);
590
+
591
+ // Wrapper for sendMessage to clear selected images
592
+ const handleSendMessage = (text: string) => {
593
+ const images = selectedImages;
594
+ setSelectedImages([]);
595
+ if (fileInputRef.current) {
596
+ fileInputRef.current.value = "";
597
+ }
598
+
599
+ // Trigger message sent event
600
+ triggerObservabilityHook("onMessageSent", text);
601
+
602
+ // TODO: send images?
603
+ return sendMessage({
604
+ id: randomUUID(),
605
+ content: text,
606
+ role: "user",
607
+ });
608
+ };
609
+
610
+ const chatContext = React.useContext(ChatContext);
611
+ const isVisible = chatContext ? chatContext.open : true;
612
+
613
+ const handleRegenerate = (messageId: string) => {
614
+ if (onRegenerate) {
615
+ onRegenerate(messageId);
616
+ }
617
+
618
+ // Trigger message regenerated event
619
+ triggerObservabilityHook("onMessageRegenerated", messageId);
620
+
621
+ reloadMessages(messageId);
622
+ };
623
+
624
+ const handleCopy = (message: string) => {
625
+ if (onCopy) {
626
+ onCopy(message);
627
+ }
628
+
629
+ // Trigger message copied event
630
+ triggerObservabilityHook("onMessageCopied", message);
631
+ };
632
+
633
+ const handleImageUpload = async (event: React.ChangeEvent<HTMLInputElement>) => {
634
+ if (!event.target.files || event.target.files.length === 0) {
635
+ return;
636
+ }
637
+
638
+ const files = Array.from(event.target.files).filter((file) => file.type.startsWith("image/"));
639
+ if (files.length === 0) return;
640
+
641
+ const fileReadPromises = files.map((file) => {
642
+ return new Promise<{ contentType: string; bytes: string }>((resolve, reject) => {
643
+ const reader = new FileReader();
644
+ reader.onload = (e) => {
645
+ const base64String = (e.target?.result as string)?.split(",")[1] || "";
646
+ if (base64String) {
647
+ resolve({
648
+ contentType: file.type,
649
+ bytes: base64String,
650
+ });
651
+ }
652
+ };
653
+ reader.onerror = reject;
654
+ reader.readAsDataURL(file);
655
+ });
656
+ });
657
+
658
+ try {
659
+ const loadedImages = await Promise.all(fileReadPromises);
660
+ setSelectedImages((prev) => [...prev, ...loadedImages]);
661
+ } catch (error) {
662
+ // Trigger chat-level error handler
663
+ triggerChatError(error, "processUploadedImages", error);
664
+ console.error("Error reading files:", error);
665
+ }
666
+ };
667
+
668
+ const removeSelectedImage = (index: number) => {
669
+ setSelectedImages((prev) => prev.filter((_, i) => i !== index));
670
+ };
671
+
672
+ const handleThumbsUp = (message: Message) => {
673
+ if (onThumbsUp) {
674
+ onThumbsUp(message);
675
+ }
676
+
677
+ // Update feedback state
678
+ setMessageFeedback((prev) => ({
679
+ ...prev,
680
+ [message.id]: "thumbsUp",
681
+ }));
682
+
683
+ // Trigger feedback given event
684
+ triggerObservabilityHook("onFeedbackGiven", message.id, "thumbsUp");
685
+ };
686
+
687
+ const handleThumbsDown = (message: Message) => {
688
+ if (onThumbsDown) {
689
+ onThumbsDown(message);
690
+ }
691
+
692
+ // Update feedback state
693
+ setMessageFeedback((prev) => ({
694
+ ...prev,
695
+ [message.id]: "thumbsDown",
696
+ }));
697
+
698
+ // Trigger feedback given event
699
+ triggerObservabilityHook("onFeedbackGiven", message.id, "thumbsDown");
700
+ };
701
+
702
+ return (
703
+ <WrappedCopilotChat icons={icons} labels={labels} className={className}>
704
+ {/* Render error above messages if present */}
705
+ {chatError &&
706
+ renderError &&
707
+ renderError({
708
+ ...chatError,
709
+ onDismiss: () => setChatError(null),
710
+ onRetry: () => {
711
+ // Clear error and potentially retry based on operation
712
+ setChatError(null);
713
+ // TODO: Implement specific retry logic based on operation type
714
+ },
715
+ })}
716
+
717
+ <Messages
718
+ AssistantMessage={AssistantMessage}
719
+ UserMessage={UserMessage}
720
+ RenderMessage={RenderMessage}
721
+ messages={messages}
722
+ inProgress={isLoading}
723
+ onRegenerate={handleRegenerate}
724
+ onCopy={handleCopy}
725
+ onThumbsUp={handleThumbsUp}
726
+ onThumbsDown={handleThumbsDown}
727
+ messageFeedback={messageFeedback}
728
+ markdownTagRenderers={markdownTagRenderers}
729
+ ImageRenderer={ImageRenderer}
730
+ ErrorMessage={ErrorMessage}
731
+ chatError={chatError}
732
+ // Legacy props - passed through to Messages component
733
+ RenderTextMessage={RenderTextMessage}
734
+ RenderActionExecutionMessage={RenderActionExecutionMessage}
735
+ RenderAgentStateMessage={RenderAgentStateMessage}
736
+ RenderResultMessage={RenderResultMessage}
737
+ RenderImageMessage={RenderImageMessage}
738
+ >
739
+ {currentSuggestions.length > 0 && (
740
+ <RenderSuggestionsList
741
+ onSuggestionClick={handleSendMessage}
742
+ suggestions={currentSuggestions}
743
+ isLoading={isLoadingSuggestions}
744
+ />
745
+ )}
746
+ </Messages>
747
+
748
+ {imageUploadsEnabled && (
749
+ <>
750
+ <ImageUploadQueue images={selectedImages} onRemoveImage={removeSelectedImage} />
751
+ <input
752
+ type="file"
753
+ multiple
754
+ ref={fileInputRef}
755
+ onChange={handleImageUpload}
756
+ accept={inputFileAccept}
757
+ style={{ display: "none" }}
758
+ />
759
+ </>
760
+ )}
761
+ <Input
762
+ inProgress={isLoading}
763
+ chatReady={Boolean(agent)}
764
+ // @ts-ignore
765
+ onSend={handleSendMessage}
766
+ isVisible={isVisible}
767
+ onStop={stopGeneration}
768
+ onUpload={imageUploadsEnabled ? () => fileInputRef.current?.click() : undefined}
769
+ hideStopButton={hideStopButton}
770
+ />
771
+ </WrappedCopilotChat>
772
+ );
773
+ }
774
+
775
+ export function WrappedCopilotChat({
776
+ children,
777
+ icons,
778
+ labels,
779
+ className,
780
+ }: {
781
+ children: React.ReactNode;
782
+ icons?: CopilotChatIcons;
783
+ labels?: CopilotChatLabels;
784
+ className?: string;
785
+ }) {
786
+ const chatContext = React.useContext(ChatContext);
787
+ if (!chatContext) {
788
+ return (
789
+ <ChatContextProvider icons={icons} labels={labels} open={true} setOpen={() => {}}>
790
+ <div className={`copilotKitChat ${className ?? ""}`}>{children}</div>
791
+ </ChatContextProvider>
792
+ );
793
+ }
794
+ return <>{children}</>;
795
+ }