@copilotkit/react-ui 1.10.0-next.1 → 1.10.0-next.10
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/CHANGELOG.md +104 -0
- package/dist/{chunk-O7KTFUAN.mjs → chunk-226ZMOE3.mjs} +2 -2
- package/dist/{chunk-WHDNKXMP.mjs → chunk-BJHJBS5M.mjs} +46 -6
- package/dist/chunk-BJHJBS5M.mjs.map +1 -0
- package/dist/{chunk-FOSKS7AI.mjs → chunk-FFJHOZX6.mjs} +5 -5
- package/dist/{chunk-QELAC6XJ.mjs → chunk-GBP47ONN.mjs} +2 -2
- package/dist/chunk-GBP47ONN.mjs.map +1 -0
- package/dist/{chunk-7CAK2CNK.mjs → chunk-GDSZGYCE.mjs} +2 -2
- package/dist/{chunk-O7PYQO73.mjs → chunk-GJ4SX4JE.mjs} +153 -37
- package/dist/chunk-GJ4SX4JE.mjs.map +1 -0
- package/dist/{chunk-TCIZDWPC.mjs → chunk-J5ZZR6YB.mjs} +2 -2
- package/dist/chunk-J5ZZR6YB.mjs.map +1 -0
- package/dist/{chunk-QN7T3GWI.mjs → chunk-JY2CSDKN.mjs} +4 -6
- package/dist/chunk-JY2CSDKN.mjs.map +1 -0
- package/dist/chunk-MIVUCSGO.mjs +126 -0
- package/dist/chunk-MIVUCSGO.mjs.map +1 -0
- package/dist/{chunk-OQM7D3Z3.mjs → chunk-T5QU6KSB.mjs} +8 -4
- package/dist/chunk-T5QU6KSB.mjs.map +1 -0
- package/dist/{chunk-Q2467VHZ.mjs → chunk-W26XFBEG.mjs} +2 -2
- package/dist/chunk-W26XFBEG.mjs.map +1 -0
- package/dist/chunk-Y44VLEUH.mjs +222 -0
- package/dist/chunk-Y44VLEUH.mjs.map +1 -0
- package/dist/components/chat/Chat.d.ts +52 -15
- package/dist/components/chat/Chat.js +1136 -869
- package/dist/components/chat/Chat.js.map +1 -1
- package/dist/components/chat/Chat.mjs +9 -8
- package/dist/components/chat/Header.js +6 -8
- package/dist/components/chat/Header.js.map +1 -1
- package/dist/components/chat/Header.mjs +4 -4
- package/dist/components/chat/Messages.d.ts +1 -1
- package/dist/components/chat/Messages.js +984 -23
- package/dist/components/chat/Messages.js.map +1 -1
- package/dist/components/chat/Messages.mjs +9 -1
- package/dist/components/chat/Modal.d.ts +2 -2
- package/dist/components/chat/Modal.js +1267 -931
- package/dist/components/chat/Modal.js.map +1 -1
- package/dist/components/chat/Modal.mjs +14 -13
- package/dist/components/chat/Popup.d.ts +1 -1
- package/dist/components/chat/Popup.js +1269 -933
- package/dist/components/chat/Popup.js.map +1 -1
- package/dist/components/chat/Popup.mjs +15 -14
- package/dist/components/chat/Sidebar.d.ts +1 -1
- package/dist/components/chat/Sidebar.js +1269 -933
- package/dist/components/chat/Sidebar.js.map +1 -1
- package/dist/components/chat/Sidebar.mjs +15 -14
- package/dist/components/chat/Suggestion.js +1 -1
- package/dist/components/chat/Suggestion.js.map +1 -1
- package/dist/components/chat/Suggestion.mjs +1 -1
- package/dist/components/chat/Suggestions.js +1 -1
- package/dist/components/chat/Suggestions.js.map +1 -1
- package/dist/components/chat/Suggestions.mjs +2 -2
- package/dist/components/chat/index.d.ts +2 -2
- package/dist/components/chat/index.js +1271 -935
- package/dist/components/chat/index.js.map +1 -1
- package/dist/components/chat/index.mjs +22 -21
- package/dist/components/chat/messages/LegacyRenderMessage.d.ts +28 -0
- package/dist/components/chat/messages/LegacyRenderMessage.js +980 -0
- package/dist/components/chat/messages/LegacyRenderMessage.js.map +1 -0
- package/dist/components/chat/messages/LegacyRenderMessage.mjs +17 -0
- package/dist/components/chat/messages/LegacyRenderMessage.mjs.map +1 -0
- package/dist/components/chat/messages/RenderMessage.js +4 -0
- package/dist/components/chat/messages/RenderMessage.js.map +1 -1
- package/dist/components/chat/messages/RenderMessage.mjs +2 -2
- package/dist/components/chat/props.d.ts +94 -2
- package/dist/components/chat/props.js.map +1 -1
- package/dist/components/dev-console/console.d.ts +1 -0
- package/dist/components/dev-console/console.js +6 -8
- package/dist/components/dev-console/console.js.map +1 -1
- package/dist/components/dev-console/console.mjs +3 -3
- package/dist/components/dev-console/index.d.ts +1 -3
- package/dist/components/dev-console/index.js +7 -9
- package/dist/components/dev-console/index.js.map +1 -1
- package/dist/components/dev-console/index.mjs +5 -5
- package/dist/components/dev-console/utils.d.ts +2 -2
- package/dist/components/dev-console/utils.js +2 -4
- package/dist/components/dev-console/utils.js.map +1 -1
- package/dist/components/dev-console/utils.mjs +1 -1
- package/dist/components/index.d.ts +3 -5
- package/dist/components/index.js +1272 -936
- package/dist/components/index.js.map +1 -1
- package/dist/components/index.mjs +24 -23
- package/dist/index.d.ts +3 -5
- package/dist/index.js +1303 -967
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +24 -23
- package/package.json +6 -6
- package/src/components/chat/Chat.tsx +241 -23
- package/src/components/chat/Messages.tsx +58 -5
- package/src/components/chat/Modal.tsx +128 -41
- package/src/components/chat/Popup.tsx +20 -0
- package/src/components/chat/Sidebar.tsx +22 -0
- package/src/components/chat/Suggestion.tsx +1 -1
- package/src/components/chat/messages/LegacyRenderMessage.tsx +143 -0
- package/src/components/chat/messages/RenderMessage.tsx +3 -0
- package/src/components/chat/props.ts +110 -1
- package/src/components/dev-console/utils.ts +1 -6
- package/dist/chunk-7RNOT3GM.mjs +0 -144
- package/dist/chunk-7RNOT3GM.mjs.map +0 -1
- package/dist/chunk-O7PYQO73.mjs.map +0 -1
- package/dist/chunk-OQM7D3Z3.mjs.map +0 -1
- package/dist/chunk-Q2467VHZ.mjs.map +0 -1
- package/dist/chunk-QELAC6XJ.mjs.map +0 -1
- package/dist/chunk-QN7T3GWI.mjs.map +0 -1
- package/dist/chunk-TCIZDWPC.mjs.map +0 -1
- package/dist/chunk-WHDNKXMP.mjs.map +0 -1
- /package/dist/{chunk-O7KTFUAN.mjs.map → chunk-226ZMOE3.mjs.map} +0 -0
- /package/dist/{chunk-FOSKS7AI.mjs.map → chunk-FFJHOZX6.mjs.map} +0 -0
- /package/dist/{chunk-7CAK2CNK.mjs.map → chunk-GDSZGYCE.mjs.map} +0 -0
|
@@ -395,559 +395,137 @@ var ChatContextProvider = ({
|
|
|
395
395
|
};
|
|
396
396
|
|
|
397
397
|
// src/components/chat/Messages.tsx
|
|
398
|
-
var
|
|
398
|
+
var import_react6 = require("react");
|
|
399
399
|
var import_react_core = require("@copilotkit/react-core");
|
|
400
|
+
|
|
401
|
+
// src/components/chat/messages/UserMessage.tsx
|
|
400
402
|
var import_jsx_runtime3 = require("react/jsx-runtime");
|
|
401
|
-
var
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
onRegenerate,
|
|
408
|
-
onCopy,
|
|
409
|
-
onThumbsUp,
|
|
410
|
-
onThumbsDown,
|
|
411
|
-
markdownTagRenderers
|
|
412
|
-
}) => {
|
|
413
|
-
const { labels } = useChatContext();
|
|
414
|
-
const { visibleMessages, interrupt } = (0, import_react_core.useCopilotChat)();
|
|
415
|
-
const initialMessages = (0, import_react2.useMemo)(() => makeInitialMessages(labels.initial), [labels.initial]);
|
|
416
|
-
const messages = [...initialMessages, ...visibleMessages];
|
|
417
|
-
const { messagesContainerRef, messagesEndRef } = useScrollToBottom(messages);
|
|
418
|
-
return /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("div", { className: "copilotKitMessages", ref: messagesContainerRef, children: [
|
|
419
|
-
/* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("div", { className: "copilotKitMessagesContainer", children: [
|
|
420
|
-
messages.map((message, index) => {
|
|
421
|
-
const isCurrentMessage = index === messages.length - 1;
|
|
422
|
-
return /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
|
|
423
|
-
RenderMessage2,
|
|
424
|
-
{
|
|
425
|
-
message,
|
|
426
|
-
inProgress,
|
|
427
|
-
index,
|
|
428
|
-
isCurrentMessage,
|
|
429
|
-
AssistantMessage: AssistantMessage2,
|
|
430
|
-
UserMessage: UserMessage2,
|
|
431
|
-
onRegenerate,
|
|
432
|
-
onCopy,
|
|
433
|
-
onThumbsUp,
|
|
434
|
-
onThumbsDown,
|
|
435
|
-
markdownTagRenderers
|
|
436
|
-
},
|
|
437
|
-
index
|
|
438
|
-
);
|
|
439
|
-
}),
|
|
440
|
-
interrupt
|
|
441
|
-
] }),
|
|
442
|
-
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)("footer", { className: "copilotKitMessagesFooter", ref: messagesEndRef, children })
|
|
443
|
-
] });
|
|
444
|
-
};
|
|
445
|
-
function makeInitialMessages(initial) {
|
|
446
|
-
if (!initial)
|
|
447
|
-
return [];
|
|
448
|
-
if (Array.isArray(initial)) {
|
|
449
|
-
return initial.map((message) => {
|
|
450
|
-
return {
|
|
451
|
-
id: message,
|
|
452
|
-
role: "assistant",
|
|
453
|
-
content: message
|
|
454
|
-
};
|
|
455
|
-
});
|
|
403
|
+
var UserMessage = (props) => {
|
|
404
|
+
const { message, ImageRenderer: ImageRenderer2 } = props;
|
|
405
|
+
const isImageMessage = message && "image" in message && message.image;
|
|
406
|
+
if (isImageMessage) {
|
|
407
|
+
const imageMessage = message;
|
|
408
|
+
return /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("div", { className: "copilotKitMessage copilotKitUserMessage", children: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(ImageRenderer2, { image: imageMessage.image, content: imageMessage.content }) });
|
|
456
409
|
}
|
|
457
|
-
return
|
|
458
|
-
|
|
459
|
-
|
|
460
|
-
|
|
461
|
-
|
|
462
|
-
|
|
463
|
-
|
|
464
|
-
|
|
465
|
-
|
|
466
|
-
|
|
467
|
-
|
|
468
|
-
|
|
469
|
-
|
|
470
|
-
|
|
471
|
-
|
|
472
|
-
|
|
473
|
-
|
|
474
|
-
|
|
475
|
-
};
|
|
476
|
-
const handleScroll = () => {
|
|
477
|
-
if (isProgrammaticScrollRef.current) {
|
|
478
|
-
isProgrammaticScrollRef.current = false;
|
|
410
|
+
return /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("div", { className: "copilotKitMessage copilotKitUserMessage", children: message == null ? void 0 : message.content });
|
|
411
|
+
};
|
|
412
|
+
|
|
413
|
+
// src/components/chat/Markdown.tsx
|
|
414
|
+
var import_react3 = require("react");
|
|
415
|
+
var import_react_markdown = __toESM(require("react-markdown"));
|
|
416
|
+
|
|
417
|
+
// src/components/chat/CodeBlock.tsx
|
|
418
|
+
var import_react2 = require("react");
|
|
419
|
+
var import_react_syntax_highlighter = require("react-syntax-highlighter");
|
|
420
|
+
|
|
421
|
+
// src/hooks/use-copy-to-clipboard.tsx
|
|
422
|
+
var React2 = __toESM(require("react"));
|
|
423
|
+
function useCopyToClipboard({ timeout = 2e3 }) {
|
|
424
|
+
const [isCopied, setIsCopied] = React2.useState(false);
|
|
425
|
+
const copyToClipboard = (value) => {
|
|
426
|
+
var _a;
|
|
427
|
+
if (typeof window === "undefined" || !((_a = navigator.clipboard) == null ? void 0 : _a.writeText)) {
|
|
479
428
|
return;
|
|
480
429
|
}
|
|
481
|
-
if (
|
|
482
|
-
const { scrollTop, scrollHeight, clientHeight } = messagesContainerRef.current;
|
|
483
|
-
isUserScrollUpRef.current = scrollTop + clientHeight < scrollHeight;
|
|
484
|
-
}
|
|
485
|
-
};
|
|
486
|
-
(0, import_react2.useEffect)(() => {
|
|
487
|
-
const container = messagesContainerRef.current;
|
|
488
|
-
if (container) {
|
|
489
|
-
container.addEventListener("scroll", handleScroll);
|
|
490
|
-
}
|
|
491
|
-
return () => {
|
|
492
|
-
if (container) {
|
|
493
|
-
container.removeEventListener("scroll", handleScroll);
|
|
494
|
-
}
|
|
495
|
-
};
|
|
496
|
-
}, []);
|
|
497
|
-
(0, import_react2.useEffect)(() => {
|
|
498
|
-
const container = messagesContainerRef.current;
|
|
499
|
-
if (!container) {
|
|
430
|
+
if (!value) {
|
|
500
431
|
return;
|
|
501
432
|
}
|
|
502
|
-
|
|
503
|
-
|
|
504
|
-
|
|
505
|
-
|
|
506
|
-
|
|
507
|
-
mutationObserver.observe(container, {
|
|
508
|
-
childList: true,
|
|
509
|
-
subtree: true,
|
|
510
|
-
characterData: true
|
|
433
|
+
navigator.clipboard.writeText(value).then(() => {
|
|
434
|
+
setIsCopied(true);
|
|
435
|
+
setTimeout(() => {
|
|
436
|
+
setIsCopied(false);
|
|
437
|
+
}, timeout);
|
|
511
438
|
});
|
|
512
|
-
|
|
513
|
-
|
|
514
|
-
};
|
|
515
|
-
}, []);
|
|
516
|
-
(0, import_react2.useEffect)(() => {
|
|
517
|
-
isUserScrollUpRef.current = false;
|
|
518
|
-
scrollToBottom();
|
|
519
|
-
}, [messages.filter((m) => m.role === "user").length]);
|
|
520
|
-
return { messagesEndRef, messagesContainerRef };
|
|
439
|
+
};
|
|
440
|
+
return { isCopied, copyToClipboard };
|
|
521
441
|
}
|
|
522
442
|
|
|
523
|
-
// src/components/chat/
|
|
524
|
-
var import_react5 = require("react");
|
|
525
|
-
|
|
526
|
-
// src/components/chat/Textarea.tsx
|
|
527
|
-
var import_react3 = require("react");
|
|
443
|
+
// src/components/chat/CodeBlock.tsx
|
|
528
444
|
var import_jsx_runtime4 = require("react/jsx-runtime");
|
|
529
|
-
var
|
|
530
|
-
|
|
531
|
-
|
|
532
|
-
|
|
533
|
-
|
|
534
|
-
|
|
535
|
-
|
|
536
|
-
|
|
537
|
-
|
|
538
|
-
|
|
539
|
-
|
|
540
|
-
|
|
541
|
-
|
|
542
|
-
|
|
543
|
-
|
|
544
|
-
|
|
545
|
-
|
|
546
|
-
|
|
547
|
-
|
|
548
|
-
|
|
549
|
-
|
|
550
|
-
|
|
551
|
-
|
|
552
|
-
|
|
553
|
-
|
|
554
|
-
|
|
555
|
-
|
|
556
|
-
|
|
557
|
-
|
|
558
|
-
|
|
559
|
-
|
|
560
|
-
|
|
561
|
-
|
|
562
|
-
|
|
563
|
-
|
|
564
|
-
|
|
565
|
-
|
|
445
|
+
var programmingLanguages = {
|
|
446
|
+
javascript: ".js",
|
|
447
|
+
python: ".py",
|
|
448
|
+
java: ".java",
|
|
449
|
+
c: ".c",
|
|
450
|
+
cpp: ".cpp",
|
|
451
|
+
"c++": ".cpp",
|
|
452
|
+
"c#": ".cs",
|
|
453
|
+
ruby: ".rb",
|
|
454
|
+
php: ".php",
|
|
455
|
+
swift: ".swift",
|
|
456
|
+
"objective-c": ".m",
|
|
457
|
+
kotlin: ".kt",
|
|
458
|
+
typescript: ".ts",
|
|
459
|
+
go: ".go",
|
|
460
|
+
perl: ".pl",
|
|
461
|
+
rust: ".rs",
|
|
462
|
+
scala: ".scala",
|
|
463
|
+
haskell: ".hs",
|
|
464
|
+
lua: ".lua",
|
|
465
|
+
shell: ".sh",
|
|
466
|
+
sql: ".sql",
|
|
467
|
+
html: ".html",
|
|
468
|
+
css: ".css"
|
|
469
|
+
// add more file extensions here, make sure the key is same as language prop in CodeBlock.tsx component
|
|
470
|
+
};
|
|
471
|
+
var generateRandomString = (length, lowercase = false) => {
|
|
472
|
+
const chars = "ABCDEFGHJKLMNPQRSTUVWXY3456789";
|
|
473
|
+
let result = "";
|
|
474
|
+
for (let i = 0; i < length; i++) {
|
|
475
|
+
result += chars.charAt(Math.floor(Math.random() * chars.length));
|
|
476
|
+
}
|
|
477
|
+
return lowercase ? result.toLowerCase() : result;
|
|
478
|
+
};
|
|
479
|
+
var CodeBlock = (0, import_react2.memo)(({ language, value }) => {
|
|
480
|
+
const { isCopied, copyToClipboard } = useCopyToClipboard({ timeout: 2e3 });
|
|
481
|
+
const downloadAsFile = () => {
|
|
482
|
+
if (typeof window === "undefined") {
|
|
483
|
+
return;
|
|
484
|
+
}
|
|
485
|
+
const fileExtension = programmingLanguages[language] || ".file";
|
|
486
|
+
const suggestedFileName = `file-${generateRandomString(3, true)}${fileExtension}`;
|
|
487
|
+
const fileName = window.prompt("Enter file name", suggestedFileName);
|
|
488
|
+
if (!fileName) {
|
|
489
|
+
return;
|
|
490
|
+
}
|
|
491
|
+
const blob = new Blob([value], { type: "text/plain" });
|
|
492
|
+
const url = URL.createObjectURL(blob);
|
|
493
|
+
const link = document.createElement("a");
|
|
494
|
+
link.download = fileName;
|
|
495
|
+
link.href = url;
|
|
496
|
+
link.style.display = "none";
|
|
497
|
+
document.body.appendChild(link);
|
|
498
|
+
link.click();
|
|
499
|
+
document.body.removeChild(link);
|
|
500
|
+
URL.revokeObjectURL(url);
|
|
501
|
+
};
|
|
502
|
+
const onCopy = () => {
|
|
503
|
+
if (isCopied)
|
|
504
|
+
return;
|
|
505
|
+
copyToClipboard(value);
|
|
506
|
+
};
|
|
507
|
+
return /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("div", { className: "copilotKitCodeBlock", children: [
|
|
508
|
+
/* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("div", { className: "copilotKitCodeBlockToolbar", children: [
|
|
509
|
+
/* @__PURE__ */ (0, import_jsx_runtime4.jsx)("span", { className: "copilotKitCodeBlockToolbarLanguage", children: language }),
|
|
510
|
+
/* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("div", { className: "copilotKitCodeBlockToolbarButtons", children: [
|
|
511
|
+
/* @__PURE__ */ (0, import_jsx_runtime4.jsx)("button", { className: "copilotKitCodeBlockToolbarButton", onClick: downloadAsFile, children: DownloadIcon }),
|
|
512
|
+
/* @__PURE__ */ (0, import_jsx_runtime4.jsx)("button", { className: "copilotKitCodeBlockToolbarButton", onClick: onCopy, children: isCopied ? CheckIcon : CopyIcon })
|
|
513
|
+
] })
|
|
514
|
+
] }),
|
|
515
|
+
/* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
|
|
516
|
+
import_react_syntax_highlighter.Prism,
|
|
566
517
|
{
|
|
567
|
-
|
|
568
|
-
|
|
569
|
-
|
|
570
|
-
|
|
571
|
-
|
|
572
|
-
|
|
573
|
-
|
|
574
|
-
style: {
|
|
575
|
-
overflow: "auto",
|
|
576
|
-
resize: "none",
|
|
577
|
-
maxHeight: `${maxHeight}px`
|
|
518
|
+
language,
|
|
519
|
+
style: highlightStyle,
|
|
520
|
+
PreTag: "div",
|
|
521
|
+
customStyle: {
|
|
522
|
+
margin: 0,
|
|
523
|
+
borderBottomLeftRadius: "0.375rem",
|
|
524
|
+
borderBottomRightRadius: "0.375rem"
|
|
578
525
|
},
|
|
579
|
-
|
|
526
|
+
children: value
|
|
580
527
|
}
|
|
581
|
-
)
|
|
582
|
-
}
|
|
583
|
-
);
|
|
584
|
-
var Textarea_default = AutoResizingTextarea;
|
|
585
|
-
|
|
586
|
-
// src/hooks/use-push-to-talk.tsx
|
|
587
|
-
var import_react_core2 = require("@copilotkit/react-core");
|
|
588
|
-
var import_runtime_client_gql = require("@copilotkit/runtime-client-gql");
|
|
589
|
-
var import_react4 = require("react");
|
|
590
|
-
var startRecording = (mediaStreamRef, mediaRecorderRef, audioContextRef, recordedChunks, onStop) => __async(void 0, null, function* () {
|
|
591
|
-
if (!mediaStreamRef.current || !audioContextRef.current) {
|
|
592
|
-
mediaStreamRef.current = yield navigator.mediaDevices.getUserMedia({ audio: true });
|
|
593
|
-
audioContextRef.current = new window.AudioContext();
|
|
594
|
-
yield audioContextRef.current.resume();
|
|
595
|
-
}
|
|
596
|
-
mediaRecorderRef.current = new MediaRecorder(mediaStreamRef.current);
|
|
597
|
-
mediaRecorderRef.current.start(1e3);
|
|
598
|
-
mediaRecorderRef.current.ondataavailable = (event) => {
|
|
599
|
-
recordedChunks.push(event.data);
|
|
600
|
-
};
|
|
601
|
-
mediaRecorderRef.current.onstop = onStop;
|
|
602
|
-
});
|
|
603
|
-
var stopRecording = (mediaRecorderRef) => {
|
|
604
|
-
if (mediaRecorderRef.current && mediaRecorderRef.current.state !== "inactive") {
|
|
605
|
-
mediaRecorderRef.current.stop();
|
|
606
|
-
}
|
|
607
|
-
};
|
|
608
|
-
var transcribeAudio = (recordedChunks, transcribeAudioUrl) => __async(void 0, null, function* () {
|
|
609
|
-
const completeBlob = new Blob(recordedChunks, { type: "audio/mp4" });
|
|
610
|
-
const formData = new FormData();
|
|
611
|
-
formData.append("file", completeBlob, "recording.mp4");
|
|
612
|
-
const response = yield fetch(transcribeAudioUrl, {
|
|
613
|
-
method: "POST",
|
|
614
|
-
body: formData
|
|
615
|
-
});
|
|
616
|
-
if (!response.ok) {
|
|
617
|
-
throw new Error(`Error: ${response.statusText}`);
|
|
618
|
-
}
|
|
619
|
-
const transcription = yield response.json();
|
|
620
|
-
return transcription.text;
|
|
621
|
-
});
|
|
622
|
-
var playAudioResponse = (text, textToSpeechUrl, audioContext) => {
|
|
623
|
-
const encodedText = encodeURIComponent(text);
|
|
624
|
-
const url = `${textToSpeechUrl}?text=${encodedText}`;
|
|
625
|
-
fetch(url).then((response) => response.arrayBuffer()).then((arrayBuffer) => audioContext.decodeAudioData(arrayBuffer)).then((audioBuffer) => {
|
|
626
|
-
const source = audioContext.createBufferSource();
|
|
627
|
-
source.buffer = audioBuffer;
|
|
628
|
-
source.connect(audioContext.destination);
|
|
629
|
-
source.start(0);
|
|
630
|
-
}).catch((error) => {
|
|
631
|
-
console.error("Error with decoding audio data", error);
|
|
632
|
-
});
|
|
633
|
-
};
|
|
634
|
-
var usePushToTalk = ({
|
|
635
|
-
sendFunction,
|
|
636
|
-
inProgress
|
|
637
|
-
}) => {
|
|
638
|
-
const [pushToTalkState, setPushToTalkState] = (0, import_react4.useState)("idle");
|
|
639
|
-
const mediaStreamRef = (0, import_react4.useRef)(null);
|
|
640
|
-
const audioContextRef = (0, import_react4.useRef)(null);
|
|
641
|
-
const mediaRecorderRef = (0, import_react4.useRef)(null);
|
|
642
|
-
const recordedChunks = (0, import_react4.useRef)([]);
|
|
643
|
-
const generalContext = (0, import_react_core2.useCopilotContext)();
|
|
644
|
-
const messagesContext = (0, import_react_core2.useCopilotMessagesContext)();
|
|
645
|
-
const context = __spreadValues(__spreadValues({}, generalContext), messagesContext);
|
|
646
|
-
const [startReadingFromMessageId, setStartReadingFromMessageId] = (0, import_react4.useState)(null);
|
|
647
|
-
(0, import_react4.useEffect)(() => {
|
|
648
|
-
if (pushToTalkState === "recording") {
|
|
649
|
-
startRecording(
|
|
650
|
-
mediaStreamRef,
|
|
651
|
-
mediaRecorderRef,
|
|
652
|
-
audioContextRef,
|
|
653
|
-
recordedChunks.current,
|
|
654
|
-
() => {
|
|
655
|
-
setPushToTalkState("transcribing");
|
|
656
|
-
}
|
|
657
|
-
);
|
|
658
|
-
} else {
|
|
659
|
-
stopRecording(mediaRecorderRef);
|
|
660
|
-
if (pushToTalkState === "transcribing") {
|
|
661
|
-
transcribeAudio(recordedChunks.current, context.copilotApiConfig.transcribeAudioUrl).then(
|
|
662
|
-
(transcription) => __async(void 0, null, function* () {
|
|
663
|
-
recordedChunks.current = [];
|
|
664
|
-
setPushToTalkState("idle");
|
|
665
|
-
const message = yield sendFunction(transcription);
|
|
666
|
-
setStartReadingFromMessageId(message.id);
|
|
667
|
-
})
|
|
668
|
-
);
|
|
669
|
-
}
|
|
670
|
-
}
|
|
671
|
-
return () => {
|
|
672
|
-
stopRecording(mediaRecorderRef);
|
|
673
|
-
};
|
|
674
|
-
}, [pushToTalkState]);
|
|
675
|
-
(0, import_react4.useEffect)(() => {
|
|
676
|
-
if (inProgress === false && startReadingFromMessageId) {
|
|
677
|
-
const lastMessageIndex = context.messages.findIndex(
|
|
678
|
-
(message) => message.id === startReadingFromMessageId
|
|
679
|
-
);
|
|
680
|
-
const aguiMessages = (0, import_runtime_client_gql.gqlToAGUI)(context.messages);
|
|
681
|
-
const messagesAfterLast = aguiMessages.slice(lastMessageIndex + 1).filter((message) => message.role === "assistant");
|
|
682
|
-
const text = messagesAfterLast.map((message) => message.content).join("\n");
|
|
683
|
-
playAudioResponse(text, context.copilotApiConfig.textToSpeechUrl, audioContextRef.current);
|
|
684
|
-
setStartReadingFromMessageId(null);
|
|
685
|
-
}
|
|
686
|
-
}, [startReadingFromMessageId, inProgress]);
|
|
687
|
-
return { pushToTalkState, setPushToTalkState };
|
|
688
|
-
};
|
|
689
|
-
|
|
690
|
-
// src/components/chat/Input.tsx
|
|
691
|
-
var import_react_core3 = require("@copilotkit/react-core");
|
|
692
|
-
|
|
693
|
-
// src/hooks/use-dark-mode.ts
|
|
694
|
-
var useDarkMode = () => {
|
|
695
|
-
if (typeof window === "undefined")
|
|
696
|
-
return false;
|
|
697
|
-
return document.documentElement.classList.contains("dark") || document.body.classList.contains("dark") || document.documentElement.getAttribute("data-theme") === "dark" || document.body.getAttribute("data-theme") === "dark" || window.matchMedia("(prefers-color-scheme: dark)").matches;
|
|
698
|
-
};
|
|
699
|
-
|
|
700
|
-
// src/components/chat/PoweredByTag.tsx
|
|
701
|
-
var import_jsx_runtime5 = require("react/jsx-runtime");
|
|
702
|
-
function PoweredByTag({ showPoweredBy = true }) {
|
|
703
|
-
const isDark = useDarkMode();
|
|
704
|
-
if (!showPoweredBy) {
|
|
705
|
-
return null;
|
|
706
|
-
}
|
|
707
|
-
const poweredByStyle = {
|
|
708
|
-
visibility: "visible",
|
|
709
|
-
display: "block",
|
|
710
|
-
position: "static",
|
|
711
|
-
textAlign: "center",
|
|
712
|
-
fontSize: "12px",
|
|
713
|
-
padding: "3px 0",
|
|
714
|
-
color: isDark ? "rgb(69, 69, 69)" : "rgb(214, 214, 214)"
|
|
715
|
-
};
|
|
716
|
-
return /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("div", { children: /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("p", { className: "poweredBy", style: poweredByStyle, children: "Powered by CopilotKit" }) });
|
|
717
|
-
}
|
|
718
|
-
|
|
719
|
-
// src/components/chat/Input.tsx
|
|
720
|
-
var import_jsx_runtime6 = require("react/jsx-runtime");
|
|
721
|
-
var MAX_NEWLINES = 6;
|
|
722
|
-
var Input = ({
|
|
723
|
-
inProgress,
|
|
724
|
-
onSend,
|
|
725
|
-
isVisible = false,
|
|
726
|
-
onStop,
|
|
727
|
-
onUpload,
|
|
728
|
-
hideStopButton = false
|
|
729
|
-
}) => {
|
|
730
|
-
var _a, _b;
|
|
731
|
-
const context = useChatContext();
|
|
732
|
-
const copilotContext = (0, import_react_core3.useCopilotContext)();
|
|
733
|
-
const showPoweredBy = !((_a = copilotContext.copilotApiConfig) == null ? void 0 : _a.publicApiKey);
|
|
734
|
-
const pushToTalkConfigured = copilotContext.copilotApiConfig.textToSpeechUrl !== void 0 && copilotContext.copilotApiConfig.transcribeAudioUrl !== void 0;
|
|
735
|
-
const textareaRef = (0, import_react5.useRef)(null);
|
|
736
|
-
const [isComposing, setIsComposing] = (0, import_react5.useState)(false);
|
|
737
|
-
const handleDivClick = (event) => {
|
|
738
|
-
var _a2;
|
|
739
|
-
const target = event.target;
|
|
740
|
-
if (target.closest("button"))
|
|
741
|
-
return;
|
|
742
|
-
if (target.tagName === "TEXTAREA")
|
|
743
|
-
return;
|
|
744
|
-
(_a2 = textareaRef.current) == null ? void 0 : _a2.focus();
|
|
745
|
-
};
|
|
746
|
-
const [text, setText] = (0, import_react5.useState)("");
|
|
747
|
-
const send = () => {
|
|
748
|
-
var _a2;
|
|
749
|
-
if (inProgress)
|
|
750
|
-
return;
|
|
751
|
-
onSend(text);
|
|
752
|
-
setText("");
|
|
753
|
-
(_a2 = textareaRef.current) == null ? void 0 : _a2.focus();
|
|
754
|
-
};
|
|
755
|
-
const { pushToTalkState, setPushToTalkState } = usePushToTalk({
|
|
756
|
-
sendFunction: onSend,
|
|
757
|
-
inProgress
|
|
758
|
-
});
|
|
759
|
-
const isInProgress = inProgress || pushToTalkState === "transcribing";
|
|
760
|
-
const buttonIcon = isInProgress && !hideStopButton ? context.icons.stopIcon : context.icons.sendIcon;
|
|
761
|
-
const showPushToTalk = pushToTalkConfigured && (pushToTalkState === "idle" || pushToTalkState === "recording") && !inProgress;
|
|
762
|
-
const canSend = (0, import_react5.useMemo)(() => {
|
|
763
|
-
var _a2;
|
|
764
|
-
const interruptEvent = (_a2 = copilotContext.langGraphInterruptAction) == null ? void 0 : _a2.event;
|
|
765
|
-
const interruptInProgress = (interruptEvent == null ? void 0 : interruptEvent.name) === "LangGraphInterruptEvent" && !(interruptEvent == null ? void 0 : interruptEvent.response);
|
|
766
|
-
return !isInProgress && text.trim().length > 0 && pushToTalkState === "idle" && !interruptInProgress;
|
|
767
|
-
}, [(_b = copilotContext.langGraphInterruptAction) == null ? void 0 : _b.event, isInProgress, text, pushToTalkState]);
|
|
768
|
-
const canStop = (0, import_react5.useMemo)(() => {
|
|
769
|
-
return isInProgress && !hideStopButton;
|
|
770
|
-
}, [isInProgress, hideStopButton]);
|
|
771
|
-
const sendDisabled = !canSend && !canStop;
|
|
772
|
-
return /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("div", { className: `copilotKitInputContainer ${showPoweredBy ? "poweredByContainer" : ""}`, children: [
|
|
773
|
-
/* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("div", { className: "copilotKitInput", onClick: handleDivClick, children: [
|
|
774
|
-
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
|
|
775
|
-
Textarea_default,
|
|
776
|
-
{
|
|
777
|
-
ref: textareaRef,
|
|
778
|
-
placeholder: context.labels.placeholder,
|
|
779
|
-
autoFocus: false,
|
|
780
|
-
maxRows: MAX_NEWLINES,
|
|
781
|
-
value: text,
|
|
782
|
-
onChange: (event) => setText(event.target.value),
|
|
783
|
-
onCompositionStart: () => setIsComposing(true),
|
|
784
|
-
onCompositionEnd: () => setIsComposing(false),
|
|
785
|
-
onKeyDown: (event) => {
|
|
786
|
-
if (event.key === "Enter" && !event.shiftKey && !isComposing) {
|
|
787
|
-
event.preventDefault();
|
|
788
|
-
if (canSend) {
|
|
789
|
-
send();
|
|
790
|
-
}
|
|
791
|
-
}
|
|
792
|
-
}
|
|
793
|
-
}
|
|
794
|
-
),
|
|
795
|
-
/* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("div", { className: "copilotKitInputControls", children: [
|
|
796
|
-
onUpload && /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("button", { onClick: onUpload, className: "copilotKitInputControlButton", children: context.icons.uploadIcon }),
|
|
797
|
-
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)("div", { style: { flexGrow: 1 } }),
|
|
798
|
-
showPushToTalk && /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
|
|
799
|
-
"button",
|
|
800
|
-
{
|
|
801
|
-
onClick: () => setPushToTalkState(pushToTalkState === "idle" ? "recording" : "transcribing"),
|
|
802
|
-
className: pushToTalkState === "recording" ? "copilotKitInputControlButton copilotKitPushToTalkRecording" : "copilotKitInputControlButton",
|
|
803
|
-
children: context.icons.pushToTalkIcon
|
|
804
|
-
}
|
|
805
|
-
),
|
|
806
|
-
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
|
|
807
|
-
"button",
|
|
808
|
-
{
|
|
809
|
-
disabled: sendDisabled,
|
|
810
|
-
onClick: isInProgress && !hideStopButton ? onStop : send,
|
|
811
|
-
"data-copilotkit-in-progress": inProgress,
|
|
812
|
-
"data-test-id": inProgress ? "copilot-chat-request-in-progress" : "copilot-chat-ready",
|
|
813
|
-
className: "copilotKitInputControlButton",
|
|
814
|
-
children: buttonIcon
|
|
815
|
-
}
|
|
816
|
-
)
|
|
817
|
-
] })
|
|
818
|
-
] }),
|
|
819
|
-
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)(PoweredByTag, { showPoweredBy })
|
|
820
|
-
] });
|
|
821
|
-
};
|
|
822
|
-
|
|
823
|
-
// src/components/chat/messages/UserMessage.tsx
|
|
824
|
-
var import_jsx_runtime7 = require("react/jsx-runtime");
|
|
825
|
-
var UserMessage = (props) => {
|
|
826
|
-
const { message, ImageRenderer: ImageRenderer2 } = props;
|
|
827
|
-
const isImageMessage = message && "image" in message && message.image;
|
|
828
|
-
if (isImageMessage) {
|
|
829
|
-
const imageMessage = message;
|
|
830
|
-
return /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("div", { className: "copilotKitMessage copilotKitUserMessage", children: /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(ImageRenderer2, { image: imageMessage.image, content: imageMessage.content }) });
|
|
831
|
-
}
|
|
832
|
-
return /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("div", { className: "copilotKitMessage copilotKitUserMessage", children: message == null ? void 0 : message.content });
|
|
833
|
-
};
|
|
834
|
-
|
|
835
|
-
// src/components/chat/Markdown.tsx
|
|
836
|
-
var import_react7 = require("react");
|
|
837
|
-
var import_react_markdown = __toESM(require("react-markdown"));
|
|
838
|
-
|
|
839
|
-
// src/components/chat/CodeBlock.tsx
|
|
840
|
-
var import_react6 = require("react");
|
|
841
|
-
var import_react_syntax_highlighter = require("react-syntax-highlighter");
|
|
842
|
-
|
|
843
|
-
// src/hooks/use-copy-to-clipboard.tsx
|
|
844
|
-
var React4 = __toESM(require("react"));
|
|
845
|
-
function useCopyToClipboard({ timeout = 2e3 }) {
|
|
846
|
-
const [isCopied, setIsCopied] = React4.useState(false);
|
|
847
|
-
const copyToClipboard = (value) => {
|
|
848
|
-
var _a;
|
|
849
|
-
if (typeof window === "undefined" || !((_a = navigator.clipboard) == null ? void 0 : _a.writeText)) {
|
|
850
|
-
return;
|
|
851
|
-
}
|
|
852
|
-
if (!value) {
|
|
853
|
-
return;
|
|
854
|
-
}
|
|
855
|
-
navigator.clipboard.writeText(value).then(() => {
|
|
856
|
-
setIsCopied(true);
|
|
857
|
-
setTimeout(() => {
|
|
858
|
-
setIsCopied(false);
|
|
859
|
-
}, timeout);
|
|
860
|
-
});
|
|
861
|
-
};
|
|
862
|
-
return { isCopied, copyToClipboard };
|
|
863
|
-
}
|
|
864
|
-
|
|
865
|
-
// src/components/chat/CodeBlock.tsx
|
|
866
|
-
var import_jsx_runtime8 = require("react/jsx-runtime");
|
|
867
|
-
var programmingLanguages = {
|
|
868
|
-
javascript: ".js",
|
|
869
|
-
python: ".py",
|
|
870
|
-
java: ".java",
|
|
871
|
-
c: ".c",
|
|
872
|
-
cpp: ".cpp",
|
|
873
|
-
"c++": ".cpp",
|
|
874
|
-
"c#": ".cs",
|
|
875
|
-
ruby: ".rb",
|
|
876
|
-
php: ".php",
|
|
877
|
-
swift: ".swift",
|
|
878
|
-
"objective-c": ".m",
|
|
879
|
-
kotlin: ".kt",
|
|
880
|
-
typescript: ".ts",
|
|
881
|
-
go: ".go",
|
|
882
|
-
perl: ".pl",
|
|
883
|
-
rust: ".rs",
|
|
884
|
-
scala: ".scala",
|
|
885
|
-
haskell: ".hs",
|
|
886
|
-
lua: ".lua",
|
|
887
|
-
shell: ".sh",
|
|
888
|
-
sql: ".sql",
|
|
889
|
-
html: ".html",
|
|
890
|
-
css: ".css"
|
|
891
|
-
// add more file extensions here, make sure the key is same as language prop in CodeBlock.tsx component
|
|
892
|
-
};
|
|
893
|
-
var generateRandomString = (length, lowercase = false) => {
|
|
894
|
-
const chars = "ABCDEFGHJKLMNPQRSTUVWXY3456789";
|
|
895
|
-
let result = "";
|
|
896
|
-
for (let i = 0; i < length; i++) {
|
|
897
|
-
result += chars.charAt(Math.floor(Math.random() * chars.length));
|
|
898
|
-
}
|
|
899
|
-
return lowercase ? result.toLowerCase() : result;
|
|
900
|
-
};
|
|
901
|
-
var CodeBlock = (0, import_react6.memo)(({ language, value }) => {
|
|
902
|
-
const { isCopied, copyToClipboard } = useCopyToClipboard({ timeout: 2e3 });
|
|
903
|
-
const downloadAsFile = () => {
|
|
904
|
-
if (typeof window === "undefined") {
|
|
905
|
-
return;
|
|
906
|
-
}
|
|
907
|
-
const fileExtension = programmingLanguages[language] || ".file";
|
|
908
|
-
const suggestedFileName = `file-${generateRandomString(3, true)}${fileExtension}`;
|
|
909
|
-
const fileName = window.prompt("Enter file name", suggestedFileName);
|
|
910
|
-
if (!fileName) {
|
|
911
|
-
return;
|
|
912
|
-
}
|
|
913
|
-
const blob = new Blob([value], { type: "text/plain" });
|
|
914
|
-
const url = URL.createObjectURL(blob);
|
|
915
|
-
const link = document.createElement("a");
|
|
916
|
-
link.download = fileName;
|
|
917
|
-
link.href = url;
|
|
918
|
-
link.style.display = "none";
|
|
919
|
-
document.body.appendChild(link);
|
|
920
|
-
link.click();
|
|
921
|
-
document.body.removeChild(link);
|
|
922
|
-
URL.revokeObjectURL(url);
|
|
923
|
-
};
|
|
924
|
-
const onCopy = () => {
|
|
925
|
-
if (isCopied)
|
|
926
|
-
return;
|
|
927
|
-
copyToClipboard(value);
|
|
928
|
-
};
|
|
929
|
-
return /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("div", { className: "copilotKitCodeBlock", children: [
|
|
930
|
-
/* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("div", { className: "copilotKitCodeBlockToolbar", children: [
|
|
931
|
-
/* @__PURE__ */ (0, import_jsx_runtime8.jsx)("span", { className: "copilotKitCodeBlockToolbarLanguage", children: language }),
|
|
932
|
-
/* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("div", { className: "copilotKitCodeBlockToolbarButtons", children: [
|
|
933
|
-
/* @__PURE__ */ (0, import_jsx_runtime8.jsx)("button", { className: "copilotKitCodeBlockToolbarButton", onClick: downloadAsFile, children: DownloadIcon }),
|
|
934
|
-
/* @__PURE__ */ (0, import_jsx_runtime8.jsx)("button", { className: "copilotKitCodeBlockToolbarButton", onClick: onCopy, children: isCopied ? CheckIcon : CopyIcon })
|
|
935
|
-
] })
|
|
936
|
-
] }),
|
|
937
|
-
/* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
|
|
938
|
-
import_react_syntax_highlighter.Prism,
|
|
939
|
-
{
|
|
940
|
-
language,
|
|
941
|
-
style: highlightStyle,
|
|
942
|
-
PreTag: "div",
|
|
943
|
-
customStyle: {
|
|
944
|
-
margin: 0,
|
|
945
|
-
borderBottomLeftRadius: "0.375rem",
|
|
946
|
-
borderBottomRightRadius: "0.375rem"
|
|
947
|
-
},
|
|
948
|
-
children: value
|
|
949
|
-
}
|
|
950
|
-
)
|
|
528
|
+
)
|
|
951
529
|
] });
|
|
952
530
|
});
|
|
953
531
|
CodeBlock.displayName = "CodeBlock";
|
|
@@ -1232,316 +810,896 @@ var highlightStyle = {
|
|
|
1232
810
|
boxShadow: "inset 5px 0 0 #f7d87c",
|
|
1233
811
|
zIndex: "0"
|
|
1234
812
|
}
|
|
1235
|
-
};
|
|
813
|
+
};
|
|
814
|
+
|
|
815
|
+
// src/components/chat/Markdown.tsx
|
|
816
|
+
var import_remark_gfm = __toESM(require("remark-gfm"));
|
|
817
|
+
var import_remark_math = __toESM(require("remark-math"));
|
|
818
|
+
var import_rehype_raw = __toESM(require("rehype-raw"));
|
|
819
|
+
var import_jsx_runtime5 = require("react/jsx-runtime");
|
|
820
|
+
var defaultComponents = {
|
|
821
|
+
a(_a) {
|
|
822
|
+
var _b = _a, { children } = _b, props = __objRest(_b, ["children"]);
|
|
823
|
+
return /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("a", __spreadProps(__spreadValues({ className: "copilotKitMarkdownElement" }, props), { target: "_blank", rel: "noopener noreferrer", children }));
|
|
824
|
+
},
|
|
825
|
+
// @ts-expect-error -- inline
|
|
826
|
+
code(_c) {
|
|
827
|
+
var _d = _c, { children, className, inline } = _d, props = __objRest(_d, ["children", "className", "inline"]);
|
|
828
|
+
if (Array.isArray(children) && children.length) {
|
|
829
|
+
if (children[0] == "\u258D") {
|
|
830
|
+
return /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
|
|
831
|
+
"span",
|
|
832
|
+
{
|
|
833
|
+
style: {
|
|
834
|
+
animation: "pulse 2s cubic-bezier(0.4, 0, 0.6, 1) infinite",
|
|
835
|
+
marginTop: "0.25rem"
|
|
836
|
+
},
|
|
837
|
+
children: "\u258D"
|
|
838
|
+
}
|
|
839
|
+
);
|
|
840
|
+
}
|
|
841
|
+
children[0] = (children == null ? void 0 : children[0]).replace("`\u258D`", "\u258D");
|
|
842
|
+
}
|
|
843
|
+
const match = /language-(\w+)/.exec(className || "");
|
|
844
|
+
const hasLanguage = match && match[1];
|
|
845
|
+
const content = String(children);
|
|
846
|
+
const hasNewlines = content.includes("\n");
|
|
847
|
+
const isInline = !hasLanguage && !hasNewlines;
|
|
848
|
+
if (isInline) {
|
|
849
|
+
return /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
|
|
850
|
+
"code",
|
|
851
|
+
__spreadProps(__spreadValues({
|
|
852
|
+
className: `copilotKitMarkdownElement copilotKitInlineCode ${className || ""}`
|
|
853
|
+
}, props), {
|
|
854
|
+
children
|
|
855
|
+
})
|
|
856
|
+
);
|
|
857
|
+
}
|
|
858
|
+
return /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
|
|
859
|
+
CodeBlock,
|
|
860
|
+
__spreadValues({
|
|
861
|
+
language: match && match[1] || "",
|
|
862
|
+
value: String(children).replace(/\n$/, "")
|
|
863
|
+
}, props),
|
|
864
|
+
Math.random()
|
|
865
|
+
);
|
|
866
|
+
},
|
|
867
|
+
h1: (_e) => {
|
|
868
|
+
var _f = _e, { children } = _f, props = __objRest(_f, ["children"]);
|
|
869
|
+
return /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("h1", __spreadProps(__spreadValues({ className: "copilotKitMarkdownElement" }, props), { children }));
|
|
870
|
+
},
|
|
871
|
+
h2: (_g) => {
|
|
872
|
+
var _h = _g, { children } = _h, props = __objRest(_h, ["children"]);
|
|
873
|
+
return /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("h2", __spreadProps(__spreadValues({ className: "copilotKitMarkdownElement" }, props), { children }));
|
|
874
|
+
},
|
|
875
|
+
h3: (_i) => {
|
|
876
|
+
var _j = _i, { children } = _j, props = __objRest(_j, ["children"]);
|
|
877
|
+
return /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("h3", __spreadProps(__spreadValues({ className: "copilotKitMarkdownElement" }, props), { children }));
|
|
878
|
+
},
|
|
879
|
+
h4: (_k) => {
|
|
880
|
+
var _l = _k, { children } = _l, props = __objRest(_l, ["children"]);
|
|
881
|
+
return /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("h4", __spreadProps(__spreadValues({ className: "copilotKitMarkdownElement" }, props), { children }));
|
|
882
|
+
},
|
|
883
|
+
h5: (_m) => {
|
|
884
|
+
var _n = _m, { children } = _n, props = __objRest(_n, ["children"]);
|
|
885
|
+
return /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("h5", __spreadProps(__spreadValues({ className: "copilotKitMarkdownElement" }, props), { children }));
|
|
886
|
+
},
|
|
887
|
+
h6: (_o) => {
|
|
888
|
+
var _p = _o, { children } = _p, props = __objRest(_p, ["children"]);
|
|
889
|
+
return /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("h6", __spreadProps(__spreadValues({ className: "copilotKitMarkdownElement" }, props), { children }));
|
|
890
|
+
},
|
|
891
|
+
p: (_q) => {
|
|
892
|
+
var _r = _q, { children } = _r, props = __objRest(_r, ["children"]);
|
|
893
|
+
return /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("p", __spreadProps(__spreadValues({ className: "copilotKitMarkdownElement" }, props), { children }));
|
|
894
|
+
},
|
|
895
|
+
pre: (_s) => {
|
|
896
|
+
var _t = _s, { children } = _t, props = __objRest(_t, ["children"]);
|
|
897
|
+
return /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("pre", __spreadProps(__spreadValues({ className: "copilotKitMarkdownElement" }, props), { children }));
|
|
898
|
+
},
|
|
899
|
+
blockquote: (_u) => {
|
|
900
|
+
var _v = _u, { children } = _v, props = __objRest(_v, ["children"]);
|
|
901
|
+
return /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("blockquote", __spreadProps(__spreadValues({ className: "copilotKitMarkdownElement" }, props), { children }));
|
|
902
|
+
},
|
|
903
|
+
ul: (_w) => {
|
|
904
|
+
var _x = _w, { children } = _x, props = __objRest(_x, ["children"]);
|
|
905
|
+
return /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("ul", __spreadProps(__spreadValues({ className: "copilotKitMarkdownElement" }, props), { children }));
|
|
906
|
+
},
|
|
907
|
+
li: (_y) => {
|
|
908
|
+
var _z = _y, { children } = _z, props = __objRest(_z, ["children"]);
|
|
909
|
+
return /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("li", __spreadProps(__spreadValues({ className: "copilotKitMarkdownElement" }, props), { children }));
|
|
910
|
+
}
|
|
911
|
+
};
|
|
912
|
+
var MemoizedReactMarkdown = (0, import_react3.memo)(
|
|
913
|
+
import_react_markdown.default,
|
|
914
|
+
(prevProps, nextProps) => prevProps.children === nextProps.children && prevProps.components === nextProps.components
|
|
915
|
+
);
|
|
916
|
+
var Markdown = ({ content, components }) => {
|
|
917
|
+
return /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("div", { className: "copilotKitMarkdown", children: /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
|
|
918
|
+
MemoizedReactMarkdown,
|
|
919
|
+
{
|
|
920
|
+
components: __spreadValues(__spreadValues({}, defaultComponents), components),
|
|
921
|
+
remarkPlugins: [import_remark_gfm.default, import_remark_math.default],
|
|
922
|
+
rehypePlugins: [import_rehype_raw.default],
|
|
923
|
+
children: content
|
|
924
|
+
}
|
|
925
|
+
) });
|
|
926
|
+
};
|
|
927
|
+
|
|
928
|
+
// src/components/chat/messages/AssistantMessage.tsx
|
|
929
|
+
var import_react4 = require("react");
|
|
930
|
+
var import_jsx_runtime6 = require("react/jsx-runtime");
|
|
931
|
+
var AssistantMessage = (props) => {
|
|
932
|
+
var _a;
|
|
933
|
+
const { icons, labels } = useChatContext();
|
|
934
|
+
const {
|
|
935
|
+
message,
|
|
936
|
+
isLoading,
|
|
937
|
+
onRegenerate,
|
|
938
|
+
onCopy,
|
|
939
|
+
onThumbsUp,
|
|
940
|
+
onThumbsDown,
|
|
941
|
+
isCurrentMessage,
|
|
942
|
+
markdownTagRenderers
|
|
943
|
+
} = props;
|
|
944
|
+
const [copied, setCopied] = (0, import_react4.useState)(false);
|
|
945
|
+
const handleCopy = () => {
|
|
946
|
+
const content2 = (message == null ? void 0 : message.content) || "";
|
|
947
|
+
if (content2 && onCopy) {
|
|
948
|
+
navigator.clipboard.writeText(content2);
|
|
949
|
+
setCopied(true);
|
|
950
|
+
onCopy(content2);
|
|
951
|
+
setTimeout(() => setCopied(false), 2e3);
|
|
952
|
+
} else if (content2) {
|
|
953
|
+
navigator.clipboard.writeText(content2);
|
|
954
|
+
setCopied(true);
|
|
955
|
+
setTimeout(() => setCopied(false), 2e3);
|
|
956
|
+
}
|
|
957
|
+
};
|
|
958
|
+
const handleRegenerate = () => {
|
|
959
|
+
if (onRegenerate)
|
|
960
|
+
onRegenerate();
|
|
961
|
+
};
|
|
962
|
+
const handleThumbsUp = () => {
|
|
963
|
+
if (onThumbsUp && message)
|
|
964
|
+
onThumbsUp(message);
|
|
965
|
+
};
|
|
966
|
+
const handleThumbsDown = () => {
|
|
967
|
+
if (onThumbsDown && message)
|
|
968
|
+
onThumbsDown(message);
|
|
969
|
+
};
|
|
970
|
+
const LoadingIcon = () => /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("span", { children: icons.activityIcon });
|
|
971
|
+
const content = (message == null ? void 0 : message.content) || "";
|
|
972
|
+
const subComponent = (_a = message == null ? void 0 : message.generativeUI) == null ? void 0 : _a.call(message);
|
|
973
|
+
return /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)(import_jsx_runtime6.Fragment, { children: [
|
|
974
|
+
content && /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("div", { className: "copilotKitMessage copilotKitAssistantMessage", children: [
|
|
975
|
+
content && /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(Markdown, { content, components: markdownTagRenderers }),
|
|
976
|
+
content && !isLoading && /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)(
|
|
977
|
+
"div",
|
|
978
|
+
{
|
|
979
|
+
className: `copilotKitMessageControls ${isCurrentMessage ? "currentMessage" : ""}`,
|
|
980
|
+
children: [
|
|
981
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
|
|
982
|
+
"button",
|
|
983
|
+
{
|
|
984
|
+
className: "copilotKitMessageControlButton",
|
|
985
|
+
onClick: handleRegenerate,
|
|
986
|
+
"aria-label": labels.regenerateResponse,
|
|
987
|
+
title: labels.regenerateResponse,
|
|
988
|
+
children: icons.regenerateIcon
|
|
989
|
+
}
|
|
990
|
+
),
|
|
991
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
|
|
992
|
+
"button",
|
|
993
|
+
{
|
|
994
|
+
className: "copilotKitMessageControlButton",
|
|
995
|
+
onClick: handleCopy,
|
|
996
|
+
"aria-label": labels.copyToClipboard,
|
|
997
|
+
title: labels.copyToClipboard,
|
|
998
|
+
children: copied ? /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("span", { style: { fontSize: "10px", fontWeight: "bold" }, children: "\u2713" }) : icons.copyIcon
|
|
999
|
+
}
|
|
1000
|
+
),
|
|
1001
|
+
onThumbsUp && /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
|
|
1002
|
+
"button",
|
|
1003
|
+
{
|
|
1004
|
+
className: "copilotKitMessageControlButton",
|
|
1005
|
+
onClick: handleThumbsUp,
|
|
1006
|
+
"aria-label": labels.thumbsUp,
|
|
1007
|
+
title: labels.thumbsUp,
|
|
1008
|
+
children: icons.thumbsUpIcon
|
|
1009
|
+
}
|
|
1010
|
+
),
|
|
1011
|
+
onThumbsDown && /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
|
|
1012
|
+
"button",
|
|
1013
|
+
{
|
|
1014
|
+
className: "copilotKitMessageControlButton",
|
|
1015
|
+
onClick: handleThumbsDown,
|
|
1016
|
+
"aria-label": labels.thumbsDown,
|
|
1017
|
+
title: labels.thumbsDown,
|
|
1018
|
+
children: icons.thumbsDownIcon
|
|
1019
|
+
}
|
|
1020
|
+
)
|
|
1021
|
+
]
|
|
1022
|
+
}
|
|
1023
|
+
)
|
|
1024
|
+
] }),
|
|
1025
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)("div", { style: { marginBottom: "0.5rem" }, children: subComponent }),
|
|
1026
|
+
isLoading && /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(LoadingIcon, {})
|
|
1027
|
+
] });
|
|
1028
|
+
};
|
|
1029
|
+
|
|
1030
|
+
// src/components/chat/messages/ImageRenderer.tsx
|
|
1031
|
+
var import_react5 = require("react");
|
|
1032
|
+
var import_jsx_runtime7 = require("react/jsx-runtime");
|
|
1033
|
+
var ImageRenderer = ({ image, content, className = "" }) => {
|
|
1034
|
+
const [imageError, setImageError] = (0, import_react5.useState)(false);
|
|
1035
|
+
const imageSrc = `data:image/${image.format};base64,${image.bytes}`;
|
|
1036
|
+
const altText = content || "User uploaded image";
|
|
1037
|
+
const handleImageError = () => {
|
|
1038
|
+
setImageError(true);
|
|
1039
|
+
};
|
|
1040
|
+
if (imageError) {
|
|
1041
|
+
return /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("div", { className: `copilotKitImageRendering copilotKitImageRenderingError ${className}`, children: [
|
|
1042
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)("div", { className: "copilotKitImageRenderingErrorMessage", children: "Failed to load image" }),
|
|
1043
|
+
content && /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("div", { className: "copilotKitImageRenderingContent", children: content })
|
|
1044
|
+
] });
|
|
1045
|
+
}
|
|
1046
|
+
return /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("div", { className: `copilotKitImageRendering ${className}`, children: [
|
|
1047
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
|
|
1048
|
+
"img",
|
|
1049
|
+
{
|
|
1050
|
+
src: imageSrc,
|
|
1051
|
+
alt: altText,
|
|
1052
|
+
className: "copilotKitImageRenderingImage",
|
|
1053
|
+
onError: handleImageError
|
|
1054
|
+
}
|
|
1055
|
+
),
|
|
1056
|
+
content && /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("div", { className: "copilotKitImageRenderingContent", children: content })
|
|
1057
|
+
] });
|
|
1058
|
+
};
|
|
1059
|
+
|
|
1060
|
+
// src/components/chat/messages/RenderMessage.tsx
|
|
1061
|
+
var import_jsx_runtime8 = require("react/jsx-runtime");
|
|
1062
|
+
function RenderMessage(_a) {
|
|
1063
|
+
var _b = _a, {
|
|
1064
|
+
UserMessage: UserMessage2 = UserMessage,
|
|
1065
|
+
AssistantMessage: AssistantMessage2 = AssistantMessage,
|
|
1066
|
+
ImageRenderer: ImageRenderer2 = ImageRenderer
|
|
1067
|
+
} = _b, props = __objRest(_b, [
|
|
1068
|
+
"UserMessage",
|
|
1069
|
+
"AssistantMessage",
|
|
1070
|
+
"ImageRenderer"
|
|
1071
|
+
]);
|
|
1072
|
+
var _a2;
|
|
1073
|
+
const {
|
|
1074
|
+
message,
|
|
1075
|
+
inProgress,
|
|
1076
|
+
index,
|
|
1077
|
+
isCurrentMessage,
|
|
1078
|
+
onRegenerate,
|
|
1079
|
+
onCopy,
|
|
1080
|
+
onThumbsUp,
|
|
1081
|
+
onThumbsDown,
|
|
1082
|
+
markdownTagRenderers
|
|
1083
|
+
} = props;
|
|
1084
|
+
switch (message.role) {
|
|
1085
|
+
case "user":
|
|
1086
|
+
return /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
|
|
1087
|
+
UserMessage2,
|
|
1088
|
+
{
|
|
1089
|
+
rawData: message,
|
|
1090
|
+
"data-message-role": "user",
|
|
1091
|
+
message,
|
|
1092
|
+
ImageRenderer: ImageRenderer2
|
|
1093
|
+
},
|
|
1094
|
+
index
|
|
1095
|
+
);
|
|
1096
|
+
case "assistant":
|
|
1097
|
+
return /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
|
|
1098
|
+
AssistantMessage2,
|
|
1099
|
+
{
|
|
1100
|
+
"data-message-role": "assistant",
|
|
1101
|
+
subComponent: (_a2 = message.generativeUI) == null ? void 0 : _a2.call(message),
|
|
1102
|
+
rawData: message,
|
|
1103
|
+
message,
|
|
1104
|
+
isLoading: inProgress && isCurrentMessage && !message.content,
|
|
1105
|
+
isGenerating: inProgress && isCurrentMessage && !!message.content,
|
|
1106
|
+
isCurrentMessage,
|
|
1107
|
+
onRegenerate: () => onRegenerate == null ? void 0 : onRegenerate(message.id),
|
|
1108
|
+
onCopy,
|
|
1109
|
+
onThumbsUp,
|
|
1110
|
+
onThumbsDown,
|
|
1111
|
+
markdownTagRenderers,
|
|
1112
|
+
ImageRenderer: ImageRenderer2
|
|
1113
|
+
},
|
|
1114
|
+
index
|
|
1115
|
+
);
|
|
1116
|
+
}
|
|
1117
|
+
}
|
|
1118
|
+
|
|
1119
|
+
// src/components/chat/messages/LegacyRenderMessage.tsx
|
|
1120
|
+
var import_runtime_client_gql = require("@copilotkit/runtime-client-gql");
|
|
1121
|
+
var import_jsx_runtime9 = require("react/jsx-runtime");
|
|
1122
|
+
var LegacyRenderMessage = ({
|
|
1123
|
+
message,
|
|
1124
|
+
inProgress,
|
|
1125
|
+
index,
|
|
1126
|
+
isCurrentMessage,
|
|
1127
|
+
actionResult,
|
|
1128
|
+
AssistantMessage: AssistantMessage2,
|
|
1129
|
+
UserMessage: UserMessage2,
|
|
1130
|
+
ImageRenderer: ImageRenderer2,
|
|
1131
|
+
onRegenerate,
|
|
1132
|
+
onCopy,
|
|
1133
|
+
onThumbsUp,
|
|
1134
|
+
onThumbsDown,
|
|
1135
|
+
markdownTagRenderers,
|
|
1136
|
+
legacyProps
|
|
1137
|
+
}) => {
|
|
1138
|
+
var _a;
|
|
1139
|
+
const {
|
|
1140
|
+
RenderTextMessage,
|
|
1141
|
+
RenderActionExecutionMessage,
|
|
1142
|
+
RenderAgentStateMessage,
|
|
1143
|
+
RenderResultMessage,
|
|
1144
|
+
RenderImageMessage
|
|
1145
|
+
} = legacyProps;
|
|
1146
|
+
const deprecatedMessage = (_a = (0, import_runtime_client_gql.aguiToGQL)(message)[0]) != null ? _a : void 0;
|
|
1147
|
+
if (deprecatedMessage.isTextMessage() && RenderTextMessage) {
|
|
1148
|
+
return /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
|
|
1149
|
+
RenderTextMessage,
|
|
1150
|
+
{
|
|
1151
|
+
message,
|
|
1152
|
+
inProgress,
|
|
1153
|
+
index,
|
|
1154
|
+
isCurrentMessage,
|
|
1155
|
+
AssistantMessage: AssistantMessage2,
|
|
1156
|
+
UserMessage: UserMessage2,
|
|
1157
|
+
onRegenerate,
|
|
1158
|
+
onCopy,
|
|
1159
|
+
onThumbsUp,
|
|
1160
|
+
onThumbsDown,
|
|
1161
|
+
markdownTagRenderers
|
|
1162
|
+
}
|
|
1163
|
+
);
|
|
1164
|
+
}
|
|
1165
|
+
if (deprecatedMessage.isActionExecutionMessage() && RenderActionExecutionMessage) {
|
|
1166
|
+
return /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
|
|
1167
|
+
RenderActionExecutionMessage,
|
|
1168
|
+
{
|
|
1169
|
+
message,
|
|
1170
|
+
inProgress,
|
|
1171
|
+
index,
|
|
1172
|
+
isCurrentMessage,
|
|
1173
|
+
actionResult,
|
|
1174
|
+
AssistantMessage: AssistantMessage2,
|
|
1175
|
+
UserMessage: UserMessage2
|
|
1176
|
+
}
|
|
1177
|
+
);
|
|
1178
|
+
}
|
|
1179
|
+
if (deprecatedMessage.isAgentStateMessage() && RenderAgentStateMessage) {
|
|
1180
|
+
return /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
|
|
1181
|
+
RenderAgentStateMessage,
|
|
1182
|
+
{
|
|
1183
|
+
message,
|
|
1184
|
+
inProgress,
|
|
1185
|
+
index,
|
|
1186
|
+
isCurrentMessage,
|
|
1187
|
+
AssistantMessage: AssistantMessage2,
|
|
1188
|
+
UserMessage: UserMessage2
|
|
1189
|
+
}
|
|
1190
|
+
);
|
|
1191
|
+
}
|
|
1192
|
+
if (deprecatedMessage.isResultMessage() && RenderResultMessage) {
|
|
1193
|
+
return /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
|
|
1194
|
+
RenderResultMessage,
|
|
1195
|
+
{
|
|
1196
|
+
message,
|
|
1197
|
+
inProgress,
|
|
1198
|
+
index,
|
|
1199
|
+
isCurrentMessage,
|
|
1200
|
+
AssistantMessage: AssistantMessage2,
|
|
1201
|
+
UserMessage: UserMessage2
|
|
1202
|
+
}
|
|
1203
|
+
);
|
|
1204
|
+
}
|
|
1205
|
+
if (deprecatedMessage.isImageMessage() && RenderImageMessage) {
|
|
1206
|
+
return /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
|
|
1207
|
+
RenderImageMessage,
|
|
1208
|
+
{
|
|
1209
|
+
message,
|
|
1210
|
+
inProgress,
|
|
1211
|
+
index,
|
|
1212
|
+
isCurrentMessage,
|
|
1213
|
+
AssistantMessage: AssistantMessage2,
|
|
1214
|
+
UserMessage: UserMessage2
|
|
1215
|
+
}
|
|
1216
|
+
);
|
|
1217
|
+
}
|
|
1218
|
+
return /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
|
|
1219
|
+
RenderMessage,
|
|
1220
|
+
{
|
|
1221
|
+
message,
|
|
1222
|
+
inProgress,
|
|
1223
|
+
index,
|
|
1224
|
+
isCurrentMessage,
|
|
1225
|
+
AssistantMessage: AssistantMessage2,
|
|
1226
|
+
UserMessage: UserMessage2,
|
|
1227
|
+
ImageRenderer: ImageRenderer2,
|
|
1228
|
+
onRegenerate,
|
|
1229
|
+
onCopy,
|
|
1230
|
+
onThumbsUp,
|
|
1231
|
+
onThumbsDown,
|
|
1232
|
+
markdownTagRenderers
|
|
1233
|
+
}
|
|
1234
|
+
);
|
|
1235
|
+
};
|
|
1236
|
+
|
|
1237
|
+
// src/components/chat/Messages.tsx
|
|
1238
|
+
var import_jsx_runtime10 = require("react/jsx-runtime");
|
|
1239
|
+
var Messages = ({
|
|
1240
|
+
inProgress,
|
|
1241
|
+
children,
|
|
1242
|
+
RenderMessage: RenderMessage2,
|
|
1243
|
+
AssistantMessage: AssistantMessage2,
|
|
1244
|
+
UserMessage: UserMessage2,
|
|
1245
|
+
ImageRenderer: ImageRenderer2,
|
|
1246
|
+
onRegenerate,
|
|
1247
|
+
onCopy,
|
|
1248
|
+
onThumbsUp,
|
|
1249
|
+
onThumbsDown,
|
|
1250
|
+
markdownTagRenderers,
|
|
1251
|
+
// Legacy props
|
|
1252
|
+
RenderTextMessage,
|
|
1253
|
+
RenderActionExecutionMessage,
|
|
1254
|
+
RenderAgentStateMessage,
|
|
1255
|
+
RenderResultMessage,
|
|
1256
|
+
RenderImageMessage
|
|
1257
|
+
}) => {
|
|
1258
|
+
const { labels } = useChatContext();
|
|
1259
|
+
const { messages: visibleMessages, interrupt } = (0, import_react_core.useCopilotChatInternal)();
|
|
1260
|
+
const initialMessages = (0, import_react6.useMemo)(() => makeInitialMessages(labels.initial), [labels.initial]);
|
|
1261
|
+
const messages = [...initialMessages, ...visibleMessages];
|
|
1262
|
+
const { messagesContainerRef, messagesEndRef } = useScrollToBottom(messages);
|
|
1263
|
+
const hasLegacyProps = !!(RenderTextMessage || RenderActionExecutionMessage || RenderAgentStateMessage || RenderResultMessage || RenderImageMessage);
|
|
1264
|
+
(0, import_react6.useEffect)(() => {
|
|
1265
|
+
if (hasLegacyProps) {
|
|
1266
|
+
console.warn(
|
|
1267
|
+
"[CopilotKit] Legacy message render props (RenderTextMessage, RenderActionExecutionMessage, etc.) are deprecated. Please use the unified 'RenderMessage' prop instead. See migration guide: https://docs.copilotkit.ai/migration/render-message"
|
|
1268
|
+
);
|
|
1269
|
+
}
|
|
1270
|
+
}, [hasLegacyProps]);
|
|
1271
|
+
const legacyProps = (0, import_react6.useMemo)(
|
|
1272
|
+
() => ({
|
|
1273
|
+
RenderTextMessage,
|
|
1274
|
+
RenderActionExecutionMessage,
|
|
1275
|
+
RenderAgentStateMessage,
|
|
1276
|
+
RenderResultMessage,
|
|
1277
|
+
RenderImageMessage
|
|
1278
|
+
}),
|
|
1279
|
+
[
|
|
1280
|
+
RenderTextMessage,
|
|
1281
|
+
RenderActionExecutionMessage,
|
|
1282
|
+
RenderAgentStateMessage,
|
|
1283
|
+
RenderResultMessage,
|
|
1284
|
+
RenderImageMessage
|
|
1285
|
+
]
|
|
1286
|
+
);
|
|
1287
|
+
const MessageRenderer = hasLegacyProps ? (props) => /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(LegacyRenderMessage, __spreadProps(__spreadValues({}, props), { legacyProps })) : RenderMessage2;
|
|
1288
|
+
return /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("div", { className: "copilotKitMessages", ref: messagesContainerRef, children: [
|
|
1289
|
+
/* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("div", { className: "copilotKitMessagesContainer", children: [
|
|
1290
|
+
messages.map((message, index) => {
|
|
1291
|
+
const isCurrentMessage = index === messages.length - 1;
|
|
1292
|
+
return /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(
|
|
1293
|
+
MessageRenderer,
|
|
1294
|
+
{
|
|
1295
|
+
message,
|
|
1296
|
+
inProgress,
|
|
1297
|
+
index,
|
|
1298
|
+
isCurrentMessage,
|
|
1299
|
+
AssistantMessage: AssistantMessage2,
|
|
1300
|
+
UserMessage: UserMessage2,
|
|
1301
|
+
ImageRenderer: ImageRenderer2,
|
|
1302
|
+
onRegenerate,
|
|
1303
|
+
onCopy,
|
|
1304
|
+
onThumbsUp,
|
|
1305
|
+
onThumbsDown,
|
|
1306
|
+
markdownTagRenderers
|
|
1307
|
+
},
|
|
1308
|
+
index
|
|
1309
|
+
);
|
|
1310
|
+
}),
|
|
1311
|
+
interrupt
|
|
1312
|
+
] }),
|
|
1313
|
+
/* @__PURE__ */ (0, import_jsx_runtime10.jsx)("footer", { className: "copilotKitMessagesFooter", ref: messagesEndRef, children })
|
|
1314
|
+
] });
|
|
1315
|
+
};
|
|
1316
|
+
function makeInitialMessages(initial) {
|
|
1317
|
+
if (!initial)
|
|
1318
|
+
return [];
|
|
1319
|
+
if (Array.isArray(initial)) {
|
|
1320
|
+
return initial.map((message) => {
|
|
1321
|
+
return {
|
|
1322
|
+
id: message,
|
|
1323
|
+
role: "assistant",
|
|
1324
|
+
content: message
|
|
1325
|
+
};
|
|
1326
|
+
});
|
|
1327
|
+
}
|
|
1328
|
+
return [
|
|
1329
|
+
{
|
|
1330
|
+
id: initial,
|
|
1331
|
+
role: "assistant",
|
|
1332
|
+
content: initial
|
|
1333
|
+
}
|
|
1334
|
+
];
|
|
1335
|
+
}
|
|
1336
|
+
function useScrollToBottom(messages) {
|
|
1337
|
+
const messagesEndRef = (0, import_react6.useRef)(null);
|
|
1338
|
+
const messagesContainerRef = (0, import_react6.useRef)(null);
|
|
1339
|
+
const isProgrammaticScrollRef = (0, import_react6.useRef)(false);
|
|
1340
|
+
const isUserScrollUpRef = (0, import_react6.useRef)(false);
|
|
1341
|
+
const scrollToBottom = () => {
|
|
1342
|
+
if (messagesContainerRef.current && messagesEndRef.current) {
|
|
1343
|
+
isProgrammaticScrollRef.current = true;
|
|
1344
|
+
messagesContainerRef.current.scrollTop = messagesContainerRef.current.scrollHeight;
|
|
1345
|
+
}
|
|
1346
|
+
};
|
|
1347
|
+
const handleScroll = () => {
|
|
1348
|
+
if (isProgrammaticScrollRef.current) {
|
|
1349
|
+
isProgrammaticScrollRef.current = false;
|
|
1350
|
+
return;
|
|
1351
|
+
}
|
|
1352
|
+
if (messagesContainerRef.current) {
|
|
1353
|
+
const { scrollTop, scrollHeight, clientHeight } = messagesContainerRef.current;
|
|
1354
|
+
isUserScrollUpRef.current = scrollTop + clientHeight < scrollHeight;
|
|
1355
|
+
}
|
|
1356
|
+
};
|
|
1357
|
+
(0, import_react6.useEffect)(() => {
|
|
1358
|
+
const container = messagesContainerRef.current;
|
|
1359
|
+
if (container) {
|
|
1360
|
+
container.addEventListener("scroll", handleScroll);
|
|
1361
|
+
}
|
|
1362
|
+
return () => {
|
|
1363
|
+
if (container) {
|
|
1364
|
+
container.removeEventListener("scroll", handleScroll);
|
|
1365
|
+
}
|
|
1366
|
+
};
|
|
1367
|
+
}, []);
|
|
1368
|
+
(0, import_react6.useEffect)(() => {
|
|
1369
|
+
const container = messagesContainerRef.current;
|
|
1370
|
+
if (!container) {
|
|
1371
|
+
return;
|
|
1372
|
+
}
|
|
1373
|
+
const mutationObserver = new MutationObserver(() => {
|
|
1374
|
+
if (!isUserScrollUpRef.current) {
|
|
1375
|
+
scrollToBottom();
|
|
1376
|
+
}
|
|
1377
|
+
});
|
|
1378
|
+
mutationObserver.observe(container, {
|
|
1379
|
+
childList: true,
|
|
1380
|
+
subtree: true,
|
|
1381
|
+
characterData: true
|
|
1382
|
+
});
|
|
1383
|
+
return () => {
|
|
1384
|
+
mutationObserver.disconnect();
|
|
1385
|
+
};
|
|
1386
|
+
}, []);
|
|
1387
|
+
(0, import_react6.useEffect)(() => {
|
|
1388
|
+
isUserScrollUpRef.current = false;
|
|
1389
|
+
scrollToBottom();
|
|
1390
|
+
}, [messages.filter((m) => m.role === "user").length]);
|
|
1391
|
+
return { messagesEndRef, messagesContainerRef };
|
|
1392
|
+
}
|
|
1393
|
+
|
|
1394
|
+
// src/components/chat/Input.tsx
|
|
1395
|
+
var import_react9 = require("react");
|
|
1396
|
+
|
|
1397
|
+
// src/components/chat/Textarea.tsx
|
|
1398
|
+
var import_react7 = require("react");
|
|
1399
|
+
var import_jsx_runtime11 = require("react/jsx-runtime");
|
|
1400
|
+
var AutoResizingTextarea = (0, import_react7.forwardRef)(
|
|
1401
|
+
({
|
|
1402
|
+
maxRows = 1,
|
|
1403
|
+
placeholder,
|
|
1404
|
+
value,
|
|
1405
|
+
onChange,
|
|
1406
|
+
onKeyDown,
|
|
1407
|
+
onCompositionStart,
|
|
1408
|
+
onCompositionEnd,
|
|
1409
|
+
autoFocus
|
|
1410
|
+
}, ref) => {
|
|
1411
|
+
const internalTextareaRef = (0, import_react7.useRef)(null);
|
|
1412
|
+
const [maxHeight, setMaxHeight] = (0, import_react7.useState)(0);
|
|
1413
|
+
(0, import_react7.useImperativeHandle)(ref, () => internalTextareaRef.current);
|
|
1414
|
+
(0, import_react7.useEffect)(() => {
|
|
1415
|
+
const calculateMaxHeight = () => {
|
|
1416
|
+
const textarea = internalTextareaRef.current;
|
|
1417
|
+
if (textarea) {
|
|
1418
|
+
textarea.style.height = "auto";
|
|
1419
|
+
const singleRowHeight = textarea.scrollHeight;
|
|
1420
|
+
setMaxHeight(singleRowHeight * maxRows);
|
|
1421
|
+
if (autoFocus) {
|
|
1422
|
+
textarea.focus();
|
|
1423
|
+
}
|
|
1424
|
+
}
|
|
1425
|
+
};
|
|
1426
|
+
calculateMaxHeight();
|
|
1427
|
+
}, [maxRows]);
|
|
1428
|
+
(0, import_react7.useEffect)(() => {
|
|
1429
|
+
const textarea = internalTextareaRef.current;
|
|
1430
|
+
if (textarea) {
|
|
1431
|
+
textarea.style.height = "auto";
|
|
1432
|
+
textarea.style.height = `${Math.min(textarea.scrollHeight, maxHeight)}px`;
|
|
1433
|
+
}
|
|
1434
|
+
}, [value, maxHeight]);
|
|
1435
|
+
return /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
|
|
1436
|
+
"textarea",
|
|
1437
|
+
{
|
|
1438
|
+
ref: internalTextareaRef,
|
|
1439
|
+
value,
|
|
1440
|
+
onChange,
|
|
1441
|
+
onKeyDown,
|
|
1442
|
+
onCompositionStart,
|
|
1443
|
+
onCompositionEnd,
|
|
1444
|
+
placeholder,
|
|
1445
|
+
style: {
|
|
1446
|
+
overflow: "auto",
|
|
1447
|
+
resize: "none",
|
|
1448
|
+
maxHeight: `${maxHeight}px`
|
|
1449
|
+
},
|
|
1450
|
+
rows: 1
|
|
1451
|
+
}
|
|
1452
|
+
);
|
|
1453
|
+
}
|
|
1454
|
+
);
|
|
1455
|
+
var Textarea_default = AutoResizingTextarea;
|
|
1236
1456
|
|
|
1237
|
-
// src/
|
|
1238
|
-
var
|
|
1239
|
-
var
|
|
1240
|
-
var
|
|
1241
|
-
var
|
|
1242
|
-
|
|
1243
|
-
|
|
1244
|
-
|
|
1245
|
-
|
|
1246
|
-
}
|
|
1247
|
-
|
|
1248
|
-
|
|
1249
|
-
|
|
1250
|
-
|
|
1251
|
-
|
|
1252
|
-
|
|
1253
|
-
|
|
1254
|
-
|
|
1255
|
-
|
|
1256
|
-
|
|
1257
|
-
|
|
1258
|
-
|
|
1259
|
-
|
|
1260
|
-
|
|
1457
|
+
// src/hooks/use-push-to-talk.tsx
|
|
1458
|
+
var import_react_core2 = require("@copilotkit/react-core");
|
|
1459
|
+
var import_runtime_client_gql2 = require("@copilotkit/runtime-client-gql");
|
|
1460
|
+
var import_react8 = require("react");
|
|
1461
|
+
var startRecording = (mediaStreamRef, mediaRecorderRef, audioContextRef, recordedChunks, onStop) => __async(void 0, null, function* () {
|
|
1462
|
+
if (!mediaStreamRef.current || !audioContextRef.current) {
|
|
1463
|
+
mediaStreamRef.current = yield navigator.mediaDevices.getUserMedia({ audio: true });
|
|
1464
|
+
audioContextRef.current = new window.AudioContext();
|
|
1465
|
+
yield audioContextRef.current.resume();
|
|
1466
|
+
}
|
|
1467
|
+
mediaRecorderRef.current = new MediaRecorder(mediaStreamRef.current);
|
|
1468
|
+
mediaRecorderRef.current.start(1e3);
|
|
1469
|
+
mediaRecorderRef.current.ondataavailable = (event) => {
|
|
1470
|
+
recordedChunks.push(event.data);
|
|
1471
|
+
};
|
|
1472
|
+
mediaRecorderRef.current.onstop = onStop;
|
|
1473
|
+
});
|
|
1474
|
+
var stopRecording = (mediaRecorderRef) => {
|
|
1475
|
+
if (mediaRecorderRef.current && mediaRecorderRef.current.state !== "inactive") {
|
|
1476
|
+
mediaRecorderRef.current.stop();
|
|
1477
|
+
}
|
|
1478
|
+
};
|
|
1479
|
+
var transcribeAudio = (recordedChunks, transcribeAudioUrl) => __async(void 0, null, function* () {
|
|
1480
|
+
const completeBlob = new Blob(recordedChunks, { type: "audio/mp4" });
|
|
1481
|
+
const formData = new FormData();
|
|
1482
|
+
formData.append("file", completeBlob, "recording.mp4");
|
|
1483
|
+
const response = yield fetch(transcribeAudioUrl, {
|
|
1484
|
+
method: "POST",
|
|
1485
|
+
body: formData
|
|
1486
|
+
});
|
|
1487
|
+
if (!response.ok) {
|
|
1488
|
+
throw new Error(`Error: ${response.statusText}`);
|
|
1489
|
+
}
|
|
1490
|
+
const transcription = yield response.json();
|
|
1491
|
+
return transcription.text;
|
|
1492
|
+
});
|
|
1493
|
+
var playAudioResponse = (text, textToSpeechUrl, audioContext) => {
|
|
1494
|
+
const encodedText = encodeURIComponent(text);
|
|
1495
|
+
const url = `${textToSpeechUrl}?text=${encodedText}`;
|
|
1496
|
+
fetch(url).then((response) => response.arrayBuffer()).then((arrayBuffer) => audioContext.decodeAudioData(arrayBuffer)).then((audioBuffer) => {
|
|
1497
|
+
const source = audioContext.createBufferSource();
|
|
1498
|
+
source.buffer = audioBuffer;
|
|
1499
|
+
source.connect(audioContext.destination);
|
|
1500
|
+
source.start(0);
|
|
1501
|
+
}).catch((error) => {
|
|
1502
|
+
console.error("Error with decoding audio data", error);
|
|
1503
|
+
});
|
|
1504
|
+
};
|
|
1505
|
+
var usePushToTalk = ({
|
|
1506
|
+
sendFunction,
|
|
1507
|
+
inProgress
|
|
1508
|
+
}) => {
|
|
1509
|
+
const [pushToTalkState, setPushToTalkState] = (0, import_react8.useState)("idle");
|
|
1510
|
+
const mediaStreamRef = (0, import_react8.useRef)(null);
|
|
1511
|
+
const audioContextRef = (0, import_react8.useRef)(null);
|
|
1512
|
+
const mediaRecorderRef = (0, import_react8.useRef)(null);
|
|
1513
|
+
const recordedChunks = (0, import_react8.useRef)([]);
|
|
1514
|
+
const generalContext = (0, import_react_core2.useCopilotContext)();
|
|
1515
|
+
const messagesContext = (0, import_react_core2.useCopilotMessagesContext)();
|
|
1516
|
+
const context = __spreadValues(__spreadValues({}, generalContext), messagesContext);
|
|
1517
|
+
const [startReadingFromMessageId, setStartReadingFromMessageId] = (0, import_react8.useState)(null);
|
|
1518
|
+
(0, import_react8.useEffect)(() => {
|
|
1519
|
+
if (pushToTalkState === "recording") {
|
|
1520
|
+
startRecording(
|
|
1521
|
+
mediaStreamRef,
|
|
1522
|
+
mediaRecorderRef,
|
|
1523
|
+
audioContextRef,
|
|
1524
|
+
recordedChunks.current,
|
|
1525
|
+
() => {
|
|
1526
|
+
setPushToTalkState("transcribing");
|
|
1527
|
+
}
|
|
1528
|
+
);
|
|
1529
|
+
} else {
|
|
1530
|
+
stopRecording(mediaRecorderRef);
|
|
1531
|
+
if (pushToTalkState === "transcribing") {
|
|
1532
|
+
transcribeAudio(recordedChunks.current, context.copilotApiConfig.transcribeAudioUrl).then(
|
|
1533
|
+
(transcription) => __async(void 0, null, function* () {
|
|
1534
|
+
recordedChunks.current = [];
|
|
1535
|
+
setPushToTalkState("idle");
|
|
1536
|
+
const message = yield sendFunction(transcription);
|
|
1537
|
+
setStartReadingFromMessageId(message.id);
|
|
1538
|
+
})
|
|
1261
1539
|
);
|
|
1262
1540
|
}
|
|
1263
|
-
children[0] = (children == null ? void 0 : children[0]).replace("`\u258D`", "\u258D");
|
|
1264
1541
|
}
|
|
1265
|
-
|
|
1266
|
-
|
|
1267
|
-
|
|
1268
|
-
|
|
1269
|
-
|
|
1270
|
-
if (
|
|
1271
|
-
|
|
1272
|
-
|
|
1273
|
-
__spreadProps(__spreadValues({
|
|
1274
|
-
className: `copilotKitMarkdownElement copilotKitInlineCode ${className || ""}`
|
|
1275
|
-
}, props), {
|
|
1276
|
-
children
|
|
1277
|
-
})
|
|
1542
|
+
return () => {
|
|
1543
|
+
stopRecording(mediaRecorderRef);
|
|
1544
|
+
};
|
|
1545
|
+
}, [pushToTalkState]);
|
|
1546
|
+
(0, import_react8.useEffect)(() => {
|
|
1547
|
+
if (inProgress === false && startReadingFromMessageId) {
|
|
1548
|
+
const lastMessageIndex = context.messages.findIndex(
|
|
1549
|
+
(message) => message.id === startReadingFromMessageId
|
|
1278
1550
|
);
|
|
1551
|
+
const aguiMessages = (0, import_runtime_client_gql2.gqlToAGUI)(context.messages);
|
|
1552
|
+
const messagesAfterLast = aguiMessages.slice(lastMessageIndex + 1).filter((message) => message.role === "assistant");
|
|
1553
|
+
const text = messagesAfterLast.map((message) => message.content).join("\n");
|
|
1554
|
+
playAudioResponse(text, context.copilotApiConfig.textToSpeechUrl, audioContextRef.current);
|
|
1555
|
+
setStartReadingFromMessageId(null);
|
|
1279
1556
|
}
|
|
1280
|
-
|
|
1281
|
-
|
|
1282
|
-
__spreadValues({
|
|
1283
|
-
language: match && match[1] || "",
|
|
1284
|
-
value: String(children).replace(/\n$/, "")
|
|
1285
|
-
}, props),
|
|
1286
|
-
Math.random()
|
|
1287
|
-
);
|
|
1288
|
-
},
|
|
1289
|
-
h1: (_e) => {
|
|
1290
|
-
var _f = _e, { children } = _f, props = __objRest(_f, ["children"]);
|
|
1291
|
-
return /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("h1", __spreadProps(__spreadValues({ className: "copilotKitMarkdownElement" }, props), { children }));
|
|
1292
|
-
},
|
|
1293
|
-
h2: (_g) => {
|
|
1294
|
-
var _h = _g, { children } = _h, props = __objRest(_h, ["children"]);
|
|
1295
|
-
return /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("h2", __spreadProps(__spreadValues({ className: "copilotKitMarkdownElement" }, props), { children }));
|
|
1296
|
-
},
|
|
1297
|
-
h3: (_i) => {
|
|
1298
|
-
var _j = _i, { children } = _j, props = __objRest(_j, ["children"]);
|
|
1299
|
-
return /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("h3", __spreadProps(__spreadValues({ className: "copilotKitMarkdownElement" }, props), { children }));
|
|
1300
|
-
},
|
|
1301
|
-
h4: (_k) => {
|
|
1302
|
-
var _l = _k, { children } = _l, props = __objRest(_l, ["children"]);
|
|
1303
|
-
return /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("h4", __spreadProps(__spreadValues({ className: "copilotKitMarkdownElement" }, props), { children }));
|
|
1304
|
-
},
|
|
1305
|
-
h5: (_m) => {
|
|
1306
|
-
var _n = _m, { children } = _n, props = __objRest(_n, ["children"]);
|
|
1307
|
-
return /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("h5", __spreadProps(__spreadValues({ className: "copilotKitMarkdownElement" }, props), { children }));
|
|
1308
|
-
},
|
|
1309
|
-
h6: (_o) => {
|
|
1310
|
-
var _p = _o, { children } = _p, props = __objRest(_p, ["children"]);
|
|
1311
|
-
return /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("h6", __spreadProps(__spreadValues({ className: "copilotKitMarkdownElement" }, props), { children }));
|
|
1312
|
-
},
|
|
1313
|
-
p: (_q) => {
|
|
1314
|
-
var _r = _q, { children } = _r, props = __objRest(_r, ["children"]);
|
|
1315
|
-
return /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("p", __spreadProps(__spreadValues({ className: "copilotKitMarkdownElement" }, props), { children }));
|
|
1316
|
-
},
|
|
1317
|
-
pre: (_s) => {
|
|
1318
|
-
var _t = _s, { children } = _t, props = __objRest(_t, ["children"]);
|
|
1319
|
-
return /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("pre", __spreadProps(__spreadValues({ className: "copilotKitMarkdownElement" }, props), { children }));
|
|
1320
|
-
},
|
|
1321
|
-
blockquote: (_u) => {
|
|
1322
|
-
var _v = _u, { children } = _v, props = __objRest(_v, ["children"]);
|
|
1323
|
-
return /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("blockquote", __spreadProps(__spreadValues({ className: "copilotKitMarkdownElement" }, props), { children }));
|
|
1324
|
-
},
|
|
1325
|
-
ul: (_w) => {
|
|
1326
|
-
var _x = _w, { children } = _x, props = __objRest(_x, ["children"]);
|
|
1327
|
-
return /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("ul", __spreadProps(__spreadValues({ className: "copilotKitMarkdownElement" }, props), { children }));
|
|
1328
|
-
},
|
|
1329
|
-
li: (_y) => {
|
|
1330
|
-
var _z = _y, { children } = _z, props = __objRest(_z, ["children"]);
|
|
1331
|
-
return /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("li", __spreadProps(__spreadValues({ className: "copilotKitMarkdownElement" }, props), { children }));
|
|
1332
|
-
}
|
|
1557
|
+
}, [startReadingFromMessageId, inProgress]);
|
|
1558
|
+
return { pushToTalkState, setPushToTalkState };
|
|
1333
1559
|
};
|
|
1334
|
-
|
|
1335
|
-
|
|
1336
|
-
|
|
1337
|
-
|
|
1338
|
-
|
|
1339
|
-
|
|
1340
|
-
|
|
1341
|
-
|
|
1342
|
-
|
|
1343
|
-
remarkPlugins: [import_remark_gfm.default, import_remark_math.default],
|
|
1344
|
-
rehypePlugins: [import_rehype_raw.default],
|
|
1345
|
-
children: content
|
|
1346
|
-
}
|
|
1347
|
-
) });
|
|
1560
|
+
|
|
1561
|
+
// src/components/chat/Input.tsx
|
|
1562
|
+
var import_react_core3 = require("@copilotkit/react-core");
|
|
1563
|
+
|
|
1564
|
+
// src/hooks/use-dark-mode.ts
|
|
1565
|
+
var useDarkMode = () => {
|
|
1566
|
+
if (typeof window === "undefined")
|
|
1567
|
+
return false;
|
|
1568
|
+
return document.documentElement.classList.contains("dark") || document.body.classList.contains("dark") || document.documentElement.getAttribute("data-theme") === "dark" || document.body.getAttribute("data-theme") === "dark" || window.matchMedia("(prefers-color-scheme: dark)").matches;
|
|
1348
1569
|
};
|
|
1349
1570
|
|
|
1350
|
-
// src/components/chat/
|
|
1351
|
-
var
|
|
1352
|
-
|
|
1353
|
-
|
|
1354
|
-
|
|
1355
|
-
|
|
1356
|
-
|
|
1357
|
-
|
|
1358
|
-
|
|
1359
|
-
|
|
1360
|
-
|
|
1361
|
-
|
|
1362
|
-
|
|
1363
|
-
|
|
1364
|
-
|
|
1365
|
-
} = props;
|
|
1366
|
-
const [copied, setCopied] = (0, import_react8.useState)(false);
|
|
1367
|
-
const handleCopy = () => {
|
|
1368
|
-
const content2 = (message == null ? void 0 : message.content) || "";
|
|
1369
|
-
if (content2 && onCopy) {
|
|
1370
|
-
navigator.clipboard.writeText(content2);
|
|
1371
|
-
setCopied(true);
|
|
1372
|
-
onCopy(content2);
|
|
1373
|
-
setTimeout(() => setCopied(false), 2e3);
|
|
1374
|
-
} else if (content2) {
|
|
1375
|
-
navigator.clipboard.writeText(content2);
|
|
1376
|
-
setCopied(true);
|
|
1377
|
-
setTimeout(() => setCopied(false), 2e3);
|
|
1378
|
-
}
|
|
1379
|
-
};
|
|
1380
|
-
const handleRegenerate = () => {
|
|
1381
|
-
if (onRegenerate)
|
|
1382
|
-
onRegenerate();
|
|
1571
|
+
// src/components/chat/PoweredByTag.tsx
|
|
1572
|
+
var import_jsx_runtime12 = require("react/jsx-runtime");
|
|
1573
|
+
function PoweredByTag({ showPoweredBy = true }) {
|
|
1574
|
+
const isDark = useDarkMode();
|
|
1575
|
+
if (!showPoweredBy) {
|
|
1576
|
+
return null;
|
|
1577
|
+
}
|
|
1578
|
+
const poweredByStyle = {
|
|
1579
|
+
visibility: "visible",
|
|
1580
|
+
display: "block",
|
|
1581
|
+
position: "static",
|
|
1582
|
+
textAlign: "center",
|
|
1583
|
+
fontSize: "12px",
|
|
1584
|
+
padding: "3px 0",
|
|
1585
|
+
color: isDark ? "rgb(69, 69, 69)" : "rgb(214, 214, 214)"
|
|
1383
1586
|
};
|
|
1384
|
-
|
|
1385
|
-
|
|
1386
|
-
|
|
1587
|
+
return /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("div", { children: /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("p", { className: "poweredBy", style: poweredByStyle, children: "Powered by CopilotKit" }) });
|
|
1588
|
+
}
|
|
1589
|
+
|
|
1590
|
+
// src/components/chat/Input.tsx
|
|
1591
|
+
var import_jsx_runtime13 = require("react/jsx-runtime");
|
|
1592
|
+
var MAX_NEWLINES = 6;
|
|
1593
|
+
var Input = ({
|
|
1594
|
+
inProgress,
|
|
1595
|
+
onSend,
|
|
1596
|
+
isVisible = false,
|
|
1597
|
+
onStop,
|
|
1598
|
+
onUpload,
|
|
1599
|
+
hideStopButton = false
|
|
1600
|
+
}) => {
|
|
1601
|
+
var _a, _b;
|
|
1602
|
+
const context = useChatContext();
|
|
1603
|
+
const copilotContext = (0, import_react_core3.useCopilotContext)();
|
|
1604
|
+
const showPoweredBy = !((_a = copilotContext.copilotApiConfig) == null ? void 0 : _a.publicApiKey);
|
|
1605
|
+
const pushToTalkConfigured = copilotContext.copilotApiConfig.textToSpeechUrl !== void 0 && copilotContext.copilotApiConfig.transcribeAudioUrl !== void 0;
|
|
1606
|
+
const textareaRef = (0, import_react9.useRef)(null);
|
|
1607
|
+
const [isComposing, setIsComposing] = (0, import_react9.useState)(false);
|
|
1608
|
+
const handleDivClick = (event) => {
|
|
1609
|
+
var _a2;
|
|
1610
|
+
const target = event.target;
|
|
1611
|
+
if (target.closest("button"))
|
|
1612
|
+
return;
|
|
1613
|
+
if (target.tagName === "TEXTAREA")
|
|
1614
|
+
return;
|
|
1615
|
+
(_a2 = textareaRef.current) == null ? void 0 : _a2.focus();
|
|
1387
1616
|
};
|
|
1388
|
-
const
|
|
1389
|
-
|
|
1390
|
-
|
|
1617
|
+
const [text, setText] = (0, import_react9.useState)("");
|
|
1618
|
+
const send = () => {
|
|
1619
|
+
var _a2;
|
|
1620
|
+
if (inProgress)
|
|
1621
|
+
return;
|
|
1622
|
+
onSend(text);
|
|
1623
|
+
setText("");
|
|
1624
|
+
(_a2 = textareaRef.current) == null ? void 0 : _a2.focus();
|
|
1391
1625
|
};
|
|
1392
|
-
const
|
|
1393
|
-
|
|
1394
|
-
|
|
1395
|
-
|
|
1396
|
-
|
|
1397
|
-
|
|
1398
|
-
|
|
1399
|
-
|
|
1626
|
+
const { pushToTalkState, setPushToTalkState } = usePushToTalk({
|
|
1627
|
+
sendFunction: onSend,
|
|
1628
|
+
inProgress
|
|
1629
|
+
});
|
|
1630
|
+
const isInProgress = inProgress || pushToTalkState === "transcribing";
|
|
1631
|
+
const buttonIcon = isInProgress && !hideStopButton ? context.icons.stopIcon : context.icons.sendIcon;
|
|
1632
|
+
const showPushToTalk = pushToTalkConfigured && (pushToTalkState === "idle" || pushToTalkState === "recording") && !inProgress;
|
|
1633
|
+
const canSend = (0, import_react9.useMemo)(() => {
|
|
1634
|
+
var _a2;
|
|
1635
|
+
const interruptEvent = (_a2 = copilotContext.langGraphInterruptAction) == null ? void 0 : _a2.event;
|
|
1636
|
+
const interruptInProgress = (interruptEvent == null ? void 0 : interruptEvent.name) === "LangGraphInterruptEvent" && !(interruptEvent == null ? void 0 : interruptEvent.response);
|
|
1637
|
+
return !isInProgress && text.trim().length > 0 && pushToTalkState === "idle" && !interruptInProgress;
|
|
1638
|
+
}, [(_b = copilotContext.langGraphInterruptAction) == null ? void 0 : _b.event, isInProgress, text, pushToTalkState]);
|
|
1639
|
+
const canStop = (0, import_react9.useMemo)(() => {
|
|
1640
|
+
return isInProgress && !hideStopButton;
|
|
1641
|
+
}, [isInProgress, hideStopButton]);
|
|
1642
|
+
const sendDisabled = !canSend && !canStop;
|
|
1643
|
+
return /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)("div", { className: `copilotKitInputContainer ${showPoweredBy ? "poweredByContainer" : ""}`, children: [
|
|
1644
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsxs)("div", { className: "copilotKitInput", onClick: handleDivClick, children: [
|
|
1645
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
|
|
1646
|
+
Textarea_default,
|
|
1400
1647
|
{
|
|
1401
|
-
|
|
1402
|
-
|
|
1403
|
-
|
|
1404
|
-
|
|
1405
|
-
|
|
1406
|
-
|
|
1407
|
-
|
|
1408
|
-
|
|
1409
|
-
|
|
1410
|
-
|
|
1411
|
-
|
|
1412
|
-
|
|
1413
|
-
|
|
1414
|
-
"button",
|
|
1415
|
-
{
|
|
1416
|
-
className: "copilotKitMessageControlButton",
|
|
1417
|
-
onClick: handleCopy,
|
|
1418
|
-
"aria-label": labels.copyToClipboard,
|
|
1419
|
-
title: labels.copyToClipboard,
|
|
1420
|
-
children: copied ? /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("span", { style: { fontSize: "10px", fontWeight: "bold" }, children: "\u2713" }) : icons.copyIcon
|
|
1421
|
-
}
|
|
1422
|
-
),
|
|
1423
|
-
onThumbsUp && /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(
|
|
1424
|
-
"button",
|
|
1425
|
-
{
|
|
1426
|
-
className: "copilotKitMessageControlButton",
|
|
1427
|
-
onClick: handleThumbsUp,
|
|
1428
|
-
"aria-label": labels.thumbsUp,
|
|
1429
|
-
title: labels.thumbsUp,
|
|
1430
|
-
children: icons.thumbsUpIcon
|
|
1431
|
-
}
|
|
1432
|
-
),
|
|
1433
|
-
onThumbsDown && /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(
|
|
1434
|
-
"button",
|
|
1435
|
-
{
|
|
1436
|
-
className: "copilotKitMessageControlButton",
|
|
1437
|
-
onClick: handleThumbsDown,
|
|
1438
|
-
"aria-label": labels.thumbsDown,
|
|
1439
|
-
title: labels.thumbsDown,
|
|
1440
|
-
children: icons.thumbsDownIcon
|
|
1648
|
+
ref: textareaRef,
|
|
1649
|
+
placeholder: context.labels.placeholder,
|
|
1650
|
+
autoFocus: false,
|
|
1651
|
+
maxRows: MAX_NEWLINES,
|
|
1652
|
+
value: text,
|
|
1653
|
+
onChange: (event) => setText(event.target.value),
|
|
1654
|
+
onCompositionStart: () => setIsComposing(true),
|
|
1655
|
+
onCompositionEnd: () => setIsComposing(false),
|
|
1656
|
+
onKeyDown: (event) => {
|
|
1657
|
+
if (event.key === "Enter" && !event.shiftKey && !isComposing) {
|
|
1658
|
+
event.preventDefault();
|
|
1659
|
+
if (canSend) {
|
|
1660
|
+
send();
|
|
1441
1661
|
}
|
|
1442
|
-
|
|
1443
|
-
|
|
1662
|
+
}
|
|
1663
|
+
}
|
|
1444
1664
|
}
|
|
1445
|
-
)
|
|
1665
|
+
),
|
|
1666
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsxs)("div", { className: "copilotKitInputControls", children: [
|
|
1667
|
+
onUpload && /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("button", { onClick: onUpload, className: "copilotKitInputControlButton", children: context.icons.uploadIcon }),
|
|
1668
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsx)("div", { style: { flexGrow: 1 } }),
|
|
1669
|
+
showPushToTalk && /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
|
|
1670
|
+
"button",
|
|
1671
|
+
{
|
|
1672
|
+
onClick: () => setPushToTalkState(pushToTalkState === "idle" ? "recording" : "transcribing"),
|
|
1673
|
+
className: pushToTalkState === "recording" ? "copilotKitInputControlButton copilotKitPushToTalkRecording" : "copilotKitInputControlButton",
|
|
1674
|
+
children: context.icons.pushToTalkIcon
|
|
1675
|
+
}
|
|
1676
|
+
),
|
|
1677
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
|
|
1678
|
+
"button",
|
|
1679
|
+
{
|
|
1680
|
+
disabled: sendDisabled,
|
|
1681
|
+
onClick: isInProgress && !hideStopButton ? onStop : send,
|
|
1682
|
+
"data-copilotkit-in-progress": inProgress,
|
|
1683
|
+
"data-test-id": inProgress ? "copilot-chat-request-in-progress" : "copilot-chat-ready",
|
|
1684
|
+
className: "copilotKitInputControlButton",
|
|
1685
|
+
children: buttonIcon
|
|
1686
|
+
}
|
|
1687
|
+
)
|
|
1688
|
+
] })
|
|
1446
1689
|
] }),
|
|
1447
|
-
/* @__PURE__ */ (0,
|
|
1448
|
-
isLoading && /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(LoadingIcon, {})
|
|
1449
|
-
] });
|
|
1450
|
-
};
|
|
1451
|
-
|
|
1452
|
-
// src/components/chat/messages/ImageRenderer.tsx
|
|
1453
|
-
var import_react9 = require("react");
|
|
1454
|
-
var import_jsx_runtime11 = require("react/jsx-runtime");
|
|
1455
|
-
var ImageRenderer = ({ image, content, className = "" }) => {
|
|
1456
|
-
const [imageError, setImageError] = (0, import_react9.useState)(false);
|
|
1457
|
-
const imageSrc = `data:image/${image.format};base64,${image.bytes}`;
|
|
1458
|
-
const altText = content || "User uploaded image";
|
|
1459
|
-
const handleImageError = () => {
|
|
1460
|
-
setImageError(true);
|
|
1461
|
-
};
|
|
1462
|
-
if (imageError) {
|
|
1463
|
-
return /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("div", { className: `copilotKitImageRendering copilotKitImageRenderingError ${className}`, children: [
|
|
1464
|
-
/* @__PURE__ */ (0, import_jsx_runtime11.jsx)("div", { className: "copilotKitImageRenderingErrorMessage", children: "Failed to load image" }),
|
|
1465
|
-
content && /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("div", { className: "copilotKitImageRenderingContent", children: content })
|
|
1466
|
-
] });
|
|
1467
|
-
}
|
|
1468
|
-
return /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("div", { className: `copilotKitImageRendering ${className}`, children: [
|
|
1469
|
-
/* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
|
|
1470
|
-
"img",
|
|
1471
|
-
{
|
|
1472
|
-
src: imageSrc,
|
|
1473
|
-
alt: altText,
|
|
1474
|
-
className: "copilotKitImageRenderingImage",
|
|
1475
|
-
onError: handleImageError
|
|
1476
|
-
}
|
|
1477
|
-
),
|
|
1478
|
-
content && /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("div", { className: "copilotKitImageRenderingContent", children: content })
|
|
1690
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsx)(PoweredByTag, { showPoweredBy })
|
|
1479
1691
|
] });
|
|
1480
1692
|
};
|
|
1481
1693
|
|
|
1482
|
-
// src/components/chat/messages/RenderMessage.tsx
|
|
1483
|
-
var import_jsx_runtime12 = require("react/jsx-runtime");
|
|
1484
|
-
function RenderMessage(_a) {
|
|
1485
|
-
var _b = _a, {
|
|
1486
|
-
UserMessage: UserMessage2 = UserMessage,
|
|
1487
|
-
AssistantMessage: AssistantMessage2 = AssistantMessage,
|
|
1488
|
-
ImageRenderer: ImageRenderer2 = ImageRenderer
|
|
1489
|
-
} = _b, props = __objRest(_b, [
|
|
1490
|
-
"UserMessage",
|
|
1491
|
-
"AssistantMessage",
|
|
1492
|
-
"ImageRenderer"
|
|
1493
|
-
]);
|
|
1494
|
-
const {
|
|
1495
|
-
message,
|
|
1496
|
-
inProgress,
|
|
1497
|
-
index,
|
|
1498
|
-
isCurrentMessage,
|
|
1499
|
-
onRegenerate,
|
|
1500
|
-
onCopy,
|
|
1501
|
-
onThumbsUp,
|
|
1502
|
-
onThumbsDown,
|
|
1503
|
-
markdownTagRenderers
|
|
1504
|
-
} = props;
|
|
1505
|
-
switch (message.role) {
|
|
1506
|
-
case "user":
|
|
1507
|
-
return /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(
|
|
1508
|
-
UserMessage2,
|
|
1509
|
-
{
|
|
1510
|
-
"data-message-role": "user",
|
|
1511
|
-
message,
|
|
1512
|
-
ImageRenderer: ImageRenderer2
|
|
1513
|
-
},
|
|
1514
|
-
index
|
|
1515
|
-
);
|
|
1516
|
-
case "assistant":
|
|
1517
|
-
return /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(
|
|
1518
|
-
AssistantMessage2,
|
|
1519
|
-
{
|
|
1520
|
-
"data-message-role": "assistant",
|
|
1521
|
-
message,
|
|
1522
|
-
isLoading: inProgress && isCurrentMessage && !message.content,
|
|
1523
|
-
isGenerating: inProgress && isCurrentMessage && !!message.content,
|
|
1524
|
-
isCurrentMessage,
|
|
1525
|
-
onRegenerate: () => onRegenerate == null ? void 0 : onRegenerate(message.id),
|
|
1526
|
-
onCopy,
|
|
1527
|
-
onThumbsUp,
|
|
1528
|
-
onThumbsDown,
|
|
1529
|
-
markdownTagRenderers,
|
|
1530
|
-
ImageRenderer: ImageRenderer2
|
|
1531
|
-
},
|
|
1532
|
-
index
|
|
1533
|
-
);
|
|
1534
|
-
}
|
|
1535
|
-
}
|
|
1536
|
-
|
|
1537
1694
|
// src/components/chat/Chat.tsx
|
|
1538
1695
|
var import_react10 = __toESM(require("react"));
|
|
1539
1696
|
var import_react_core5 = require("@copilotkit/react-core");
|
|
1540
1697
|
var import_shared = require("@copilotkit/shared");
|
|
1698
|
+
var import_shared2 = require("@copilotkit/shared");
|
|
1541
1699
|
var import_react_core6 = require("@copilotkit/react-core");
|
|
1542
1700
|
|
|
1543
1701
|
// src/components/chat/ImageUploadQueue.tsx
|
|
1544
|
-
var
|
|
1702
|
+
var import_jsx_runtime14 = require("react/jsx-runtime");
|
|
1545
1703
|
var ImageUploadQueue = ({
|
|
1546
1704
|
images,
|
|
1547
1705
|
onRemoveImage,
|
|
@@ -1549,7 +1707,7 @@ var ImageUploadQueue = ({
|
|
|
1549
1707
|
}) => {
|
|
1550
1708
|
if (images.length === 0)
|
|
1551
1709
|
return null;
|
|
1552
|
-
return /* @__PURE__ */ (0,
|
|
1710
|
+
return /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
|
|
1553
1711
|
"div",
|
|
1554
1712
|
{
|
|
1555
1713
|
className: `copilotKitImageUploadQueue ${className}`,
|
|
@@ -1560,7 +1718,7 @@ var ImageUploadQueue = ({
|
|
|
1560
1718
|
margin: "8px",
|
|
1561
1719
|
padding: "8px"
|
|
1562
1720
|
},
|
|
1563
|
-
children: images.map((image, index) => /* @__PURE__ */ (0,
|
|
1721
|
+
children: images.map((image, index) => /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)(
|
|
1564
1722
|
"div",
|
|
1565
1723
|
{
|
|
1566
1724
|
className: "copilotKitImageUploadQueueItem",
|
|
@@ -1573,7 +1731,7 @@ var ImageUploadQueue = ({
|
|
|
1573
1731
|
overflow: "hidden"
|
|
1574
1732
|
},
|
|
1575
1733
|
children: [
|
|
1576
|
-
/* @__PURE__ */ (0,
|
|
1734
|
+
/* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
|
|
1577
1735
|
"img",
|
|
1578
1736
|
{
|
|
1579
1737
|
src: `data:${image.contentType};base64,${image.bytes}`,
|
|
@@ -1585,7 +1743,7 @@ var ImageUploadQueue = ({
|
|
|
1585
1743
|
}
|
|
1586
1744
|
}
|
|
1587
1745
|
),
|
|
1588
|
-
/* @__PURE__ */ (0,
|
|
1746
|
+
/* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
|
|
1589
1747
|
"button",
|
|
1590
1748
|
{
|
|
1591
1749
|
onClick: () => onRemoveImage(index),
|
|
@@ -1620,12 +1778,12 @@ var ImageUploadQueue = ({
|
|
|
1620
1778
|
|
|
1621
1779
|
// src/components/chat/Suggestion.tsx
|
|
1622
1780
|
var import_react_core4 = require("@copilotkit/react-core");
|
|
1623
|
-
var
|
|
1781
|
+
var import_jsx_runtime15 = require("react/jsx-runtime");
|
|
1624
1782
|
function Suggestion({ title, onClick, partial, className }) {
|
|
1625
1783
|
if (!title)
|
|
1626
1784
|
return null;
|
|
1627
|
-
const { isLoading } = (0, import_react_core4.
|
|
1628
|
-
return /* @__PURE__ */ (0,
|
|
1785
|
+
const { isLoading } = (0, import_react_core4.useCopilotChatInternal)();
|
|
1786
|
+
return /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(
|
|
1629
1787
|
"button",
|
|
1630
1788
|
{
|
|
1631
1789
|
disabled: partial || isLoading,
|
|
@@ -1635,15 +1793,15 @@ function Suggestion({ title, onClick, partial, className }) {
|
|
|
1635
1793
|
},
|
|
1636
1794
|
className: className || (partial ? "suggestion loading" : "suggestion"),
|
|
1637
1795
|
"data-test-id": "suggestion",
|
|
1638
|
-
children: partial ? SmallSpinnerIcon : /* @__PURE__ */ (0,
|
|
1796
|
+
children: partial ? SmallSpinnerIcon : /* @__PURE__ */ (0, import_jsx_runtime15.jsx)("span", { children: title })
|
|
1639
1797
|
}
|
|
1640
1798
|
);
|
|
1641
1799
|
}
|
|
1642
1800
|
|
|
1643
1801
|
// src/components/chat/Suggestions.tsx
|
|
1644
|
-
var
|
|
1802
|
+
var import_jsx_runtime16 = require("react/jsx-runtime");
|
|
1645
1803
|
function Suggestions({ suggestions, onSuggestionClick }) {
|
|
1646
|
-
return /* @__PURE__ */ (0,
|
|
1804
|
+
return /* @__PURE__ */ (0, import_jsx_runtime16.jsx)("div", { className: "suggestions", children: suggestions.map((suggestion, index) => /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
|
|
1647
1805
|
Suggestion,
|
|
1648
1806
|
{
|
|
1649
1807
|
title: suggestion.title,
|
|
@@ -1657,7 +1815,7 @@ function Suggestions({ suggestions, onSuggestionClick }) {
|
|
|
1657
1815
|
}
|
|
1658
1816
|
|
|
1659
1817
|
// src/components/chat/Chat.tsx
|
|
1660
|
-
var
|
|
1818
|
+
var import_jsx_runtime17 = require("react/jsx-runtime");
|
|
1661
1819
|
function CopilotChat({
|
|
1662
1820
|
instructions,
|
|
1663
1821
|
suggestions = "auto",
|
|
@@ -1683,11 +1841,83 @@ function CopilotChat({
|
|
|
1683
1841
|
ImageRenderer: ImageRenderer2 = ImageRenderer,
|
|
1684
1842
|
imageUploadsEnabled,
|
|
1685
1843
|
inputFileAccept = "image/*",
|
|
1686
|
-
hideStopButton
|
|
1844
|
+
hideStopButton,
|
|
1845
|
+
observabilityHooks,
|
|
1846
|
+
renderError,
|
|
1847
|
+
// Legacy props - deprecated
|
|
1848
|
+
RenderTextMessage,
|
|
1849
|
+
RenderActionExecutionMessage,
|
|
1850
|
+
RenderAgentStateMessage,
|
|
1851
|
+
RenderResultMessage,
|
|
1852
|
+
RenderImageMessage
|
|
1687
1853
|
}) {
|
|
1688
|
-
const { additionalInstructions, setChatInstructions } = (0, import_react_core5.useCopilotContext)();
|
|
1854
|
+
const { additionalInstructions, setChatInstructions, copilotApiConfig, setBannerError } = (0, import_react_core5.useCopilotContext)();
|
|
1855
|
+
const { publicApiKey, chatApiEndpoint } = copilotApiConfig;
|
|
1689
1856
|
const [selectedImages, setSelectedImages] = (0, import_react10.useState)([]);
|
|
1857
|
+
const [chatError, setChatError] = (0, import_react10.useState)(null);
|
|
1690
1858
|
const fileInputRef = (0, import_react10.useRef)(null);
|
|
1859
|
+
const triggerObservabilityHook = (0, import_react10.useCallback)(
|
|
1860
|
+
(hookName, ...args) => {
|
|
1861
|
+
if (publicApiKey && (observabilityHooks == null ? void 0 : observabilityHooks[hookName])) {
|
|
1862
|
+
observabilityHooks[hookName](...args);
|
|
1863
|
+
}
|
|
1864
|
+
if ((observabilityHooks == null ? void 0 : observabilityHooks[hookName]) && !publicApiKey) {
|
|
1865
|
+
setBannerError(
|
|
1866
|
+
new import_shared.CopilotKitError({
|
|
1867
|
+
message: "observabilityHooks requires a publicApiKey to function.",
|
|
1868
|
+
code: import_shared.CopilotKitErrorCode.MISSING_PUBLIC_API_KEY_ERROR,
|
|
1869
|
+
severity: import_shared.Severity.CRITICAL,
|
|
1870
|
+
visibility: import_shared.ErrorVisibility.BANNER
|
|
1871
|
+
})
|
|
1872
|
+
);
|
|
1873
|
+
import_shared.styledConsole.publicApiKeyRequired("observabilityHooks");
|
|
1874
|
+
}
|
|
1875
|
+
},
|
|
1876
|
+
[publicApiKey, observabilityHooks, setBannerError]
|
|
1877
|
+
);
|
|
1878
|
+
const triggerChatError = (0, import_react10.useCallback)(
|
|
1879
|
+
(error, operation, originalError) => {
|
|
1880
|
+
const errorMessage = (error == null ? void 0 : error.message) || (error == null ? void 0 : error.toString()) || "An error occurred";
|
|
1881
|
+
setChatError({
|
|
1882
|
+
message: errorMessage,
|
|
1883
|
+
operation,
|
|
1884
|
+
timestamp: Date.now()
|
|
1885
|
+
});
|
|
1886
|
+
if (publicApiKey && (observabilityHooks == null ? void 0 : observabilityHooks.onError)) {
|
|
1887
|
+
const errorEvent = {
|
|
1888
|
+
type: "error",
|
|
1889
|
+
timestamp: Date.now(),
|
|
1890
|
+
context: {
|
|
1891
|
+
source: "ui",
|
|
1892
|
+
request: {
|
|
1893
|
+
operation,
|
|
1894
|
+
url: chatApiEndpoint,
|
|
1895
|
+
startTime: Date.now()
|
|
1896
|
+
},
|
|
1897
|
+
technical: {
|
|
1898
|
+
environment: "browser",
|
|
1899
|
+
userAgent: typeof navigator !== "undefined" ? navigator.userAgent : void 0,
|
|
1900
|
+
stackTrace: originalError instanceof Error ? originalError.stack : void 0
|
|
1901
|
+
}
|
|
1902
|
+
},
|
|
1903
|
+
error
|
|
1904
|
+
};
|
|
1905
|
+
observabilityHooks.onError(errorEvent);
|
|
1906
|
+
}
|
|
1907
|
+
if ((observabilityHooks == null ? void 0 : observabilityHooks.onError) && !publicApiKey) {
|
|
1908
|
+
setBannerError(
|
|
1909
|
+
new import_shared.CopilotKitError({
|
|
1910
|
+
message: "observabilityHooks.onError requires a publicApiKey to function.",
|
|
1911
|
+
code: import_shared.CopilotKitErrorCode.MISSING_PUBLIC_API_KEY_ERROR,
|
|
1912
|
+
severity: import_shared.Severity.CRITICAL,
|
|
1913
|
+
visibility: import_shared.ErrorVisibility.BANNER
|
|
1914
|
+
})
|
|
1915
|
+
);
|
|
1916
|
+
import_shared.styledConsole.publicApiKeyRequired("observabilityHooks.onError");
|
|
1917
|
+
}
|
|
1918
|
+
},
|
|
1919
|
+
[publicApiKey, chatApiEndpoint, observabilityHooks, setBannerError]
|
|
1920
|
+
);
|
|
1691
1921
|
(0, import_react10.useEffect)(() => {
|
|
1692
1922
|
if (!imageUploadsEnabled)
|
|
1693
1923
|
return;
|
|
@@ -1727,12 +1957,13 @@ function CopilotChat({
|
|
|
1727
1957
|
const loadedImages = (yield Promise.all(imagePromises)).filter((img) => img !== null);
|
|
1728
1958
|
setSelectedImages((prev) => [...prev, ...loadedImages]);
|
|
1729
1959
|
} catch (error) {
|
|
1960
|
+
triggerChatError(error, "processClipboardImages", error);
|
|
1730
1961
|
console.error("Error processing pasted images:", error);
|
|
1731
1962
|
}
|
|
1732
1963
|
});
|
|
1733
1964
|
document.addEventListener("paste", handlePaste);
|
|
1734
1965
|
return () => document.removeEventListener("paste", handlePaste);
|
|
1735
|
-
}, [imageUploadsEnabled]);
|
|
1966
|
+
}, [imageUploadsEnabled, triggerChatError]);
|
|
1736
1967
|
(0, import_react10.useEffect)(() => {
|
|
1737
1968
|
if (!(additionalInstructions == null ? void 0 : additionalInstructions.length)) {
|
|
1738
1969
|
setChatInstructions(instructions || "");
|
|
@@ -1746,7 +1977,7 @@ function CopilotChat({
|
|
|
1746
1977
|
setChatInstructions(combinedAdditionalInstructions.join("\n") || "");
|
|
1747
1978
|
}, [instructions, additionalInstructions]);
|
|
1748
1979
|
const {
|
|
1749
|
-
|
|
1980
|
+
messages,
|
|
1750
1981
|
isLoading,
|
|
1751
1982
|
sendMessage,
|
|
1752
1983
|
stopGeneration,
|
|
@@ -1760,12 +1991,24 @@ function CopilotChat({
|
|
|
1760
1991
|
onStopGeneration,
|
|
1761
1992
|
onReloadMessages
|
|
1762
1993
|
);
|
|
1994
|
+
const prevIsLoading = (0, import_react10.useRef)(isLoading);
|
|
1995
|
+
(0, import_react10.useEffect)(() => {
|
|
1996
|
+
if (prevIsLoading.current !== isLoading) {
|
|
1997
|
+
if (isLoading) {
|
|
1998
|
+
triggerObservabilityHook("onChatStarted");
|
|
1999
|
+
} else {
|
|
2000
|
+
triggerObservabilityHook("onChatStopped");
|
|
2001
|
+
}
|
|
2002
|
+
prevIsLoading.current = isLoading;
|
|
2003
|
+
}
|
|
2004
|
+
}, [isLoading, triggerObservabilityHook]);
|
|
1763
2005
|
const handleSendMessage = (text) => {
|
|
1764
2006
|
const images = selectedImages;
|
|
1765
2007
|
setSelectedImages([]);
|
|
1766
2008
|
if (fileInputRef.current) {
|
|
1767
2009
|
fileInputRef.current.value = "";
|
|
1768
2010
|
}
|
|
2011
|
+
triggerObservabilityHook("onMessageSent", text);
|
|
1769
2012
|
return sendMessage(text, images);
|
|
1770
2013
|
};
|
|
1771
2014
|
const chatContext = import_react10.default.useContext(ChatContext);
|
|
@@ -1774,12 +2017,14 @@ function CopilotChat({
|
|
|
1774
2017
|
if (onRegenerate) {
|
|
1775
2018
|
onRegenerate(messageId);
|
|
1776
2019
|
}
|
|
2020
|
+
triggerObservabilityHook("onMessageRegenerated", messageId);
|
|
1777
2021
|
reloadMessages(messageId);
|
|
1778
2022
|
};
|
|
1779
2023
|
const handleCopy = (message) => {
|
|
1780
2024
|
if (onCopy) {
|
|
1781
2025
|
onCopy(message);
|
|
1782
2026
|
}
|
|
2027
|
+
triggerObservabilityHook("onMessageCopied", message);
|
|
1783
2028
|
};
|
|
1784
2029
|
const handleImageUpload = (event) => __async(this, null, function* () {
|
|
1785
2030
|
if (!event.target.files || event.target.files.length === 0) {
|
|
@@ -1809,28 +2054,52 @@ function CopilotChat({
|
|
|
1809
2054
|
const loadedImages = yield Promise.all(fileReadPromises);
|
|
1810
2055
|
setSelectedImages((prev) => [...prev, ...loadedImages]);
|
|
1811
2056
|
} catch (error) {
|
|
2057
|
+
triggerChatError(error, "processUploadedImages", error);
|
|
1812
2058
|
console.error("Error reading files:", error);
|
|
1813
2059
|
}
|
|
1814
2060
|
});
|
|
1815
2061
|
const removeSelectedImage = (index) => {
|
|
1816
2062
|
setSelectedImages((prev) => prev.filter((_, i) => i !== index));
|
|
1817
2063
|
};
|
|
1818
|
-
|
|
1819
|
-
|
|
2064
|
+
const handleThumbsUp = (message) => {
|
|
2065
|
+
if (onThumbsUp) {
|
|
2066
|
+
onThumbsUp(message);
|
|
2067
|
+
}
|
|
2068
|
+
triggerObservabilityHook("onFeedbackGiven", message.id, "thumbsUp");
|
|
2069
|
+
};
|
|
2070
|
+
const handleThumbsDown = (message) => {
|
|
2071
|
+
if (onThumbsDown) {
|
|
2072
|
+
onThumbsDown(message);
|
|
2073
|
+
}
|
|
2074
|
+
triggerObservabilityHook("onFeedbackGiven", message.id, "thumbsDown");
|
|
2075
|
+
};
|
|
2076
|
+
return /* @__PURE__ */ (0, import_jsx_runtime17.jsxs)(WrappedCopilotChat, { icons, labels, className, children: [
|
|
2077
|
+
chatError && renderError && renderError(__spreadProps(__spreadValues({}, chatError), {
|
|
2078
|
+
onDismiss: () => setChatError(null),
|
|
2079
|
+
onRetry: () => {
|
|
2080
|
+
setChatError(null);
|
|
2081
|
+
}
|
|
2082
|
+
})),
|
|
2083
|
+
/* @__PURE__ */ (0, import_jsx_runtime17.jsx)(
|
|
1820
2084
|
Messages2,
|
|
1821
2085
|
{
|
|
1822
2086
|
AssistantMessage: AssistantMessage2,
|
|
1823
2087
|
UserMessage: UserMessage2,
|
|
1824
2088
|
RenderMessage: RenderMessage2,
|
|
1825
|
-
messages
|
|
2089
|
+
messages,
|
|
1826
2090
|
inProgress: isLoading,
|
|
1827
2091
|
onRegenerate: handleRegenerate,
|
|
1828
2092
|
onCopy: handleCopy,
|
|
1829
|
-
onThumbsUp,
|
|
1830
|
-
onThumbsDown,
|
|
2093
|
+
onThumbsUp: handleThumbsUp,
|
|
2094
|
+
onThumbsDown: handleThumbsDown,
|
|
1831
2095
|
markdownTagRenderers,
|
|
1832
2096
|
ImageRenderer: ImageRenderer2,
|
|
1833
|
-
|
|
2097
|
+
RenderTextMessage,
|
|
2098
|
+
RenderActionExecutionMessage,
|
|
2099
|
+
RenderAgentStateMessage,
|
|
2100
|
+
RenderResultMessage,
|
|
2101
|
+
RenderImageMessage,
|
|
2102
|
+
children: currentSuggestions.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(
|
|
1834
2103
|
RenderSuggestionsList,
|
|
1835
2104
|
{
|
|
1836
2105
|
onSuggestionClick: handleSendMessage,
|
|
@@ -1839,9 +2108,9 @@ function CopilotChat({
|
|
|
1839
2108
|
)
|
|
1840
2109
|
}
|
|
1841
2110
|
),
|
|
1842
|
-
imageUploadsEnabled && /* @__PURE__ */ (0,
|
|
1843
|
-
/* @__PURE__ */ (0,
|
|
1844
|
-
/* @__PURE__ */ (0,
|
|
2111
|
+
imageUploadsEnabled && /* @__PURE__ */ (0, import_jsx_runtime17.jsxs)(import_jsx_runtime17.Fragment, { children: [
|
|
2112
|
+
/* @__PURE__ */ (0, import_jsx_runtime17.jsx)(ImageUploadQueue, { images: selectedImages, onRemoveImage: removeSelectedImage }),
|
|
2113
|
+
/* @__PURE__ */ (0, import_jsx_runtime17.jsx)(
|
|
1845
2114
|
"input",
|
|
1846
2115
|
{
|
|
1847
2116
|
type: "file",
|
|
@@ -1853,7 +2122,7 @@ function CopilotChat({
|
|
|
1853
2122
|
}
|
|
1854
2123
|
)
|
|
1855
2124
|
] }),
|
|
1856
|
-
/* @__PURE__ */ (0,
|
|
2125
|
+
/* @__PURE__ */ (0, import_jsx_runtime17.jsx)(
|
|
1857
2126
|
Input2,
|
|
1858
2127
|
{
|
|
1859
2128
|
inProgress: isLoading,
|
|
@@ -1877,16 +2146,16 @@ function WrappedCopilotChat({
|
|
|
1877
2146
|
}) {
|
|
1878
2147
|
const chatContext = import_react10.default.useContext(ChatContext);
|
|
1879
2148
|
if (!chatContext) {
|
|
1880
|
-
return /* @__PURE__ */ (0,
|
|
1881
|
-
}, children: /* @__PURE__ */ (0,
|
|
2149
|
+
return /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(ChatContextProvider, { icons, labels, open: true, setOpen: () => {
|
|
2150
|
+
}, children: /* @__PURE__ */ (0, import_jsx_runtime17.jsx)("div", { className: `copilotKitChat ${className != null ? className : ""}`, children }) });
|
|
1882
2151
|
}
|
|
1883
|
-
return /* @__PURE__ */ (0,
|
|
2152
|
+
return /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(import_jsx_runtime17.Fragment, { children });
|
|
1884
2153
|
}
|
|
1885
2154
|
var useCopilotChatLogic = (chatSuggestions, makeSystemMessage, onInProgress, onSubmitMessage, onStopGeneration, onReloadMessages) => {
|
|
1886
2155
|
var _a;
|
|
1887
2156
|
const {
|
|
1888
|
-
|
|
1889
|
-
|
|
2157
|
+
messages,
|
|
2158
|
+
sendMessage,
|
|
1890
2159
|
setMessages,
|
|
1891
2160
|
reloadMessages: defaultReloadMessages,
|
|
1892
2161
|
stopGeneration: defaultStopGeneration,
|
|
@@ -1897,7 +2166,7 @@ var useCopilotChatLogic = (chatSuggestions, makeSystemMessage, onInProgress, onS
|
|
|
1897
2166
|
generateSuggestions,
|
|
1898
2167
|
resetSuggestions: resetSuggestionsFromHook,
|
|
1899
2168
|
isLoadingSuggestions
|
|
1900
|
-
} = (0, import_react_core5.
|
|
2169
|
+
} = (0, import_react_core5.useCopilotChatInternal)({
|
|
1901
2170
|
makeSystemMessage
|
|
1902
2171
|
});
|
|
1903
2172
|
const generalContext = (0, import_react_core5.useCopilotContext)();
|
|
@@ -1932,12 +2201,12 @@ var useCopilotChatLogic = (chatSuggestions, makeSystemMessage, onInProgress, onS
|
|
|
1932
2201
|
if (Object.keys(generalContext.chatSuggestionConfiguration).length === 0) {
|
|
1933
2202
|
return;
|
|
1934
2203
|
}
|
|
1935
|
-
if (
|
|
2204
|
+
if (messages.length === 0 && !hasGeneratedInitialSuggestions.current) {
|
|
1936
2205
|
hasGeneratedInitialSuggestions.current = true;
|
|
1937
2206
|
generateSuggestionsWithErrorHandling("initial");
|
|
1938
2207
|
return;
|
|
1939
2208
|
}
|
|
1940
|
-
if (
|
|
2209
|
+
if (messages.length > 0 && suggestions.length === 0) {
|
|
1941
2210
|
generateSuggestionsWithErrorHandling("post-message");
|
|
1942
2211
|
return;
|
|
1943
2212
|
}
|
|
@@ -1945,7 +2214,7 @@ var useCopilotChatLogic = (chatSuggestions, makeSystemMessage, onInProgress, onS
|
|
|
1945
2214
|
chatSuggestions,
|
|
1946
2215
|
isLoadingSuggestions,
|
|
1947
2216
|
suggestionsFailed,
|
|
1948
|
-
|
|
2217
|
+
messages.length,
|
|
1949
2218
|
isLoading,
|
|
1950
2219
|
suggestions.length,
|
|
1951
2220
|
Object.keys(generalContext.chatSuggestionConfiguration).join(","),
|
|
@@ -1975,7 +2244,7 @@ var useCopilotChatLogic = (chatSuggestions, makeSystemMessage, onInProgress, onS
|
|
|
1975
2244
|
(0, import_react10.useEffect)(() => {
|
|
1976
2245
|
onInProgress == null ? void 0 : onInProgress(isLoading);
|
|
1977
2246
|
}, [onInProgress, isLoading]);
|
|
1978
|
-
const
|
|
2247
|
+
const safelySendMessage = (messageContent, imagesToUse) => __async(void 0, null, function* () {
|
|
1979
2248
|
const images = imagesToUse || [];
|
|
1980
2249
|
if (chatSuggestions === "auto" || chatSuggestions === "manual") {
|
|
1981
2250
|
setSuggestions([]);
|
|
@@ -1983,7 +2252,7 @@ var useCopilotChatLogic = (chatSuggestions, makeSystemMessage, onInProgress, onS
|
|
|
1983
2252
|
let firstMessage = null;
|
|
1984
2253
|
if (messageContent.trim().length > 0) {
|
|
1985
2254
|
const textMessage = {
|
|
1986
|
-
id: (0,
|
|
2255
|
+
id: (0, import_shared2.randomId)(),
|
|
1987
2256
|
role: "user",
|
|
1988
2257
|
content: messageContent
|
|
1989
2258
|
};
|
|
@@ -1994,7 +2263,7 @@ var useCopilotChatLogic = (chatSuggestions, makeSystemMessage, onInProgress, onS
|
|
|
1994
2263
|
console.error("Error in onSubmitMessage:", error);
|
|
1995
2264
|
}
|
|
1996
2265
|
}
|
|
1997
|
-
yield
|
|
2266
|
+
yield sendMessage(textMessage, {
|
|
1998
2267
|
followUp: images.length === 0,
|
|
1999
2268
|
clearSuggestions: chatSuggestions === "auto" || chatSuggestions === "manual"
|
|
2000
2269
|
});
|
|
@@ -2005,25 +2274,24 @@ var useCopilotChatLogic = (chatSuggestions, makeSystemMessage, onInProgress, onS
|
|
|
2005
2274
|
if (images.length > 0) {
|
|
2006
2275
|
for (let i = 0; i < images.length; i++) {
|
|
2007
2276
|
const imageMessage = {
|
|
2008
|
-
id: (0,
|
|
2277
|
+
id: (0, import_shared2.randomId)(),
|
|
2009
2278
|
role: "user",
|
|
2010
2279
|
image: {
|
|
2011
2280
|
format: images[i].contentType.replace("image/", ""),
|
|
2012
2281
|
bytes: images[i].bytes
|
|
2013
2282
|
}
|
|
2014
2283
|
};
|
|
2015
|
-
yield
|
|
2284
|
+
yield sendMessage(imageMessage, { followUp: i === images.length - 1 });
|
|
2016
2285
|
if (!firstMessage) {
|
|
2017
2286
|
firstMessage = imageMessage;
|
|
2018
2287
|
}
|
|
2019
2288
|
}
|
|
2020
2289
|
}
|
|
2021
2290
|
if (!firstMessage) {
|
|
2022
|
-
return { role: "user", content: "", id: (0,
|
|
2291
|
+
return { role: "user", content: "", id: (0, import_shared2.randomId)() };
|
|
2023
2292
|
}
|
|
2024
2293
|
return firstMessage;
|
|
2025
2294
|
});
|
|
2026
|
-
const messages = visibleMessages;
|
|
2027
2295
|
const currentAgentName = (_a = generalContext.agentSession) == null ? void 0 : _a.agentName;
|
|
2028
2296
|
const restartCurrentAgent = (hint) => __async(void 0, null, function* () {
|
|
2029
2297
|
if (generalContext.agentSession) {
|
|
@@ -2047,9 +2315,9 @@ var useCopilotChatLogic = (chatSuggestions, makeSystemMessage, onInProgress, onS
|
|
|
2047
2315
|
yield (0, import_react_core6.runAgent)(
|
|
2048
2316
|
generalContext.agentSession.agentName,
|
|
2049
2317
|
stableContext,
|
|
2050
|
-
|
|
2051
|
-
|
|
2052
|
-
|
|
2318
|
+
messagesContext.messages,
|
|
2319
|
+
sendMessage,
|
|
2320
|
+
runChatCompletion
|
|
2053
2321
|
);
|
|
2054
2322
|
}
|
|
2055
2323
|
});
|
|
@@ -2105,10 +2373,9 @@ var useCopilotChatLogic = (chatSuggestions, makeSystemMessage, onInProgress, onS
|
|
|
2105
2373
|
}
|
|
2106
2374
|
return {
|
|
2107
2375
|
messages,
|
|
2108
|
-
visibleMessages,
|
|
2109
2376
|
isLoading,
|
|
2110
2377
|
suggestions,
|
|
2111
|
-
sendMessage,
|
|
2378
|
+
sendMessage: safelySendMessage,
|
|
2112
2379
|
stopGeneration,
|
|
2113
2380
|
reloadMessages,
|
|
2114
2381
|
resetSuggestions,
|