@copilotkit/react-ui 1.10.0-next.8 → 1.10.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +132 -0
- package/dist/{chunk-U5ATIGWH.mjs → chunk-BJHJBS5M.mjs} +45 -5
- package/dist/chunk-BJHJBS5M.mjs.map +1 -0
- package/dist/{chunk-KLV4ERV6.mjs → chunk-GBP47ONN.mjs} +2 -2
- package/dist/{chunk-3DVMCBME.mjs → chunk-GJ4SX4JE.mjs} +97 -35
- package/dist/chunk-GJ4SX4JE.mjs.map +1 -0
- package/dist/{chunk-APLX7E54.mjs → chunk-J5ZZR6YB.mjs} +2 -2
- package/dist/chunk-MIVUCSGO.mjs +126 -0
- package/dist/chunk-MIVUCSGO.mjs.map +1 -0
- package/dist/{chunk-JHUTTP5C.mjs → chunk-T5QU6KSB.mjs} +5 -1
- package/dist/chunk-T5QU6KSB.mjs.map +1 -0
- package/dist/{chunk-BPU3FDT4.mjs → chunk-Y44VLEUH.mjs} +30 -11
- package/dist/chunk-Y44VLEUH.mjs.map +1 -0
- package/dist/components/chat/Chat.d.ts +32 -2
- package/dist/components/chat/Chat.js +1084 -865
- package/dist/components/chat/Chat.js.map +1 -1
- package/dist/components/chat/Chat.mjs +7 -6
- 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.js +1107 -875
- package/dist/components/chat/Modal.js.map +1 -1
- package/dist/components/chat/Modal.mjs +8 -7
- package/dist/components/chat/Popup.js +1109 -877
- package/dist/components/chat/Popup.js.map +1 -1
- package/dist/components/chat/Popup.mjs +9 -8
- package/dist/components/chat/Sidebar.js +1109 -877
- package/dist/components/chat/Sidebar.js.map +1 -1
- package/dist/components/chat/Sidebar.mjs +9 -8
- package/dist/components/chat/index.js +1111 -879
- package/dist/components/chat/index.js.map +1 -1
- package/dist/components/chat/index.mjs +16 -15
- 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 +1 -1
- package/dist/components/chat/props.d.ts +55 -1
- package/dist/components/chat/props.js.map +1 -1
- package/dist/components/index.js +1111 -879
- package/dist/components/index.js.map +1 -1
- package/dist/components/index.mjs +16 -15
- package/dist/index.js +1113 -881
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +16 -15
- package/package.json +4 -4
- package/src/components/chat/Chat.tsx +144 -21
- package/src/components/chat/Messages.tsx +56 -3
- package/src/components/chat/Modal.tsx +24 -3
- package/src/components/chat/messages/LegacyRenderMessage.tsx +143 -0
- package/src/components/chat/messages/RenderMessage.tsx +3 -0
- package/src/components/chat/props.ts +64 -1
- package/dist/chunk-3DVMCBME.mjs.map +0 -1
- package/dist/chunk-BPU3FDT4.mjs.map +0 -1
- package/dist/chunk-JHUTTP5C.mjs.map +0 -1
- package/dist/chunk-U5ATIGWH.mjs.map +0 -1
- /package/dist/{chunk-KLV4ERV6.mjs.map → chunk-GBP47ONN.mjs.map} +0 -0
- /package/dist/{chunk-APLX7E54.mjs.map → chunk-J5ZZR6YB.mjs.map} +0 -0
package/dist/index.mjs
CHANGED
|
@@ -4,12 +4,12 @@ import "./chunk-MMVDU6DF.mjs";
|
|
|
4
4
|
import "./chunk-SC6JRFAJ.mjs";
|
|
5
5
|
import {
|
|
6
6
|
CopilotSidebar
|
|
7
|
-
} from "./chunk-
|
|
7
|
+
} from "./chunk-GBP47ONN.mjs";
|
|
8
8
|
import "./chunk-WB3YULQ4.mjs";
|
|
9
9
|
import {
|
|
10
10
|
CopilotPopup
|
|
11
|
-
} from "./chunk-
|
|
12
|
-
import "./chunk-
|
|
11
|
+
} from "./chunk-J5ZZR6YB.mjs";
|
|
12
|
+
import "./chunk-Y44VLEUH.mjs";
|
|
13
13
|
import "./chunk-C3GSYRC3.mjs";
|
|
14
14
|
import "./chunk-GDSZGYCE.mjs";
|
|
15
15
|
import "./chunk-V7W6IM2V.mjs";
|
|
@@ -26,17 +26,7 @@ import "./chunk-BH6PCAAL.mjs";
|
|
|
26
26
|
import "./chunk-UFN2VWSR.mjs";
|
|
27
27
|
import {
|
|
28
28
|
CopilotChat
|
|
29
|
-
} from "./chunk-
|
|
30
|
-
import "./chunk-JHUTTP5C.mjs";
|
|
31
|
-
import {
|
|
32
|
-
AssistantMessage
|
|
33
|
-
} from "./chunk-GCKKSSBU.mjs";
|
|
34
|
-
import {
|
|
35
|
-
ImageRenderer
|
|
36
|
-
} from "./chunk-DBKRAOH7.mjs";
|
|
37
|
-
import {
|
|
38
|
-
UserMessage
|
|
39
|
-
} from "./chunk-VVL6JFCJ.mjs";
|
|
29
|
+
} from "./chunk-GJ4SX4JE.mjs";
|
|
40
30
|
import {
|
|
41
31
|
Suggestions
|
|
42
32
|
} from "./chunk-226ZMOE3.mjs";
|
|
@@ -47,10 +37,21 @@ import "./chunk-PLHTVHUW.mjs";
|
|
|
47
37
|
import "./chunk-DTRPPNSA.mjs";
|
|
48
38
|
import "./chunk-CGEAG65D.mjs";
|
|
49
39
|
import "./chunk-QIOJXTIQ.mjs";
|
|
40
|
+
import "./chunk-BJHJBS5M.mjs";
|
|
41
|
+
import "./chunk-MIVUCSGO.mjs";
|
|
42
|
+
import "./chunk-T5QU6KSB.mjs";
|
|
43
|
+
import {
|
|
44
|
+
AssistantMessage
|
|
45
|
+
} from "./chunk-GCKKSSBU.mjs";
|
|
46
|
+
import {
|
|
47
|
+
ImageRenderer
|
|
48
|
+
} from "./chunk-DBKRAOH7.mjs";
|
|
49
|
+
import {
|
|
50
|
+
UserMessage
|
|
51
|
+
} from "./chunk-VVL6JFCJ.mjs";
|
|
50
52
|
import {
|
|
51
53
|
Markdown
|
|
52
54
|
} from "./chunk-E6MQUIZW.mjs";
|
|
53
|
-
import "./chunk-U5ATIGWH.mjs";
|
|
54
55
|
import {
|
|
55
56
|
useChatContext
|
|
56
57
|
} from "./chunk-IEMQ2SQW.mjs";
|
package/package.json
CHANGED
|
@@ -9,7 +9,7 @@
|
|
|
9
9
|
"publishConfig": {
|
|
10
10
|
"access": "public"
|
|
11
11
|
},
|
|
12
|
-
"version": "1.10.0
|
|
12
|
+
"version": "1.10.0",
|
|
13
13
|
"sideEffects": [
|
|
14
14
|
"**/*.css"
|
|
15
15
|
],
|
|
@@ -51,9 +51,9 @@
|
|
|
51
51
|
"rehype-raw": "^7.0.0",
|
|
52
52
|
"remark-gfm": "^4.0.1",
|
|
53
53
|
"remark-math": "^6.0.0",
|
|
54
|
-
"@copilotkit/react-core": "1.10.0
|
|
55
|
-
"@copilotkit/runtime-client-gql": "1.10.0
|
|
56
|
-
"@copilotkit/shared": "1.10.0
|
|
54
|
+
"@copilotkit/react-core": "1.10.0",
|
|
55
|
+
"@copilotkit/runtime-client-gql": "1.10.0",
|
|
56
|
+
"@copilotkit/shared": "1.10.0"
|
|
57
57
|
},
|
|
58
58
|
"keywords": [
|
|
59
59
|
"copilotkit",
|
|
@@ -85,6 +85,7 @@ import type { SuggestionItem } from "@copilotkit/react-core";
|
|
|
85
85
|
import {
|
|
86
86
|
CopilotKitError,
|
|
87
87
|
CopilotKitErrorCode,
|
|
88
|
+
CopilotErrorEvent,
|
|
88
89
|
Message,
|
|
89
90
|
Severity,
|
|
90
91
|
ErrorVisibility,
|
|
@@ -239,6 +240,31 @@ export interface CopilotChatProps {
|
|
|
239
240
|
*/
|
|
240
241
|
Messages?: React.ComponentType<MessagesProps>;
|
|
241
242
|
|
|
243
|
+
/**
|
|
244
|
+
* @deprecated - use RenderMessage instead
|
|
245
|
+
*/
|
|
246
|
+
RenderTextMessage?: React.ComponentType<RenderMessageProps>;
|
|
247
|
+
|
|
248
|
+
/**
|
|
249
|
+
* @deprecated - use RenderMessage instead
|
|
250
|
+
*/
|
|
251
|
+
RenderActionExecutionMessage?: React.ComponentType<RenderMessageProps>;
|
|
252
|
+
|
|
253
|
+
/**
|
|
254
|
+
* @deprecated - use RenderMessage instead
|
|
255
|
+
*/
|
|
256
|
+
RenderAgentStateMessage?: React.ComponentType<RenderMessageProps>;
|
|
257
|
+
|
|
258
|
+
/**
|
|
259
|
+
* @deprecated - use RenderMessage instead
|
|
260
|
+
*/
|
|
261
|
+
RenderResultMessage?: React.ComponentType<RenderMessageProps>;
|
|
262
|
+
|
|
263
|
+
/**
|
|
264
|
+
* @deprecated - use RenderMessage instead
|
|
265
|
+
*/
|
|
266
|
+
RenderImageMessage?: React.ComponentType<RenderMessageProps>;
|
|
267
|
+
|
|
242
268
|
/**
|
|
243
269
|
* A custom RenderMessage component to use instead of the default.
|
|
244
270
|
*
|
|
@@ -281,6 +307,18 @@ export interface CopilotChatProps {
|
|
|
281
307
|
* These hooks only work when publicApiKey is provided.
|
|
282
308
|
*/
|
|
283
309
|
observabilityHooks?: CopilotObservabilityHooks;
|
|
310
|
+
|
|
311
|
+
/**
|
|
312
|
+
* Custom error renderer for chat-specific errors.
|
|
313
|
+
* When provided, errors will be displayed inline within the chat interface.
|
|
314
|
+
*/
|
|
315
|
+
renderError?: (error: {
|
|
316
|
+
message: string;
|
|
317
|
+
operation?: string;
|
|
318
|
+
timestamp: number;
|
|
319
|
+
onDismiss: () => void;
|
|
320
|
+
onRetry?: () => void;
|
|
321
|
+
}) => React.ReactNode;
|
|
284
322
|
}
|
|
285
323
|
|
|
286
324
|
interface OnStopGenerationArguments {
|
|
@@ -368,19 +406,35 @@ export function CopilotChat({
|
|
|
368
406
|
inputFileAccept = "image/*",
|
|
369
407
|
hideStopButton,
|
|
370
408
|
observabilityHooks,
|
|
409
|
+
renderError,
|
|
410
|
+
|
|
411
|
+
// Legacy props - deprecated
|
|
412
|
+
RenderTextMessage,
|
|
413
|
+
RenderActionExecutionMessage,
|
|
414
|
+
RenderAgentStateMessage,
|
|
415
|
+
RenderResultMessage,
|
|
416
|
+
RenderImageMessage,
|
|
371
417
|
}: CopilotChatProps) {
|
|
372
418
|
const { additionalInstructions, setChatInstructions, copilotApiConfig, setBannerError } =
|
|
373
419
|
useCopilotContext();
|
|
420
|
+
|
|
421
|
+
// Destructure stable values to avoid object reference changes
|
|
422
|
+
const { publicApiKey, chatApiEndpoint } = copilotApiConfig;
|
|
374
423
|
const [selectedImages, setSelectedImages] = useState<Array<ImageUpload>>([]);
|
|
424
|
+
const [chatError, setChatError] = useState<{
|
|
425
|
+
message: string;
|
|
426
|
+
operation?: string;
|
|
427
|
+
timestamp: number;
|
|
428
|
+
} | null>(null);
|
|
375
429
|
const fileInputRef = useRef<HTMLInputElement>(null);
|
|
376
430
|
|
|
377
431
|
// Helper function to trigger event hooks only if publicApiKey is provided
|
|
378
432
|
const triggerObservabilityHook = useCallback(
|
|
379
433
|
(hookName: keyof CopilotObservabilityHooks, ...args: any[]) => {
|
|
380
|
-
if (
|
|
434
|
+
if (publicApiKey && observabilityHooks?.[hookName]) {
|
|
381
435
|
(observabilityHooks[hookName] as any)(...args);
|
|
382
436
|
}
|
|
383
|
-
if (observabilityHooks?.[hookName] && !
|
|
437
|
+
if (observabilityHooks?.[hookName] && !publicApiKey) {
|
|
384
438
|
setBannerError(
|
|
385
439
|
new CopilotKitError({
|
|
386
440
|
message: "observabilityHooks requires a publicApiKey to function.",
|
|
@@ -392,7 +446,58 @@ export function CopilotChat({
|
|
|
392
446
|
styledConsole.publicApiKeyRequired("observabilityHooks");
|
|
393
447
|
}
|
|
394
448
|
},
|
|
395
|
-
[
|
|
449
|
+
[publicApiKey, observabilityHooks, setBannerError],
|
|
450
|
+
);
|
|
451
|
+
|
|
452
|
+
// Helper function to trigger chat error and render error UI
|
|
453
|
+
const triggerChatError = useCallback(
|
|
454
|
+
(error: any, operation: string, originalError?: any) => {
|
|
455
|
+
const errorMessage = error?.message || error?.toString() || "An error occurred";
|
|
456
|
+
|
|
457
|
+
// Set chat error state for rendering
|
|
458
|
+
setChatError({
|
|
459
|
+
message: errorMessage,
|
|
460
|
+
operation,
|
|
461
|
+
timestamp: Date.now(),
|
|
462
|
+
});
|
|
463
|
+
|
|
464
|
+
// Also trigger observability hook if available
|
|
465
|
+
if (publicApiKey && observabilityHooks?.onError) {
|
|
466
|
+
const errorEvent: CopilotErrorEvent = {
|
|
467
|
+
type: "error",
|
|
468
|
+
timestamp: Date.now(),
|
|
469
|
+
context: {
|
|
470
|
+
source: "ui",
|
|
471
|
+
request: {
|
|
472
|
+
operation,
|
|
473
|
+
url: chatApiEndpoint,
|
|
474
|
+
startTime: Date.now(),
|
|
475
|
+
},
|
|
476
|
+
technical: {
|
|
477
|
+
environment: "browser",
|
|
478
|
+
userAgent: typeof navigator !== "undefined" ? navigator.userAgent : undefined,
|
|
479
|
+
stackTrace: originalError instanceof Error ? originalError.stack : undefined,
|
|
480
|
+
},
|
|
481
|
+
},
|
|
482
|
+
error,
|
|
483
|
+
};
|
|
484
|
+
observabilityHooks.onError(errorEvent);
|
|
485
|
+
}
|
|
486
|
+
|
|
487
|
+
// Show banner error if onError hook is used without publicApiKey
|
|
488
|
+
if (observabilityHooks?.onError && !publicApiKey) {
|
|
489
|
+
setBannerError(
|
|
490
|
+
new CopilotKitError({
|
|
491
|
+
message: "observabilityHooks.onError requires a publicApiKey to function.",
|
|
492
|
+
code: CopilotKitErrorCode.MISSING_PUBLIC_API_KEY_ERROR,
|
|
493
|
+
severity: Severity.CRITICAL,
|
|
494
|
+
visibility: ErrorVisibility.BANNER,
|
|
495
|
+
}),
|
|
496
|
+
);
|
|
497
|
+
styledConsole.publicApiKeyRequired("observabilityHooks.onError");
|
|
498
|
+
}
|
|
499
|
+
},
|
|
500
|
+
[publicApiKey, chatApiEndpoint, observabilityHooks, setBannerError],
|
|
396
501
|
);
|
|
397
502
|
|
|
398
503
|
// Clipboard paste handler
|
|
@@ -436,14 +541,15 @@ export function CopilotChat({
|
|
|
436
541
|
const loadedImages = (await Promise.all(imagePromises)).filter((img) => img !== null);
|
|
437
542
|
setSelectedImages((prev) => [...prev, ...loadedImages]);
|
|
438
543
|
} catch (error) {
|
|
439
|
-
//
|
|
544
|
+
// Trigger chat-level error handler
|
|
545
|
+
triggerChatError(error, "processClipboardImages", error);
|
|
440
546
|
console.error("Error processing pasted images:", error);
|
|
441
547
|
}
|
|
442
548
|
};
|
|
443
549
|
|
|
444
550
|
document.addEventListener("paste", handlePaste);
|
|
445
551
|
return () => document.removeEventListener("paste", handlePaste);
|
|
446
|
-
}, [imageUploadsEnabled]);
|
|
552
|
+
}, [imageUploadsEnabled, triggerChatError]);
|
|
447
553
|
|
|
448
554
|
useEffect(() => {
|
|
449
555
|
if (!additionalInstructions?.length) {
|
|
@@ -469,7 +575,7 @@ export function CopilotChat({
|
|
|
469
575
|
}, [instructions, additionalInstructions]);
|
|
470
576
|
|
|
471
577
|
const {
|
|
472
|
-
|
|
578
|
+
messages,
|
|
473
579
|
isLoading,
|
|
474
580
|
sendMessage,
|
|
475
581
|
stopGeneration,
|
|
@@ -563,7 +669,8 @@ export function CopilotChat({
|
|
|
563
669
|
const loadedImages = await Promise.all(fileReadPromises);
|
|
564
670
|
setSelectedImages((prev) => [...prev, ...loadedImages]);
|
|
565
671
|
} catch (error) {
|
|
566
|
-
//
|
|
672
|
+
// Trigger chat-level error handler
|
|
673
|
+
triggerChatError(error, "processUploadedImages", error);
|
|
567
674
|
console.error("Error reading files:", error);
|
|
568
675
|
}
|
|
569
676
|
};
|
|
@@ -592,11 +699,24 @@ export function CopilotChat({
|
|
|
592
699
|
|
|
593
700
|
return (
|
|
594
701
|
<WrappedCopilotChat icons={icons} labels={labels} className={className}>
|
|
702
|
+
{/* Render error above messages if present */}
|
|
703
|
+
{chatError &&
|
|
704
|
+
renderError &&
|
|
705
|
+
renderError({
|
|
706
|
+
...chatError,
|
|
707
|
+
onDismiss: () => setChatError(null),
|
|
708
|
+
onRetry: () => {
|
|
709
|
+
// Clear error and potentially retry based on operation
|
|
710
|
+
setChatError(null);
|
|
711
|
+
// TODO: Implement specific retry logic based on operation type
|
|
712
|
+
},
|
|
713
|
+
})}
|
|
714
|
+
|
|
595
715
|
<Messages
|
|
596
716
|
AssistantMessage={AssistantMessage}
|
|
597
717
|
UserMessage={UserMessage}
|
|
598
718
|
RenderMessage={RenderMessage}
|
|
599
|
-
messages={
|
|
719
|
+
messages={messages}
|
|
600
720
|
inProgress={isLoading}
|
|
601
721
|
onRegenerate={handleRegenerate}
|
|
602
722
|
onCopy={handleCopy}
|
|
@@ -604,6 +724,12 @@ export function CopilotChat({
|
|
|
604
724
|
onThumbsDown={handleThumbsDown}
|
|
605
725
|
markdownTagRenderers={markdownTagRenderers}
|
|
606
726
|
ImageRenderer={ImageRenderer}
|
|
727
|
+
// Legacy props - passed through to Messages component
|
|
728
|
+
RenderTextMessage={RenderTextMessage}
|
|
729
|
+
RenderActionExecutionMessage={RenderActionExecutionMessage}
|
|
730
|
+
RenderAgentStateMessage={RenderAgentStateMessage}
|
|
731
|
+
RenderResultMessage={RenderResultMessage}
|
|
732
|
+
RenderImageMessage={RenderImageMessage}
|
|
607
733
|
>
|
|
608
734
|
{currentSuggestions.length > 0 && (
|
|
609
735
|
<RenderSuggestionsList
|
|
@@ -669,8 +795,8 @@ export const useCopilotChatLogic = (
|
|
|
669
795
|
onReloadMessages?: OnReloadMessages,
|
|
670
796
|
) => {
|
|
671
797
|
const {
|
|
672
|
-
|
|
673
|
-
|
|
798
|
+
messages,
|
|
799
|
+
sendMessage,
|
|
674
800
|
setMessages,
|
|
675
801
|
reloadMessages: defaultReloadMessages,
|
|
676
802
|
stopGeneration: defaultStopGeneration,
|
|
@@ -734,14 +860,14 @@ export const useCopilotChatLogic = (
|
|
|
734
860
|
}
|
|
735
861
|
|
|
736
862
|
// Generate initial suggestions when chat is empty
|
|
737
|
-
if (
|
|
863
|
+
if (messages.length === 0 && !hasGeneratedInitialSuggestions.current) {
|
|
738
864
|
hasGeneratedInitialSuggestions.current = true;
|
|
739
865
|
generateSuggestionsWithErrorHandling("initial");
|
|
740
866
|
return;
|
|
741
867
|
}
|
|
742
868
|
|
|
743
869
|
// Generate post-message suggestions after assistant responds
|
|
744
|
-
if (
|
|
870
|
+
if (messages.length > 0 && suggestions.length === 0) {
|
|
745
871
|
generateSuggestionsWithErrorHandling("post-message");
|
|
746
872
|
return;
|
|
747
873
|
}
|
|
@@ -749,7 +875,7 @@ export const useCopilotChatLogic = (
|
|
|
749
875
|
chatSuggestions,
|
|
750
876
|
isLoadingSuggestions,
|
|
751
877
|
suggestionsFailed,
|
|
752
|
-
|
|
878
|
+
messages.length,
|
|
753
879
|
isLoading,
|
|
754
880
|
suggestions.length,
|
|
755
881
|
Object.keys(generalContext.chatSuggestionConfiguration).join(","), // Use stable string instead of object reference
|
|
@@ -789,7 +915,7 @@ export const useCopilotChatLogic = (
|
|
|
789
915
|
onInProgress?.(isLoading);
|
|
790
916
|
}, [onInProgress, isLoading]);
|
|
791
917
|
|
|
792
|
-
const
|
|
918
|
+
const safelySendMessage = async (
|
|
793
919
|
messageContent: string,
|
|
794
920
|
imagesToUse?: Array<{ contentType: string; bytes: string }>,
|
|
795
921
|
) => {
|
|
@@ -821,7 +947,7 @@ export const useCopilotChatLogic = (
|
|
|
821
947
|
}
|
|
822
948
|
|
|
823
949
|
// Send the message and clear suggestions for auto/manual modes
|
|
824
|
-
await
|
|
950
|
+
await sendMessage(textMessage, {
|
|
825
951
|
followUp: images.length === 0,
|
|
826
952
|
clearSuggestions: chatSuggestions === "auto" || chatSuggestions === "manual",
|
|
827
953
|
});
|
|
@@ -842,7 +968,7 @@ export const useCopilotChatLogic = (
|
|
|
842
968
|
bytes: images[i].bytes,
|
|
843
969
|
},
|
|
844
970
|
} as unknown as Message;
|
|
845
|
-
await
|
|
971
|
+
await sendMessage(imageMessage, { followUp: i === images.length - 1 });
|
|
846
972
|
if (!firstMessage) {
|
|
847
973
|
firstMessage = imageMessage;
|
|
848
974
|
}
|
|
@@ -859,7 +985,6 @@ export const useCopilotChatLogic = (
|
|
|
859
985
|
return firstMessage;
|
|
860
986
|
};
|
|
861
987
|
|
|
862
|
-
const messages = visibleMessages;
|
|
863
988
|
const currentAgentName = generalContext.agentSession?.agentName;
|
|
864
989
|
const restartCurrentAgent = async (hint?: HintFunction) => {
|
|
865
990
|
if (generalContext.agentSession) {
|
|
@@ -887,9 +1012,8 @@ export const useCopilotChatLogic = (
|
|
|
887
1012
|
generalContext.agentSession.agentName,
|
|
888
1013
|
stableContext,
|
|
889
1014
|
messagesContext.messages,
|
|
890
|
-
|
|
1015
|
+
sendMessage,
|
|
891
1016
|
runChatCompletion,
|
|
892
|
-
hint,
|
|
893
1017
|
);
|
|
894
1018
|
}
|
|
895
1019
|
};
|
|
@@ -950,10 +1074,9 @@ export const useCopilotChatLogic = (
|
|
|
950
1074
|
|
|
951
1075
|
return {
|
|
952
1076
|
messages,
|
|
953
|
-
visibleMessages,
|
|
954
1077
|
isLoading,
|
|
955
1078
|
suggestions,
|
|
956
|
-
sendMessage,
|
|
1079
|
+
sendMessage: safelySendMessage,
|
|
957
1080
|
stopGeneration,
|
|
958
1081
|
reloadMessages,
|
|
959
1082
|
resetSuggestions,
|
|
@@ -3,6 +3,7 @@ import { MessagesProps } from "./props";
|
|
|
3
3
|
import { useChatContext } from "./ChatContext";
|
|
4
4
|
import { Message } from "@copilotkit/shared";
|
|
5
5
|
import { useCopilotChatInternal as useCopilotChat } from "@copilotkit/react-core";
|
|
6
|
+
import { LegacyRenderMessage, LegacyRenderProps } from "./messages/LegacyRenderMessage";
|
|
6
7
|
|
|
7
8
|
export const Messages = ({
|
|
8
9
|
inProgress,
|
|
@@ -10,25 +11,76 @@ export const Messages = ({
|
|
|
10
11
|
RenderMessage,
|
|
11
12
|
AssistantMessage,
|
|
12
13
|
UserMessage,
|
|
14
|
+
ImageRenderer,
|
|
13
15
|
onRegenerate,
|
|
14
16
|
onCopy,
|
|
15
17
|
onThumbsUp,
|
|
16
18
|
onThumbsDown,
|
|
17
19
|
markdownTagRenderers,
|
|
20
|
+
|
|
21
|
+
// Legacy props
|
|
22
|
+
RenderTextMessage,
|
|
23
|
+
RenderActionExecutionMessage,
|
|
24
|
+
RenderAgentStateMessage,
|
|
25
|
+
RenderResultMessage,
|
|
26
|
+
RenderImageMessage,
|
|
18
27
|
}: MessagesProps) => {
|
|
19
28
|
const { labels } = useChatContext();
|
|
20
|
-
const { visibleMessages, interrupt } = useCopilotChat();
|
|
29
|
+
const { messages: visibleMessages, interrupt } = useCopilotChat();
|
|
21
30
|
const initialMessages = useMemo(() => makeInitialMessages(labels.initial), [labels.initial]);
|
|
22
31
|
const messages = [...initialMessages, ...visibleMessages];
|
|
23
32
|
const { messagesContainerRef, messagesEndRef } = useScrollToBottom(messages);
|
|
24
33
|
|
|
34
|
+
// Check if any legacy props are provided
|
|
35
|
+
const hasLegacyProps = !!(
|
|
36
|
+
RenderTextMessage ||
|
|
37
|
+
RenderActionExecutionMessage ||
|
|
38
|
+
RenderAgentStateMessage ||
|
|
39
|
+
RenderResultMessage ||
|
|
40
|
+
RenderImageMessage
|
|
41
|
+
);
|
|
42
|
+
|
|
43
|
+
// Show deprecation warning if legacy props are used
|
|
44
|
+
useEffect(() => {
|
|
45
|
+
if (hasLegacyProps) {
|
|
46
|
+
console.warn(
|
|
47
|
+
"[CopilotKit] Legacy message render props (RenderTextMessage, RenderActionExecutionMessage, etc.) are deprecated. " +
|
|
48
|
+
"Please use the unified 'RenderMessage' prop instead. " +
|
|
49
|
+
"See migration guide: https://docs.copilotkit.ai/migration/render-message",
|
|
50
|
+
);
|
|
51
|
+
}
|
|
52
|
+
}, [hasLegacyProps]);
|
|
53
|
+
|
|
54
|
+
// Create legacy props object for the adapter
|
|
55
|
+
const legacyProps: LegacyRenderProps = useMemo(
|
|
56
|
+
() => ({
|
|
57
|
+
RenderTextMessage,
|
|
58
|
+
RenderActionExecutionMessage,
|
|
59
|
+
RenderAgentStateMessage,
|
|
60
|
+
RenderResultMessage,
|
|
61
|
+
RenderImageMessage,
|
|
62
|
+
}),
|
|
63
|
+
[
|
|
64
|
+
RenderTextMessage,
|
|
65
|
+
RenderActionExecutionMessage,
|
|
66
|
+
RenderAgentStateMessage,
|
|
67
|
+
RenderResultMessage,
|
|
68
|
+
RenderImageMessage,
|
|
69
|
+
],
|
|
70
|
+
);
|
|
71
|
+
|
|
72
|
+
// Determine which render component to use
|
|
73
|
+
const MessageRenderer = hasLegacyProps
|
|
74
|
+
? (props: any) => <LegacyRenderMessage {...props} legacyProps={legacyProps} />
|
|
75
|
+
: RenderMessage;
|
|
76
|
+
|
|
25
77
|
return (
|
|
26
78
|
<div className="copilotKitMessages" ref={messagesContainerRef}>
|
|
27
79
|
<div className="copilotKitMessagesContainer">
|
|
28
80
|
{messages.map((message, index) => {
|
|
29
81
|
const isCurrentMessage = index === messages.length - 1;
|
|
30
82
|
return (
|
|
31
|
-
<
|
|
83
|
+
<MessageRenderer
|
|
32
84
|
key={index}
|
|
33
85
|
message={message}
|
|
34
86
|
inProgress={inProgress}
|
|
@@ -36,6 +88,7 @@ export const Messages = ({
|
|
|
36
88
|
isCurrentMessage={isCurrentMessage}
|
|
37
89
|
AssistantMessage={AssistantMessage}
|
|
38
90
|
UserMessage={UserMessage}
|
|
91
|
+
ImageRenderer={ImageRenderer}
|
|
39
92
|
onRegenerate={onRegenerate}
|
|
40
93
|
onCopy={onCopy}
|
|
41
94
|
onThumbsUp={onThumbsUp}
|
|
@@ -69,7 +122,7 @@ function makeInitialMessages(initial: string | string[] | undefined): Message[]
|
|
|
69
122
|
return [
|
|
70
123
|
{
|
|
71
124
|
id: initial,
|
|
72
|
-
role: "
|
|
125
|
+
role: "assistant",
|
|
73
126
|
content: initial,
|
|
74
127
|
},
|
|
75
128
|
];
|
|
@@ -10,6 +10,13 @@ import { CopilotChat, CopilotChatProps } from "./Chat";
|
|
|
10
10
|
import { AssistantMessage as DefaultAssistantMessage } from "./messages/AssistantMessage";
|
|
11
11
|
import { UserMessage as DefaultUserMessage } from "./messages/UserMessage";
|
|
12
12
|
import { useCopilotContext } from "@copilotkit/react-core";
|
|
13
|
+
import {
|
|
14
|
+
CopilotKitError,
|
|
15
|
+
CopilotKitErrorCode,
|
|
16
|
+
Severity,
|
|
17
|
+
ErrorVisibility,
|
|
18
|
+
styledConsole,
|
|
19
|
+
} from "@copilotkit/shared";
|
|
13
20
|
|
|
14
21
|
export interface CopilotModalProps extends CopilotChatProps {
|
|
15
22
|
/**
|
|
@@ -79,16 +86,30 @@ const CopilotModalInner = ({
|
|
|
79
86
|
hitEscapeToClose: boolean;
|
|
80
87
|
shortcut: string;
|
|
81
88
|
}) => {
|
|
82
|
-
const { copilotApiConfig } = useCopilotContext();
|
|
89
|
+
const { copilotApiConfig, setBannerError } = useCopilotContext();
|
|
90
|
+
|
|
91
|
+
// Destructure stable values to avoid object reference changes
|
|
92
|
+
const { publicApiKey } = copilotApiConfig;
|
|
83
93
|
|
|
84
94
|
// Helper function to trigger event hooks only if publicApiKey is provided
|
|
85
95
|
const triggerObservabilityHook = useCallback(
|
|
86
96
|
(hookName: keyof CopilotObservabilityHooks, ...args: any[]) => {
|
|
87
|
-
if (
|
|
97
|
+
if (publicApiKey && observabilityHooks?.[hookName]) {
|
|
88
98
|
(observabilityHooks[hookName] as any)(...args);
|
|
89
99
|
}
|
|
100
|
+
if (observabilityHooks?.[hookName] && !publicApiKey) {
|
|
101
|
+
setBannerError(
|
|
102
|
+
new CopilotKitError({
|
|
103
|
+
message: "observabilityHooks requires a publicApiKey to function.",
|
|
104
|
+
code: CopilotKitErrorCode.MISSING_PUBLIC_API_KEY_ERROR,
|
|
105
|
+
severity: Severity.CRITICAL,
|
|
106
|
+
visibility: ErrorVisibility.BANNER,
|
|
107
|
+
}),
|
|
108
|
+
);
|
|
109
|
+
styledConsole.publicApiKeyRequired("observabilityHooks");
|
|
110
|
+
}
|
|
90
111
|
},
|
|
91
|
-
[
|
|
112
|
+
[publicApiKey, observabilityHooks, setBannerError],
|
|
92
113
|
);
|
|
93
114
|
|
|
94
115
|
const { open } = useChatContext();
|
|
@@ -0,0 +1,143 @@
|
|
|
1
|
+
import React from "react";
|
|
2
|
+
import { RenderMessageProps } from "../props";
|
|
3
|
+
import { RenderMessage as DefaultRenderMessage } from "./RenderMessage";
|
|
4
|
+
import { aguiToGQL } from "@copilotkit/runtime-client-gql";
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* Legacy message render props interface for backwards compatibility
|
|
8
|
+
*/
|
|
9
|
+
export interface LegacyRenderProps {
|
|
10
|
+
RenderTextMessage?: React.ComponentType<RenderMessageProps>;
|
|
11
|
+
RenderActionExecutionMessage?: React.ComponentType<RenderMessageProps>;
|
|
12
|
+
RenderAgentStateMessage?: React.ComponentType<RenderMessageProps>;
|
|
13
|
+
RenderResultMessage?: React.ComponentType<RenderMessageProps>;
|
|
14
|
+
RenderImageMessage?: React.ComponentType<RenderMessageProps>;
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
/**
|
|
18
|
+
* Props for the LegacyRenderMessage component
|
|
19
|
+
*/
|
|
20
|
+
export interface LegacyRenderMessageProps extends RenderMessageProps {
|
|
21
|
+
legacyProps: LegacyRenderProps;
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
/**
|
|
25
|
+
* Legacy message adapter component that maps old render props to new message types.
|
|
26
|
+
* This component provides backwards compatibility for the deprecated render props.
|
|
27
|
+
*/
|
|
28
|
+
export const LegacyRenderMessage: React.FC<LegacyRenderMessageProps> = ({
|
|
29
|
+
message,
|
|
30
|
+
inProgress,
|
|
31
|
+
index,
|
|
32
|
+
isCurrentMessage,
|
|
33
|
+
actionResult,
|
|
34
|
+
AssistantMessage,
|
|
35
|
+
UserMessage,
|
|
36
|
+
ImageRenderer,
|
|
37
|
+
onRegenerate,
|
|
38
|
+
onCopy,
|
|
39
|
+
onThumbsUp,
|
|
40
|
+
onThumbsDown,
|
|
41
|
+
markdownTagRenderers,
|
|
42
|
+
legacyProps,
|
|
43
|
+
}) => {
|
|
44
|
+
const {
|
|
45
|
+
RenderTextMessage,
|
|
46
|
+
RenderActionExecutionMessage,
|
|
47
|
+
RenderAgentStateMessage,
|
|
48
|
+
RenderResultMessage,
|
|
49
|
+
RenderImageMessage,
|
|
50
|
+
} = legacyProps;
|
|
51
|
+
|
|
52
|
+
const deprecatedMessage = aguiToGQL(message)[0] ?? undefined;
|
|
53
|
+
|
|
54
|
+
// Route to appropriate legacy renderer based on message type
|
|
55
|
+
if (deprecatedMessage.isTextMessage() && RenderTextMessage) {
|
|
56
|
+
return (
|
|
57
|
+
<RenderTextMessage
|
|
58
|
+
message={message}
|
|
59
|
+
inProgress={inProgress}
|
|
60
|
+
index={index}
|
|
61
|
+
isCurrentMessage={isCurrentMessage}
|
|
62
|
+
AssistantMessage={AssistantMessage}
|
|
63
|
+
UserMessage={UserMessage}
|
|
64
|
+
onRegenerate={onRegenerate}
|
|
65
|
+
onCopy={onCopy}
|
|
66
|
+
onThumbsUp={onThumbsUp}
|
|
67
|
+
onThumbsDown={onThumbsDown}
|
|
68
|
+
markdownTagRenderers={markdownTagRenderers}
|
|
69
|
+
/>
|
|
70
|
+
);
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
if (deprecatedMessage.isActionExecutionMessage() && RenderActionExecutionMessage) {
|
|
74
|
+
return (
|
|
75
|
+
<RenderActionExecutionMessage
|
|
76
|
+
message={message}
|
|
77
|
+
inProgress={inProgress}
|
|
78
|
+
index={index}
|
|
79
|
+
isCurrentMessage={isCurrentMessage}
|
|
80
|
+
actionResult={actionResult}
|
|
81
|
+
AssistantMessage={AssistantMessage}
|
|
82
|
+
UserMessage={UserMessage}
|
|
83
|
+
/>
|
|
84
|
+
);
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
if (deprecatedMessage.isAgentStateMessage() && RenderAgentStateMessage) {
|
|
88
|
+
return (
|
|
89
|
+
<RenderAgentStateMessage
|
|
90
|
+
message={message}
|
|
91
|
+
inProgress={inProgress}
|
|
92
|
+
index={index}
|
|
93
|
+
isCurrentMessage={isCurrentMessage}
|
|
94
|
+
AssistantMessage={AssistantMessage}
|
|
95
|
+
UserMessage={UserMessage}
|
|
96
|
+
/>
|
|
97
|
+
);
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
if (deprecatedMessage.isResultMessage() && RenderResultMessage) {
|
|
101
|
+
return (
|
|
102
|
+
<RenderResultMessage
|
|
103
|
+
message={message}
|
|
104
|
+
inProgress={inProgress}
|
|
105
|
+
index={index}
|
|
106
|
+
isCurrentMessage={isCurrentMessage}
|
|
107
|
+
AssistantMessage={AssistantMessage}
|
|
108
|
+
UserMessage={UserMessage}
|
|
109
|
+
/>
|
|
110
|
+
);
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
if (deprecatedMessage.isImageMessage() && RenderImageMessage) {
|
|
114
|
+
return (
|
|
115
|
+
<RenderImageMessage
|
|
116
|
+
message={message}
|
|
117
|
+
inProgress={inProgress}
|
|
118
|
+
index={index}
|
|
119
|
+
isCurrentMessage={isCurrentMessage}
|
|
120
|
+
AssistantMessage={AssistantMessage}
|
|
121
|
+
UserMessage={UserMessage}
|
|
122
|
+
/>
|
|
123
|
+
);
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
// Fallback to default RenderMessage for any unhandled cases
|
|
127
|
+
return (
|
|
128
|
+
<DefaultRenderMessage
|
|
129
|
+
message={message}
|
|
130
|
+
inProgress={inProgress}
|
|
131
|
+
index={index}
|
|
132
|
+
isCurrentMessage={isCurrentMessage}
|
|
133
|
+
AssistantMessage={AssistantMessage}
|
|
134
|
+
UserMessage={UserMessage}
|
|
135
|
+
ImageRenderer={ImageRenderer}
|
|
136
|
+
onRegenerate={onRegenerate}
|
|
137
|
+
onCopy={onCopy}
|
|
138
|
+
onThumbsUp={onThumbsUp}
|
|
139
|
+
onThumbsDown={onThumbsDown}
|
|
140
|
+
markdownTagRenderers={markdownTagRenderers}
|
|
141
|
+
/>
|
|
142
|
+
);
|
|
143
|
+
};
|