@copilotkit/react-ui 1.8.6 → 1.8.7

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 (149) hide show
  1. package/CHANGELOG.md +20 -0
  2. package/dist/{chunk-Q2YY2NX3.mjs → chunk-24TDU7MY.mjs} +2 -2
  3. package/dist/{chunk-XNQO5AZZ.mjs → chunk-ABHUX6T6.mjs} +2 -2
  4. package/dist/{chunk-QJKMOGWN.mjs → chunk-BDNHZ3GW.mjs} +4 -3
  5. package/dist/chunk-BDNHZ3GW.mjs.map +1 -0
  6. package/dist/{chunk-NMNC4ROZ.mjs → chunk-DSQGQJI4.mjs} +2 -2
  7. package/dist/{chunk-HEIDCT7I.mjs → chunk-HWMFMBJC.mjs} +2 -2
  8. package/dist/chunk-HWMFMBJC.mjs.map +1 -0
  9. package/dist/{chunk-UN2E3HCK.mjs → chunk-IEMQ2SQW.mjs} +6 -4
  10. package/dist/chunk-IEMQ2SQW.mjs.map +1 -0
  11. package/dist/{chunk-ZY25LVYR.mjs → chunk-IJADIQAR.mjs} +20 -2
  12. package/dist/chunk-IJADIQAR.mjs.map +1 -0
  13. package/dist/{chunk-X6EFGEBJ.mjs → chunk-JOL7NS2W.mjs} +2 -2
  14. package/dist/{chunk-PCTCOQK2.mjs → chunk-KENCH7RN.mjs} +2 -2
  15. package/dist/{chunk-ZLRUNNS7.mjs → chunk-O34Z4XM2.mjs} +170 -30
  16. package/dist/chunk-O34Z4XM2.mjs.map +1 -0
  17. package/dist/{chunk-5M7ODWKH.mjs → chunk-OZXUB3V7.mjs} +3 -3
  18. package/dist/chunk-PLHTVHUW.mjs +82 -0
  19. package/dist/chunk-PLHTVHUW.mjs.map +1 -0
  20. package/dist/{chunk-62QMTKMJ.mjs → chunk-POWCBXRY.mjs} +3 -3
  21. package/dist/chunk-PXEVB7IK.mjs +1 -0
  22. package/dist/{chunk-HIORSNVD.mjs → chunk-Q2NFQTCQ.mjs} +2 -2
  23. package/dist/chunk-SLTG4L62.mjs +78 -0
  24. package/dist/chunk-SLTG4L62.mjs.map +1 -0
  25. package/dist/{chunk-SMJ3QQCE.mjs → chunk-T7N77F5Y.mjs} +2 -2
  26. package/dist/{chunk-YOEL33HG.mjs → chunk-UFN2VWSR.mjs} +2 -2
  27. package/dist/{chunk-2OTVZXDX.mjs → chunk-UH2UFL5W.mjs} +3 -3
  28. package/dist/{chunk-D5XIJNXQ.mjs → chunk-VGPQYMKJ.mjs} +8 -8
  29. package/dist/{chunk-WNC6OCIB.mjs → chunk-XFCMZH2H.mjs} +2 -2
  30. package/dist/{chunk-ORSMX3SE.mjs → chunk-XWG3L6QC.mjs} +15 -1
  31. package/dist/{chunk-ORSMX3SE.mjs.map → chunk-XWG3L6QC.mjs.map} +1 -1
  32. package/dist/{chunk-TOQ7P4DO.mjs → chunk-XZNY26GH.mjs} +2 -2
  33. package/dist/{chunk-GOAED4H6.mjs → chunk-Y7UO3RPW.mjs} +10 -10
  34. package/dist/components/chat/Button.js.map +1 -1
  35. package/dist/components/chat/Button.mjs +3 -3
  36. package/dist/components/chat/Chat.d.ts +23 -3
  37. package/dist/components/chat/Chat.js +341 -30
  38. package/dist/components/chat/Chat.js.map +1 -1
  39. package/dist/components/chat/Chat.mjs +16 -14
  40. package/dist/components/chat/ChatContext.d.ts +5 -0
  41. package/dist/components/chat/ChatContext.js +15 -1
  42. package/dist/components/chat/ChatContext.js.map +1 -1
  43. package/dist/components/chat/ChatContext.mjs +2 -2
  44. package/dist/components/chat/CodeBlock.js.map +1 -1
  45. package/dist/components/chat/CodeBlock.mjs +2 -2
  46. package/dist/components/chat/Header.js.map +1 -1
  47. package/dist/components/chat/Header.mjs +5 -5
  48. package/dist/components/chat/Icons.d.ts +2 -1
  49. package/dist/components/chat/Icons.js +17 -2
  50. package/dist/components/chat/Icons.js.map +1 -1
  51. package/dist/components/chat/Icons.mjs +5 -3
  52. package/dist/components/chat/ImageUploadQueue.d.ts +13 -0
  53. package/dist/components/chat/ImageUploadQueue.js +106 -0
  54. package/dist/components/chat/ImageUploadQueue.js.map +1 -0
  55. package/dist/components/chat/ImageUploadQueue.mjs +8 -0
  56. package/dist/components/chat/ImageUploadQueue.mjs.map +1 -0
  57. package/dist/components/chat/Input.d.ts +1 -1
  58. package/dist/components/chat/Input.js +2 -1
  59. package/dist/components/chat/Input.js.map +1 -1
  60. package/dist/components/chat/Input.mjs +3 -3
  61. package/dist/components/chat/Markdown.js.map +1 -1
  62. package/dist/components/chat/Markdown.mjs +3 -3
  63. package/dist/components/chat/Messages.d.ts +1 -1
  64. package/dist/components/chat/Messages.js +18 -0
  65. package/dist/components/chat/Messages.js.map +1 -1
  66. package/dist/components/chat/Messages.mjs +3 -3
  67. package/dist/components/chat/Modal.js +348 -37
  68. package/dist/components/chat/Modal.js.map +1 -1
  69. package/dist/components/chat/Modal.mjs +22 -20
  70. package/dist/components/chat/Popup.js +350 -39
  71. package/dist/components/chat/Popup.js.map +1 -1
  72. package/dist/components/chat/Popup.mjs +23 -21
  73. package/dist/components/chat/Sidebar.js +350 -39
  74. package/dist/components/chat/Sidebar.js.map +1 -1
  75. package/dist/components/chat/Sidebar.mjs +23 -21
  76. package/dist/components/chat/Suggestion.js.map +1 -1
  77. package/dist/components/chat/Suggestion.mjs +2 -2
  78. package/dist/components/chat/Window.js.map +1 -1
  79. package/dist/components/chat/Window.mjs +3 -3
  80. package/dist/components/chat/index.d.ts +1 -0
  81. package/dist/components/chat/index.js +354 -41
  82. package/dist/components/chat/index.js.map +1 -1
  83. package/dist/components/chat/index.mjs +30 -25
  84. package/dist/components/chat/messages/AssistantMessage.js.map +1 -1
  85. package/dist/components/chat/messages/AssistantMessage.mjs +5 -5
  86. package/dist/components/chat/messages/RenderActionExecutionMessage.js.map +1 -1
  87. package/dist/components/chat/messages/RenderActionExecutionMessage.mjs +6 -6
  88. package/dist/components/chat/messages/RenderAgentStateMessage.js.map +1 -1
  89. package/dist/components/chat/messages/RenderAgentStateMessage.mjs +6 -6
  90. package/dist/components/chat/messages/RenderImageMessage.d.ts +7 -0
  91. package/dist/components/chat/messages/RenderImageMessage.js +774 -0
  92. package/dist/components/chat/messages/RenderImageMessage.js.map +1 -0
  93. package/dist/components/chat/messages/RenderImageMessage.mjs +15 -0
  94. package/dist/components/chat/messages/RenderImageMessage.mjs.map +1 -0
  95. package/dist/components/chat/messages/RenderResultMessage.js.map +1 -1
  96. package/dist/components/chat/messages/RenderResultMessage.mjs +6 -6
  97. package/dist/components/chat/messages/RenderTextMessage.js +1 -1
  98. package/dist/components/chat/messages/RenderTextMessage.js.map +1 -1
  99. package/dist/components/chat/messages/RenderTextMessage.mjs +7 -7
  100. package/dist/components/chat/messages/UserMessage.js +1 -1
  101. package/dist/components/chat/messages/UserMessage.js.map +1 -1
  102. package/dist/components/chat/messages/UserMessage.mjs +1 -1
  103. package/dist/components/chat/props.d.ts +3 -0
  104. package/dist/components/chat/props.js.map +1 -1
  105. package/dist/components/dev-console/console.js.map +1 -1
  106. package/dist/components/dev-console/console.mjs +3 -3
  107. package/dist/components/dev-console/index.js.map +1 -1
  108. package/dist/components/dev-console/index.mjs +3 -3
  109. package/dist/components/index.d.ts +1 -0
  110. package/dist/components/index.js +354 -41
  111. package/dist/components/index.js.map +1 -1
  112. package/dist/components/index.mjs +30 -25
  113. package/dist/index.d.ts +1 -0
  114. package/dist/index.js +354 -41
  115. package/dist/index.js.map +1 -1
  116. package/dist/index.mjs +30 -25
  117. package/package.json +6 -6
  118. package/src/components/chat/Chat.tsx +198 -18
  119. package/src/components/chat/ChatContext.tsx +7 -0
  120. package/src/components/chat/Icons.tsx +14 -0
  121. package/src/components/chat/ImageUploadQueue.tsx +77 -0
  122. package/src/components/chat/Input.tsx +8 -1
  123. package/src/components/chat/Messages.tsx +17 -0
  124. package/src/components/chat/index.tsx +1 -0
  125. package/src/components/chat/messages/RenderImageMessage.tsx +64 -0
  126. package/src/components/chat/messages/UserMessage.tsx +5 -1
  127. package/src/components/chat/props.ts +3 -0
  128. package/dist/chunk-HEIDCT7I.mjs.map +0 -1
  129. package/dist/chunk-QJKMOGWN.mjs.map +0 -1
  130. package/dist/chunk-SQMEPWVT.mjs +0 -1
  131. package/dist/chunk-UN2E3HCK.mjs.map +0 -1
  132. package/dist/chunk-ZLRUNNS7.mjs.map +0 -1
  133. package/dist/chunk-ZY25LVYR.mjs.map +0 -1
  134. /package/dist/{chunk-Q2YY2NX3.mjs.map → chunk-24TDU7MY.mjs.map} +0 -0
  135. /package/dist/{chunk-XNQO5AZZ.mjs.map → chunk-ABHUX6T6.mjs.map} +0 -0
  136. /package/dist/{chunk-NMNC4ROZ.mjs.map → chunk-DSQGQJI4.mjs.map} +0 -0
  137. /package/dist/{chunk-X6EFGEBJ.mjs.map → chunk-JOL7NS2W.mjs.map} +0 -0
  138. /package/dist/{chunk-PCTCOQK2.mjs.map → chunk-KENCH7RN.mjs.map} +0 -0
  139. /package/dist/{chunk-5M7ODWKH.mjs.map → chunk-OZXUB3V7.mjs.map} +0 -0
  140. /package/dist/{chunk-62QMTKMJ.mjs.map → chunk-POWCBXRY.mjs.map} +0 -0
  141. /package/dist/{chunk-SQMEPWVT.mjs.map → chunk-PXEVB7IK.mjs.map} +0 -0
  142. /package/dist/{chunk-HIORSNVD.mjs.map → chunk-Q2NFQTCQ.mjs.map} +0 -0
  143. /package/dist/{chunk-SMJ3QQCE.mjs.map → chunk-T7N77F5Y.mjs.map} +0 -0
  144. /package/dist/{chunk-YOEL33HG.mjs.map → chunk-UFN2VWSR.mjs.map} +0 -0
  145. /package/dist/{chunk-2OTVZXDX.mjs.map → chunk-UH2UFL5W.mjs.map} +0 -0
  146. /package/dist/{chunk-D5XIJNXQ.mjs.map → chunk-VGPQYMKJ.mjs.map} +0 -0
  147. /package/dist/{chunk-WNC6OCIB.mjs.map → chunk-XFCMZH2H.mjs.map} +0 -0
  148. /package/dist/{chunk-TOQ7P4DO.mjs.map → chunk-XZNY26GH.mjs.map} +0 -0
  149. /package/dist/{chunk-GOAED4H6.mjs.map → chunk-Y7UO3RPW.mjs.map} +0 -0
