@copilotkit/react-ui 0.22.0 → 0.36.0-mme-pre.1
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.
- package/.turbo/turbo-build.log +211 -178
- package/CHANGELOG.md +24 -0
- package/dist/chunk-4MKP23AD.mjs +97 -0
- package/dist/chunk-4MKP23AD.mjs.map +1 -0
- package/dist/{chunk-T3WYKWNC.mjs → chunk-6XLZXLM5.mjs} +6 -6
- package/dist/chunk-6XLZXLM5.mjs.map +1 -0
- package/dist/{chunk-73EBDGYK.mjs → chunk-7FES2IQA.mjs} +5 -5
- package/dist/chunk-7FES2IQA.mjs.map +1 -0
- package/dist/chunk-ANO23V2M.mjs +135 -0
- package/dist/chunk-ANO23V2M.mjs.map +1 -0
- package/dist/chunk-BL65ZC6L.mjs +83 -0
- package/dist/chunk-BL65ZC6L.mjs.map +1 -0
- package/dist/{chunk-YEHO5VMA.mjs → chunk-CE7PJAAO.mjs} +2 -2
- package/dist/{chunk-7YXG7D47.mjs → chunk-FZC7X5PK.mjs} +57 -2
- package/dist/chunk-FZC7X5PK.mjs.map +1 -0
- package/dist/chunk-LTCJCXCP.mjs +29 -0
- package/dist/chunk-LTCJCXCP.mjs.map +1 -0
- package/dist/chunk-MRFF7GSQ.mjs +1 -0
- package/dist/{chunk-7JYUCW7H.mjs → chunk-PAQWLSA4.mjs} +2 -2
- package/dist/{chunk-YTIGBBTC.mjs → chunk-RT2XG2T7.mjs} +2 -2
- package/dist/chunk-RT2XG2T7.mjs.map +1 -0
- package/dist/chunk-T26KLXLH.mjs +1 -0
- package/dist/{chunk-6U3O2JZP.mjs → chunk-T3JTSIHT.mjs} +32 -39
- package/dist/chunk-T3JTSIHT.mjs.map +1 -0
- package/dist/{chunk-MBYUBR3F.mjs → chunk-UPTB2MVO.mjs} +2 -2
- package/dist/chunk-VUZA5AFH.mjs +73 -0
- package/dist/chunk-VUZA5AFH.mjs.map +1 -0
- package/dist/{chunk-YAORLSQ3.mjs → chunk-XRODMID5.mjs} +6 -6
- package/dist/chunk-XRODMID5.mjs.map +1 -0
- package/dist/{chunk-WDHLWSSU.mjs → chunk-YQ3D5IQV.mjs} +2 -2
- package/dist/{chunk-WM6BS77F.mjs → chunk-YQFVRDNC.mjs} +2 -2
- package/dist/{chunk-WM6BS77F.mjs.map → chunk-YQFVRDNC.mjs.map} +1 -1
- package/dist/chunk-ZO3GLN23.mjs +137 -0
- package/dist/chunk-ZO3GLN23.mjs.map +1 -0
- package/dist/components/chat/Button.js.map +1 -1
- package/dist/components/chat/Button.mjs +3 -3
- package/dist/components/chat/Chat.d.ts +66 -46
- package/dist/components/chat/Chat.js +433 -278
- package/dist/components/chat/Chat.js.map +1 -1
- package/dist/components/chat/Chat.mjs +15 -14
- package/dist/components/chat/ChatContext.d.ts +16 -16
- package/dist/components/chat/ChatContext.js +43 -27
- package/dist/components/chat/ChatContext.js.map +1 -1
- package/dist/components/chat/ChatContext.mjs +2 -2
- package/dist/components/chat/CodeBlock.js.map +1 -1
- package/dist/components/chat/CodeBlock.mjs +2 -2
- package/dist/components/chat/Header.js.map +1 -1
- package/dist/components/chat/Header.mjs +3 -3
- package/dist/components/chat/Icons.d.ts +7 -5
- package/dist/components/chat/Icons.js +57 -0
- package/dist/components/chat/Icons.js.map +1 -1
- package/dist/components/chat/Icons.mjs +5 -1
- package/dist/components/chat/Input.d.ts +1 -1
- package/dist/components/chat/Input.js +148 -11
- package/dist/components/chat/Input.js.map +1 -1
- package/dist/components/chat/Input.mjs +5 -4
- package/dist/components/chat/Markdown.js.map +1 -1
- package/dist/components/chat/Markdown.mjs +3 -3
- package/dist/components/chat/Messages.d.ts +1 -1
- package/dist/components/chat/Messages.js +2 -2
- package/dist/components/chat/Messages.js.map +1 -1
- package/dist/components/chat/Messages.mjs +5 -5
- package/dist/components/chat/Modal.d.ts +50 -0
- package/dist/components/chat/Modal.js +1584 -0
- package/dist/components/chat/Modal.js.map +1 -0
- package/dist/components/chat/Modal.mjs +23 -0
- package/dist/components/chat/Modal.mjs.map +1 -0
- package/dist/components/chat/Popup.d.ts +56 -4
- package/dist/components/chat/Popup.js +428 -78
- package/dist/components/chat/Popup.js.map +1 -1
- package/dist/components/chat/Popup.mjs +15 -12
- package/dist/components/chat/Response.js.map +1 -1
- package/dist/components/chat/Response.mjs +3 -3
- package/dist/components/chat/Sidebar.d.ts +7 -8
- package/dist/components/chat/Sidebar.js +430 -80
- package/dist/components/chat/Sidebar.js.map +1 -1
- package/dist/components/chat/Sidebar.mjs +15 -12
- package/dist/components/chat/Suggestion.d.ts +13 -0
- package/dist/components/chat/Suggestion.js +172 -0
- package/dist/components/chat/Suggestion.js.map +1 -0
- package/dist/components/chat/Suggestion.mjs +11 -0
- package/dist/components/chat/Suggestion.mjs.map +1 -0
- package/dist/components/chat/Textarea.d.ts +4 -4
- package/dist/components/chat/Textarea.js +1 -1
- package/dist/components/chat/Textarea.js.map +1 -1
- package/dist/components/chat/Textarea.mjs +1 -1
- package/dist/components/chat/index.d.ts +4 -2
- package/dist/components/chat/index.js +436 -84
- package/dist/components/chat/index.js.map +1 -1
- package/dist/components/chat/index.mjs +22 -16
- package/dist/components/chat/props.d.ts +10 -3
- package/dist/components/chat/props.js.map +1 -1
- package/dist/components/index.d.ts +4 -2
- package/dist/components/index.js +436 -84
- package/dist/components/index.js.map +1 -1
- package/dist/components/index.mjs +22 -16
- package/dist/hooks/index.d.ts +1 -2
- package/dist/hooks/index.js +36 -0
- package/dist/hooks/index.js.map +1 -1
- package/dist/hooks/index.mjs +8 -1
- package/dist/hooks/use-copilot-chat-suggestions.d.ts +87 -0
- package/dist/hooks/use-copilot-chat-suggestions.js +53 -0
- package/dist/hooks/use-copilot-chat-suggestions.js.map +1 -0
- package/dist/hooks/use-copilot-chat-suggestions.mjs +8 -0
- package/dist/hooks/use-copilot-chat-suggestions.mjs.map +1 -0
- package/dist/hooks/use-push-to-talk.d.ts +19 -0
- package/dist/hooks/use-push-to-talk.js +177 -0
- package/dist/hooks/use-push-to-talk.js.map +1 -0
- package/dist/hooks/use-push-to-talk.mjs +12 -0
- package/dist/hooks/use-push-to-talk.mjs.map +1 -0
- package/dist/index.css +101 -13
- package/dist/index.css.map +1 -1
- package/dist/index.d.ts +5 -2
- package/dist/index.js +465 -86
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +29 -19
- package/dist/types/suggestions.d.ts +8 -0
- package/dist/types/suggestions.js +19 -0
- package/dist/types/suggestions.js.map +1 -0
- package/dist/types/suggestions.mjs +1 -0
- package/dist/types/suggestions.mjs.map +1 -0
- package/package.json +6 -6
- package/src/components/chat/Button.tsx +1 -2
- package/src/components/chat/Chat.tsx +163 -104
- package/src/components/chat/ChatContext.tsx +36 -38
- package/src/components/chat/Icons.tsx +44 -0
- package/src/components/chat/Input.tsx +38 -7
- package/src/components/chat/Messages.tsx +3 -3
- package/src/components/chat/Modal.tsx +115 -0
- package/src/components/chat/Popup.tsx +53 -7
- package/src/components/chat/Sidebar.tsx +62 -9
- package/src/components/chat/Suggestion.tsx +109 -0
- package/src/components/chat/Textarea.tsx +1 -1
- package/src/components/chat/index.tsx +1 -0
- package/src/components/chat/props.ts +10 -2
- package/src/css/input.css +18 -8
- package/src/css/messages.css +7 -1
- package/src/css/panel.css +38 -0
- package/src/css/response.css +1 -4
- package/src/css/suggestions.css +35 -0
- package/src/css/window.css +3 -1
- package/src/hooks/index.ts +1 -1
- package/src/hooks/use-copilot-chat-suggestions.tsx +117 -0
- package/src/hooks/use-push-to-talk.tsx +162 -0
- package/src/styles.css +2 -0
- package/src/types/suggestions.ts +6 -0
- package/typedoc.json +4 -0
- package/dist/chunk-6U3O2JZP.mjs.map +0 -1
- package/dist/chunk-73EBDGYK.mjs.map +0 -1
- package/dist/chunk-7LMXXGJT.mjs +0 -75
- package/dist/chunk-7LMXXGJT.mjs.map +0 -1
- package/dist/chunk-7YXG7D47.mjs.map +0 -1
- package/dist/chunk-H4VKQGVU.mjs +0 -1
- package/dist/chunk-KE3N45ZY.mjs +0 -63
- package/dist/chunk-KE3N45ZY.mjs.map +0 -1
- package/dist/chunk-T3WYKWNC.mjs.map +0 -1
- package/dist/chunk-UGQQ4WEQ.mjs +0 -1
- package/dist/chunk-YAORLSQ3.mjs.map +0 -1
- package/dist/chunk-YTIGBBTC.mjs.map +0 -1
- /package/dist/{chunk-YEHO5VMA.mjs.map → chunk-CE7PJAAO.mjs.map} +0 -0
- /package/dist/{chunk-H4VKQGVU.mjs.map → chunk-MRFF7GSQ.mjs.map} +0 -0
- /package/dist/{chunk-7JYUCW7H.mjs.map → chunk-PAQWLSA4.mjs.map} +0 -0
- /package/dist/{chunk-UGQQ4WEQ.mjs.map → chunk-T26KLXLH.mjs.map} +0 -0
- /package/dist/{chunk-MBYUBR3F.mjs.map → chunk-UPTB2MVO.mjs.map} +0 -0
- /package/dist/{chunk-WDHLWSSU.mjs.map → chunk-YQ3D5IQV.mjs.map} +0 -0
|
@@ -1,21 +1,66 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
1
|
+
/**
|
|
2
|
+
* An embeddable chat panel for CopilotKit.
|
|
3
|
+
*
|
|
4
|
+
* <img src="/images/CopilotChat/CopilotChat.gif" width="500" />
|
|
5
|
+
*
|
|
6
|
+
* A chatbot panel component for the CopilotKit framework. The component allows for a high degree
|
|
7
|
+
* of customization through various props and custom CSS.
|
|
8
|
+
*
|
|
9
|
+
* <RequestExample>
|
|
10
|
+
* ```jsx CopilotChat Example
|
|
11
|
+
* import { CopilotChat } from "@copilotkit/react-ui";
|
|
12
|
+
*
|
|
13
|
+
* <CopilotChat
|
|
14
|
+
* labels={{
|
|
15
|
+
* title: "Your Assistant",
|
|
16
|
+
* initial: "Hi! 👋 How can I assist you today?",
|
|
17
|
+
* }}
|
|
18
|
+
* />
|
|
19
|
+
* ```
|
|
20
|
+
* </RequestExample>
|
|
21
|
+
*
|
|
22
|
+
* ## Custom CSS
|
|
23
|
+
*
|
|
24
|
+
* You can customize the colors of the panel by overriding the CSS variables
|
|
25
|
+
* defined in the [default styles](https://github.com/CopilotKit/CopilotKit/blob/main/CopilotKit/packages/react-ui/src/css/colors.css).
|
|
26
|
+
*
|
|
27
|
+
* For example, to set the primary color to purple:
|
|
28
|
+
*
|
|
29
|
+
* ```jsx
|
|
30
|
+
* <div style={{ "--copilot-kit-primary-color": "#7D5BA6" }}>
|
|
31
|
+
* <CopilotPopup />
|
|
32
|
+
* </div>
|
|
33
|
+
* ```
|
|
34
|
+
*
|
|
35
|
+
* To further customize the panel, you can override the CSS classes defined
|
|
36
|
+
* [here](https://github.com/CopilotKit/CopilotKit/blob/main/CopilotKit/packages/react-ui/src/css/).
|
|
37
|
+
*
|
|
38
|
+
* For example:
|
|
39
|
+
*
|
|
40
|
+
* ```css
|
|
41
|
+
* .copilotKitButton {
|
|
42
|
+
* border-radius: 0;
|
|
43
|
+
* }
|
|
44
|
+
* ```
|
|
45
|
+
*/
|
|
46
|
+
|
|
4
47
|
import {
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
ResponseButtonProps,
|
|
11
|
-
} from "./props";
|
|
12
|
-
import { Window as DefaultWindow } from "./Window";
|
|
13
|
-
import { Button as DefaultButton } from "./Button";
|
|
14
|
-
import { Header as DefaultHeader } from "./Header";
|
|
48
|
+
ChatContext,
|
|
49
|
+
ChatContextProvider,
|
|
50
|
+
CopilotChatIcons,
|
|
51
|
+
CopilotChatLabels,
|
|
52
|
+
} from "./ChatContext";
|
|
15
53
|
import { Messages as DefaultMessages } from "./Messages";
|
|
16
54
|
import { Input as DefaultInput } from "./Input";
|
|
17
|
-
import { nanoid } from "nanoid";
|
|
18
55
|
import { ResponseButton as DefaultResponseButton } from "./Response";
|
|
56
|
+
import { Suggestion } from "./Suggestion";
|
|
57
|
+
import React, { useEffect, useRef, useState } from "react";
|
|
58
|
+
import { SystemMessageFunction, useCopilotChat, useCopilotContext } from "@copilotkit/react-core";
|
|
59
|
+
import { nanoid } from "nanoid";
|
|
60
|
+
import { reloadSuggestions } from "./Suggestion";
|
|
61
|
+
import { CopilotChatSuggestion } from "../../types/suggestions";
|
|
62
|
+
import { Message } from "@copilotkit/shared";
|
|
63
|
+
import { InputProps, MessagesProps, ResponseButtonProps } from "./props";
|
|
19
64
|
|
|
20
65
|
/**
|
|
21
66
|
* Props for CopilotChat component.
|
|
@@ -31,29 +76,6 @@ export interface CopilotChatProps {
|
|
|
31
76
|
*/
|
|
32
77
|
instructions?: string;
|
|
33
78
|
|
|
34
|
-
/**
|
|
35
|
-
* Whether the chat window should be open by default.
|
|
36
|
-
* @default false
|
|
37
|
-
*/
|
|
38
|
-
defaultOpen?: boolean;
|
|
39
|
-
|
|
40
|
-
/**
|
|
41
|
-
* If the chat window should close when the user clicks outside of it.
|
|
42
|
-
* @default true
|
|
43
|
-
*/
|
|
44
|
-
clickOutsideToClose?: boolean;
|
|
45
|
-
|
|
46
|
-
/**
|
|
47
|
-
* If the chat window should close when the user hits the Escape key.
|
|
48
|
-
* @default true
|
|
49
|
-
*/
|
|
50
|
-
hitEscapeToClose?: boolean;
|
|
51
|
-
|
|
52
|
-
/**
|
|
53
|
-
* A callback that gets called when the chat window opens or closes.
|
|
54
|
-
*/
|
|
55
|
-
onSetOpen?: (open: boolean) => void;
|
|
56
|
-
|
|
57
79
|
/**
|
|
58
80
|
* A callback that gets called when the in progress state changes.
|
|
59
81
|
*/
|
|
@@ -64,13 +86,6 @@ export interface CopilotChatProps {
|
|
|
64
86
|
*/
|
|
65
87
|
onSubmitMessage?: (message: string) => void;
|
|
66
88
|
|
|
67
|
-
/**
|
|
68
|
-
* The shortcut key to open the chat window.
|
|
69
|
-
* Uses Command-<shortcut> on a Mac and Ctrl-<shortcut> on Windows.
|
|
70
|
-
* @default "e"
|
|
71
|
-
*/
|
|
72
|
-
shortcut?: string;
|
|
73
|
-
|
|
74
89
|
/**
|
|
75
90
|
* Icons can be used to set custom icons for the chat window.
|
|
76
91
|
*/
|
|
@@ -95,21 +110,6 @@ export interface CopilotChatProps {
|
|
|
95
110
|
*/
|
|
96
111
|
showResponseButton?: boolean;
|
|
97
112
|
|
|
98
|
-
/**
|
|
99
|
-
* A custom Window component to use instead of the default.
|
|
100
|
-
*/
|
|
101
|
-
Window?: React.ComponentType<WindowProps>;
|
|
102
|
-
|
|
103
|
-
/**
|
|
104
|
-
* A custom Button component to use instead of the default.
|
|
105
|
-
*/
|
|
106
|
-
Button?: React.ComponentType<ButtonProps>;
|
|
107
|
-
|
|
108
|
-
/**
|
|
109
|
-
* A custom Header component to use instead of the default.
|
|
110
|
-
*/
|
|
111
|
-
Header?: React.ComponentType<HeaderProps>;
|
|
112
|
-
|
|
113
113
|
/**
|
|
114
114
|
* A custom Messages component to use instead of the default.
|
|
115
115
|
*/
|
|
@@ -136,75 +136,134 @@ export interface CopilotChatProps {
|
|
|
136
136
|
children?: React.ReactNode;
|
|
137
137
|
}
|
|
138
138
|
|
|
139
|
-
export
|
|
139
|
+
export function CopilotChat({
|
|
140
140
|
instructions,
|
|
141
|
-
defaultOpen = false,
|
|
142
|
-
clickOutsideToClose = true,
|
|
143
|
-
hitEscapeToClose = true,
|
|
144
|
-
onSetOpen,
|
|
145
141
|
onSubmitMessage,
|
|
146
|
-
shortcut = "/",
|
|
147
142
|
icons,
|
|
148
143
|
labels,
|
|
149
144
|
makeSystemMessage,
|
|
150
145
|
showResponseButton = true,
|
|
151
146
|
onInProgress,
|
|
152
|
-
Window = DefaultWindow,
|
|
153
|
-
Button = DefaultButton,
|
|
154
|
-
Header = DefaultHeader,
|
|
155
147
|
Messages = DefaultMessages,
|
|
156
148
|
Input = DefaultInput,
|
|
157
149
|
ResponseButton = DefaultResponseButton,
|
|
158
150
|
className,
|
|
159
|
-
|
|
160
|
-
|
|
151
|
+
}: CopilotChatProps) {
|
|
152
|
+
const { visibleMessages, isLoading, currentSuggestions, sendMessage, stop, reload } =
|
|
153
|
+
useCopilotChatLogic(instructions, makeSystemMessage, onInProgress, onSubmitMessage);
|
|
154
|
+
|
|
155
|
+
const context = React.useContext(ChatContext);
|
|
156
|
+
let open = true;
|
|
157
|
+
let setOpen: (open: boolean) => void = () => {};
|
|
158
|
+
if (context) {
|
|
159
|
+
icons = context.icons;
|
|
160
|
+
labels = context.labels;
|
|
161
|
+
open = context.open;
|
|
162
|
+
setOpen = context.setOpen;
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
return (
|
|
166
|
+
<ChatContextProvider icons={icons} labels={labels} open={open} setOpen={setOpen}>
|
|
167
|
+
<div className={`copilotKitPanel ${className}`}>
|
|
168
|
+
<Messages messages={visibleMessages} inProgress={isLoading}>
|
|
169
|
+
{currentSuggestions.length > 0 && (
|
|
170
|
+
<div>
|
|
171
|
+
<h6>Suggested:</h6>
|
|
172
|
+
<div className="suggestions">
|
|
173
|
+
{currentSuggestions.map((suggestion, index) => (
|
|
174
|
+
<Suggestion
|
|
175
|
+
key={index}
|
|
176
|
+
title={suggestion.title}
|
|
177
|
+
message={suggestion.message}
|
|
178
|
+
partial={suggestion.partial}
|
|
179
|
+
className={suggestion.className}
|
|
180
|
+
onClick={(message) => sendMessage(message)}
|
|
181
|
+
/>
|
|
182
|
+
))}
|
|
183
|
+
</div>
|
|
184
|
+
</div>
|
|
185
|
+
)}
|
|
186
|
+
{showResponseButton && visibleMessages.length > 0 && (
|
|
187
|
+
<ResponseButton onClick={isLoading ? stop : reload} inProgress={isLoading} />
|
|
188
|
+
)}
|
|
189
|
+
</Messages>
|
|
190
|
+
<Input inProgress={isLoading} onSend={sendMessage} isVisible={true} />
|
|
191
|
+
</div>
|
|
192
|
+
</ChatContextProvider>
|
|
193
|
+
);
|
|
194
|
+
}
|
|
195
|
+
|
|
196
|
+
const SUGGESTIONS_DEBOUNCE_TIMEOUT = 1000;
|
|
197
|
+
|
|
198
|
+
export const useCopilotChatLogic = (
|
|
199
|
+
instructions?: string,
|
|
200
|
+
makeSystemMessage?: SystemMessageFunction,
|
|
201
|
+
onInProgress?: (isLoading: boolean) => void,
|
|
202
|
+
onSubmitMessage?: (messageContent: string) => void,
|
|
203
|
+
) => {
|
|
161
204
|
const { visibleMessages, append, reload, stop, isLoading, input, setInput } = useCopilotChat({
|
|
162
205
|
id: nanoid(),
|
|
163
206
|
makeSystemMessage,
|
|
164
207
|
additionalInstructions: instructions,
|
|
165
208
|
});
|
|
166
209
|
|
|
210
|
+
const [currentSuggestions, setCurrentSuggestions] = useState<CopilotChatSuggestion[]>([]);
|
|
211
|
+
const suggestionsAbortControllerRef = useRef<AbortController | null>(null);
|
|
212
|
+
const debounceTimerRef = useRef<any>();
|
|
213
|
+
|
|
214
|
+
const abortSuggestions = () => {
|
|
215
|
+
suggestionsAbortControllerRef.current?.abort();
|
|
216
|
+
suggestionsAbortControllerRef.current = null;
|
|
217
|
+
};
|
|
218
|
+
|
|
219
|
+
const context = useCopilotContext();
|
|
220
|
+
|
|
167
221
|
useEffect(() => {
|
|
168
222
|
onInProgress?.(isLoading);
|
|
169
|
-
}, [isLoading]);
|
|
170
223
|
|
|
171
|
-
|
|
224
|
+
abortSuggestions();
|
|
172
225
|
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
226
|
+
debounceTimerRef.current = setTimeout(
|
|
227
|
+
() => {
|
|
228
|
+
if (!isLoading && Object.keys(context.chatSuggestionConfiguration).length !== 0) {
|
|
229
|
+
suggestionsAbortControllerRef.current = new AbortController();
|
|
230
|
+
reloadSuggestions(
|
|
231
|
+
context,
|
|
232
|
+
context.chatSuggestionConfiguration,
|
|
233
|
+
setCurrentSuggestions,
|
|
234
|
+
suggestionsAbortControllerRef,
|
|
235
|
+
);
|
|
236
|
+
}
|
|
237
|
+
},
|
|
238
|
+
currentSuggestions.length == 0 ? 0 : SUGGESTIONS_DEBOUNCE_TIMEOUT,
|
|
239
|
+
);
|
|
177
240
|
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
241
|
+
return () => {
|
|
242
|
+
clearTimeout(debounceTimerRef.current);
|
|
243
|
+
};
|
|
244
|
+
}, [isLoading, context.chatSuggestionConfiguration]);
|
|
245
|
+
|
|
246
|
+
const sendMessage = async (messageContent: string) => {
|
|
247
|
+
abortSuggestions();
|
|
248
|
+
setCurrentSuggestions([]);
|
|
249
|
+
onSubmitMessage?.(messageContent);
|
|
250
|
+
const message: Message = {
|
|
181
251
|
id: nanoid(),
|
|
182
|
-
content:
|
|
252
|
+
content: messageContent,
|
|
183
253
|
role: "user",
|
|
184
|
-
}
|
|
254
|
+
};
|
|
255
|
+
append(message);
|
|
256
|
+
return message;
|
|
185
257
|
};
|
|
186
258
|
|
|
187
|
-
return
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
hitEscapeToClose={hitEscapeToClose}
|
|
198
|
-
>
|
|
199
|
-
<Header open={openState} setOpen={setOpen} />
|
|
200
|
-
<Messages messages={visibleMessages} inProgress={isLoading} />
|
|
201
|
-
<Input inProgress={isLoading} onSend={sendMessage} isVisible={openState}>
|
|
202
|
-
{showResponseButton && visibleMessages.length > 0 && (
|
|
203
|
-
<ResponseButton onClick={isLoading ? stop : reload} inProgress={isLoading} />
|
|
204
|
-
)}
|
|
205
|
-
</Input>
|
|
206
|
-
</Window>
|
|
207
|
-
</div>
|
|
208
|
-
</ChatContextProvider>
|
|
209
|
-
);
|
|
259
|
+
return {
|
|
260
|
+
visibleMessages,
|
|
261
|
+
isLoading,
|
|
262
|
+
currentSuggestions,
|
|
263
|
+
sendMessage,
|
|
264
|
+
stop,
|
|
265
|
+
reload,
|
|
266
|
+
input,
|
|
267
|
+
setInput,
|
|
268
|
+
};
|
|
210
269
|
};
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import React, { useMemo } from "react";
|
|
1
|
+
import React, { useMemo, useState } from "react";
|
|
2
2
|
import * as DefaultIcons from "./Icons";
|
|
3
3
|
|
|
4
4
|
/**
|
|
@@ -52,6 +52,13 @@ export interface CopilotChatIcons {
|
|
|
52
52
|
* @default <RegenerateIcon />
|
|
53
53
|
*/
|
|
54
54
|
regenerateIcon?: React.ReactNode;
|
|
55
|
+
|
|
56
|
+
/**
|
|
57
|
+
* The icons to use for push to talk.
|
|
58
|
+
* @default <PushToTalkIcon />
|
|
59
|
+
*/
|
|
60
|
+
|
|
61
|
+
pushToTalkIcon?: React.ReactNode;
|
|
55
62
|
}
|
|
56
63
|
|
|
57
64
|
/**
|
|
@@ -75,12 +82,6 @@ export interface CopilotChatLabels {
|
|
|
75
82
|
*/
|
|
76
83
|
placeholder?: string;
|
|
77
84
|
|
|
78
|
-
/**
|
|
79
|
-
* The message to display while the chat GPT is "thinking".
|
|
80
|
-
* @default "Thinking..."
|
|
81
|
-
*/
|
|
82
|
-
thinking?: string;
|
|
83
|
-
|
|
84
85
|
/**
|
|
85
86
|
* The message to display when an error occurs.
|
|
86
87
|
* @default "❌ An error occurred. Please try again."
|
|
@@ -140,38 +141,35 @@ export const ChatContextProvider = ({
|
|
|
140
141
|
open,
|
|
141
142
|
setOpen,
|
|
142
143
|
}: ChatContextProps) => {
|
|
143
|
-
const context =
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
stopGenerating: "Stop generating",
|
|
153
|
-
regenerateResponse: "Regenerate response",
|
|
154
|
-
},
|
|
155
|
-
...labels,
|
|
144
|
+
const context = {
|
|
145
|
+
labels: {
|
|
146
|
+
...{
|
|
147
|
+
initial: "",
|
|
148
|
+
title: "CopilotKit",
|
|
149
|
+
placeholder: "Type a message...",
|
|
150
|
+
error: "❌ An error occurred. Please try again.",
|
|
151
|
+
stopGenerating: "Stop generating",
|
|
152
|
+
regenerateResponse: "Regenerate response",
|
|
156
153
|
},
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
154
|
+
...labels,
|
|
155
|
+
},
|
|
156
|
+
|
|
157
|
+
icons: {
|
|
158
|
+
...{
|
|
159
|
+
openIcon: DefaultIcons.OpenIcon,
|
|
160
|
+
closeIcon: DefaultIcons.CloseIcon,
|
|
161
|
+
headerCloseIcon: DefaultIcons.HeaderCloseIcon,
|
|
162
|
+
sendIcon: DefaultIcons.SendIcon,
|
|
163
|
+
activityIcon: DefaultIcons.ActivityIcon,
|
|
164
|
+
spinnerIcon: DefaultIcons.SpinnerIcon,
|
|
165
|
+
stopIcon: DefaultIcons.StopIcon,
|
|
166
|
+
regenerateIcon: DefaultIcons.RegenerateIcon,
|
|
167
|
+
pushToTalkIcon: DefaultIcons.PushToTalkIcon,
|
|
170
168
|
},
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
169
|
+
icons,
|
|
170
|
+
},
|
|
171
|
+
open,
|
|
172
|
+
setOpen,
|
|
173
|
+
};
|
|
176
174
|
return <ChatContext.Provider value={context}>{children}</ChatContext.Provider>;
|
|
177
175
|
};
|
|
@@ -92,6 +92,33 @@ export const SpinnerIcon = (
|
|
|
92
92
|
</svg>
|
|
93
93
|
);
|
|
94
94
|
|
|
95
|
+
export const SmallSpinnerIcon = (
|
|
96
|
+
<svg
|
|
97
|
+
style={{
|
|
98
|
+
animation: "copilotKitSpinAnimation 1s linear infinite",
|
|
99
|
+
}}
|
|
100
|
+
width="13"
|
|
101
|
+
height="13"
|
|
102
|
+
xmlns="http://www.w3.org/2000/svg"
|
|
103
|
+
fill="none"
|
|
104
|
+
viewBox="0 0 24 24"
|
|
105
|
+
>
|
|
106
|
+
<circle
|
|
107
|
+
style={{ opacity: 0.25 }}
|
|
108
|
+
cx="12"
|
|
109
|
+
cy="12"
|
|
110
|
+
r="10"
|
|
111
|
+
stroke="currentColor"
|
|
112
|
+
strokeWidth="4"
|
|
113
|
+
></circle>
|
|
114
|
+
<path
|
|
115
|
+
style={{ opacity: 0.75 }}
|
|
116
|
+
fill="currentColor"
|
|
117
|
+
d="M4 12a8 8 0 018-8V0C5.373 0 0 5.373 0 12h4zm2 5.291A7.962 7.962 0 014 12H0c0 3.042 1.135 5.824 3 7.938l3-2.647z"
|
|
118
|
+
></path>
|
|
119
|
+
</svg>
|
|
120
|
+
);
|
|
121
|
+
|
|
95
122
|
export const ActivityIcon = (
|
|
96
123
|
<svg
|
|
97
124
|
style={{
|
|
@@ -177,3 +204,20 @@ export const RegenerateIcon = (
|
|
|
177
204
|
<path d="M197.67 186.37a8 8 0 0 1 0 11.29C196.58 198.73 170.82 224 128 224c-37.39 0-64.53-22.4-80-39.85V208a8 8 0 0 1-16 0v-48a8 8 0 0 1 8-8h48a8 8 0 0 1 0 16H55.44C67.76 183.35 93 208 128 208c36 0 58.14-21.46 58.36-21.68a8 8 0 0 1 11.31.05ZM216 40a8 8 0 0 0-8 8v23.85C192.53 54.4 165.39 32 128 32c-42.82 0-68.58 25.27-69.66 26.34a8 8 0 0 0 11.3 11.34C69.86 69.46 92 48 128 48c35 0 60.24 24.65 72.56 40H168a8 8 0 0 0 0 16h48a8 8 0 0 0 8-8V48a8 8 0 0 0-8-8Z" />
|
|
178
205
|
</svg>
|
|
179
206
|
);
|
|
207
|
+
|
|
208
|
+
export const PushToTalkIcon = (
|
|
209
|
+
<svg
|
|
210
|
+
xmlns="http://www.w3.org/2000/svg"
|
|
211
|
+
fill="none"
|
|
212
|
+
viewBox="0 0 24 24"
|
|
213
|
+
strokeWidth={1.5}
|
|
214
|
+
stroke="currentColor"
|
|
215
|
+
className="w-6 h-6"
|
|
216
|
+
>
|
|
217
|
+
<path
|
|
218
|
+
strokeLinecap="round"
|
|
219
|
+
strokeLinejoin="round"
|
|
220
|
+
d="M12 18.75a6 6 0 0 0 6-6v-1.5m-6 7.5a6 6 0 0 1-6-6v-1.5m6 7.5v3.75m-3.75 0h7.5M12 15.75a3 3 0 0 1-3-3V4.5a3 3 0 1 1 6 0v8.25a3 3 0 0 1-3 3Z"
|
|
221
|
+
/>
|
|
222
|
+
</svg>
|
|
223
|
+
);
|
|
@@ -2,9 +2,17 @@ import React, { useEffect, useRef, useState } from "react";
|
|
|
2
2
|
import { InputProps } from "./props";
|
|
3
3
|
import { useChatContext } from "./ChatContext";
|
|
4
4
|
import AutoResizingTextarea from "./Textarea";
|
|
5
|
+
import { usePushToTalk } from "../../hooks/use-push-to-talk";
|
|
6
|
+
import { useCopilotContext } from "@copilotkit/react-core";
|
|
5
7
|
|
|
6
|
-
export const Input = ({ inProgress, onSend,
|
|
8
|
+
export const Input = ({ inProgress, onSend, isVisible = false }: InputProps) => {
|
|
7
9
|
const context = useChatContext();
|
|
10
|
+
const copilotContext = useCopilotContext();
|
|
11
|
+
|
|
12
|
+
const pushToTalkConfigured =
|
|
13
|
+
copilotContext.copilotApiConfig.textToSpeechUrl !== undefined &&
|
|
14
|
+
copilotContext.copilotApiConfig.transcribeAudioUrl !== undefined;
|
|
15
|
+
|
|
8
16
|
const textareaRef = useRef<HTMLTextAreaElement>(null);
|
|
9
17
|
|
|
10
18
|
const handleDivClick = (event: React.MouseEvent<HTMLDivElement>) => {
|
|
@@ -29,15 +37,23 @@ export const Input = ({ inProgress, onSend, children, isVisible = false }: Input
|
|
|
29
37
|
}
|
|
30
38
|
}, [isVisible]);
|
|
31
39
|
|
|
32
|
-
const
|
|
33
|
-
|
|
40
|
+
const { pushToTalkState, setPushToTalkState } = usePushToTalk({
|
|
41
|
+
sendFunction: onSend,
|
|
42
|
+
inProgress,
|
|
43
|
+
});
|
|
44
|
+
|
|
45
|
+
const sendIcon =
|
|
46
|
+
inProgress || pushToTalkState === "transcribing"
|
|
47
|
+
? context.icons.activityIcon
|
|
48
|
+
: context.icons.sendIcon;
|
|
49
|
+
const showPushToTalk =
|
|
50
|
+
pushToTalkConfigured &&
|
|
51
|
+
(pushToTalkState === "idle" || pushToTalkState === "recording") &&
|
|
52
|
+
!inProgress;
|
|
53
|
+
const sendDisabled = inProgress || text.length === 0 || pushToTalkState !== "idle";
|
|
34
54
|
|
|
35
55
|
return (
|
|
36
56
|
<div className="copilotKitInput" onClick={handleDivClick}>
|
|
37
|
-
<span>{children}</span>
|
|
38
|
-
<button className="copilotKitSendButton" disabled={disabled} onClick={send}>
|
|
39
|
-
{icon}
|
|
40
|
-
</button>
|
|
41
57
|
<AutoResizingTextarea
|
|
42
58
|
ref={textareaRef}
|
|
43
59
|
placeholder={context.labels.placeholder}
|
|
@@ -52,6 +68,21 @@ export const Input = ({ inProgress, onSend, children, isVisible = false }: Input
|
|
|
52
68
|
}
|
|
53
69
|
}}
|
|
54
70
|
/>
|
|
71
|
+
<div className="copilotKitInputControls">
|
|
72
|
+
{showPushToTalk && (
|
|
73
|
+
<button
|
|
74
|
+
onClick={() =>
|
|
75
|
+
setPushToTalkState(pushToTalkState === "idle" ? "recording" : "transcribing")
|
|
76
|
+
}
|
|
77
|
+
className={pushToTalkState === "recording" ? "copilotKitPushToTalkRecording" : ""}
|
|
78
|
+
>
|
|
79
|
+
{context.icons.pushToTalkIcon}
|
|
80
|
+
</button>
|
|
81
|
+
)}
|
|
82
|
+
<button disabled={sendDisabled} onClick={send}>
|
|
83
|
+
{sendIcon}
|
|
84
|
+
</button>
|
|
85
|
+
</div>
|
|
55
86
|
</div>
|
|
56
87
|
);
|
|
57
88
|
};
|
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
import React, { useEffect, useMemo } from "react";
|
|
2
|
-
import { MessagesProps } from "./props";
|
|
2
|
+
import { MessagesProps, SuggestionsProps } from "./props";
|
|
3
3
|
import { useChatContext } from "./ChatContext";
|
|
4
4
|
import { nanoid } from "nanoid";
|
|
5
5
|
import { Message, decodeResult } from "@copilotkit/shared";
|
|
6
6
|
import { Markdown } from "./Markdown";
|
|
7
7
|
import { ActionRenderProps, RenderFunctionStatus, useCopilotContext } from "@copilotkit/react-core";
|
|
8
8
|
|
|
9
|
-
export const Messages = ({ messages, inProgress }: MessagesProps) => {
|
|
9
|
+
export const Messages = ({ messages, inProgress, children }: MessagesProps) => {
|
|
10
10
|
const { chatComponentsCache } = useCopilotContext();
|
|
11
11
|
const context = useChatContext();
|
|
12
12
|
const initialMessages = useMemo(
|
|
@@ -145,7 +145,7 @@ export const Messages = ({ messages, inProgress }: MessagesProps) => {
|
|
|
145
145
|
);
|
|
146
146
|
}
|
|
147
147
|
})}
|
|
148
|
-
<
|
|
148
|
+
<footer ref={messagesEndRef}>{children}</footer>
|
|
149
149
|
</div>
|
|
150
150
|
);
|
|
151
151
|
};
|
|
@@ -0,0 +1,115 @@
|
|
|
1
|
+
import React from "react";
|
|
2
|
+
import { ChatContextProvider } from "./ChatContext";
|
|
3
|
+
import { ButtonProps, HeaderProps, WindowProps } from "./props";
|
|
4
|
+
import { Window as DefaultWindow } from "./Window";
|
|
5
|
+
import { Button as DefaultButton } from "./Button";
|
|
6
|
+
import { Header as DefaultHeader } from "./Header";
|
|
7
|
+
import { Messages as DefaultMessages } from "./Messages";
|
|
8
|
+
import { Input as DefaultInput } from "./Input";
|
|
9
|
+
import { ResponseButton as DefaultResponseButton } from "./Response";
|
|
10
|
+
import { CopilotChat, CopilotChatProps } from "./Chat";
|
|
11
|
+
|
|
12
|
+
export interface CopilotModalProps extends CopilotChatProps {
|
|
13
|
+
/**
|
|
14
|
+
* Whether the chat window should be open by default.
|
|
15
|
+
* @default false
|
|
16
|
+
*/
|
|
17
|
+
defaultOpen?: boolean;
|
|
18
|
+
|
|
19
|
+
/**
|
|
20
|
+
* If the chat window should close when the user clicks outside of it.
|
|
21
|
+
* @default true
|
|
22
|
+
*/
|
|
23
|
+
clickOutsideToClose?: boolean;
|
|
24
|
+
|
|
25
|
+
/**
|
|
26
|
+
* If the chat window should close when the user hits the Escape key.
|
|
27
|
+
* @default true
|
|
28
|
+
*/
|
|
29
|
+
hitEscapeToClose?: boolean;
|
|
30
|
+
|
|
31
|
+
/**
|
|
32
|
+
* The shortcut key to open the chat window.
|
|
33
|
+
* Uses Command-[shortcut] on a Mac and Ctrl-[shortcut] on Windows.
|
|
34
|
+
* @default "/"
|
|
35
|
+
*/
|
|
36
|
+
shortcut?: string;
|
|
37
|
+
|
|
38
|
+
/**
|
|
39
|
+
* A callback that gets called when the chat window opens or closes.
|
|
40
|
+
*/
|
|
41
|
+
onSetOpen?: (open: boolean) => void;
|
|
42
|
+
|
|
43
|
+
/**
|
|
44
|
+
* A custom Window component to use instead of the default.
|
|
45
|
+
*/
|
|
46
|
+
Window?: React.ComponentType<WindowProps>;
|
|
47
|
+
|
|
48
|
+
/**
|
|
49
|
+
* A custom Button component to use instead of the default.
|
|
50
|
+
*/
|
|
51
|
+
Button?: React.ComponentType<ButtonProps>;
|
|
52
|
+
|
|
53
|
+
/**
|
|
54
|
+
* A custom Header component to use instead of the default.
|
|
55
|
+
*/
|
|
56
|
+
Header?: React.ComponentType<HeaderProps>;
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
export const CopilotModal = ({
|
|
60
|
+
instructions,
|
|
61
|
+
defaultOpen = false,
|
|
62
|
+
clickOutsideToClose = true,
|
|
63
|
+
hitEscapeToClose = true,
|
|
64
|
+
onSetOpen,
|
|
65
|
+
onSubmitMessage,
|
|
66
|
+
shortcut = "/",
|
|
67
|
+
icons,
|
|
68
|
+
labels,
|
|
69
|
+
makeSystemMessage,
|
|
70
|
+
showResponseButton = true,
|
|
71
|
+
onInProgress,
|
|
72
|
+
Window = DefaultWindow,
|
|
73
|
+
Button = DefaultButton,
|
|
74
|
+
Header = DefaultHeader,
|
|
75
|
+
Messages = DefaultMessages,
|
|
76
|
+
Input = DefaultInput,
|
|
77
|
+
ResponseButton = DefaultResponseButton,
|
|
78
|
+
className,
|
|
79
|
+
children,
|
|
80
|
+
}: CopilotModalProps) => {
|
|
81
|
+
const [openState, setOpenState] = React.useState(defaultOpen);
|
|
82
|
+
|
|
83
|
+
const setOpen = (open: boolean) => {
|
|
84
|
+
onSetOpen?.(open);
|
|
85
|
+
setOpenState(open);
|
|
86
|
+
};
|
|
87
|
+
|
|
88
|
+
return (
|
|
89
|
+
<ChatContextProvider icons={icons} labels={labels} open={openState} setOpen={setOpenState}>
|
|
90
|
+
{children}
|
|
91
|
+
<div className={className}>
|
|
92
|
+
<Button open={openState} setOpen={setOpen}></Button>
|
|
93
|
+
<Window
|
|
94
|
+
open={openState}
|
|
95
|
+
setOpen={setOpen}
|
|
96
|
+
clickOutsideToClose={clickOutsideToClose}
|
|
97
|
+
shortcut={shortcut}
|
|
98
|
+
hitEscapeToClose={hitEscapeToClose}
|
|
99
|
+
>
|
|
100
|
+
<Header open={openState} setOpen={setOpen} />
|
|
101
|
+
<CopilotChat
|
|
102
|
+
instructions={instructions}
|
|
103
|
+
makeSystemMessage={makeSystemMessage}
|
|
104
|
+
onInProgress={onInProgress}
|
|
105
|
+
onSubmitMessage={onSubmitMessage}
|
|
106
|
+
showResponseButton={showResponseButton}
|
|
107
|
+
Messages={Messages}
|
|
108
|
+
Input={Input}
|
|
109
|
+
ResponseButton={ResponseButton}
|
|
110
|
+
/>
|
|
111
|
+
</Window>
|
|
112
|
+
</div>
|
|
113
|
+
</ChatContextProvider>
|
|
114
|
+
);
|
|
115
|
+
};
|