@copilotkit/react-ui 1.10.6 → 1.50.0-beta.0

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 (122) hide show
  1. package/dist/{chunk-H5Y4W7DM.mjs → chunk-3JYVJHL5.mjs} +6 -6
  2. package/dist/chunk-3YWFGNSM.mjs +32 -0
  3. package/dist/chunk-3YWFGNSM.mjs.map +1 -0
  4. package/dist/{chunk-BAD2NFZ7.mjs → chunk-CQ2WALZ7.mjs} +2 -2
  5. package/dist/{chunk-W7ONZTSW.mjs → chunk-E6WVAOQA.mjs} +11 -5
  6. package/dist/chunk-E6WVAOQA.mjs.map +1 -0
  7. package/dist/{chunk-ME2WM7IP.mjs → chunk-G35HUUDA.mjs} +36 -260
  8. package/dist/chunk-G35HUUDA.mjs.map +1 -0
  9. package/dist/{chunk-EZQA3UPQ.mjs → chunk-HBZW7E5Z.mjs} +16 -13
  10. package/dist/chunk-HBZW7E5Z.mjs.map +1 -0
  11. package/dist/{chunk-3QYTKBWC.mjs → chunk-IHFR6PYG.mjs} +8 -5
  12. package/dist/chunk-IHFR6PYG.mjs.map +1 -0
  13. package/dist/{chunk-5XLGXUQI.mjs → chunk-MPF6BJUF.mjs} +7 -3
  14. package/dist/chunk-MPF6BJUF.mjs.map +1 -0
  15. package/dist/{chunk-W26XFBEG.mjs → chunk-NGJ32FAP.mjs} +3 -3
  16. package/dist/chunk-NGJ32FAP.mjs.map +1 -0
  17. package/dist/{chunk-2LIO4Z3E.mjs → chunk-ODEHR7KI.mjs} +9 -2
  18. package/dist/chunk-ODEHR7KI.mjs.map +1 -0
  19. package/dist/chunk-OYRZ4VLU.mjs +12 -0
  20. package/dist/chunk-OYRZ4VLU.mjs.map +1 -0
  21. package/dist/chunk-QB3GUN2N.mjs +31 -0
  22. package/dist/chunk-QB3GUN2N.mjs.map +1 -0
  23. package/dist/{chunk-7RDGZ5JL.mjs → chunk-SOB5EIL7.mjs} +2 -2
  24. package/dist/components/chat/Chat.d.ts +3 -98
  25. package/dist/components/chat/Chat.js +100 -279
  26. package/dist/components/chat/Chat.js.map +1 -1
  27. package/dist/components/chat/Chat.mjs +12 -14
  28. package/dist/components/chat/Input.d.ts +1 -1
  29. package/dist/components/chat/Input.js +11 -8
  30. package/dist/components/chat/Input.js.map +1 -1
  31. package/dist/components/chat/Input.mjs +2 -2
  32. package/dist/components/chat/Messages.d.ts +4 -4
  33. package/dist/components/chat/Messages.js +44 -8
  34. package/dist/components/chat/Messages.js.map +1 -1
  35. package/dist/components/chat/Messages.mjs +5 -5
  36. package/dist/components/chat/Modal.d.ts +1 -6
  37. package/dist/components/chat/Modal.js +106 -283
  38. package/dist/components/chat/Modal.js.map +1 -1
  39. package/dist/components/chat/Modal.mjs +11 -11
  40. package/dist/components/chat/Popup.d.ts +1 -6
  41. package/dist/components/chat/Popup.js +106 -283
  42. package/dist/components/chat/Popup.js.map +1 -1
  43. package/dist/components/chat/Popup.mjs +12 -12
  44. package/dist/components/chat/Sidebar.d.ts +1 -6
  45. package/dist/components/chat/Sidebar.js +106 -283
  46. package/dist/components/chat/Sidebar.js.map +1 -1
  47. package/dist/components/chat/Sidebar.mjs +12 -12
  48. package/dist/components/chat/Suggestion.js.map +1 -1
  49. package/dist/components/chat/Suggestion.mjs +1 -1
  50. package/dist/components/chat/Suggestions.d.ts +1 -1
  51. package/dist/components/chat/Suggestions.js +19 -12
  52. package/dist/components/chat/Suggestions.js.map +1 -1
  53. package/dist/components/chat/Suggestions.mjs +2 -2
  54. package/dist/components/chat/index.d.ts +0 -5
  55. package/dist/components/chat/index.js +106 -283
  56. package/dist/components/chat/index.js.map +1 -1
  57. package/dist/components/chat/index.mjs +13 -13
  58. package/dist/components/chat/messages/AssistantMessage.js +7 -4
  59. package/dist/components/chat/messages/AssistantMessage.js.map +1 -1
  60. package/dist/components/chat/messages/AssistantMessage.mjs +1 -1
  61. package/dist/components/chat/messages/LegacyRenderMessage.js +37 -7
  62. package/dist/components/chat/messages/LegacyRenderMessage.js.map +1 -1
  63. package/dist/components/chat/messages/LegacyRenderMessage.mjs +4 -4
  64. package/dist/components/chat/messages/RenderMessage.js +30 -7
  65. package/dist/components/chat/messages/RenderMessage.js.map +1 -1
  66. package/dist/components/chat/messages/RenderMessage.mjs +3 -3
  67. package/dist/components/chat/messages/UserMessage.js +19 -3
  68. package/dist/components/chat/messages/UserMessage.js.map +1 -1
  69. package/dist/components/chat/messages/UserMessage.mjs +1 -1
  70. package/dist/components/chat/props.d.ts +16 -0
  71. package/dist/components/chat/props.js.map +1 -1
  72. package/dist/components/index.d.ts +0 -5
  73. package/dist/components/index.js +106 -283
  74. package/dist/components/index.js.map +1 -1
  75. package/dist/components/index.mjs +13 -13
  76. package/dist/hooks/index.d.ts +1 -0
  77. package/dist/hooks/index.js +2 -24
  78. package/dist/hooks/index.js.map +1 -1
  79. package/dist/hooks/index.mjs +1 -1
  80. package/dist/hooks/use-copilot-chat-suggestions.d.ts +4 -26
  81. package/dist/hooks/use-copilot-chat-suggestions.js +2 -24
  82. package/dist/hooks/use-copilot-chat-suggestions.js.map +1 -1
  83. package/dist/hooks/use-copilot-chat-suggestions.mjs +1 -1
  84. package/dist/index.css +8 -1
  85. package/dist/index.css.map +1 -1
  86. package/dist/index.d.ts +0 -5
  87. package/dist/index.js +109 -308
  88. package/dist/index.js.map +1 -1
  89. package/dist/index.mjs +14 -14
  90. package/dist/types/suggestions.d.ts +1 -0
  91. package/dist/types/suggestions.js.map +1 -1
  92. package/package.json +23 -22
  93. package/src/components/chat/Chat.tsx +40 -325
  94. package/src/components/chat/Input.tsx +13 -12
  95. package/src/components/chat/Messages.tsx +10 -4
  96. package/src/components/chat/Suggestion.tsx +2 -2
  97. package/src/components/chat/Suggestions.tsx +6 -2
  98. package/src/components/chat/messages/AssistantMessage.tsx +14 -4
  99. package/src/components/chat/messages/LegacyRenderMessage.tsx +7 -0
  100. package/src/components/chat/messages/RenderMessage.tsx +4 -0
  101. package/src/components/chat/messages/UserMessage.tsx +30 -6
  102. package/src/components/chat/props.ts +19 -0
  103. package/src/css/messages.css +10 -1
  104. package/src/hooks/use-copilot-chat-suggestions.tsx +6 -57
  105. package/src/types/suggestions.ts +1 -0
  106. package/tsup.config.ts +1 -1
  107. package/dist/chunk-226ZMOE3.mjs +0 -24
  108. package/dist/chunk-226ZMOE3.mjs.map +0 -1
  109. package/dist/chunk-2LIO4Z3E.mjs.map +0 -1
  110. package/dist/chunk-3QYTKBWC.mjs.map +0 -1
  111. package/dist/chunk-5XLGXUQI.mjs.map +0 -1
  112. package/dist/chunk-EYRKZDP5.mjs +0 -32
  113. package/dist/chunk-EYRKZDP5.mjs.map +0 -1
  114. package/dist/chunk-EZQA3UPQ.mjs.map +0 -1
  115. package/dist/chunk-ME2WM7IP.mjs.map +0 -1
  116. package/dist/chunk-VVL6JFCJ.mjs +0 -16
  117. package/dist/chunk-VVL6JFCJ.mjs.map +0 -1
  118. package/dist/chunk-W26XFBEG.mjs.map +0 -1
  119. package/dist/chunk-W7ONZTSW.mjs.map +0 -1
  120. /package/dist/{chunk-H5Y4W7DM.mjs.map → chunk-3JYVJHL5.mjs.map} +0 -0
  121. /package/dist/{chunk-BAD2NFZ7.mjs.map → chunk-CQ2WALZ7.mjs.map} +0 -0
  122. /package/dist/{chunk-7RDGZ5JL.mjs.map → chunk-SOB5EIL7.mjs.map} +0 -0