@@ -59,6 +59,15 @@ interface CopilotChatProps {
59
59
  * Labels can be used to set custom labels for the chat window.
60
60
  */
61
61
  labels?: CopilotChatLabels;
62
+ /**
63
+ * Enable image upload button (image inputs only supported on some models)
64
+ */
65
+ imageUploadsEnabled?: boolean;
66
+ /**
67
+ * The 'accept' attribute for the file input used for image uploads.
68
+ * Defaults to "image/*".
69
+ */
70
+ inputFileAccept?: string;
62
71
  /**
63
72
  * A function that takes in context string and instructions and returns
64
73
  * the system message to include in the chat request.
@@ -94,6 +103,10 @@ interface CopilotChatProps {
94
103
  * A custom RenderResultMessage component to use instead of the default.
95
104
  */
96
105
  RenderResultMessage?: React__default.ComponentType<RenderMessageProps>;
106
+ /**
107
+ * A custom RenderImageMessage component to use instead of the default.
108
+ */
109
+ RenderImageMessage?: React__default.ComponentType<RenderMessageProps>;
97
110
  /**
98
111
  * A custom Input component to use instead of the default.
99
112
  */
@@ -149,7 +162,11 @@ type OnReloadMessagesArguments = OnStopGenerationArguments & {
149
162
  };
150
163
  type OnStopGeneration = (args: OnStopGenerationArguments) => void;
151
164
  type OnReloadMessages = (args: OnReloadMessagesArguments) => void;
152
- declare function CopilotChat({ instructions, onSubmitMessage, makeSystemMessage, onInProgress, onStopGeneration, onReloadMessages, onRegenerate, onCopy, onThumbsUp, onThumbsDown, Messages, RenderTextMessage, RenderActionExecutionMessage, RenderAgentStateMessage, RenderResultMessage, Input, className, icons, labels, AssistantMessage, UserMessage, }: CopilotChatProps): react_jsx_runtime.JSX.Element;
165
+ type ImageUpload = {
166
+ contentType: string;
167
+ bytes: string;
168
+ };
169
+ declare function CopilotChat({ instructions, onSubmitMessage, makeSystemMessage, onInProgress, onStopGeneration, onReloadMessages, onRegenerate, onCopy, onThumbsUp, onThumbsDown, Messages, RenderTextMessage, RenderActionExecutionMessage, RenderAgentStateMessage, RenderResultMessage, RenderImageMessage, Input, className, icons, labels, AssistantMessage, UserMessage, imageUploadsEnabled, inputFileAccept, }: CopilotChatProps): react_jsx_runtime.JSX.Element;
153
170
  declare function WrappedCopilotChat({ children, icons, labels, className, }: {
154
171
  children: React__default.ReactNode;
155
172
  icons?: CopilotChatIcons;
@@ -160,9 +177,12 @@ declare const useCopilotChatLogic: (makeSystemMessage?: SystemMessageFunction, o
160
177
  visibleMessages: Message[];
161
178
  isLoading: boolean;
162
179
  currentSuggestions: CopilotChatSuggestion[];
163
- sendMessage: (messageContent: string) => Promise<Message>;
180
+ sendMessage: (messageContent: string, imagesToUse?: Array<{
181
+ contentType: string;
182
+ bytes: string;
183
+ }>) => Promise<Message>;
164
184
  stopGeneration: () => void;
165
185
  reloadMessages: (messageId: string) => void;
166
186
  };
167
187
 
168
- export { CopilotChat, CopilotChatProps, OnReloadMessages, OnReloadMessagesArguments, OnStopGeneration, WrappedCopilotChat, useCopilotChatLogic };
188
+ export { CopilotChat, CopilotChatProps, ImageUpload, OnReloadMessages, OnReloadMessagesArguments, OnStopGeneration, WrappedCopilotChat, useCopilotChatLogic };
@@ -299,6 +299,19 @@ var DownloadIcon = /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
299
299
  )
300
300
  }
301
301
  );
