@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,6 +1,6 @@
|
|
|
1
1
|
import {
|
|
2
|
-
|
|
3
|
-
} from "./chunk-
|
|
2
|
+
CopilotModal
|
|
3
|
+
} from "./chunk-T3JTSIHT.mjs";
|
|
4
4
|
import {
|
|
5
5
|
__spreadProps,
|
|
6
6
|
__spreadValues
|
|
@@ -9,7 +9,7 @@ import {
|
|
|
9
9
|
// src/components/chat/Sidebar.tsx
|
|
10
10
|
import { useState } from "react";
|
|
11
11
|
import { jsx } from "react/jsx-runtime";
|
|
12
|
-
|
|
12
|
+
function CopilotSidebar(props) {
|
|
13
13
|
props = __spreadProps(__spreadValues({}, props), {
|
|
14
14
|
className: props.className ? props.className + " copilotKitSidebar" : "copilotKitSidebar"
|
|
15
15
|
});
|
|
@@ -21,10 +21,10 @@ var CopilotSidebar = (props) => {
|
|
|
21
21
|
(_a = props.onSetOpen) == null ? void 0 : _a.call(props, open);
|
|
22
22
|
setExpandedClassName(open ? "sidebarExpanded" : "");
|
|
23
23
|
};
|
|
24
|
-
return /* @__PURE__ */ jsx("div", { className: `copilotKitSidebarContentWrapper ${expandedClassName}`, children: /* @__PURE__ */ jsx(
|
|
25
|
-
}
|
|
24
|
+
return /* @__PURE__ */ jsx("div", { className: `copilotKitSidebarContentWrapper ${expandedClassName}`, children: /* @__PURE__ */ jsx(CopilotModal, __spreadProps(__spreadValues(__spreadValues({}, props), { onSetOpen }), { children: props.children })) });
|
|
25
|
+
}
|
|
26
26
|
|
|
27
27
|
export {
|
|
28
28
|
CopilotSidebar
|
|
29
29
|
};
|
|
30
|
-
//# sourceMappingURL=chunk-
|
|
30
|
+
//# sourceMappingURL=chunk-6XLZXLM5.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/components/chat/Sidebar.tsx"],"sourcesContent":["/**\n * A chatbot sidebar component for CopilotKit.\n *\n * <img src=\"/images/CopilotSidebar/CopilotSidebar.gif\" width=\"500\" />\n *\n * <img referrerPolicy=\"no-referrer-when-downgrade\" src=\"https://static.scarf.sh/a.png?x-pxid=a9b290bb-38f9-4518-ac3b-8f54fdbf43be\" />\n *\n * A chatbot sidebar component for the CopilotKit framework. Highly customizable through various props and custom CSS.\n *\n * <RequestExample>\n * ```jsx CopilotSidebar Example\n * import { CopilotSidebar } from \"@copilotkit/react-ui\";\n *\n * <CopilotSidebar\n * labels={{\n * title: \"Your Assistant\",\n * initial: \"Hi! 👋 How can I assist you today?\",\n * }}\n * >\n * <YourApp/>\n * </CopilotSidebar>\n * ```\n * </RequestExample>\n *\n *\n * See [CopilotPopup](./CopilotPopup) for a popup version of this component.\n *\n * <Note>\n * To make the sidebar push your content to the side, wrap your content in the\n * sidebar component. If you want the sidebar to overlay your content, place the\n * sidebar component outside of your content.\n * </Note>\n *\n * ## Custom CSS\n *\n * You can customize the colors of the chat window by overriding the CSS variables\n * defined in the [default styles](https://github.com/CopilotKit/CopilotKit/blob/main/CopilotKit/packages/react-ui/src/css/colors.css).\n *\n * For example, to set the primary color to purple:\n *\n * ```jsx\n * <div style={{ \"--copilot-kit-primary-color\": \"#7D5BA6\" }}>\n * <CopilotSidebar />\n * </div>\n * ```\n *\n * To further customize the chat window, you can override the CSS classes defined\n * [here](https://github.com/CopilotKit/CopilotKit/blob/main/CopilotKit/packages/react-ui/src/css/).\n *\n * For example:\n *\n * ```css\n * .copilotKitButton {\n * border-radius: 0;\n * }\n * ```\n */\nimport React, { useState } from \"react\";\nimport { CopilotModal, CopilotModalProps } from \"./Modal\";\n\nexport function CopilotSidebar(props: CopilotModalProps) {\n props = {\n ...props,\n className: props.className ? props.className + \" copilotKitSidebar\" : \"copilotKitSidebar\",\n };\n const [expandedClassName, setExpandedClassName] = useState(\n props.defaultOpen ? \"sidebarExpanded\" : \"\",\n );\n\n const onSetOpen = (open: boolean) => {\n props.onSetOpen?.(open);\n setExpandedClassName(open ? \"sidebarExpanded\" : \"\");\n };\n\n return (\n <div className={`copilotKitSidebarContentWrapper ${expandedClassName}`}>\n <CopilotModal {...props} {...{ onSetOpen }}>\n {props.children}\n </CopilotModal>\n </div>\n );\n}\n"],"mappings":";;;;;;;;;AAyDA,SAAgB,gBAAgB;AAmB1B;AAhBC,SAAS,eAAe,OAA0B;AACvD,UAAQ,iCACH,QADG;AAAA,IAEN,WAAW,MAAM,YAAY,MAAM,YAAY,uBAAuB;AAAA,EACxE;AACA,QAAM,CAAC,mBAAmB,oBAAoB,IAAI;AAAA,IAChD,MAAM,cAAc,oBAAoB;AAAA,EAC1C;AAEA,QAAM,YAAY,CAAC,SAAkB;AArEvC;AAsEI,gBAAM,cAAN,+BAAkB;AAClB,yBAAqB,OAAO,oBAAoB,EAAE;AAAA,EACpD;AAEA,SACE,oBAAC,SAAI,WAAW,mCAAmC,qBACjD,8BAAC,8DAAiB,QAAW,EAAE,UAAU,IAAxC,EACE,gBAAM,WACT,GACF;AAEJ;","names":[]}
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
import {
|
|
2
2
|
Markdown
|
|
3
|
-
} from "./chunk-
|
|
3
|
+
} from "./chunk-YQ3D5IQV.mjs";
|
|
4
4
|
import {
|
|
5
5
|
useChatContext
|
|
6
|
-
} from "./chunk-
|
|
6
|
+
} from "./chunk-VUZA5AFH.mjs";
|
|
7
7
|
|
|
8
8
|
// src/components/chat/Messages.tsx
|
|
9
9
|
import React, { useEffect, useMemo } from "react";
|
|
@@ -11,7 +11,7 @@ import { nanoid } from "nanoid";
|
|
|
11
11
|
import { decodeResult } from "@copilotkit/shared";
|
|
12
12
|
import { useCopilotContext } from "@copilotkit/react-core";
|
|
13
13
|
import { jsx, jsxs } from "react/jsx-runtime";
|
|
14
|
-
var Messages = ({ messages, inProgress }) => {
|
|
14
|
+
var Messages = ({ messages, inProgress, children }) => {
|
|
15
15
|
const { chatComponentsCache } = useCopilotContext();
|
|
16
16
|
const context = useChatContext();
|
|
17
17
|
const initialMessages = useMemo(
|
|
@@ -97,7 +97,7 @@ var Messages = ({ messages, inProgress }) => {
|
|
|
97
97
|
return /* @__PURE__ */ jsx("div", { className: `copilotKitMessage copilotKitAssistantMessage`, children: /* @__PURE__ */ jsx(Markdown, { content: message.content }) }, index);
|
|
98
98
|
}
|
|
99
99
|
}),
|
|
100
|
-
/* @__PURE__ */ jsx("
|
|
100
|
+
/* @__PURE__ */ jsx("footer", { ref: messagesEndRef, children })
|
|
101
101
|
] });
|
|
102
102
|
};
|
|
103
103
|
function makeInitialMessages(initial) {
|
|
@@ -119,4 +119,4 @@ function makeInitialMessages(initial) {
|
|
|
119
119
|
export {
|
|
120
120
|
Messages
|
|
121
121
|
};
|
|
122
|
-
//# sourceMappingURL=chunk-
|
|
122
|
+
//# sourceMappingURL=chunk-7FES2IQA.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/components/chat/Messages.tsx"],"sourcesContent":["import React, { useEffect, useMemo } from \"react\";\nimport { MessagesProps, SuggestionsProps } from \"./props\";\nimport { useChatContext } from \"./ChatContext\";\nimport { nanoid } from \"nanoid\";\nimport { Message, decodeResult } from \"@copilotkit/shared\";\nimport { Markdown } from \"./Markdown\";\nimport { ActionRenderProps, RenderFunctionStatus, useCopilotContext } from \"@copilotkit/react-core\";\n\nexport const Messages = ({ messages, inProgress, children }: MessagesProps) => {\n const { chatComponentsCache } = useCopilotContext();\n const context = useChatContext();\n const initialMessages = useMemo(\n () => makeInitialMessages(context.labels.initial),\n [context.labels.initial],\n );\n messages = [...initialMessages, ...messages];\n\n const functionResults: Record<string, string> = {};\n\n for (let i = 0; i < messages.length; i++) {\n if (messages[i].role === \"assistant\" && messages[i].function_call) {\n const id = messages[i].id;\n if (i + 1 < messages.length && messages[i + 1].role === \"function\") {\n functionResults[id] = decodeResult(messages[i + 1].content || \"\");\n }\n }\n }\n\n const messagesEndRef = React.useRef<HTMLDivElement>(null);\n\n const scrollToBottom = () => {\n if (messagesEndRef.current) {\n messagesEndRef.current.scrollIntoView({\n behavior: \"auto\",\n });\n }\n };\n\n useEffect(() => {\n scrollToBottom();\n }, [messages]);\n\n return (\n <div className=\"copilotKitMessages\">\n {messages.map((message, index) => {\n const isCurrentMessage = index === messages.length - 1;\n\n if (message.role === \"user\") {\n return (\n <div key={index} className=\"copilotKitMessage copilotKitUserMessage\">\n {message.content}\n </div>\n );\n } else if (message.role == \"assistant\") {\n if (isCurrentMessage && inProgress && !message.content && !message.partialFunctionCall) {\n // The message is in progress and there is no content- show the spinner\n return (\n <div key={index} className={`copilotKitMessage copilotKitAssistantMessage`}>\n {context.icons.spinnerIcon}\n </div>\n );\n } else if (message.function_call || message.partialFunctionCall) {\n // Find the action that corresponds to the function call if any\n const functionCallName: string = (message.function_call?.name ||\n message.partialFunctionCall?.name)!;\n if (\n chatComponentsCache.current !== null &&\n chatComponentsCache.current[functionCallName]\n ) {\n const render = chatComponentsCache.current[functionCallName];\n\n // render a static string\n if (typeof render === \"string\") {\n // when render is static, we show it only when in progress\n if (isCurrentMessage && inProgress) {\n return (\n <div key={index} className={`copilotKitMessage copilotKitAssistantMessage`}>\n {context.icons.spinnerIcon} <span className=\"inProgressLabel\">{render}</span>\n </div>\n );\n }\n // Done - silent by default to avoid a series of \"done\" messages\n else {\n return null;\n }\n }\n // render is a function\n else {\n const args = message.function_call\n ? JSON.parse(message.function_call.arguments || \"{}\")\n : message.partialFunctionCall?.arguments;\n\n let status: RenderFunctionStatus = \"inProgress\";\n\n if (functionResults[message.id] !== undefined) {\n status = \"complete\";\n } else if (message.function_call) {\n status = \"executing\";\n }\n\n const toRender = render({\n status: status as any,\n args,\n result: functionResults[message.id],\n });\n\n // No result and complete: stay silent\n if (!toRender && status === \"complete\") {\n return null;\n }\n\n if (typeof toRender === \"string\") {\n return (\n <div key={index} className={`copilotKitMessage copilotKitAssistantMessage`}>\n {isCurrentMessage && inProgress && context.icons.spinnerIcon} {toRender}\n </div>\n );\n } else {\n return (\n <div key={index} className=\"copilotKitCustomAssistantMessage\">\n {toRender}\n </div>\n );\n }\n }\n }\n // No render function found- show the default message\n else if ((!inProgress || !isCurrentMessage) && message.function_call) {\n // Done - silent by default to avoid a series of \"done\" messages\n return null;\n } else {\n // In progress\n return (\n <div key={index} className={`copilotKitMessage copilotKitAssistantMessage`}>\n {context.icons.spinnerIcon}\n </div>\n );\n }\n }\n\n return (\n <div key={index} className={`copilotKitMessage copilotKitAssistantMessage`}>\n <Markdown content={message.content} />\n </div>\n );\n }\n })}\n <footer ref={messagesEndRef}>{children}</footer>\n </div>\n );\n};\n\nfunction makeInitialMessages(initial?: string | string[]): Message[] {\n let initialArray: string[] = [];\n if (initial) {\n if (Array.isArray(initial)) {\n initialArray.push(...initial);\n } else {\n initialArray.push(initial);\n }\n }\n\n return initialArray.map((message) => ({\n id: nanoid(),\n role: \"assistant\",\n content: message,\n }));\n}\n"],"mappings":"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","names":[]}
|
|
@@ -0,0 +1,135 @@
|
|
|
1
|
+
import {
|
|
2
|
+
__async
|
|
3
|
+
} from "./chunk-MRXNTQOX.mjs";
|
|
4
|
+
|
|
5
|
+
// src/hooks/use-push-to-talk.tsx
|
|
6
|
+
import { useCopilotContext } from "@copilotkit/react-core";
|
|
7
|
+
import { useEffect, useRef, useState } from "react";
|
|
8
|
+
var checkMicrophonePermission = () => __async(void 0, null, function* () {
|
|
9
|
+
try {
|
|
10
|
+
const permissionStatus = yield navigator.permissions.query({
|
|
11
|
+
name: "microphone"
|
|
12
|
+
});
|
|
13
|
+
if (permissionStatus.state === "granted") {
|
|
14
|
+
return true;
|
|
15
|
+
} else {
|
|
16
|
+
return false;
|
|
17
|
+
}
|
|
18
|
+
} catch (err) {
|
|
19
|
+
console.error("Error checking microphone permission", err);
|
|
20
|
+
}
|
|
21
|
+
});
|
|
22
|
+
var requestMicAndPlaybackPermission = () => __async(void 0, null, function* () {
|
|
23
|
+
try {
|
|
24
|
+
const stream = yield navigator.mediaDevices.getUserMedia({ audio: true });
|
|
25
|
+
const audioContext = new window.AudioContext();
|
|
26
|
+
yield audioContext.resume();
|
|
27
|
+
return { stream, audioContext };
|
|
28
|
+
} catch (err) {
|
|
29
|
+
console.error("Error requesting microphone and playback permissions", err);
|
|
30
|
+
return null;
|
|
31
|
+
}
|
|
32
|
+
});
|
|
33
|
+
var startRecording = (mediaStreamRef, mediaRecorderRef, audioContextRef, recordedChunks, onStop) => __async(void 0, null, function* () {
|
|
34
|
+
if (!mediaStreamRef.current || !audioContextRef.current) {
|
|
35
|
+
mediaStreamRef.current = yield navigator.mediaDevices.getUserMedia({ audio: true });
|
|
36
|
+
audioContextRef.current = new window.AudioContext();
|
|
37
|
+
yield audioContextRef.current.resume();
|
|
38
|
+
}
|
|
39
|
+
mediaRecorderRef.current = new MediaRecorder(mediaStreamRef.current);
|
|
40
|
+
mediaRecorderRef.current.start(1e3);
|
|
41
|
+
mediaRecorderRef.current.ondataavailable = (event) => {
|
|
42
|
+
recordedChunks.push(event.data);
|
|
43
|
+
};
|
|
44
|
+
mediaRecorderRef.current.onstop = onStop;
|
|
45
|
+
});
|
|
46
|
+
var stopRecording = (mediaRecorderRef) => {
|
|
47
|
+
if (mediaRecorderRef.current && mediaRecorderRef.current.state !== "inactive") {
|
|
48
|
+
mediaRecorderRef.current.stop();
|
|
49
|
+
}
|
|
50
|
+
};
|
|
51
|
+
var transcribeAudio = (recordedChunks, transcribeAudioUrl) => __async(void 0, null, function* () {
|
|
52
|
+
const completeBlob = new Blob(recordedChunks, { type: "audio/mp4" });
|
|
53
|
+
const formData = new FormData();
|
|
54
|
+
formData.append("file", completeBlob, "recording.mp4");
|
|
55
|
+
const response = yield fetch(transcribeAudioUrl, {
|
|
56
|
+
method: "POST",
|
|
57
|
+
body: formData
|
|
58
|
+
});
|
|
59
|
+
if (!response.ok) {
|
|
60
|
+
throw new Error(`Error: ${response.statusText}`);
|
|
61
|
+
}
|
|
62
|
+
const transcription = yield response.json();
|
|
63
|
+
return transcription.text;
|
|
64
|
+
});
|
|
65
|
+
var playAudioResponse = (text, textToSpeechUrl, audioContext) => {
|
|
66
|
+
const encodedText = encodeURIComponent(text);
|
|
67
|
+
const url = `${textToSpeechUrl}?text=${encodedText}`;
|
|
68
|
+
fetch(url).then((response) => response.arrayBuffer()).then((arrayBuffer) => audioContext.decodeAudioData(arrayBuffer)).then((audioBuffer) => {
|
|
69
|
+
const source = audioContext.createBufferSource();
|
|
70
|
+
source.buffer = audioBuffer;
|
|
71
|
+
source.connect(audioContext.destination);
|
|
72
|
+
source.start(0);
|
|
73
|
+
}).catch((error) => {
|
|
74
|
+
console.error("Error with decoding audio data", error);
|
|
75
|
+
});
|
|
76
|
+
};
|
|
77
|
+
var usePushToTalk = ({
|
|
78
|
+
sendFunction,
|
|
79
|
+
inProgress
|
|
80
|
+
}) => {
|
|
81
|
+
const [pushToTalkState, setPushToTalkState] = useState("idle");
|
|
82
|
+
const mediaStreamRef = useRef(null);
|
|
83
|
+
const audioContextRef = useRef(null);
|
|
84
|
+
const mediaRecorderRef = useRef(null);
|
|
85
|
+
const recordedChunks = useRef([]);
|
|
86
|
+
const context = useCopilotContext();
|
|
87
|
+
const [startReadingFromMessageId, setStartReadingFromMessageId] = useState(null);
|
|
88
|
+
useEffect(() => {
|
|
89
|
+
if (pushToTalkState === "recording") {
|
|
90
|
+
startRecording(
|
|
91
|
+
mediaStreamRef,
|
|
92
|
+
mediaRecorderRef,
|
|
93
|
+
audioContextRef,
|
|
94
|
+
recordedChunks.current,
|
|
95
|
+
() => {
|
|
96
|
+
setPushToTalkState("transcribing");
|
|
97
|
+
}
|
|
98
|
+
);
|
|
99
|
+
} else {
|
|
100
|
+
stopRecording(mediaRecorderRef);
|
|
101
|
+
if (pushToTalkState === "transcribing") {
|
|
102
|
+
transcribeAudio(recordedChunks.current, context.copilotApiConfig.transcribeAudioUrl).then(
|
|
103
|
+
(transcription) => __async(void 0, null, function* () {
|
|
104
|
+
recordedChunks.current = [];
|
|
105
|
+
setPushToTalkState("idle");
|
|
106
|
+
const message = yield sendFunction(transcription);
|
|
107
|
+
setStartReadingFromMessageId(message.id);
|
|
108
|
+
})
|
|
109
|
+
);
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
return () => {
|
|
113
|
+
stopRecording(mediaRecorderRef);
|
|
114
|
+
};
|
|
115
|
+
}, [pushToTalkState]);
|
|
116
|
+
useEffect(() => {
|
|
117
|
+
if (inProgress === false && startReadingFromMessageId) {
|
|
118
|
+
const lastMessageIndex = context.messages.findIndex(
|
|
119
|
+
(message) => message.id === startReadingFromMessageId
|
|
120
|
+
);
|
|
121
|
+
const messagesAfterLast = context.messages.slice(lastMessageIndex + 1).filter((message) => message.role === "assistant" && message.content);
|
|
122
|
+
const text = messagesAfterLast.map((message) => message.content).join("\n");
|
|
123
|
+
playAudioResponse(text, context.copilotApiConfig.textToSpeechUrl, audioContextRef.current);
|
|
124
|
+
setStartReadingFromMessageId(null);
|
|
125
|
+
}
|
|
126
|
+
}, [startReadingFromMessageId, inProgress]);
|
|
127
|
+
return { pushToTalkState, setPushToTalkState };
|
|
128
|
+
};
|
|
129
|
+
|
|
130
|
+
export {
|
|
131
|
+
checkMicrophonePermission,
|
|
132
|
+
requestMicAndPlaybackPermission,
|
|
133
|
+
usePushToTalk
|
|
134
|
+
};
|
|
135
|
+
//# sourceMappingURL=chunk-ANO23V2M.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/hooks/use-push-to-talk.tsx"],"sourcesContent":["import { CopilotContextParams, useCopilotContext } from \"@copilotkit/react-core\";\nimport { Message } from \"@copilotkit/shared\";\nimport { MutableRefObject, useEffect, useRef, useState } from \"react\";\n\nexport const checkMicrophonePermission = async () => {\n try {\n const permissionStatus = await navigator.permissions.query({\n name: \"microphone\" as PermissionName,\n });\n if (permissionStatus.state === \"granted\") {\n return true;\n } else {\n return false;\n }\n } catch (err) {\n console.error(\"Error checking microphone permission\", err);\n }\n};\n\nexport const requestMicAndPlaybackPermission = async () => {\n try {\n const stream = await navigator.mediaDevices.getUserMedia({ audio: true });\n const audioContext = new window.AudioContext();\n await audioContext.resume();\n return { stream, audioContext };\n } catch (err) {\n console.error(\"Error requesting microphone and playback permissions\", err);\n return null;\n }\n};\n\nconst startRecording = async (\n mediaStreamRef: MutableRefObject<MediaStream | null>,\n mediaRecorderRef: MutableRefObject<MediaRecorder | null>,\n audioContextRef: MutableRefObject<AudioContext | null>,\n recordedChunks: Blob[],\n onStop: () => void,\n) => {\n if (!mediaStreamRef.current || !audioContextRef.current) {\n mediaStreamRef.current = await navigator.mediaDevices.getUserMedia({ audio: true });\n audioContextRef.current = new window.AudioContext();\n await audioContextRef.current.resume();\n }\n\n mediaRecorderRef.current = new MediaRecorder(mediaStreamRef.current!);\n mediaRecorderRef.current.start(1000);\n mediaRecorderRef.current.ondataavailable = (event) => {\n recordedChunks.push(event.data);\n };\n mediaRecorderRef.current.onstop = onStop;\n};\n\nconst stopRecording = (mediaRecorderRef: MutableRefObject<MediaRecorder | null>) => {\n if (mediaRecorderRef.current && mediaRecorderRef.current.state !== \"inactive\") {\n mediaRecorderRef.current.stop();\n }\n};\n\nconst transcribeAudio = async (recordedChunks: Blob[], transcribeAudioUrl: string) => {\n const completeBlob = new Blob(recordedChunks, { type: \"audio/mp4\" });\n const formData = new FormData();\n formData.append(\"file\", completeBlob, \"recording.mp4\");\n\n const response = await fetch(transcribeAudioUrl, {\n method: \"POST\",\n body: formData,\n });\n\n if (!response.ok) {\n throw new Error(`Error: ${response.statusText}`);\n }\n\n const transcription = await response.json();\n return transcription.text;\n};\n\nconst playAudioResponse = (text: string, textToSpeechUrl: string, audioContext: AudioContext) => {\n const encodedText = encodeURIComponent(text);\n const url = `${textToSpeechUrl}?text=${encodedText}`;\n\n fetch(url)\n .then((response) => response.arrayBuffer())\n .then((arrayBuffer) => audioContext.decodeAudioData(arrayBuffer))\n .then((audioBuffer) => {\n const source = audioContext.createBufferSource();\n source.buffer = audioBuffer;\n source.connect(audioContext.destination);\n source.start(0);\n })\n .catch((error) => {\n console.error(\"Error with decoding audio data\", error);\n });\n};\n\nexport type PushToTalkState = \"idle\" | \"recording\" | \"transcribing\";\n\nexport type SendFunction = (text: string) => Promise<Message>;\n\nexport const usePushToTalk = ({\n sendFunction,\n inProgress,\n}: {\n sendFunction: SendFunction;\n inProgress: boolean;\n}) => {\n const [pushToTalkState, setPushToTalkState] = useState<PushToTalkState>(\"idle\");\n const mediaStreamRef = useRef<MediaStream | null>(null);\n const audioContextRef = useRef<AudioContext | null>(null);\n const mediaRecorderRef = useRef<MediaRecorder | null>(null);\n const recordedChunks = useRef<Blob[]>([]);\n const context = useCopilotContext();\n const [startReadingFromMessageId, setStartReadingFromMessageId] = useState<string | null>(null);\n\n useEffect(() => {\n if (pushToTalkState === \"recording\") {\n startRecording(\n mediaStreamRef,\n mediaRecorderRef,\n audioContextRef,\n recordedChunks.current,\n () => {\n setPushToTalkState(\"transcribing\");\n },\n );\n } else {\n stopRecording(mediaRecorderRef);\n if (pushToTalkState === \"transcribing\") {\n transcribeAudio(recordedChunks.current, context.copilotApiConfig.transcribeAudioUrl!).then(\n async (transcription) => {\n recordedChunks.current = [];\n setPushToTalkState(\"idle\");\n const message = await sendFunction(transcription);\n setStartReadingFromMessageId(message.id);\n },\n );\n }\n }\n\n return () => {\n stopRecording(mediaRecorderRef);\n };\n }, [pushToTalkState]);\n\n useEffect(() => {\n if (inProgress === false && startReadingFromMessageId) {\n const lastMessageIndex = context.messages.findIndex(\n (message) => message.id === startReadingFromMessageId,\n );\n\n const messagesAfterLast = context.messages\n .slice(lastMessageIndex + 1)\n .filter((message) => message.role === \"assistant\" && message.content);\n\n const text = messagesAfterLast.map((message) => message.content).join(\"\\n\");\n playAudioResponse(text, context.copilotApiConfig.textToSpeechUrl!, audioContextRef.current!);\n\n setStartReadingFromMessageId(null);\n }\n }, [startReadingFromMessageId, inProgress]);\n\n return { pushToTalkState, setPushToTalkState };\n};\n"],"mappings":"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","names":[]}
|
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
import {
|
|
2
|
+
Textarea_default
|
|
3
|
+
} from "./chunk-YQFVRDNC.mjs";
|
|
4
|
+
import {
|
|
5
|
+
useChatContext
|
|
6
|
+
} from "./chunk-VUZA5AFH.mjs";
|
|
7
|
+
import {
|
|
8
|
+
usePushToTalk
|
|
9
|
+
} from "./chunk-ANO23V2M.mjs";
|
|
10
|
+
|
|
11
|
+
// src/components/chat/Input.tsx
|
|
12
|
+
import { useEffect, useRef, useState } from "react";
|
|
13
|
+
import { useCopilotContext } from "@copilotkit/react-core";
|
|
14
|
+
import { jsx, jsxs } from "react/jsx-runtime";
|
|
15
|
+
var Input = ({ inProgress, onSend, isVisible = false }) => {
|
|
16
|
+
const context = useChatContext();
|
|
17
|
+
const copilotContext = useCopilotContext();
|
|
18
|
+
const pushToTalkConfigured = copilotContext.copilotApiConfig.textToSpeechUrl !== void 0 && copilotContext.copilotApiConfig.transcribeAudioUrl !== void 0;
|
|
19
|
+
const textareaRef = useRef(null);
|
|
20
|
+
const handleDivClick = (event) => {
|
|
21
|
+
var _a;
|
|
22
|
+
if (event.target !== event.currentTarget)
|
|
23
|
+
return;
|
|
24
|
+
(_a = textareaRef.current) == null ? void 0 : _a.focus();
|
|
25
|
+
};
|
|
26
|
+
const [text, setText] = useState("");
|
|
27
|
+
const send = () => {
|
|
28
|
+
var _a;
|
|
29
|
+
if (inProgress)
|
|
30
|
+
return;
|
|
31
|
+
onSend(text);
|
|
32
|
+
setText("");
|
|
33
|
+
(_a = textareaRef.current) == null ? void 0 : _a.focus();
|
|
34
|
+
};
|
|
35
|
+
useEffect(() => {
|
|
36
|
+
var _a;
|
|
37
|
+
if (isVisible) {
|
|
38
|
+
(_a = textareaRef.current) == null ? void 0 : _a.focus();
|
|
39
|
+
}
|
|
40
|
+
}, [isVisible]);
|
|
41
|
+
const { pushToTalkState, setPushToTalkState } = usePushToTalk({
|
|
42
|
+
sendFunction: onSend,
|
|
43
|
+
inProgress
|
|
44
|
+
});
|
|
45
|
+
const sendIcon = inProgress || pushToTalkState === "transcribing" ? context.icons.activityIcon : context.icons.sendIcon;
|
|
46
|
+
const showPushToTalk = pushToTalkConfigured && (pushToTalkState === "idle" || pushToTalkState === "recording") && !inProgress;
|
|
47
|
+
const sendDisabled = inProgress || text.length === 0 || pushToTalkState !== "idle";
|
|
48
|
+
return /* @__PURE__ */ jsxs("div", { className: "copilotKitInput", onClick: handleDivClick, children: [
|
|
49
|
+
/* @__PURE__ */ jsx(
|
|
50
|
+
Textarea_default,
|
|
51
|
+
{
|
|
52
|
+
ref: textareaRef,
|
|
53
|
+
placeholder: context.labels.placeholder,
|
|
54
|
+
autoFocus: true,
|
|
55
|
+
maxRows: 5,
|
|
56
|
+
value: text,
|
|
57
|
+
onChange: (event) => setText(event.target.value),
|
|
58
|
+
onKeyDown: (event) => {
|
|
59
|
+
if (event.key === "Enter" && !event.shiftKey) {
|
|
60
|
+
event.preventDefault();
|
|
61
|
+
send();
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
),
|
|
66
|
+
/* @__PURE__ */ jsxs("div", { className: "copilotKitInputControls", children: [
|
|
67
|
+
showPushToTalk && /* @__PURE__ */ jsx(
|
|
68
|
+
"button",
|
|
69
|
+
{
|
|
70
|
+
onClick: () => setPushToTalkState(pushToTalkState === "idle" ? "recording" : "transcribing"),
|
|
71
|
+
className: pushToTalkState === "recording" ? "copilotKitPushToTalkRecording" : "",
|
|
72
|
+
children: context.icons.pushToTalkIcon
|
|
73
|
+
}
|
|
74
|
+
),
|
|
75
|
+
/* @__PURE__ */ jsx("button", { disabled: sendDisabled, onClick: send, children: sendIcon })
|
|
76
|
+
] })
|
|
77
|
+
] });
|
|
78
|
+
};
|
|
79
|
+
|
|
80
|
+
export {
|
|
81
|
+
Input
|
|
82
|
+
};
|
|
83
|
+
//# sourceMappingURL=chunk-BL65ZC6L.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/components/chat/Input.tsx"],"sourcesContent":["import React, { useEffect, 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\";\n\nexport const Input = ({ inProgress, onSend, isVisible = false }: InputProps) => {\n const context = useChatContext();\n const copilotContext = useCopilotContext();\n\n const pushToTalkConfigured =\n copilotContext.copilotApiConfig.textToSpeechUrl !== undefined &&\n copilotContext.copilotApiConfig.transcribeAudioUrl !== undefined;\n\n const textareaRef = useRef<HTMLTextAreaElement>(null);\n\n const handleDivClick = (event: React.MouseEvent<HTMLDivElement>) => {\n // Check if the clicked element is not the textarea itself\n if (event.target !== event.currentTarget) return;\n\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 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 sendIcon =\n inProgress || pushToTalkState === \"transcribing\"\n ? context.icons.activityIcon\n : context.icons.sendIcon;\n const showPushToTalk =\n pushToTalkConfigured &&\n (pushToTalkState === \"idle\" || pushToTalkState === \"recording\") &&\n !inProgress;\n const sendDisabled = inProgress || text.length === 0 || pushToTalkState !== \"idle\";\n\n return (\n <div className=\"copilotKitInput\" onClick={handleDivClick}>\n <AutoResizingTextarea\n ref={textareaRef}\n placeholder={context.labels.placeholder}\n autoFocus={true}\n maxRows={5}\n value={text}\n onChange={(event) => setText(event.target.value)}\n onKeyDown={(event) => {\n if (event.key === \"Enter\" && !event.shiftKey) {\n event.preventDefault();\n send();\n }\n }}\n />\n <div className=\"copilotKitInputControls\">\n {showPushToTalk && (\n <button\n onClick={() =>\n setPushToTalkState(pushToTalkState === \"idle\" ? \"recording\" : \"transcribing\")\n }\n className={pushToTalkState === \"recording\" ? \"copilotKitPushToTalkRecording\" : \"\"}\n >\n {context.icons.pushToTalkIcon}\n </button>\n )}\n <button disabled={sendDisabled} onClick={send}>\n {sendIcon}\n </button>\n </div>\n </div>\n );\n};\n"],"mappings":";;;;;;;;;;;AAAA,SAAgB,WAAW,QAAQ,gBAAgB;AAKnD,SAAS,yBAAyB;AAmD5B,cAcA,YAdA;AAjDC,IAAM,QAAQ,CAAC,EAAE,YAAY,QAAQ,YAAY,MAAM,MAAkB;AAC9E,QAAM,UAAU,eAAe;AAC/B,QAAM,iBAAiB,kBAAkB;AAEzC,QAAM,uBACJ,eAAe,iBAAiB,oBAAoB,UACpD,eAAe,iBAAiB,uBAAuB;AAEzD,QAAM,cAAc,OAA4B,IAAI;AAEpD,QAAM,iBAAiB,CAAC,UAA4C;AAjBtE;AAmBI,QAAI,MAAM,WAAW,MAAM;AAAe;AAE1C,sBAAY,YAAZ,mBAAqB;AAAA,EACvB;AAEA,QAAM,CAAC,MAAM,OAAO,IAAI,SAAS,EAAE;AACnC,QAAM,OAAO,MAAM;AAzBrB;AA0BI,QAAI;AAAY;AAChB,WAAO,IAAI;AACX,YAAQ,EAAE;AAEV,sBAAY,YAAZ,mBAAqB;AAAA,EACvB;AAEA,YAAU,MAAM;AAjClB;AAkCI,QAAI,WAAW;AACb,wBAAY,YAAZ,mBAAqB;AAAA,IACvB;AAAA,EACF,GAAG,CAAC,SAAS,CAAC;AAEd,QAAM,EAAE,iBAAiB,mBAAmB,IAAI,cAAc;AAAA,IAC5D,cAAc;AAAA,IACd;AAAA,EACF,CAAC;AAED,QAAM,WACJ,cAAc,oBAAoB,iBAC9B,QAAQ,MAAM,eACd,QAAQ,MAAM;AACpB,QAAM,iBACJ,yBACC,oBAAoB,UAAU,oBAAoB,gBACnD,CAAC;AACH,QAAM,eAAe,cAAc,KAAK,WAAW,KAAK,oBAAoB;AAE5E,SACE,qBAAC,SAAI,WAAU,mBAAkB,SAAS,gBACxC;AAAA;AAAA,MAAC;AAAA;AAAA,QACC,KAAK;AAAA,QACL,aAAa,QAAQ,OAAO;AAAA,QAC5B,WAAW;AAAA,QACX,SAAS;AAAA,QACT,OAAO;AAAA,QACP,UAAU,CAAC,UAAU,QAAQ,MAAM,OAAO,KAAK;AAAA,QAC/C,WAAW,CAAC,UAAU;AACpB,cAAI,MAAM,QAAQ,WAAW,CAAC,MAAM,UAAU;AAC5C,kBAAM,eAAe;AACrB,iBAAK;AAAA,UACP;AAAA,QACF;AAAA;AAAA,IACF;AAAA,IACA,qBAAC,SAAI,WAAU,2BACZ;AAAA,wBACC;AAAA,QAAC;AAAA;AAAA,UACC,SAAS,MACP,mBAAmB,oBAAoB,SAAS,cAAc,cAAc;AAAA,UAE9E,WAAW,oBAAoB,cAAc,kCAAkC;AAAA,UAE9E,kBAAQ,MAAM;AAAA;AAAA,MACjB;AAAA,MAEF,oBAAC,YAAO,UAAU,cAAc,SAAS,MACtC,oBACH;AAAA,OACF;AAAA,KACF;AAEJ;","names":[]}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import {
|
|
2
2
|
useChatContext
|
|
3
|
-
} from "./chunk-
|
|
3
|
+
} from "./chunk-VUZA5AFH.mjs";
|
|
4
4
|
|
|
5
5
|
// src/components/chat/Response.tsx
|
|
6
6
|
import { jsx, jsxs } from "react/jsx-runtime";
|
|
@@ -15,4 +15,4 @@ var ResponseButton = ({ onClick, inProgress }) => {
|
|
|
15
15
|
export {
|
|
16
16
|
ResponseButton
|
|
17
17
|
};
|
|
18
|
-
//# sourceMappingURL=chunk-
|
|
18
|
+
//# sourceMappingURL=chunk-CE7PJAAO.mjs.map
|
|
@@ -105,6 +105,40 @@ var SpinnerIcon = /* @__PURE__ */ jsxs(
|
|
|
105
105
|
]
|
|
106
106
|
}
|
|
107
107
|
);
|
|
108
|
+
var SmallSpinnerIcon = /* @__PURE__ */ jsxs(
|
|
109
|
+
"svg",
|
|
110
|
+
{
|
|
111
|
+
style: {
|
|
112
|
+
animation: "copilotKitSpinAnimation 1s linear infinite"
|
|
113
|
+
},
|
|
114
|
+
width: "13",
|
|
115
|
+
height: "13",
|
|
116
|
+
xmlns: "http://www.w3.org/2000/svg",
|
|
117
|
+
fill: "none",
|
|
118
|
+
viewBox: "0 0 24 24",
|
|
119
|
+
children: [
|
|
120
|
+
/* @__PURE__ */ jsx(
|
|
121
|
+
"circle",
|
|
122
|
+
{
|
|
123
|
+
style: { opacity: 0.25 },
|
|
124
|
+
cx: "12",
|
|
125
|
+
cy: "12",
|
|
126
|
+
r: "10",
|
|
127
|
+
stroke: "currentColor",
|
|
128
|
+
strokeWidth: "4"
|
|
129
|
+
}
|
|
130
|
+
),
|
|
131
|
+
/* @__PURE__ */ jsx(
|
|
132
|
+
"path",
|
|
133
|
+
{
|
|
134
|
+
style: { opacity: 0.75 },
|
|
135
|
+
fill: "currentColor",
|
|
136
|
+
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"
|
|
137
|
+
}
|
|
138
|
+
)
|
|
139
|
+
]
|
|
140
|
+
}
|
|
141
|
+
);
|
|
108
142
|
var ActivityIcon = /* @__PURE__ */ jsxs(
|
|
109
143
|
"svg",
|
|
110
144
|
{
|
|
@@ -190,6 +224,25 @@ var RegenerateIcon = /* @__PURE__ */ jsx(
|
|
|
190
224
|
children: /* @__PURE__ */ jsx("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" })
|
|
191
225
|
}
|
|
192
226
|
);
|
|
227
|
+
var PushToTalkIcon = /* @__PURE__ */ jsx(
|
|
228
|
+
"svg",
|
|
229
|
+
{
|
|
230
|
+
xmlns: "http://www.w3.org/2000/svg",
|
|
231
|
+
fill: "none",
|
|
232
|
+
viewBox: "0 0 24 24",
|
|
233
|
+
strokeWidth: 1.5,
|
|
234
|
+
stroke: "currentColor",
|
|
235
|
+
className: "w-6 h-6",
|
|
236
|
+
children: /* @__PURE__ */ jsx(
|
|
237
|
+
"path",
|
|
238
|
+
{
|
|
239
|
+
strokeLinecap: "round",
|
|
240
|
+
strokeLinejoin: "round",
|
|
241
|
+
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"
|
|
242
|
+
}
|
|
243
|
+
)
|
|
244
|
+
}
|
|
245
|
+
);
|
|
193
246
|
|
|
194
247
|
export {
|
|
195
248
|
OpenIcon,
|
|
@@ -197,11 +250,13 @@ export {
|
|
|
197
250
|
HeaderCloseIcon,
|
|
198
251
|
SendIcon,
|
|
199
252
|
SpinnerIcon,
|
|
253
|
+
SmallSpinnerIcon,
|
|
200
254
|
ActivityIcon,
|
|
201
255
|
CheckIcon,
|
|
202
256
|
DownloadIcon,
|
|
203
257
|
CopyIcon,
|
|
204
258
|
StopIcon,
|
|
205
|
-
RegenerateIcon
|
|
259
|
+
RegenerateIcon,
|
|
260
|
+
PushToTalkIcon
|
|
206
261
|
};
|
|
207
|
-
//# sourceMappingURL=chunk-
|
|
262
|
+
//# sourceMappingURL=chunk-FZC7X5PK.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/components/chat/Icons.tsx"],"sourcesContent":["import React from \"react\";\n\nexport const OpenIcon = (\n <svg\n xmlns=\"http://www.w3.org/2000/svg\"\n viewBox=\"0 0 24 24\"\n fill=\"currentColor\"\n width=\"24\"\n height=\"24\"\n >\n <g transform=\"translate(24, 0) scale(-1, 1)\">\n <path\n fillRule=\"evenodd\"\n d=\"M5.337 21.718a6.707 6.707 0 01-.533-.074.75.75 0 01-.44-1.223 3.73 3.73 0 00.814-1.686c.023-.115-.022-.317-.254-.543C3.274 16.587 2.25 14.41 2.25 12c0-5.03 4.428-9 9.75-9s9.75 3.97 9.75 9c0 5.03-4.428 9-9.75 9-.833 0-1.643-.097-2.417-.279a6.721 6.721 0 01-4.246.997z\"\n clipRule=\"evenodd\"\n />\n </g>\n </svg>\n);\n\nexport const CloseIcon = (\n <svg\n xmlns=\"http://www.w3.org/2000/svg\"\n fill=\"none\"\n viewBox=\"0 0 24 24\"\n strokeWidth=\"1.5\"\n stroke=\"currentColor\"\n width=\"24\"\n height=\"24\"\n >\n <path strokeLinecap=\"round\" strokeLinejoin=\"round\" d=\"M19.5 8.25l-7.5 7.5-7.5-7.5\" />\n </svg>\n);\n\nexport const HeaderCloseIcon = (\n <svg\n xmlns=\"http://www.w3.org/2000/svg\"\n fill=\"none\"\n viewBox=\"0 0 24 24\"\n strokeWidth=\"1.5\"\n stroke=\"currentColor\"\n width=\"24\"\n height=\"24\"\n >\n <path strokeLinecap=\"round\" strokeLinejoin=\"round\" d=\"M6 18L18 6M6 6l12 12\" />\n </svg>\n);\n\nexport const SendIcon = (\n <svg\n xmlns=\"http://www.w3.org/2000/svg\"\n fill=\"none\"\n viewBox=\"0 0 24 24\"\n strokeWidth={1.5}\n stroke=\"currentColor\"\n width=\"24\"\n height=\"24\"\n >\n <path\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n d=\"M6 12L3.269 3.126A59.768 59.768 0 0121.485 12 59.77 59.77 0 013.27 20.876L5.999 12zm0 0h7.5\"\n />\n </svg>\n);\n\nexport const SpinnerIcon = (\n <svg\n style={{\n animation: \"copilotKitSpinAnimation 1s linear infinite\",\n color: \"rgb(107 114 128)\",\n }}\n width=\"24\"\n height=\"24\"\n xmlns=\"http://www.w3.org/2000/svg\"\n fill=\"none\"\n viewBox=\"0 0 24 24\"\n >\n <circle\n style={{ opacity: 0.25 }}\n cx=\"12\"\n cy=\"12\"\n r=\"10\"\n stroke=\"currentColor\"\n strokeWidth=\"4\"\n ></circle>\n <path\n style={{ opacity: 0.75 }}\n fill=\"currentColor\"\n 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\"\n ></path>\n </svg>\n);\n\nexport const SmallSpinnerIcon = (\n <svg\n style={{\n animation: \"copilotKitSpinAnimation 1s linear infinite\",\n }}\n width=\"13\"\n height=\"13\"\n xmlns=\"http://www.w3.org/2000/svg\"\n fill=\"none\"\n viewBox=\"0 0 24 24\"\n >\n <circle\n style={{ opacity: 0.25 }}\n cx=\"12\"\n cy=\"12\"\n r=\"10\"\n stroke=\"currentColor\"\n strokeWidth=\"4\"\n ></circle>\n <path\n style={{ opacity: 0.75 }}\n fill=\"currentColor\"\n 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\"\n ></path>\n </svg>\n);\n\nexport const ActivityIcon = (\n <svg\n style={{\n display: \"inline-block\",\n marginLeft: \"0.25rem\",\n marginRight: \"0.25rem\",\n }}\n height=\"24\"\n width=\"24\"\n viewBox=\"0 0 27 27\"\n xmlns=\"http://www.w3.org/2000/svg\"\n fill=\"currentColor\"\n >\n <circle className=\"copilotKitActivityDot1\" cx=\"4\" cy=\"12\" r=\"3\" />\n <circle className=\"copilotKitActivityDot1 copilotKitActivityDot2\" cx=\"12\" cy=\"12\" r=\"3\" />\n <circle className=\"copilotKitActivityDot1 copilotKitActivityDot3\" cx=\"20\" cy=\"12\" r=\"3\" />\n </svg>\n);\n\nexport function CheckIcon({ className, ...props }: React.ComponentProps<\"svg\">) {\n return (\n <svg\n xmlns=\"http://www.w3.org/2000/svg\"\n viewBox=\"0 0 256 256\"\n fill=\"currentColor\"\n style={{ height: \"1rem\", width: \"1rem\" }}\n className={className}\n {...props}\n >\n <path d=\"m229.66 77.66-128 128a8 8 0 0 1-11.32 0l-56-56a8 8 0 0 1 11.32-11.32L96 188.69 218.34 66.34a8 8 0 0 1 11.32 11.32Z\" />\n </svg>\n );\n}\n\nexport function DownloadIcon({ className, ...props }: React.ComponentProps<\"svg\">) {\n return (\n <svg\n xmlns=\"http://www.w3.org/2000/svg\"\n viewBox=\"0 0 256 256\"\n fill=\"currentColor\"\n style={{ height: \"1rem\", width: \"1rem\" }}\n className={className}\n {...props}\n >\n <path d=\"M224 152v56a16 16 0 0 1-16 16H48a16 16 0 0 1-16-16v-56a8 8 0 0 1 16 0v56h160v-56a8 8 0 0 1 16 0Zm-101.66 5.66a8 8 0 0 0 11.32 0l40-40a8 8 0 0 0-11.32-11.32L136 132.69V40a8 8 0 0 0-16 0v92.69l-26.34-26.35a8 8 0 0 0-11.32 11.32Z\" />\n </svg>\n );\n}\n\nexport function CopyIcon({ className, ...props }: React.ComponentProps<\"svg\">) {\n return (\n <svg\n xmlns=\"http://www.w3.org/2000/svg\"\n viewBox=\"0 0 256 256\"\n fill=\"currentColor\"\n style={{ height: \"1rem\", width: \"1rem\" }}\n className={className}\n {...props}\n >\n <path d=\"M216 32H88a8 8 0 0 0-8 8v40H40a8 8 0 0 0-8 8v128a8 8 0 0 0 8 8h128a8 8 0 0 0 8-8v-40h40a8 8 0 0 0 8-8V40a8 8 0 0 0-8-8Zm-56 176H48V96h112Zm48-48h-32V88a8 8 0 0 0-8-8H96V48h112Z\" />\n </svg>\n );\n}\n\nexport const StopIcon = (\n <svg\n xmlns=\"http://www.w3.org/2000/svg\"\n viewBox=\"0 0 256 256\"\n fill=\"currentColor\"\n style={{ height: \"1rem\", width: \"1rem\" }}\n >\n <path d=\"M128 24a104 104 0 1 0 104 104A104.11 104.11 0 0 0 128 24Zm0 192a88 88 0 1 1 88-88 88.1 88.1 0 0 1-88 88Zm24-120h-48a8 8 0 0 0-8 8v48a8 8 0 0 0 8 8h48a8 8 0 0 0 8-8v-48a8 8 0 0 0-8-8Zm-8 48h-32v-32h32Z\" />\n </svg>\n);\n\nexport const RegenerateIcon = (\n <svg\n xmlns=\"http://www.w3.org/2000/svg\"\n viewBox=\"0 0 256 256\"\n fill=\"currentColor\"\n style={{ height: \"1rem\", width: \"1rem\" }}\n >\n <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\" />\n </svg>\n);\n\nexport const PushToTalkIcon = (\n <svg\n xmlns=\"http://www.w3.org/2000/svg\"\n fill=\"none\"\n viewBox=\"0 0 24 24\"\n strokeWidth={1.5}\n stroke=\"currentColor\"\n className=\"w-6 h-6\"\n >\n <path\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n 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\"\n />\n </svg>\n);\n"],"mappings":"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","names":[]}
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
// src/hooks/use-copilot-chat-suggestions.tsx
|
|
2
|
+
import { useEffect } from "react";
|
|
3
|
+
import { nanoid } from "nanoid";
|
|
4
|
+
import { useCopilotContext } from "@copilotkit/react-core";
|
|
5
|
+
function useCopilotChatSuggestions({
|
|
6
|
+
instructions,
|
|
7
|
+
className,
|
|
8
|
+
minSuggestions = 1,
|
|
9
|
+
maxSuggestions = 3
|
|
10
|
+
}, dependencies = []) {
|
|
11
|
+
const context = useCopilotContext();
|
|
12
|
+
useEffect(() => {
|
|
13
|
+
const id = nanoid();
|
|
14
|
+
context.addChatSuggestionConfiguration(id, {
|
|
15
|
+
instructions,
|
|
16
|
+
minSuggestions,
|
|
17
|
+
maxSuggestions,
|
|
18
|
+
className
|
|
19
|
+
});
|
|
20
|
+
return () => {
|
|
21
|
+
context.removeChatSuggestionConfiguration(id);
|
|
22
|
+
};
|
|
23
|
+
}, dependencies);
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
export {
|
|
27
|
+
useCopilotChatSuggestions
|
|
28
|
+
};
|
|
29
|
+
//# sourceMappingURL=chunk-LTCJCXCP.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/hooks/use-copilot-chat-suggestions.tsx"],"sourcesContent":["/**\n * A hook for providing suggestions to the user in the Copilot chat.\n *\n * <Warning>\n * useCopilotChatSuggestions is experimental. The interface is not final and\n * can change without further notice.\n * </Warning>\n *\n * <img src=\"/images/useCopilotChatSuggestions/use-copilot-chat-suggestions.gif\" width=\"500\" />\n *\n * <img referrerPolicy=\"no-referrer-when-downgrade\" src=\"https://static.scarf.sh/a.png?x-pxid=a9b290bb-38f9-4518-ac3b-8f54fdbf43be\" />\n *\n * `useCopilotChatSuggestions` integrates auto-generated chat suggestions into your application in the context of your\n * app's state. It dynamically manages suggestions based on provided configurations and\n * dependencies.\n *\n * <RequestExample>\n * ```jsx useCopilotChatSuggestions Example\n * import { useCopilotChatSuggestions }\n * from \"@copilotkit/react-ui\";\n *\n * useCopilotChatSuggestions({\n * instructions: \"Your instructions for suggestions.\",\n * })\n * ```\n * </RequestExample>\n *\n * ## Basic Setup\n *\n * To incorporate this hook into your React components, start by importing it:\n *\n * ```tsx\n * import { useCopilotChatSuggestions } from \"@copilotkit/react-ui\";\n * ```\n *\n * Then, use it in your component to initiate suggestion functionality:\n *\n * ```tsx\n * useCopilotChatSuggestions({\n * instructions: \"Your instructions for suggestions.\",\n * });\n * ```\n *\n * ## Dependency Management\n *\n * ```tsx\n * import { useCopilotChatSuggestions } from \"@copilotkit/react-ui\";\n *\n * useCopilotChatSuggestions(\n * {\n * instructions: \"Suggest the most relevant next actions.\",\n * },\n * [appState],\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 { useChatContext } from \"../components\";\nimport { nanoid } from \"nanoid\";\nimport { CopilotChatSuggestionConfiguration, useCopilotContext } from \"@copilotkit/react-core\";\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 * An optional class name to apply to the suggestions.\n */\n className?: string;\n}\n\nexport function useCopilotChatSuggestions(\n {\n instructions,\n className,\n minSuggestions = 1,\n maxSuggestions = 3,\n }: UseCopilotChatSuggestionsConfiguration,\n dependencies: any[] = [],\n) {\n const context = useCopilotContext();\n\n useEffect(() => {\n const id = nanoid();\n\n context.addChatSuggestionConfiguration(id, {\n instructions,\n minSuggestions,\n maxSuggestions,\n className,\n });\n\n return () => {\n context.removeChatSuggestionConfiguration(id);\n };\n }, dependencies);\n}\n"],"mappings":";AAiEA,SAAS,iBAAiB;AAE1B,SAAS,cAAc;AACvB,SAA6C,yBAAyB;AAuB/D,SAAS,0BACd;AAAA,EACE;AAAA,EACA;AAAA,EACA,iBAAiB;AAAA,EACjB,iBAAiB;AACnB,GACA,eAAsB,CAAC,GACvB;AACA,QAAM,UAAU,kBAAkB;AAElC,YAAU,MAAM;AACd,UAAM,KAAK,OAAO;AAElB,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,YAAY;AACjB;","names":[]}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
//# sourceMappingURL=chunk-MRFF7GSQ.mjs.map
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import {
|
|
2
2
|
useChatContext
|
|
3
|
-
} from "./chunk-
|
|
3
|
+
} from "./chunk-VUZA5AFH.mjs";
|
|
4
4
|
|
|
5
5
|
// src/components/chat/Header.tsx
|
|
6
6
|
import { jsx, jsxs } from "react/jsx-runtime";
|
|
@@ -15,4 +15,4 @@ var Header = ({ setOpen }) => {
|
|
|
15
15
|
export {
|
|
16
16
|
Header
|
|
17
17
|
};
|
|
18
|
-
//# sourceMappingURL=chunk-
|
|
18
|
+
//# sourceMappingURL=chunk-PAQWLSA4.mjs.map
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import {
|
|
2
2
|
useChatContext
|
|
3
|
-
} from "./chunk-
|
|
3
|
+
} from "./chunk-VUZA5AFH.mjs";
|
|
4
4
|
|
|
5
5
|
// src/components/chat/Button.tsx
|
|
6
6
|
import { jsx, jsxs } from "react/jsx-runtime";
|
|
@@ -22,4 +22,4 @@ var Button = ({ open, setOpen }) => {
|
|
|
22
22
|
export {
|
|
23
23
|
Button
|
|
24
24
|
};
|
|
25
|
-
//# sourceMappingURL=chunk-
|
|
25
|
+
//# sourceMappingURL=chunk-RT2XG2T7.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/components/chat/Button.tsx"],"sourcesContent":["import { ButtonProps } from \"./props\";\nimport { useChatContext } from \"./ChatContext\";\n\nexport const Button = ({ open, setOpen }: ButtonProps) => {\n const context = useChatContext();\n\n return (\n <div onClick={() => setOpen(!open)}>\n <button\n className={`copilotKitButton ${open ? \"open\" : \"\"}`}\n aria-label={open ? \"Close Chat\" : \"Open Chat\"}\n >\n <div className=\"copilotKitButtonIcon copilotKitButtonIconOpen\">\n {context.icons.openIcon}\n </div>\n <div className=\"copilotKitButtonIcon copilotKitButtonIconClose\">\n {context.icons.closeIcon}\n </div>\n </button>\n </div>\n );\n};\n"],"mappings":";;;;;AAQM,SAIE,KAJF;AALC,IAAM,SAAS,CAAC,EAAE,MAAM,QAAQ,MAAmB;AACxD,QAAM,UAAU,eAAe;AAE/B,SACE,oBAAC,SAAI,SAAS,MAAM,QAAQ,CAAC,IAAI,GAC/B;AAAA,IAAC;AAAA;AAAA,MACC,WAAW,oBAAoB,OAAO,SAAS;AAAA,MAC/C,cAAY,OAAO,eAAe;AAAA,MAElC;AAAA,4BAAC,SAAI,WAAU,iDACZ,kBAAQ,MAAM,UACjB;AAAA,QACA,oBAAC,SAAI,WAAU,kDACZ,kBAAQ,MAAM,WACjB;AAAA;AAAA;AAAA,EACF,GACF;AAEJ;","names":[]}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
//# sourceMappingURL=chunk-T26KLXLH.mjs.map
|