@@ -1,8 +1,8 @@
1
- import { useEffect, useMemo, useRef } from "react";
1
+ import React, { useEffect, useMemo, useRef } from "react";
2
2
  import { MessagesProps } from "./props";
3
3
  import { useChatContext } from "./ChatContext";
4
4
  import { Message } from "@copilotkit/shared";
5
- import { useCopilotChatInternal as useCopilotChat } from "@copilotkit/react-core";
5
+ import { useCopilotChatInternal } from "@copilotkit/react-core";
6
6
  import { LegacyRenderMessage, LegacyRenderProps } from "./messages/LegacyRenderMessage";
7
7
 
8
8
  export const Messages = ({
@@ -17,6 +17,7 @@ export const Messages = ({
17
17
  onCopy,
18
18
  onThumbsUp,
19
19
  onThumbsDown,
20
+ messageFeedback,
20
21
  markdownTagRenderers,
21
22
  chatError,
22
23
 
@@ -27,8 +28,8 @@ export const Messages = ({
27
28
  RenderResultMessage,
28
29
  RenderImageMessage,
29
30
  }: MessagesProps) => {
30
- const { labels } = useChatContext();
31
- const { messages: visibleMessages, interrupt } = useCopilotChat();
31
+ const { labels, icons } = useChatContext();
32
+ const { messages: visibleMessages, interrupt } = useCopilotChatInternal();
32
33
  const initialMessages = useMemo(() => makeInitialMessages(labels.initial), [labels.initial]);
33
34
  const messages = [...initialMessages, ...visibleMessages];
34
35
  const { messagesContainerRef, messagesEndRef } = useScrollToBottom(messages);
@@ -76,6 +77,8 @@ export const Messages = ({
76
77
  ? (props: any) => <LegacyRenderMessage {...props} legacyProps={legacyProps} />
77
78
  : RenderMessage;
78
79
 
80
+ const LoadingIcon = () => <span>{icons.activityIcon}</span>;
81
+
79
82
  return (
80
83
  <div className="copilotKitMessages" ref={messagesContainerRef}>
81
84
  <div className="copilotKitMessagesContainer">
@@ -85,6 +88,7 @@ export const Messages = ({
85
88
  <MessageRenderer
86
89
  key={index}
87
90
  message={message}
91
+ messages={messages}
88
92
  inProgress={inProgress}
89
93
  index={index}
90
94
  isCurrentMessage={isCurrentMessage}
@@ -95,10 +99,12 @@ export const Messages = ({
95
99
  onCopy={onCopy}
96
100
  onThumbsUp={onThumbsUp}
97
101
  onThumbsDown={onThumbsDown}
102
+ messageFeedback={messageFeedback}
98
103
  markdownTagRenderers={markdownTagRenderers}
99
104
  />
100
105
  );
101
106
  })}
107
+ {messages[messages.length - 1]?.role === "user" && inProgress && <LoadingIcon />}
102
108
  {interrupt}
103
109
  {chatError && ErrorMessage && <ErrorMessage error={chatError} isCurrentMessage />}
104
110
  </div>
@@ -1,4 +1,4 @@
1
- import { useCopilotChatInternal as useCopilotChat } from "@copilotkit/react-core";
1
+ import { useCopilotChatInternal } from "@copilotkit/react-core";
2
2
  import { SmallSpinnerIcon } from "./Icons";
3
3
 
4
4
  interface SuggestionsProps {
@@ -11,7 +11,7 @@ interface SuggestionsProps {
11
11
 
12
12
  export function Suggestion({ title, onClick, partial, className }: SuggestionsProps) {
13
13
  if (!title) return null;
14
- const { isLoading } = useCopilotChat();
14
+ const { isLoading } = useCopilotChatInternal();
15
15
 
16
16
  return (
17
17
  <button
@@ -1,7 +1,11 @@
1
1
  import { Suggestion } from "./Suggestion";
2
2
  import { RenderSuggestionsListProps } from "./props";
3
3
 
4
- export function Suggestions({ suggestions, onSuggestionClick }: RenderSuggestionsListProps) {
4
+ export function Suggestions({
5
+ suggestions,
6
+ onSuggestionClick,
7
+ isLoading,
8
+ }: RenderSuggestionsListProps) {
5
9
  return (
6
10
  <div className="suggestions">
7
11
  {suggestions.map((suggestion, index) => (
@@ -9,7 +13,7 @@ export function Suggestions({ suggestions, onSuggestionClick }: RenderSuggestion
9
13
  key={index}
10
14
  title={suggestion.title}
11
15
  message={suggestion.message}
12
- partial={suggestion.partial}
16
+ partial={suggestion.isLoading ?? suggestion.partial ?? isLoading}
13
17
  className={suggestion.className}
14
18
  onClick={() => onSuggestionClick(suggestion.message)}
15
19
  />
@@ -2,6 +2,7 @@ import { AssistantMessageProps } from "../props";
2
2
  import { useChatContext } from "../ChatContext";
3
3
  import { Markdown } from "../Markdown";
4
4
  import { useState } from "react";
5
+ import React from "react";
5
6
 
6
7
  export const AssistantMessage = (props: AssistantMessageProps) => {
7
8
  const { icons, labels } = useChatContext();
@@ -13,6 +14,7 @@ export const AssistantMessage = (props: AssistantMessageProps) => {
13
14
  onThumbsUp,
14
15
  onThumbsDown,
15
16
  isCurrentMessage,
17
+ feedback,
16
18
  markdownTagRenderers,
17
19
  } = props;
18
20
  const [copied, setCopied] = useState(false);
@@ -36,11 +38,15 @@ export const AssistantMessage = (props: AssistantMessageProps) => {
36
38
  };
37
39
 
38
40
  const handleThumbsUp = () => {
39
- if (onThumbsUp && message) onThumbsUp(message);
41
+ if (onThumbsUp && message) {
42
+ onThumbsUp(message);
43
+ }
40
44
  };
41
45
 
42
46
  const handleThumbsDown = () => {
43
- if (onThumbsDown && message) onThumbsDown(message);
47
+ if (onThumbsDown && message) {
48
+ onThumbsDown(message);
49
+ }
44
50
  };
45
51
 
46
52
  const LoadingIcon = () => <span>{icons.activityIcon}</span>;
@@ -79,7 +85,9 @@ export const AssistantMessage = (props: AssistantMessageProps) => {
79
85
  </button>
80
86
  {onThumbsUp && (
81
87
  <button
82
- className="copilotKitMessageControlButton"
88
+ className={`copilotKitMessageControlButton ${
89
+ feedback === "thumbsUp" ? "active" : ""
90
+ }`}
83
91
  onClick={handleThumbsUp}
84
92
  aria-label={labels.thumbsUp}
85
93
  title={labels.thumbsUp}
@@ -89,7 +97,9 @@ export const AssistantMessage = (props: AssistantMessageProps) => {
89
97
  )}
90
98
  {onThumbsDown && (
91
99
  <button
92
- className="copilotKitMessageControlButton"
100
+ className={`copilotKitMessageControlButton ${
101
+ feedback === "thumbsDown" ? "active" : ""
102
+ }`}
93
103
  onClick={handleThumbsDown}
94
104
  aria-label={labels.thumbsDown}
95
105
  title={labels.thumbsDown}
@@ -27,6 +27,7 @@ export interface LegacyRenderMessageProps extends RenderMessageProps {
27
27
  */
28
28
  export const LegacyRenderMessage: React.FC<LegacyRenderMessageProps> = ({
29
29
  message,
30
+ messages,
30
31
  inProgress,
31
32
  index,
32
33
  isCurrentMessage,
@@ -56,6 +57,7 @@ export const LegacyRenderMessage: React.FC<LegacyRenderMessageProps> = ({
56
57
  return (
57
58
  <RenderTextMessage
58
59
  message={message}
60
+ messages={messages}
59
61
  inProgress={inProgress}
60
62
  index={index}
61
63
  isCurrentMessage={isCurrentMessage}
@@ -73,6 +75,7 @@ export const LegacyRenderMessage: React.FC<LegacyRenderMessageProps> = ({
73
75
  if (deprecatedMessage.isActionExecutionMessage() && RenderActionExecutionMessage) {
74
76
  return (
75
77
  <RenderActionExecutionMessage
78
+ messages={messages}
76
79
  message={message}
77
80
  inProgress={inProgress}
78
81
  index={index}
@@ -87,6 +90,7 @@ export const LegacyRenderMessage: React.FC<LegacyRenderMessageProps> = ({
87
90
  if (deprecatedMessage.isAgentStateMessage() && RenderAgentStateMessage) {
88
91
  return (
89
92
  <RenderAgentStateMessage
93
+ messages={messages}
90
94
  message={message}
91
95
  inProgress={inProgress}
92
96
  index={index}
@@ -100,6 +104,7 @@ export const LegacyRenderMessage: React.FC<LegacyRenderMessageProps> = ({
100
104
  if (deprecatedMessage.isResultMessage() && RenderResultMessage) {
101
105
  return (
102
106
  <RenderResultMessage
107
+ messages={messages}
103
108
  message={message}
104
109
  inProgress={inProgress}
105
110
  index={index}
@@ -113,6 +118,7 @@ export const LegacyRenderMessage: React.FC<LegacyRenderMessageProps> = ({
113
118
  if (deprecatedMessage.isImageMessage() && RenderImageMessage) {
114
119
  return (
115
120
  <RenderImageMessage
121
+ messages={messages}
116
122
  message={message}
117
123
  inProgress={inProgress}
118
124
  index={index}
@@ -126,6 +132,7 @@ export const LegacyRenderMessage: React.FC<LegacyRenderMessageProps> = ({
126
132
  // Fallback to default RenderMessage for any unhandled cases
127
133
  return (
128
134
  <DefaultRenderMessage
135
+ messages={messages}
129
136
  message={message}
130
137
  inProgress={inProgress}
131
138
  index={index}
@@ -11,6 +11,7 @@ export function RenderMessage({
11
11
  }: RenderMessageProps) {
12
12
  const {
13
13
  message,
14
+ messages,
14
15
  inProgress,
15
16
  index,
16
17
  isCurrentMessage,
@@ -18,6 +19,7 @@ export function RenderMessage({
18
19
  onCopy,
19
20
  onThumbsUp,
20
21
  onThumbsDown,
22
+ messageFeedback,
21
23
  markdownTagRenderers,
22
24
  } = props;
23
25
 
@@ -40,6 +42,7 @@ export function RenderMessage({
40
42
  subComponent={message.generativeUI?.()}
41
43
  rawData={message}
42
44
  message={message}
45
+ messages={messages}
43
46
  isLoading={inProgress && isCurrentMessage && !message.content}
44
47
  isGenerating={inProgress && isCurrentMessage && !!message.content}
45
48
  isCurrentMessage={isCurrentMessage}
@@ -47,6 +50,7 @@ export function RenderMessage({
47
50
  onCopy={onCopy}
48
51
  onThumbsUp={onThumbsUp}
49
52
  onThumbsDown={onThumbsDown}
53
+ feedback={messageFeedback?.[message.id] || null}
50
54
  markdownTagRenderers={markdownTagRenderers}
51
55
  ImageRenderer={ImageRenderer}
52
56
  />
@@ -1,20 +1,44 @@
1
1
  import { UserMessageProps } from "../props";
2
2
 
3
+ type UserMessageContent = NonNullable<UserMessageProps["message"]>["content"];
4
+
5
+ const getTextContent = (content: UserMessageContent | undefined): string | undefined => {
6
+ if (typeof content === "undefined") {
7
+ return undefined;
8
+ }
9
+
10
+ if (typeof content === "string") {
11
+ return content;
12
+ }
13
+
14
+ return content
15
+ .map((part) => {
16
+ if (part.type === "text") {
17
+ return part.text;
18
+ }
19
+ return undefined;
20
+ })
21
+ .filter((value): value is string => typeof value === "string" && value.length > 0)
22
+ .join(" ")
23
+ .trim() || undefined;
24
+ };
25
+
3
26
  export const UserMessage = (props: UserMessageProps) => {
4
27
  const { message, ImageRenderer } = props;
5
- const isImageMessage = message && "image" in message && message.image;
28
+ const isImageMessage = message && "image" in message && Boolean(message.image);
6
29
 
7
- // Image message
8
30
  if (isImageMessage) {
9
- const imageMessage = message;
31
+ const imageMessage = message!;
32
+ const content = getTextContent(imageMessage?.content);
10
33
 
11
34
  return (
12
35
  <div className="copilotKitMessage copilotKitUserMessage">
13
- <ImageRenderer image={imageMessage.image!} content={imageMessage.content} />
36
+ <ImageRenderer image={imageMessage.image!} content={content} />
14
37
  </div>
15
38
  );
16
39
  }
17
40
 
18
- // Regular text message
19
- return <div className="copilotKitMessage copilotKitUserMessage">{message?.content}</div>;
41
+ const content = getTextContent(message?.content);
42
+
43
+ return <div className="copilotKitMessage copilotKitUserMessage">{content}</div>;
20
44
  };
@@ -109,6 +109,11 @@ export interface MessagesProps {
109
109
  */
110
110
  onThumbsDown?: (message: Message) => void;
111
111
 
112
+ /**
113
+ * Map of message IDs to their feedback state
114
+ */
115
+ messageFeedback?: Record<string, "thumbsUp" | "thumbsDown">;
116
+
112
117
  /**
113
118
  * A list of markdown components to render in assistant message.
114
119
  * Useful when you want to render custom elements in the message (e.g a reference tag element)
@@ -163,6 +168,7 @@ export interface AssistantMessageProps {
163
168
  */
164
169
 
165
170
  message?: AIMessage;
171
+ messages?: Message[];
166
172
 
167
173
  /**
168
174
  * Indicates if this is the last message
@@ -199,6 +205,11 @@ export interface AssistantMessageProps {
199
205
  */
200
206
  onThumbsDown?: (message: Message) => void;
201
207
 
208
+ /**
209
+ * The feedback state for this message ("thumbsUp" or "thumbsDown")
210
+ */
211
+ feedback?: "thumbsUp" | "thumbsDown" | null;
212
+
202
213
  /**
203
214
  * A list of markdown components to render in assistant message.
204
215
  * Useful when you want to render custom elements in the message (e.g a reference tag element)
@@ -261,6 +272,7 @@ export interface ErrorMessageProps {
261
272
 
262
273
  export interface RenderMessageProps {
263
274
  message: Message;
275
+ messages: Message[];
264
276
  inProgress: boolean;
265
277
  index: number;
266
278
  isCurrentMessage: boolean;
@@ -289,6 +301,11 @@ export interface RenderMessageProps {
289
301
  */
290
302
  onThumbsDown?: (message: Message) => void;
291
303
 
304
+ /**
305
+ * Map of message IDs to their feedback state
306
+ */
307
+ messageFeedback?: Record<string, "thumbsUp" | "thumbsDown">;
308
+
292
309
  /**
293
310
  * A list of markdown components to render in assistant message.
294
311
  * Useful when you want to render custom elements in the message (e.g a reference tag element)
@@ -303,11 +320,13 @@ export interface InputProps {
303
320
  onStop?: () => void;
304
321
  onUpload?: () => void;
305
322
  hideStopButton?: boolean;
323
+ chatReady?: boolean;
306
324
  }
307
325
 
308
326
  export interface RenderSuggestionsListProps {
309
327
  suggestions: CopilotChatSuggestion[];
310
328
  onSuggestionClick: (message: string) => void;
329
+ isLoading: boolean;
311
330
  }
312
331
 
313
332
  export interface ImageRendererProps {
@@ -121,6 +121,16 @@
121
121
  transform: scale(1.05);
122
122
  }
123
123
 
124
+ .copilotKitMessageControlButton.active {
125
+ background-color: var(--copilot-kit-primary-color);
126
+ color: var(--copilot-kit-contrast-color);
127
+ }
128
+
129
+ .copilotKitMessageControlButton.active:hover {
130
+ background-color: color-mix(in srgb, var(--copilot-kit-primary-color) 90%, black);
131
+ color: var(--copilot-kit-contrast-color);
132
+ }
133
+
124
134
  .copilotKitMessageControlButton svg {
125
135
  width: 1rem;
126
136
  height: 1rem;
@@ -159,7 +169,6 @@
159
169
  border-radius: 50%;
160
170
  border-top-color: var(--copilot-kit-primary-color);
161
171
  animation: copilotKitSpinAnimation 1s linear infinite;
162
- margin-left: 8px;
163
172
  }
164
173
 
165
174
  @keyframes copilotKitActivityDotAnimation {
@@ -58,65 +58,14 @@
58
58
  * The hook registers the configuration with the chat context upon component mount and
59
59
  * removes it on unmount, ensuring a clean and efficient lifecycle management.
60
60
  */
61
-
62
- import { useEffect } from "react";
63
- import { useCopilotContext } from "@copilotkit/react-core";
64
- import { randomId } from "@copilotkit/shared";
65
-
66
- interface UseCopilotChatSuggestionsConfiguration {
67
- /**
68
- * A prompt or instructions for the GPT to generate suggestions.
69
- */
70
- instructions: string;
71
- /**
72
- * The minimum number of suggestions to generate. Defaults to `1`.
73
- * @default 1
74
- */
75
- minSuggestions?: number;
76
- /**
77
- * The maximum number of suggestions to generate. Defaults to `3`.
78
- * @default 1
79
- */
80
- maxSuggestions?: number;
81
-
82
- /**
83
- * Whether the suggestions are available. Defaults to `enabled`.
84
- * @default enabled
85
- */
86
- available?: "enabled" | "disabled";
87
-
88
- /**
89
- * An optional class name to apply to the suggestions.
90
- */
91
- className?: string;
92
- }
61
+ import {
62
+ useConfigureChatSuggestions,
63
+ type UseCopilotChatSuggestionsConfiguration,
64
+ } from "@copilotkit/react-core";
93
65
 
94
66
  export function useCopilotChatSuggestions(
95
- {
96
- available = "enabled",
97
- instructions,
98
- className,
99
- minSuggestions = 1,
100
- maxSuggestions = 3,
101
- }: UseCopilotChatSuggestionsConfiguration,
67
+ config: UseCopilotChatSuggestionsConfiguration,
102
68
  dependencies: any[] = [],
103
69
  ) {
104
- const context = useCopilotContext();
105
-
106
- useEffect(() => {
107
- if (available === "disabled") return;
108
-
109
- const id = randomId();
110
-
111
- context.addChatSuggestionConfiguration(id, {
112
- instructions,
113
- minSuggestions,
114
- maxSuggestions,
115
- className,
116
- });
117
-
118
- return () => {
119
- context.removeChatSuggestionConfiguration(id);
120
- };
121
- }, [...dependencies, instructions, minSuggestions, maxSuggestions, className, available]);
70
+ useConfigureChatSuggestions(config, dependencies);
122
71
  }
@@ -2,5 +2,6 @@ export interface CopilotChatSuggestion {
2
2
  title: string;
3
3
  message: string;
4
4
  partial?: boolean;
5
+ isLoading?: boolean;
5
6
  className?: string;
6
7
  }
package/tsup.config.ts CHANGED
@@ -5,7 +5,7 @@ export default defineConfig((options: Options) => ({
5
5
  format: ["esm", "cjs"],
6
6
  dts: true,
7
7
  minify: false,
8
- external: ["react"],
8
+ external: ["react", "@copilotkitnext/core", "@copilotkitnext/react"],
9
9
  sourcemap: true,
10
10
  ...options,
11
11
  }));
@@ -1,24 +0,0 @@
1
- import {
2
- Suggestion
3
- } from "./chunk-W26XFBEG.mjs";
4
-
5
- // src/components/chat/Suggestions.tsx
6
- import { jsx } from "react/jsx-runtime";
7
- function Suggestions({ suggestions, onSuggestionClick }) {
8
- return /* @__PURE__ */ jsx("div", { className: "suggestions", children: suggestions.map((suggestion, index) => /* @__PURE__ */ jsx(
9
- Suggestion,
10
- {
11
- title: suggestion.title,
12
- message: suggestion.message,
13
- partial: suggestion.partial,
14
- className: suggestion.className,
15
- onClick: () => onSuggestionClick(suggestion.message)
16
- },
17
- index
18
- )) });
19
- }
20
-
21
- export {
22
- Suggestions
23
- };
24
- //# sourceMappingURL=chunk-226ZMOE3.mjs.map
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../src/components/chat/Suggestions.tsx"],"sourcesContent":["import { Suggestion } from \"./Suggestion\";\nimport { RenderSuggestionsListProps } from \"./props\";\n\nexport function Suggestions({ suggestions, onSuggestionClick }: RenderSuggestionsListProps) {\n return (\n <div className=\"suggestions\">\n {suggestions.map((suggestion, index) => (\n <Suggestion\n key={index}\n title={suggestion.title}\n message={suggestion.message}\n partial={suggestion.partial}\n className={suggestion.className}\n onClick={() => onSuggestionClick(suggestion.message)}\n />\n ))}\n </div>\n );\n}\n"],"mappings":";;;;;AAOQ;AAJD,SAAS,YAAY,EAAE,aAAa,kBAAkB,GAA+B;AAC1F,SACE,oBAAC,SAAI,WAAU,eACZ,sBAAY,IAAI,CAAC,YAAY,UAC5B;AAAA,IAAC;AAAA;AAAA,MAEC,OAAO,WAAW;AAAA,MAClB,SAAS,WAAW;AAAA,MACpB,SAAS,WAAW;AAAA,MACpB,WAAW,WAAW;AAAA,MACtB,SAAS,MAAM,kBAAkB,WAAW,OAAO;AAAA;AAAA,IAL9C;AAAA,EAMP,CACD,GACH;AAEJ;","names":[]}
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../src/components/chat/messages/LegacyRenderMessage.tsx"],"sourcesContent":["import React from \"react\";\nimport { RenderMessageProps } from \"../props\";\nimport { RenderMessage as DefaultRenderMessage } from \"./RenderMessage\";\nimport { aguiToGQL } from \"@copilotkit/runtime-client-gql\";\n\n/**\n * Legacy message render props interface for backwards compatibility\n */\nexport interface LegacyRenderProps {\n RenderTextMessage?: React.ComponentType<RenderMessageProps>;\n RenderActionExecutionMessage?: React.ComponentType<RenderMessageProps>;\n RenderAgentStateMessage?: React.ComponentType<RenderMessageProps>;\n RenderResultMessage?: React.ComponentType<RenderMessageProps>;\n RenderImageMessage?: React.ComponentType<RenderMessageProps>;\n}\n\n/**\n * Props for the LegacyRenderMessage component\n */\nexport interface LegacyRenderMessageProps extends RenderMessageProps {\n legacyProps: LegacyRenderProps;\n}\n\n/**\n * Legacy message adapter component that maps old render props to new message types.\n * This component provides backwards compatibility for the deprecated render props.\n */\nexport const LegacyRenderMessage: React.FC<LegacyRenderMessageProps> = ({\n message,\n inProgress,\n index,\n isCurrentMessage,\n actionResult,\n AssistantMessage,\n UserMessage,\n ImageRenderer,\n onRegenerate,\n onCopy,\n onThumbsUp,\n onThumbsDown,\n markdownTagRenderers,\n legacyProps,\n}) => {\n const {\n RenderTextMessage,\n RenderActionExecutionMessage,\n RenderAgentStateMessage,\n RenderResultMessage,\n RenderImageMessage,\n } = legacyProps;\n\n const deprecatedMessage = aguiToGQL(message)[0] ?? undefined;\n\n // Route to appropriate legacy renderer based on message type\n if (deprecatedMessage.isTextMessage() && RenderTextMessage) {\n return (\n <RenderTextMessage\n message={message}\n inProgress={inProgress}\n index={index}\n isCurrentMessage={isCurrentMessage}\n AssistantMessage={AssistantMessage}\n UserMessage={UserMessage}\n onRegenerate={onRegenerate}\n onCopy={onCopy}\n onThumbsUp={onThumbsUp}\n onThumbsDown={onThumbsDown}\n markdownTagRenderers={markdownTagRenderers}\n />\n );\n }\n\n if (deprecatedMessage.isActionExecutionMessage() && RenderActionExecutionMessage) {\n return (\n <RenderActionExecutionMessage\n message={message}\n inProgress={inProgress}\n index={index}\n isCurrentMessage={isCurrentMessage}\n actionResult={actionResult}\n AssistantMessage={AssistantMessage}\n UserMessage={UserMessage}\n />\n );\n }\n\n if (deprecatedMessage.isAgentStateMessage() && RenderAgentStateMessage) {\n return (\n <RenderAgentStateMessage\n message={message}\n inProgress={inProgress}\n index={index}\n isCurrentMessage={isCurrentMessage}\n AssistantMessage={AssistantMessage}\n UserMessage={UserMessage}\n />\n );\n }\n\n if (deprecatedMessage.isResultMessage() && RenderResultMessage) {\n return (\n <RenderResultMessage\n message={message}\n inProgress={inProgress}\n index={index}\n isCurrentMessage={isCurrentMessage}\n AssistantMessage={AssistantMessage}\n UserMessage={UserMessage}\n />\n );\n }\n\n if (deprecatedMessage.isImageMessage() && RenderImageMessage) {\n return (\n <RenderImageMessage\n message={message}\n inProgress={inProgress}\n index={index}\n isCurrentMessage={isCurrentMessage}\n AssistantMessage={AssistantMessage}\n UserMessage={UserMessage}\n />\n );\n }\n\n // Fallback to default RenderMessage for any unhandled cases\n return (\n <DefaultRenderMessage\n message={message}\n inProgress={inProgress}\n index={index}\n isCurrentMessage={isCurrentMessage}\n AssistantMessage={AssistantMessage}\n UserMessage={UserMessage}\n ImageRenderer={ImageRenderer}\n onRegenerate={onRegenerate}\n onCopy={onCopy}\n onThumbsUp={onThumbsUp}\n onThumbsDown={onThumbsDown}\n markdownTagRenderers={markdownTagRenderers}\n />\n );\n};\n"],"mappings":";;;;;AAGA,SAAS,iBAAiB;AAqDpB;AA7BC,IAAM,sBAA0D,CAAC;AAAA,EACtE;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF,MAAM;AA1CN;AA2CE,QAAM;AAAA,IACJ;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF,IAAI;AAEJ,QAAM,qBAAoB,eAAU,OAAO,EAAE,CAAC,MAApB,YAAyB;AAGnD,MAAI,kBAAkB,cAAc,KAAK,mBAAmB;AAC1D,WACE;AAAA,MAAC;AAAA;AAAA,QACC;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA;AAAA,IACF;AAAA,EAEJ;AAEA,MAAI,kBAAkB,yBAAyB,KAAK,8BAA8B;AAChF,WACE;AAAA,MAAC;AAAA;AAAA,QACC;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA;AAAA,IACF;AAAA,EAEJ;AAEA,MAAI,kBAAkB,oBAAoB,KAAK,yBAAyB;AACtE,WACE;AAAA,MAAC;AAAA;AAAA,QACC;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA;AAAA,IACF;AAAA,EAEJ;AAEA,MAAI,kBAAkB,gBAAgB,KAAK,qBAAqB;AAC9D,WACE;AAAA,MAAC;AAAA;AAAA,QACC;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA;AAAA,IACF;AAAA,EAEJ;AAEA,MAAI,kBAAkB,eAAe,KAAK,oBAAoB;AAC5D,WACE;AAAA,MAAC;AAAA;AAAA,QACC;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA;AAAA,IACF;AAAA,EAEJ;AAGA,SACE;AAAA,IAAC;AAAA;AAAA,MACC;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA;AAAA,EACF;AAEJ;","names":[]}
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../src/components/chat/messages/AssistantMessage.tsx"],"sourcesContent":["import { AssistantMessageProps } from \"../props\";\nimport { useChatContext } from \"../ChatContext\";\nimport { Markdown } from \"../Markdown\";\nimport { useState } from \"react\";\n\nexport const AssistantMessage = (props: AssistantMessageProps) => {\n const { icons, labels } = useChatContext();\n const {\n message,\n isLoading,\n onRegenerate,\n onCopy,\n onThumbsUp,\n onThumbsDown,\n isCurrentMessage,\n markdownTagRenderers,\n } = props;\n const [copied, setCopied] = useState(false);\n\n const handleCopy = () => {\n const content = message?.content || \"\";\n if (content && onCopy) {\n navigator.clipboard.writeText(content);\n setCopied(true);\n onCopy(content);\n setTimeout(() => setCopied(false), 2000);\n } else if (content) {\n navigator.clipboard.writeText(content);\n setCopied(true);\n setTimeout(() => setCopied(false), 2000);\n }\n };\n\n const handleRegenerate = () => {\n if (onRegenerate) onRegenerate();\n };\n\n const handleThumbsUp = () => {\n if (onThumbsUp && message) onThumbsUp(message);\n };\n\n const handleThumbsDown = () => {\n if (onThumbsDown && message) onThumbsDown(message);\n };\n\n const LoadingIcon = () => <span>{icons.activityIcon}</span>;\n const content = message?.content || \"\";\n const subComponent = message?.generativeUI?.();\n\n return (\n <>\n {content && (\n <div className=\"copilotKitMessage copilotKitAssistantMessage\">\n {content && <Markdown content={content} components={markdownTagRenderers} />}\n\n {content && !isLoading && (\n <div\n className={`copilotKitMessageControls ${isCurrentMessage ? \"currentMessage\" : \"\"}`}\n >\n <button\n className=\"copilotKitMessageControlButton\"\n onClick={handleRegenerate}\n aria-label={labels.regenerateResponse}\n title={labels.regenerateResponse}\n >\n {icons.regenerateIcon}\n </button>\n <button\n className=\"copilotKitMessageControlButton\"\n onClick={handleCopy}\n aria-label={labels.copyToClipboard}\n title={labels.copyToClipboard}\n >\n {copied ? (\n <span style={{ fontSize: \"10px\", fontWeight: \"bold\" }}>✓</span>\n ) : (\n icons.copyIcon\n )}\n </button>\n {onThumbsUp && (\n <button\n className=\"copilotKitMessageControlButton\"\n onClick={handleThumbsUp}\n aria-label={labels.thumbsUp}\n title={labels.thumbsUp}\n >\n {icons.thumbsUpIcon}\n </button>\n )}\n {onThumbsDown && (\n <button\n className=\"copilotKitMessageControlButton\"\n onClick={handleThumbsDown}\n aria-label={labels.thumbsDown}\n title={labels.thumbsDown}\n >\n {icons.thumbsDownIcon}\n </button>\n )}\n </div>\n )}\n </div>\n )}\n <div style={{ marginBottom: \"0.5rem\" }}>{subComponent}</div>\n {isLoading && <LoadingIcon />}\n </>\n );\n};\n"],"mappings":";;;;;;;;AAGA,SAAS,gBAAgB;AA0CG,SAKxB,UALwB,KAWhB,YAXgB;AAxCrB,IAAM,mBAAmB,CAAC,UAAiC;AALlE;AAME,QAAM,EAAE,OAAO,OAAO,IAAI,eAAe;AACzC,QAAM;AAAA,IACJ;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF,IAAI;AACJ,QAAM,CAAC,QAAQ,SAAS,IAAI,SAAS,KAAK;AAE1C,QAAM,aAAa,MAAM;AACvB,UAAMA,YAAU,mCAAS,YAAW;AACpC,QAAIA,YAAW,QAAQ;AACrB,gBAAU,UAAU,UAAUA,QAAO;AACrC,gBAAU,IAAI;AACd,aAAOA,QAAO;AACd,iBAAW,MAAM,UAAU,KAAK,GAAG,GAAI;AAAA,IACzC,WAAWA,UAAS;AAClB,gBAAU,UAAU,UAAUA,QAAO;AACrC,gBAAU,IAAI;AACd,iBAAW,MAAM,UAAU,KAAK,GAAG,GAAI;AAAA,IACzC;AAAA,EACF;AAEA,QAAM,mBAAmB,MAAM;AAC7B,QAAI;AAAc,mBAAa;AAAA,EACjC;AAEA,QAAM,iBAAiB,MAAM;AAC3B,QAAI,cAAc;AAAS,iBAAW,OAAO;AAAA,EAC/C;AAEA,QAAM,mBAAmB,MAAM;AAC7B,QAAI,gBAAgB;AAAS,mBAAa,OAAO;AAAA,EACnD;AAEA,QAAM,cAAc,MAAM,oBAAC,UAAM,gBAAM,cAAa;AACpD,QAAM,WAAU,mCAAS,YAAW;AACpC,QAAM,gBAAe,wCAAS,iBAAT;AAErB,SACE,iCACG;AAAA,eACC,qBAAC,SAAI,WAAU,gDACZ;AAAA,iBAAW,oBAAC,YAAS,SAAkB,YAAY,sBAAsB;AAAA,MAEzE,WAAW,CAAC,aACX;AAAA,QAAC;AAAA;AAAA,UACC,WAAW,6BAA6B,mBAAmB,mBAAmB;AAAA,UAE9E;AAAA;AAAA,cAAC;AAAA;AAAA,gBACC,WAAU;AAAA,gBACV,SAAS;AAAA,gBACT,cAAY,OAAO;AAAA,gBACnB,OAAO,OAAO;AAAA,gBAEb,gBAAM;AAAA;AAAA,YACT;AAAA,YACA;AAAA,cAAC;AAAA;AAAA,gBACC,WAAU;AAAA,gBACV,SAAS;AAAA,gBACT,cAAY,OAAO;AAAA,gBACnB,OAAO,OAAO;AAAA,gBAEb,mBACC,oBAAC,UAAK,OAAO,EAAE,UAAU,QAAQ,YAAY,OAAO,GAAG,oBAAC,IAExD,MAAM;AAAA;AAAA,YAEV;AAAA,YACC,cACC;AAAA,cAAC;AAAA;AAAA,gBACC,WAAU;AAAA,gBACV,SAAS;AAAA,gBACT,cAAY,OAAO;AAAA,gBACnB,OAAO,OAAO;AAAA,gBAEb,gBAAM;AAAA;AAAA,YACT;AAAA,YAED,gBACC;AAAA,cAAC;AAAA;AAAA,gBACC,WAAU;AAAA,gBACV,SAAS;AAAA,gBACT,cAAY,OAAO;AAAA,gBACnB,OAAO,OAAO;AAAA,gBAEb,gBAAM;AAAA;AAAA,YACT;AAAA;AAAA;AAAA,MAEJ;AAAA,OAEJ;AAAA,IAEF,oBAAC,SAAI,OAAO,EAAE,cAAc,SAAS,GAAI,wBAAa;AAAA,IACrD,aAAa,oBAAC,eAAY;AAAA,KAC7B;AAEJ;","names":["content"]}
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../src/components/chat/messages/RenderMessage.tsx"],"sourcesContent":["import { RenderMessageProps } from \"../props\";\nimport { UserMessage as DefaultUserMessage } from \"./UserMessage\";\nimport { AssistantMessage as DefaultAssistantMessage } from \"./AssistantMessage\";\nimport { ImageRenderer as DefaultImageRenderer } from \"./ImageRenderer\";\n\nexport function RenderMessage({\n UserMessage = DefaultUserMessage,\n AssistantMessage = DefaultAssistantMessage,\n ImageRenderer = DefaultImageRenderer,\n ...props\n}: RenderMessageProps) {\n const {\n message,\n inProgress,\n index,\n isCurrentMessage,\n onRegenerate,\n onCopy,\n onThumbsUp,\n onThumbsDown,\n markdownTagRenderers,\n } = props;\n\n switch (message.role) {\n case \"user\":\n return (\n <UserMessage\n key={index}\n rawData={message}\n data-message-role=\"user\"\n message={message}\n ImageRenderer={ImageRenderer}\n />\n );\n case \"assistant\":\n return (\n <AssistantMessage\n key={index}\n data-message-role=\"assistant\"\n subComponent={message.generativeUI?.()}\n rawData={message}\n message={message}\n isLoading={inProgress && isCurrentMessage && !message.content}\n isGenerating={inProgress && isCurrentMessage && !!message.content}\n isCurrentMessage={isCurrentMessage}\n onRegenerate={() => onRegenerate?.(message.id)}\n onCopy={onCopy}\n onThumbsUp={onThumbsUp}\n onThumbsDown={onThumbsDown}\n markdownTagRenderers={markdownTagRenderers}\n ImageRenderer={ImageRenderer}\n />\n );\n }\n}\n"],"mappings":";;;;;;;;;;;;;;AA0BQ;AArBD,SAAS,cAAc,IAKP;AALO,eAC5B;AAAA,iBAAAA,eAAc;AAAA,IACd,kBAAAC,oBAAmB;AAAA,IACnB,eAAAC,iBAAgB;AAAA,EARlB,IAK8B,IAIzB,kBAJyB,IAIzB;AAAA,IAHH;AAAA,IACA;AAAA,IACA;AAAA;AARF,MAAAC;AAWE,QAAM;AAAA,IACJ;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF,IAAI;AAEJ,UAAQ,QAAQ,MAAM;AAAA,IACpB,KAAK;AACH,aACE;AAAA,QAACH;AAAA,QAAA;AAAA,UAEC,SAAS;AAAA,UACT,qBAAkB;AAAA,UAClB;AAAA,UACA,eAAeE;AAAA;AAAA,QAJV;AAAA,MAKP;AAAA,IAEJ,KAAK;AACH,aACE;AAAA,QAACD;AAAA,QAAA;AAAA,UAEC,qBAAkB;AAAA,UAClB,eAAcE,MAAA,QAAQ,iBAAR,gBAAAA,IAAA;AAAA,UACd,SAAS;AAAA,UACT;AAAA,UACA,WAAW,cAAc,oBAAoB,CAAC,QAAQ;AAAA,UACtD,cAAc,cAAc,oBAAoB,CAAC,CAAC,QAAQ;AAAA,UAC1D;AAAA,UACA,cAAc,MAAM,6CAAe,QAAQ;AAAA,UAC3C;AAAA,UACA;AAAA,UACA;AAAA,UACA;AAAA,UACA,eAAeD;AAAA;AAAA,QAbV;AAAA,MAcP;AAAA,EAEN;AACF;","names":["UserMessage","AssistantMessage","ImageRenderer","_a"]}
@@ -1,32 +0,0 @@
1
- // src/hooks/use-copilot-chat-suggestions.tsx
2
- import { useEffect } from "react";
3
- import { useCopilotContext } from "@copilotkit/react-core";
4
- import { randomId } from "@copilotkit/shared";
5
- function useCopilotChatSuggestions({
6
- available = "enabled",
7
- instructions,
8
- className,
9
- minSuggestions = 1,
10
- maxSuggestions = 3
11
- }, dependencies = []) {
12
- const context = useCopilotContext();
13
- useEffect(() => {
14
- if (available === "disabled")
15
- return;
16
- const id = randomId();
17
- context.addChatSuggestionConfiguration(id, {
18
- instructions,
19
- minSuggestions,
20
- maxSuggestions,
21
- className
22
- });
23
- return () => {
24
- context.removeChatSuggestionConfiguration(id);
25
- };
26
- }, [...dependencies, instructions, minSuggestions, maxSuggestions, className, available]);
27
- }
28
-
29
- export {
30
- useCopilotChatSuggestions
31
- };
32
- //# sourceMappingURL=chunk-EYRKZDP5.mjs.map
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../src/hooks/use-copilot-chat-suggestions.tsx"],"sourcesContent":["/**\n * <Callout type=\"warning\">\n * useCopilotChatSuggestions is experimental. The interface is not final and\n * can change without notice.\n * </Callout>\n *\n * `useCopilotReadable` is a React hook that provides app-state and other information\n * to the Copilot. Optionally, the hook can also handle hierarchical state within your\n * application, passing these parent-child relationships to the Copilot.\n *\n * <br/>\n * <img src=\"https://cdn.copilotkit.ai/docs/copilotkit/images/use-copilot-chat-suggestions/use-copilot-chat-suggestions.gif\" width=\"500\" />\n *\n * ## Usage\n *\n * ### Install Dependencies\n *\n * This component is part of the [@copilotkit/react-ui](https://npmjs.com/package/@copilotkit/react-ui) package.\n *\n * ```shell npm2yarn \\\"@copilotkit/react-ui\"\\\n * npm install @copilotkit/react-core @copilotkit/react-ui\n * ```\n *\n * ### Simple Usage\n *\n * ```tsx\n * import { useCopilotChatSuggestions } from \"@copilotkit/react-ui\";\n *\n * export function MyComponent() {\n * const [employees, setEmployees] = useState([]);\n *\n * useCopilotChatSuggestions({\n * instructions: `The following employees are on duty: ${JSON.stringify(employees)}`,\n * });\n * }\n * ```\n *\n * ### Dependency Management\n *\n * ```tsx\n * import { useCopilotChatSuggestions } from \"@copilotkit/react-ui\";\n *\n * export function MyComponent() {\n * useCopilotChatSuggestions(\n * {\n * instructions: \"Suggest the most relevant next actions.\",\n * },\n * [appState],\n * );\n * }\n * ```\n *\n * In the example above, the suggestions are generated based on the given instructions.\n * The hook monitors `appState`, and updates suggestions accordingly whenever it changes.\n *\n * ### Behavior and Lifecycle\n *\n * The hook registers the configuration with the chat context upon component mount and\n * removes it on unmount, ensuring a clean and efficient lifecycle management.\n */\n\nimport { useEffect } from \"react\";\nimport { useCopilotContext } from \"@copilotkit/react-core\";\nimport { randomId } from \"@copilotkit/shared\";\n\ninterface UseCopilotChatSuggestionsConfiguration {\n /**\n * A prompt or instructions for the GPT to generate suggestions.\n */\n instructions: string;\n /**\n * The minimum number of suggestions to generate. Defaults to `1`.\n * @default 1\n */\n minSuggestions?: number;\n /**\n * The maximum number of suggestions to generate. Defaults to `3`.\n * @default 1\n */\n maxSuggestions?: number;\n\n /**\n * Whether the suggestions are available. Defaults to `enabled`.\n * @default enabled\n */\n available?: \"enabled\" | \"disabled\";\n\n /**\n * An optional class name to apply to the suggestions.\n */\n className?: string;\n}\n\nexport function useCopilotChatSuggestions(\n {\n available = \"enabled\",\n instructions,\n className,\n minSuggestions = 1,\n maxSuggestions = 3,\n }: UseCopilotChatSuggestionsConfiguration,\n dependencies: any[] = [],\n) {\n const context = useCopilotContext();\n\n useEffect(() => {\n if (available === \"disabled\") return;\n\n const id = randomId();\n\n context.addChatSuggestionConfiguration(id, {\n instructions,\n minSuggestions,\n maxSuggestions,\n className,\n });\n\n return () => {\n context.removeChatSuggestionConfiguration(id);\n };\n }, [...dependencies, instructions, minSuggestions, maxSuggestions, className, available]);\n}\n"],"mappings":";AA6DA,SAAS,iBAAiB;AAC1B,SAAS,yBAAyB;AAClC,SAAS,gBAAgB;AA8BlB,SAAS,0BACd;AAAA,EACE,YAAY;AAAA,EACZ;AAAA,EACA;AAAA,EACA,iBAAiB;AAAA,EACjB,iBAAiB;AACnB,GACA,eAAsB,CAAC,GACvB;AACA,QAAM,UAAU,kBAAkB;AAElC,YAAU,MAAM;AACd,QAAI,cAAc;AAAY;AAE9B,UAAM,KAAK,SAAS;AAEpB,YAAQ,+BAA+B,IAAI;AAAA,MACzC;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,IACF,CAAC;AAED,WAAO,MAAM;AACX,cAAQ,kCAAkC,EAAE;AAAA,IAC9C;AAAA,EACF,GAAG,CAAC,GAAG,cAAc,cAAc,gBAAgB,gBAAgB,WAAW,SAAS,CAAC;AAC1F;","names":[]}
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../src/components/chat/Input.tsx"],"sourcesContent":["import React, { useMemo, useRef, useState } from \"react\";\nimport { InputProps } from \"./props\";\nimport { useChatContext } from \"./ChatContext\";\nimport AutoResizingTextarea from \"./Textarea\";\nimport { usePushToTalk } from \"../../hooks/use-push-to-talk\";\nimport { useCopilotContext } from \"@copilotkit/react-core\";\nimport { PoweredByTag } from \"./PoweredByTag\";\n\nconst MAX_NEWLINES = 6;\n\nexport const Input = ({\n inProgress,\n onSend,\n isVisible = false,\n onStop,\n onUpload,\n hideStopButton = false,\n}: InputProps) => {\n const context = useChatContext();\n const copilotContext = useCopilotContext();\n\n const showPoweredBy = !copilotContext.copilotApiConfig?.publicApiKey;\n\n const pushToTalkConfigured =\n copilotContext.copilotApiConfig.textToSpeechUrl !== undefined &&\n copilotContext.copilotApiConfig.transcribeAudioUrl !== undefined;\n\n const textareaRef = useRef<HTMLTextAreaElement>(null);\n const [isComposing, setIsComposing] = useState(false);\n\n const handleDivClick = (event: React.MouseEvent<HTMLDivElement>) => {\n const target = event.target as HTMLElement;\n\n // If the user clicked a button or inside a button, don't focus the textarea\n if (target.closest(\"button\")) return;\n\n // If the user clicked the textarea, do nothing (it's already focused)\n if (target.tagName === \"TEXTAREA\") return;\n\n // Otherwise, focus the textarea\n textareaRef.current?.focus();\n };\n\n const [text, setText] = useState(\"\");\n const send = () => {\n if (inProgress) return;\n onSend(text);\n setText(\"\");\n\n textareaRef.current?.focus();\n };\n\n // tylerslaton:\n //\n // This scrolls CopilotKit into view always. Reading the commit history, it was likely\n // added to fix a bug but it is causing issues now.\n //\n // For the future, if we want this behavior again, we will need to find a way to do it without\n // forcing CopilotKit to always be in view. This code causes this because focusing an element\n // in most browsers will scroll that element into view.\n //\n // useEffect(() => {\n // if (isVisible) {\n // textareaRef.current?.focus();\n // }\n // }, [isVisible]);\n\n const { pushToTalkState, setPushToTalkState } = usePushToTalk({\n sendFunction: onSend,\n inProgress,\n });\n\n const isInProgress = inProgress || pushToTalkState === \"transcribing\";\n const buttonIcon =\n isInProgress && !hideStopButton ? context.icons.stopIcon : context.icons.sendIcon;\n const showPushToTalk =\n pushToTalkConfigured &&\n (pushToTalkState === \"idle\" || pushToTalkState === \"recording\") &&\n !inProgress;\n\n const canSend = useMemo(() => {\n const interruptEvent = copilotContext.langGraphInterruptAction?.event;\n const interruptInProgress =\n interruptEvent?.name === \"LangGraphInterruptEvent\" && !interruptEvent?.response;\n\n return (\n !isInProgress && text.trim().length > 0 && pushToTalkState === \"idle\" && !interruptInProgress\n );\n }, [copilotContext.langGraphInterruptAction?.event, isInProgress, text, pushToTalkState]);\n\n const canStop = useMemo(() => {\n return isInProgress && !hideStopButton;\n }, [isInProgress, hideStopButton]);\n\n const sendDisabled = !canSend && !canStop;\n\n return (\n <div className={`copilotKitInputContainer ${showPoweredBy ? \"poweredByContainer\" : \"\"}`}>\n <div className=\"copilotKitInput\" onClick={handleDivClick}>\n <AutoResizingTextarea\n ref={textareaRef}\n placeholder={context.labels.placeholder}\n autoFocus={false}\n maxRows={MAX_NEWLINES}\n value={text}\n onChange={(event) => setText(event.target.value)}\n onCompositionStart={() => setIsComposing(true)}\n onCompositionEnd={() => setIsComposing(false)}\n onKeyDown={(event) => {\n if (event.key === \"Enter\" && !event.shiftKey && !isComposing) {\n event.preventDefault();\n if (canSend) {\n send();\n }\n }\n }}\n />\n <div className=\"copilotKitInputControls\">\n {onUpload && (\n <button onClick={onUpload} className=\"copilotKitInputControlButton\">\n {context.icons.uploadIcon}\n </button>\n )}\n\n <div style={{ flexGrow: 1 }} />\n\n {showPushToTalk && (\n <button\n onClick={() =>\n setPushToTalkState(pushToTalkState === \"idle\" ? \"recording\" : \"transcribing\")\n }\n className={\n pushToTalkState === \"recording\"\n ? \"copilotKitInputControlButton copilotKitPushToTalkRecording\"\n : \"copilotKitInputControlButton\"\n }\n >\n {context.icons.pushToTalkIcon}\n </button>\n )}\n <button\n disabled={sendDisabled}\n onClick={isInProgress && !hideStopButton ? onStop : send}\n data-copilotkit-in-progress={inProgress}\n data-test-id={inProgress ? \"copilot-chat-request-in-progress\" : \"copilot-chat-ready\"}\n className=\"copilotKitInputControlButton\"\n >\n {buttonIcon}\n </button>\n </div>\n </div>\n <PoweredByTag showPoweredBy={showPoweredBy} />\n </div>\n );\n};\n"],"mappings":"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","names":["_a"]}