302
+ var UploadIcon = /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
303
+ "svg",
304
+ {
305
+ xmlns: "http://www.w3.org/2000/svg",
306
+ fill: "none",
307
+ viewBox: "0 0 24 24",
308
+ strokeWidth: "1.5",
309
+ stroke: "currentColor",
310
+ width: "24",
311
+ height: "24",
312
+ children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)("path", { strokeLinecap: "round", strokeLinejoin: "round", d: "M12 4.5v15m7.5-7.5h-15" })
313
+ }
314
+ );
302
315
  var CheckIcon = /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
303
316
  "svg",
304
317
  {
@@ -364,7 +377,8 @@ var ChatContextProvider = ({
364
377
  pushToTalkIcon: MicrophoneIcon,
365
378
  copyIcon: CopyIcon,
366
379
  thumbsUpIcon: ThumbsUpIcon,
367
- thumbsDownIcon: ThumbsDownIcon
380
+ thumbsDownIcon: ThumbsDownIcon,
381
+ uploadIcon: UploadIcon
368
382
  }), icons),
369
383
  [icons]
370
384
  );
@@ -393,6 +407,7 @@ var Messages = ({
393
407
  RenderActionExecutionMessage: RenderActionExecutionMessage2,
394
408
  RenderAgentStateMessage: RenderAgentStateMessage2,
395
409
  RenderResultMessage: RenderResultMessage2,
410
+ RenderImageMessage: RenderImageMessage2,
396
411
  AssistantMessage: AssistantMessage2,
397
412
  UserMessage: UserMessage2,
398
413
  onRegenerate,
@@ -481,6 +496,23 @@ var Messages = ({
481
496
  },
482
497
  index
483
498
  );
499
+ } else if (message.isImageMessage && message.isImageMessage()) {
500
+ return /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
501
+ RenderImageMessage2,
502
+ {
503
+ message,
504
+ inProgress,
505
+ index,
506
+ isCurrentMessage,
507
+ AssistantMessage: AssistantMessage2,
508
+ UserMessage: UserMessage2,
509
+ onRegenerate,
510
+ onCopy,
511
+ onThumbsUp,
512
+ onThumbsDown
513
+ },
514
+ index
515
+ );
484
516
  }
485
517
  }),
486
518
  interrupt
@@ -723,7 +755,7 @@ var usePushToTalk = ({
723
755
  // src/components/chat/Input.tsx
724
756
  var import_react_core3 = require("@copilotkit/react-core");
725
757
  var import_jsx_runtime5 = require("react/jsx-runtime");
726
- var Input = ({ inProgress, onSend, isVisible = false, onStop }) => {
758
+ var Input = ({ inProgress, onSend, isVisible = false, onStop, onUpload }) => {
727
759
  const context = useChatContext();
728
760
  const copilotContext = (0, import_react_core3.useCopilotContext)();
729
761
  const pushToTalkConfigured = copilotContext.copilotApiConfig.textToSpeechUrl !== void 0 && copilotContext.copilotApiConfig.transcribeAudioUrl !== void 0;
@@ -787,6 +819,7 @@ var Input = ({ inProgress, onSend, isVisible = false, onStop }) => {
787
819
  }
788
820
  ),
789
821
  /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("div", { className: "copilotKitInputControls", children: [
822
+ onUpload && /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("button", { onClick: onUpload, className: "copilotKitInputControlButton", children: context.icons.uploadIcon }),
790
823
  /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("div", { style: { flexGrow: 1 } }),
791
824
  showPushToTalk && /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
792
825
  "button",
@@ -814,7 +847,7 @@ var Input = ({ inProgress, onSend, isVisible = false, onStop }) => {
814
847
  // src/components/chat/messages/UserMessage.tsx
815
848
  var import_jsx_runtime6 = require("react/jsx-runtime");
816
849
  var UserMessage = (props) => {
817
- return /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("div", { className: "copilotKitMessage copilotKitUserMessage", children: props.message });
850
+ return /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("div", { className: "copilotKitMessage copilotKitUserMessage", children: props.subComponent || props.message });
818
851
  };
819
852
 
820
853
  // src/components/chat/Markdown.tsx
@@ -1668,13 +1701,77 @@ function RenderAgentStateMessage(_a) {
1668
1701
  }
1669
1702
  }
1670
1703
 
1704
+ // src/components/chat/messages/RenderImageMessage.tsx
1705
+ var import_jsx_runtime14 = require("react/jsx-runtime");
1706
+ function RenderImageMessage(_a) {
1707
+ var _b = _a, {
1708
+ UserMessage: UserMessage2 = UserMessage,
1709
+ AssistantMessage: AssistantMessage2 = AssistantMessage
1710
+ } = _b, props = __objRest(_b, [
1711
+ "UserMessage",
1712
+ "AssistantMessage"
1713
+ ]);
1714
+ const {
1715
+ message,
1716
+ inProgress,
1717
+ index,
1718
+ isCurrentMessage,
1719
+ onRegenerate,
1720
+ onCopy,
1721
+ onThumbsUp,
1722
+ onThumbsDown
1723
+ } = props;
1724
+ if (message.isImageMessage()) {
1725
+ const imageData = `data:${message.format};base64,${message.bytes}`;
1726
+ const imageComponent = /* @__PURE__ */ (0, import_jsx_runtime14.jsx)("div", { className: "copilotKitImage", children: /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
1727
+ "img",
1728
+ {
1729
+ src: imageData,
1730
+ alt: "User uploaded image",
1731
+ style: { maxWidth: "100%", maxHeight: "300px", borderRadius: "8px" }
1732
+ }
1733
+ ) });
1734
+ if (message.role === "user") {
1735
+ return /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
1736
+ UserMessage2,
1737
+ {
1738
+ "data-message-role": "user",
1739
+ message: "",
1740
+ rawData: message,
1741
+ subComponent: imageComponent
1742
+ },
1743
+ index
1744
+ );
1745
+ } else if (message.role === "assistant") {
1746
+ return /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
1747
+ AssistantMessage2,
1748
+ {
1749
+ "data-message-role": "assistant",
1750
+ message: "",
1751
+ rawData: message,
1752
+ subComponent: imageComponent,
1753
+ isLoading: inProgress && isCurrentMessage && !message.bytes,
1754
+ isGenerating: inProgress && isCurrentMessage && !!message.bytes,
1755
+ isCurrentMessage,
1756
+ onRegenerate: () => onRegenerate == null ? void 0 : onRegenerate(message.id),
1757
+ onCopy,
1758
+ onThumbsUp,
1759
+ onThumbsDown
1760
+ },
1761
+ index
1762
+ );
1763
+ }
1764
+ }
1765
+ return null;
1766
+ }
1767
+
1671
1768
  // src/components/chat/Suggestion.tsx
1672
1769
  var import_react_core6 = require("@copilotkit/react-core");
1673
1770
  var import_shared = require("@copilotkit/shared");
1674
1771
  var import_runtime_client_gql3 = require("@copilotkit/runtime-client-gql");
1675
- var import_jsx_runtime14 = require("react/jsx-runtime");
1772
+ var import_jsx_runtime15 = require("react/jsx-runtime");
1676
1773
  function Suggestion({ title, message, onClick, partial, className }) {
1677
- return /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
1774
+ return /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(
1678
1775
  "button",
1679
1776
  {
1680
1777
  disabled: partial,
@@ -1684,7 +1781,7 @@ function Suggestion({ title, message, onClick, partial, className }) {
1684
1781
  },
1685
1782
  className: className || (partial ? "suggestion loading" : "suggestion"),
1686
1783
  "data-test-id": "suggestion",
1687
- children: partial ? SmallSpinnerIcon : /* @__PURE__ */ (0, import_jsx_runtime14.jsx)("span", { children: title })
1784
+ children: partial ? SmallSpinnerIcon : /* @__PURE__ */ (0, import_jsx_runtime15.jsx)("span", { children: title })
1688
1785
  }
1689
1786
  );
1690
1787
  }
@@ -1764,7 +1861,87 @@ var import_react_core7 = require("@copilotkit/react-core");
1764
1861
  var import_runtime_client_gql4 = require("@copilotkit/runtime-client-gql");
1765
1862
  var import_shared2 = require("@copilotkit/shared");
1766
1863
  var import_react_core8 = require("@copilotkit/react-core");
1767
- var import_jsx_runtime15 = require("react/jsx-runtime");
1864
+
1865
+ // src/components/chat/ImageUploadQueue.tsx
1866
+ var import_jsx_runtime16 = require("react/jsx-runtime");
1867
+ var ImageUploadQueue = ({
1868
+ images,
1869
+ onRemoveImage,
1870
+ className = ""
1871
+ }) => {
1872
+ if (images.length === 0)
1873
+ return null;
1874
+ return /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
1875
+ "div",
1876
+ {
1877
+ className: `copilotKitImageUploadQueue ${className}`,
1878
+ style: {
1879
+ display: "flex",
1880
+ flexWrap: "wrap",
1881
+ gap: "8px",
1882
+ margin: "8px",
1883
+ padding: "8px"
1884
+ },
1885
+ children: images.map((image, index) => /* @__PURE__ */ (0, import_jsx_runtime16.jsxs)(
1886
+ "div",
1887
+ {
1888
+ className: "copilotKitImageUploadQueueItem",
1889
+ style: {
1890
+ position: "relative",
1891
+ display: "inline-block",
1892
+ width: "60px",
1893
+ height: "60px",
1894
+ borderRadius: "4px",
1895
+ overflow: "hidden"
1896
+ },
1897
+ children: [
1898
+ /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
1899
+ "img",
1900
+ {
1901
+ src: `data:${image.contentType};base64,${image.bytes}`,
1902
+ alt: `Selected image ${index + 1}`,
1903
+ style: {
1904
+ width: "100%",
1905
+ height: "100%",
1906
+ objectFit: "cover"
1907
+ }
1908
+ }
1909
+ ),
1910
+ /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
1911
+ "button",
1912
+ {
1913
+ onClick: () => onRemoveImage(index),
1914
+ className: "copilotKitImageUploadQueueRemoveButton",
1915
+ style: {
1916
+ position: "absolute",
1917
+ top: "2px",
1918
+ right: "2px",
1919
+ background: "rgba(0,0,0,0.6)",
1920
+ color: "white",
1921
+ border: "none",
1922
+ borderRadius: "50%",
1923
+ width: "18px",
1924
+ height: "18px",
1925
+ display: "flex",
1926
+ alignItems: "center",
1927
+ justifyContent: "center",
1928
+ cursor: "pointer",
1929
+ fontSize: "10px",
1930
+ padding: 0
1931
+ },
1932
+ children: "\u2715"
1933
+ }
1934
+ )
1935
+ ]
1936
+ },
1937
+ index
1938
+ ))
1939
+ }
1940
+ );
1941
+ };
1942
+
1943
+ // src/components/chat/Chat.tsx
1944
+ var import_jsx_runtime17 = require("react/jsx-runtime");
1768
1945
  function CopilotChat({
1769
1946
  instructions,
1770
1947
  onSubmitMessage,
@@ -1781,14 +1958,64 @@ function CopilotChat({
1781
1958
  RenderActionExecutionMessage: RenderActionExecutionMessage2 = RenderActionExecutionMessage,
1782
1959
  RenderAgentStateMessage: RenderAgentStateMessage2 = RenderAgentStateMessage,
1783
1960
  RenderResultMessage: RenderResultMessage2 = RenderResultMessage,
1961
+ RenderImageMessage: RenderImageMessage2 = RenderImageMessage,
1784
1962
  Input: Input2 = Input,
1785
1963
  className,
1786
1964
  icons,
1787
1965
  labels,
1788
1966
  AssistantMessage: AssistantMessage2 = AssistantMessage,
1789
- UserMessage: UserMessage2 = UserMessage
1967
+ UserMessage: UserMessage2 = UserMessage,
1968
+ imageUploadsEnabled,
1969
+ inputFileAccept = "image/*"
1790
1970
  }) {
1791
1971
  const { additionalInstructions, setChatInstructions } = (0, import_react_core7.useCopilotContext)();
1972
+ const [selectedImages, setSelectedImages] = (0, import_react9.useState)([]);
1973
+ const fileInputRef = (0, import_react9.useRef)(null);
1974
+ (0, import_react9.useEffect)(() => {
1975
+ if (!imageUploadsEnabled)
1976
+ return;
1977
+ const handlePaste = (e) => __async(this, null, function* () {
1978
+ var _a, _b;
1979
+ const target = e.target;
1980
+ if (!((_a = target.parentElement) == null ? void 0 : _a.classList.contains("copilotKitInput")))
1981
+ return;
1982
+ const items = Array.from(((_b = e.clipboardData) == null ? void 0 : _b.items) || []);
1983
+ const imageItems = items.filter((item) => item.type.startsWith("image/"));
1984
+ if (imageItems.length === 0)
1985
+ return;
1986
+ e.preventDefault();
1987
+ const imagePromises = imageItems.map((item) => {
1988
+ const file = item.getAsFile();
1989
+ if (!file)
1990
+ return Promise.resolve(null);
1991
+ return new Promise((resolve, reject) => {
1992
+ const reader = new FileReader();
1993
+ reader.onload = (e2) => {
1994
+ var _a2, _b2;
1995
+ const base64String = (_b2 = (_a2 = e2.target) == null ? void 0 : _a2.result) == null ? void 0 : _b2.split(",")[1];
1996
+ if (base64String) {
1997
+ resolve({
1998
+ contentType: file.type,
1999
+ bytes: base64String
2000
+ });
2001
+ } else {
2002
+ resolve(null);
2003
+ }
2004
+ };
2005
+ reader.onerror = reject;
2006
+ reader.readAsDataURL(file);
2007
+ });
2008
+ });
2009
+ try {
2010
+ const loadedImages = (yield Promise.all(imagePromises)).filter((img) => img !== null);
2011
+ setSelectedImages((prev) => [...prev, ...loadedImages]);
2012
+ } catch (error) {
2013
+ console.error("Error processing pasted images:", error);
2014
+ }
2015
+ });
2016
+ document.addEventListener("paste", handlePaste);
2017
+ return () => document.removeEventListener("paste", handlePaste);
2018
+ }, [imageUploadsEnabled]);
1792
2019
  (0, import_react9.useEffect)(() => {
1793
2020
  if (!(additionalInstructions == null ? void 0 : additionalInstructions.length)) {
1794
2021
  setChatInstructions(instructions || "");
@@ -1816,6 +2043,14 @@ function CopilotChat({
1816
2043
  onStopGeneration,
1817
2044
  onReloadMessages
1818
2045
  );
2046
+ const handleSendMessage = (text) => {
2047
+ const images = selectedImages;
2048
+ setSelectedImages([]);
2049
+ if (fileInputRef.current) {
2050
+ fileInputRef.current.value = "";
2051
+ }
2052
+ return sendMessage(text, images);
2053
+ };
1819
2054
  const chatContext = import_react9.default.useContext(ChatContext);
1820
2055
  const isVisible = chatContext ? chatContext.open : true;
1821
2056
  const handleRegenerate = (messageId) => {
@@ -1829,8 +2064,42 @@ function CopilotChat({
1829
2064
  onCopy(message);
1830
2065
  }
1831
2066
  };
1832
- return /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)(WrappedCopilotChat, { icons, labels, className, children: [
1833
- /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(
2067
+ const handleImageUpload = (event) => __async(this, null, function* () {
2068
+ if (!event.target.files || event.target.files.length === 0) {
2069
+ return;
2070
+ }
2071
+ const files = Array.from(event.target.files).filter((file) => file.type.startsWith("image/"));
2072
+ if (files.length === 0)
2073
+ return;
2074
+ const fileReadPromises = files.map((file) => {
2075
+ return new Promise((resolve, reject) => {
2076
+ const reader = new FileReader();
2077
+ reader.onload = (e) => {
2078
+ var _a, _b;
2079
+ const base64String = ((_b = (_a = e.target) == null ? void 0 : _a.result) == null ? void 0 : _b.split(",")[1]) || "";
2080
+ if (base64String) {
2081
+ resolve({
2082
+ contentType: file.type,
2083
+ bytes: base64String
2084
+ });
2085
+ }
2086
+ };
2087
+ reader.onerror = reject;
2088
+ reader.readAsDataURL(file);
2089
+ });
2090
+ });
2091
+ try {
2092
+ const loadedImages = yield Promise.all(fileReadPromises);
2093
+ setSelectedImages((prev) => [...prev, ...loadedImages]);
2094
+ } catch (error) {
2095
+ console.error("Error reading files:", error);
2096
+ }
2097
+ });
2098
+ const removeSelectedImage = (index) => {
2099
+ setSelectedImages((prev) => prev.filter((_, i) => i !== index));
2100
+ };
2101
+ return /* @__PURE__ */ (0, import_jsx_runtime17.jsxs)(WrappedCopilotChat, { icons, labels, className, children: [
2102
+ /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(
1834
2103
  Messages2,
1835
2104
  {
1836
2105
  AssistantMessage: AssistantMessage2,
@@ -1839,32 +2108,51 @@ function CopilotChat({
1839
2108
  RenderActionExecutionMessage: RenderActionExecutionMessage2,
1840
2109
  RenderAgentStateMessage: RenderAgentStateMessage2,
1841
2110
  RenderResultMessage: RenderResultMessage2,
2111
+ RenderImageMessage: RenderImageMessage2,
1842
2112
  messages: visibleMessages,
1843
2113
  inProgress: isLoading,
1844
2114
  onRegenerate: handleRegenerate,
1845
2115
  onCopy: handleCopy,
1846
2116
  onThumbsUp,
1847
2117
  onThumbsDown,
1848
- children: currentSuggestions.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime15.jsx)("div", { className: "suggestions", children: currentSuggestions.map((suggestion, index) => /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(
2118
+ children: currentSuggestions.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime17.jsx)("div", { className: "suggestions", children: currentSuggestions.map((suggestion, index) => /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(
1849
2119
  Suggestion,
1850
2120
  {
1851
2121
  title: suggestion.title,
1852
2122
  message: suggestion.message,
1853
2123
  partial: suggestion.partial,
1854
2124
  className: suggestion.className,
1855
- onClick: (message) => sendMessage(message)
2125
+ onClick: (message) => handleSendMessage(message)
1856
2126
  },
1857
2127
  index
1858
2128
  )) })
1859
2129
  }
1860
2130
  ),
1861
- /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(
2131
+ imageUploadsEnabled && /* @__PURE__ */ (0, import_jsx_runtime17.jsxs)(import_jsx_runtime17.Fragment, { children: [
2132
+ /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(ImageUploadQueue, { images: selectedImages, onRemoveImage: removeSelectedImage }),
2133
+ /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(
2134
+ "input",
2135
+ {
2136
+ type: "file",
2137
+ multiple: true,
2138
+ ref: fileInputRef,
2139
+ onChange: handleImageUpload,
2140
+ accept: inputFileAccept,
2141
+ style: { display: "none" }
2142
+ }
2143
+ )
2144
+ ] }),
2145
+ /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(
1862
2146
  Input2,
1863
2147
  {
1864
2148
  inProgress: isLoading,
1865
- onSend: sendMessage,
2149
+ onSend: handleSendMessage,
1866
2150
  isVisible,
1867
- onStop: stopGeneration
2151
+ onStop: stopGeneration,
2152
+ onUpload: imageUploadsEnabled ? () => {
2153
+ var _a;
2154
+ return (_a = fileInputRef.current) == null ? void 0 : _a.click();
2155
+ } : void 0
1868
2156
  }
1869
2157
  )
1870
2158
  ] });
@@ -1877,10 +2165,10 @@ function WrappedCopilotChat({
1877
2165
  }) {
1878
2166
  const chatContext = import_react9.default.useContext(ChatContext);
1879
2167
  if (!chatContext) {
1880
- return /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(ChatContextProvider, { icons, labels, open: true, setOpen: () => {
1881
- }, children: /* @__PURE__ */ (0, import_jsx_runtime15.jsx)("div", { className: `copilotKitChat ${className}`, children }) });
2168
+ return /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(ChatContextProvider, { icons, labels, open: true, setOpen: () => {
2169
+ }, children: /* @__PURE__ */ (0, import_jsx_runtime17.jsx)("div", { className: `copilotKitChat ${className}`, children }) });
1882
2170
  }
1883
- return /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(import_jsx_runtime15.Fragment, { children });
2171
+ return /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(import_jsx_runtime17.Fragment, { children });
1884
2172
  }
1885
2173
  var SUGGESTIONS_DEBOUNCE_TIMEOUT = 1e3;
1886
2174
  var useCopilotChatLogic = (makeSystemMessage, onInProgress, onSubmitMessage, onStopGeneration, onReloadMessages) => {
@@ -1934,22 +2222,45 @@ var useCopilotChatLogic = (makeSystemMessage, onInProgress, onSubmitMessage, onS
1934
2222
  // global context
1935
2223
  visibleMessages.length == 0
1936
2224
  ]);
1937
- const sendMessage = (messageContent) => __async(void 0, null, function* () {
2225
+ const sendMessage = (messageContent, imagesToUse) => __async(void 0, null, function* () {
2226
+ const images = imagesToUse || [];
1938
2227
  abortSuggestions();
1939
2228
  setCurrentSuggestions([]);
1940
- const message = new import_runtime_client_gql4.TextMessage({
1941
- content: messageContent,
1942
- role: import_runtime_client_gql4.Role.User
1943
- });
1944
- if (onSubmitMessage) {
1945
- try {
1946
- yield onSubmitMessage(messageContent);
1947
- } catch (error) {
1948
- console.error("Error in onSubmitMessage:", error);
2229
+ let firstMessage = null;
2230
+ if (messageContent.trim().length > 0) {
2231
+ const textMessage = new import_runtime_client_gql4.TextMessage({
2232
+ content: messageContent,
2233
+ role: import_runtime_client_gql4.Role.User
2234
+ });
2235
+ if (onSubmitMessage) {
2236
+ try {
2237
+ yield onSubmitMessage(messageContent);
2238
+ } catch (error) {
2239
+ console.error("Error in onSubmitMessage:", error);
2240
+ }
2241
+ }
2242
+ yield appendMessage(textMessage, { followUp: images.length === 0 });
2243
+ if (!firstMessage) {
2244
+ firstMessage = textMessage;
2245
+ }
2246
+ }
2247
+ if (images.length > 0) {
2248
+ for (let i = 0; i < images.length; i++) {
2249
+ const imageMessage = new import_runtime_client_gql4.ImageMessage({
2250
+ format: images[i].contentType.replace("image/", ""),
2251
+ bytes: images[i].bytes,
2252
+ role: import_runtime_client_gql4.Role.User
2253
+ });
2254
+ yield appendMessage(imageMessage, { followUp: i === images.length - 1 });
2255
+ if (!firstMessage) {
2256
+ firstMessage = imageMessage;
2257
+ }
1949
2258
  }
1950
2259
  }
1951
- appendMessage(message);
1952
- return message;
2260
+ if (!firstMessage) {
2261
+ return new import_runtime_client_gql4.TextMessage({ content: "", role: import_runtime_client_gql4.Role.User });
2262
+ }
2263
+ return firstMessage;
1953
2264
  });
1954
2265
  const messages = visibleMessages;
1955
2266
  const { setMessages } = messagesContext;