@copilotkit/react-ui 1.10.0-next.3 → 1.10.0-next.5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (92) hide show
  1. package/CHANGELOG.md +20 -0
  2. package/dist/{chunk-O7KTFUAN.mjs → chunk-226ZMOE3.mjs} +2 -2
  3. package/dist/{chunk-PF3QW6U5.mjs → chunk-BXX6RM44.mjs} +2 -2
  4. package/dist/chunk-BXX6RM44.mjs.map +1 -0
  5. package/dist/chunk-BY42E5VF.mjs +203 -0
  6. package/dist/chunk-BY42E5VF.mjs.map +1 -0
  7. package/dist/{chunk-SGFUVPDB.mjs → chunk-FFJHOZX6.mjs} +2 -2
  8. package/dist/{chunk-GVKA7RQQ.mjs → chunk-GDSZGYCE.mjs} +2 -2
  9. package/dist/{chunk-QN7T3GWI.mjs → chunk-JY2CSDKN.mjs} +4 -6
  10. package/dist/chunk-JY2CSDKN.mjs.map +1 -0
  11. package/dist/{chunk-7L34XQRL.mjs → chunk-K344MVUT.mjs} +61 -8
  12. package/dist/chunk-K344MVUT.mjs.map +1 -0
  13. package/dist/{chunk-QNG5G23E.mjs → chunk-MYWIJSW6.mjs} +2 -2
  14. package/dist/chunk-MYWIJSW6.mjs.map +1 -0
  15. package/dist/{chunk-WHDNKXMP.mjs → chunk-U5ATIGWH.mjs} +2 -2
  16. package/dist/chunk-U5ATIGWH.mjs.map +1 -0
  17. package/dist/{chunk-Q2467VHZ.mjs → chunk-W26XFBEG.mjs} +2 -2
  18. package/dist/chunk-W26XFBEG.mjs.map +1 -0
  19. package/dist/components/chat/Chat.d.ts +19 -12
  20. package/dist/components/chat/Chat.js +57 -10
  21. package/dist/components/chat/Chat.js.map +1 -1
  22. package/dist/components/chat/Chat.mjs +4 -4
  23. package/dist/components/chat/Header.js +6 -8
  24. package/dist/components/chat/Header.js.map +1 -1
  25. package/dist/components/chat/Header.mjs +3 -3
  26. package/dist/components/chat/Messages.js +1 -1
  27. package/dist/components/chat/Messages.js.map +1 -1
  28. package/dist/components/chat/Messages.mjs +1 -1
  29. package/dist/components/chat/Modal.d.ts +2 -2
  30. package/dist/components/chat/Modal.js +179 -76
  31. package/dist/components/chat/Modal.js.map +1 -1
  32. package/dist/components/chat/Modal.mjs +8 -8
  33. package/dist/components/chat/Popup.d.ts +1 -1
  34. package/dist/components/chat/Popup.js +179 -76
  35. package/dist/components/chat/Popup.js.map +1 -1
  36. package/dist/components/chat/Popup.mjs +9 -9
  37. package/dist/components/chat/Sidebar.d.ts +1 -1
  38. package/dist/components/chat/Sidebar.js +179 -76
  39. package/dist/components/chat/Sidebar.js.map +1 -1
  40. package/dist/components/chat/Sidebar.mjs +9 -9
  41. package/dist/components/chat/Suggestion.js +1 -1
  42. package/dist/components/chat/Suggestion.js.map +1 -1
  43. package/dist/components/chat/Suggestion.mjs +1 -1
  44. package/dist/components/chat/Suggestions.js +1 -1
  45. package/dist/components/chat/Suggestions.js.map +1 -1
  46. package/dist/components/chat/Suggestions.mjs +2 -2
  47. package/dist/components/chat/index.d.ts +2 -2
  48. package/dist/components/chat/index.js +179 -76
  49. package/dist/components/chat/index.js.map +1 -1
  50. package/dist/components/chat/index.mjs +10 -10
  51. package/dist/components/chat/props.d.ts +39 -1
  52. package/dist/components/chat/props.js.map +1 -1
  53. package/dist/components/dev-console/console.d.ts +1 -0
  54. package/dist/components/dev-console/console.js +6 -8
  55. package/dist/components/dev-console/console.js.map +1 -1
  56. package/dist/components/dev-console/console.mjs +2 -2
  57. package/dist/components/dev-console/index.d.ts +1 -3
  58. package/dist/components/dev-console/index.js +7 -9
  59. package/dist/components/dev-console/index.js.map +1 -1
  60. package/dist/components/dev-console/index.mjs +2 -2
  61. package/dist/components/dev-console/utils.d.ts +2 -2
  62. package/dist/components/dev-console/utils.js +2 -4
  63. package/dist/components/dev-console/utils.js.map +1 -1
  64. package/dist/components/dev-console/utils.mjs +1 -1
  65. package/dist/components/index.d.ts +3 -5
  66. package/dist/components/index.js +180 -77
  67. package/dist/components/index.js.map +1 -1
  68. package/dist/components/index.mjs +10 -10
  69. package/dist/index.d.ts +3 -5
  70. package/dist/index.js +184 -81
  71. package/dist/index.js.map +1 -1
  72. package/dist/index.mjs +10 -10
  73. package/package.json +5 -5
  74. package/src/components/chat/Chat.tsx +99 -5
  75. package/src/components/chat/Messages.tsx +2 -2
  76. package/src/components/chat/Modal.tsx +107 -41
  77. package/src/components/chat/Popup.tsx +20 -0
  78. package/src/components/chat/Sidebar.tsx +22 -0
  79. package/src/components/chat/Suggestion.tsx +1 -1
  80. package/src/components/chat/props.ts +46 -0
  81. package/src/components/dev-console/utils.ts +1 -6
  82. package/dist/chunk-7L34XQRL.mjs.map +0 -1
  83. package/dist/chunk-DNSSBMAS.mjs +0 -144
  84. package/dist/chunk-DNSSBMAS.mjs.map +0 -1
  85. package/dist/chunk-PF3QW6U5.mjs.map +0 -1
  86. package/dist/chunk-Q2467VHZ.mjs.map +0 -1
  87. package/dist/chunk-QN7T3GWI.mjs.map +0 -1
  88. package/dist/chunk-QNG5G23E.mjs.map +0 -1
  89. package/dist/chunk-WHDNKXMP.mjs.map +0 -1
  90. /package/dist/{chunk-O7KTFUAN.mjs.map → chunk-226ZMOE3.mjs.map} +0 -0
  91. /package/dist/{chunk-SGFUVPDB.mjs.map → chunk-FFJHOZX6.mjs.map} +0 -0
  92. /package/dist/{chunk-GVKA7RQQ.mjs.map → chunk-GDSZGYCE.mjs.map} +0 -0
package/dist/index.mjs CHANGED
@@ -4,29 +4,29 @@ import "./chunk-MMVDU6DF.mjs";
4
4
  import "./chunk-SC6JRFAJ.mjs";
5
5
  import {
6
6
  CopilotSidebar
7
- } from "./chunk-QNG5G23E.mjs";
7
+ } from "./chunk-MYWIJSW6.mjs";
8
8
  import "./chunk-WB3YULQ4.mjs";
9
9
  import {
10
10
  CopilotPopup
11
- } from "./chunk-PF3QW6U5.mjs";
12
- import "./chunk-DNSSBMAS.mjs";
11
+ } from "./chunk-BXX6RM44.mjs";
12
+ import "./chunk-BY42E5VF.mjs";
13
13
  import "./chunk-C3GSYRC3.mjs";
14
- import "./chunk-GVKA7RQQ.mjs";
14
+ import "./chunk-GDSZGYCE.mjs";
15
15
  import "./chunk-V7W6IM2V.mjs";
16
16
  import {
17
17
  CopilotDevConsole
18
- } from "./chunk-SGFUVPDB.mjs";
18
+ } from "./chunk-FFJHOZX6.mjs";
19
19
  import "./chunk-Q5V6S67N.mjs";
20
20
  import {
21
21
  shouldShowDevConsole
22
- } from "./chunk-QN7T3GWI.mjs";
22
+ } from "./chunk-JY2CSDKN.mjs";
23
23
  import "./chunk-KXE2JCUH.mjs";
24
24
  import "./chunk-NRA3CFEE.mjs";
25
25
  import "./chunk-BH6PCAAL.mjs";
26
26
  import "./chunk-UFN2VWSR.mjs";
27
27
  import {
28
28
  CopilotChat
29
- } from "./chunk-7L34XQRL.mjs";
29
+ } from "./chunk-K344MVUT.mjs";
30
30
  import "./chunk-JHUTTP5C.mjs";
31
31
  import {
32
32
  AssistantMessage
@@ -39,10 +39,10 @@ import {
39
39
  } from "./chunk-VVL6JFCJ.mjs";
40
40
  import {
41
41
  Suggestions
42
- } from "./chunk-O7KTFUAN.mjs";
42
+ } from "./chunk-226ZMOE3.mjs";
43
43
  import {
44
44
  Suggestion
45
- } from "./chunk-Q2467VHZ.mjs";
45
+ } from "./chunk-W26XFBEG.mjs";
46
46
  import "./chunk-PLHTVHUW.mjs";
47
47
  import "./chunk-DTRPPNSA.mjs";
48
48
  import "./chunk-CGEAG65D.mjs";
@@ -50,7 +50,7 @@ import "./chunk-QIOJXTIQ.mjs";
50
50
  import {
51
51
  Markdown
52
52
  } from "./chunk-E6MQUIZW.mjs";
53
- import "./chunk-WHDNKXMP.mjs";
53
+ import "./chunk-U5ATIGWH.mjs";
54
54
  import {
55
55
  useChatContext
56
56
  } 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-next.3",
12
+ "version": "1.10.0-next.5",
13
13
  "sideEffects": [
14
14
  "**/*.css"
15
15
  ],
@@ -40,8 +40,8 @@
40
40
  "ts-jest": "^29.1.1",
41
41
  "tsup": "^6.7.0",
42
42
  "typescript": "^5.2.3",
43
- "tailwind-config": "1.4.6",
44
43
  "eslint-config-custom": "1.4.6",
44
+ "tailwind-config": "1.4.6",
45
45
  "tsconfig": "1.4.6"
46
46
  },
47
47
  "dependencies": {
@@ -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/runtime-client-gql": "1.10.0-next.3",
55
- "@copilotkit/shared": "1.10.0-next.3",
56
- "@copilotkit/react-core": "1.10.0-next.3"
54
+ "@copilotkit/react-core": "1.10.0-next.5",
55
+ "@copilotkit/runtime-client-gql": "1.10.0-next.5",
56
+ "@copilotkit/shared": "1.10.0-next.5"
57
57
  },
58
58
  "keywords": [
59
59
  "copilotkit",
@@ -27,6 +27,23 @@
27
27
  * />
28
28
  * ```
29
29
  *
30
+ * ### With Observability Hooks
31
+ *
32
+ * To monitor user interactions, provide the `observabilityHooks` prop.
33
+ * **Note:** This requires a `publicApiKey` in the `<CopilotKit>` provider.
34
+ *
35
+ * ```tsx
36
+ * <CopilotKit publicApiKey="YOUR_PUBLIC_API_KEY">
37
+ * <CopilotChat
38
+ * observabilityHooks={{
39
+ * onMessageSent: (message) => {
40
+ * console.log("Message sent:", message);
41
+ * },
42
+ * }}
43
+ * />
44
+ * </CopilotKit>
45
+ * ```
46
+ *
30
47
  * ### Look & Feel
31
48
  *
32
49
  * By default, CopilotKit components do not have any styles. You can import CopilotKit's stylesheet at the root of your project:
@@ -60,16 +77,24 @@ import { ImageRenderer as DefaultImageRenderer } from "./messages/ImageRenderer"
60
77
  import React, { useEffect, useRef, useState, useCallback, useMemo } from "react";
61
78
  import {
62
79
  SystemMessageFunction,
63
- useCopilotChat,
80
+ useCopilotChatInternal as useCopilotChat,
64
81
  useCopilotContext,
65
82
  useCopilotMessagesContext,
66
83
  } from "@copilotkit/react-core";
67
84
  import type { SuggestionItem } from "@copilotkit/react-core";
68
- import { Message } from "@copilotkit/shared";
85
+ import {
86
+ CopilotKitError,
87
+ CopilotKitErrorCode,
88
+ Message,
89
+ Severity,
90
+ ErrorVisibility,
91
+ styledConsole,
92
+ } from "@copilotkit/shared";
69
93
  import { randomId } from "@copilotkit/shared";
70
94
  import {
71
95
  AssistantMessageProps,
72
96
  ComponentsMap,
97
+ CopilotObservabilityHooks,
73
98
  ImageRendererProps,
74
99
  InputProps,
75
100
  MessagesProps,
@@ -250,6 +275,12 @@ export interface CopilotChatProps {
250
275
  children?: React.ReactNode;
251
276
 
252
277
  hideStopButton?: boolean;
278
+
279
+ /**
280
+ * Event hooks for CopilotKit chat events.
281
+ * These hooks only work when publicApiKey is provided.
282
+ */
283
+ observabilityHooks?: CopilotObservabilityHooks;
253
284
  }
254
285
 
255
286
  interface OnStopGenerationArguments {
@@ -336,11 +367,34 @@ export function CopilotChat({
336
367
  imageUploadsEnabled,
337
368
  inputFileAccept = "image/*",
338
369
  hideStopButton,
370
+ observabilityHooks,
339
371
  }: CopilotChatProps) {
340
- const { additionalInstructions, setChatInstructions } = useCopilotContext();
372
+ const { additionalInstructions, setChatInstructions, copilotApiConfig, setBannerError } =
373
+ useCopilotContext();
341
374
  const [selectedImages, setSelectedImages] = useState<Array<ImageUpload>>([]);
342
375
  const fileInputRef = useRef<HTMLInputElement>(null);
343
376
 
377
+ // Helper function to trigger event hooks only if publicApiKey is provided
378
+ const triggerObservabilityHook = useCallback(
379
+ (hookName: keyof CopilotObservabilityHooks, ...args: any[]) => {
380
+ if (copilotApiConfig.publicApiKey && observabilityHooks?.[hookName]) {
381
+ (observabilityHooks[hookName] as any)(...args);
382
+ }
383
+ if (observabilityHooks?.[hookName] && !copilotApiConfig.publicApiKey) {
384
+ setBannerError(
385
+ new CopilotKitError({
386
+ message: "observabilityHooks requires a publicApiKey to function.",
387
+ code: CopilotKitErrorCode.MISSING_PUBLIC_API_KEY_ERROR,
388
+ severity: Severity.CRITICAL,
389
+ visibility: ErrorVisibility.BANNER,
390
+ }),
391
+ );
392
+ styledConsole.publicApiKeyRequired("observabilityHooks");
393
+ }
394
+ },
395
+ [copilotApiConfig.publicApiKey, observabilityHooks],
396
+ );
397
+
344
398
  // Clipboard paste handler
345
399
  useEffect(() => {
346
400
  if (!imageUploadsEnabled) return;
@@ -430,6 +484,19 @@ export function CopilotChat({
430
484
  onReloadMessages,
431
485
  );
432
486
 
487
+ // Track loading state changes for chat start/stop events
488
+ const prevIsLoading = useRef(isLoading);
489
+ useEffect(() => {
490
+ if (prevIsLoading.current !== isLoading) {
491
+ if (isLoading) {
492
+ triggerObservabilityHook("onChatStarted");
493
+ } else {
494
+ triggerObservabilityHook("onChatStopped");
495
+ }
496
+ prevIsLoading.current = isLoading;
497
+ }
498
+ }, [isLoading, triggerObservabilityHook]);
499
+
433
500
  // Wrapper for sendMessage to clear selected images
434
501
  const handleSendMessage = (text: string) => {
435
502
  const images = selectedImages;
@@ -438,6 +505,9 @@ export function CopilotChat({
438
505
  fileInputRef.current.value = "";
439
506
  }
440
507
 
508
+ // Trigger message sent event
509
+ triggerObservabilityHook("onMessageSent", text);
510
+
441
511
  return sendMessage(text, images);
442
512
  };
443
513
 
@@ -449,6 +519,9 @@ export function CopilotChat({
449
519
  onRegenerate(messageId);
450
520
  }
451
521
 
522
+ // Trigger message regenerated event
523
+ triggerObservabilityHook("onMessageRegenerated", messageId);
524
+
452
525
  reloadMessages(messageId);
453
526
  };
454
527
 
@@ -456,6 +529,9 @@ export function CopilotChat({
456
529
  if (onCopy) {
457
530
  onCopy(message);
458
531
  }
532
+
533
+ // Trigger message copied event
534
+ triggerObservabilityHook("onMessageCopied", message);
459
535
  };
460
536
 
461
537
  const handleImageUpload = async (event: React.ChangeEvent<HTMLInputElement>) => {
@@ -496,6 +572,24 @@ export function CopilotChat({
496
572
  setSelectedImages((prev) => prev.filter((_, i) => i !== index));
497
573
  };
498
574
 
575
+ const handleThumbsUp = (message: Message) => {
576
+ if (onThumbsUp) {
577
+ onThumbsUp(message);
578
+ }
579
+
580
+ // Trigger feedback given event
581
+ triggerObservabilityHook("onFeedbackGiven", message.id, "thumbsUp");
582
+ };
583
+
584
+ const handleThumbsDown = (message: Message) => {
585
+ if (onThumbsDown) {
586
+ onThumbsDown(message);
587
+ }
588
+
589
+ // Trigger feedback given event
590
+ triggerObservabilityHook("onFeedbackGiven", message.id, "thumbsDown");
591
+ };
592
+
499
593
  return (
500
594
  <WrappedCopilotChat icons={icons} labels={labels} className={className}>
501
595
  <Messages
@@ -506,8 +600,8 @@ export function CopilotChat({
506
600
  inProgress={isLoading}
507
601
  onRegenerate={handleRegenerate}
508
602
  onCopy={handleCopy}
509
- onThumbsUp={onThumbsUp}
510
- onThumbsDown={onThumbsDown}
603
+ onThumbsUp={handleThumbsUp}
604
+ onThumbsDown={handleThumbsDown}
511
605
  markdownTagRenderers={markdownTagRenderers}
512
606
  ImageRenderer={ImageRenderer}
513
607
  >
@@ -1,8 +1,8 @@
1
1
  import { useEffect, useMemo, useRef } from "react";
2
2
  import { MessagesProps } from "./props";
3
3
  import { useChatContext } from "./ChatContext";
4
- import { Message, Role } from "@copilotkit/shared";
5
- import { useCopilotChat } from "@copilotkit/react-core";
4
+ import { Message } from "@copilotkit/shared";
5
+ import { useCopilotChatInternal as useCopilotChat } from "@copilotkit/react-core";
6
6
 
7
7
  export const Messages = ({
8
8
  inProgress,
@@ -1,6 +1,6 @@
1
- import React, { useMemo } from "react";
2
- import { ChatContextProvider } from "./ChatContext";
3
- import { ButtonProps, HeaderProps, WindowProps } from "./props";
1
+ import React, { useMemo, useCallback, useEffect, useRef } from "react";
2
+ import { ChatContextProvider, useChatContext } from "./ChatContext";
3
+ import { ButtonProps, HeaderProps, WindowProps, CopilotObservabilityHooks } from "./props";
4
4
  import { Window as DefaultWindow } from "./Window";
5
5
  import { Button as DefaultButton } from "./Button";
6
6
  import { Header as DefaultHeader } from "./Header";
@@ -9,6 +9,7 @@ import { Input as DefaultInput } from "./Input";
9
9
  import { CopilotChat, CopilotChatProps } from "./Chat";
10
10
  import { AssistantMessage as DefaultAssistantMessage } from "./messages/AssistantMessage";
11
11
  import { UserMessage as DefaultUserMessage } from "./messages/UserMessage";
12
+ import { useCopilotContext } from "@copilotkit/react-core";
12
13
 
13
14
  export interface CopilotModalProps extends CopilotChatProps {
14
15
  /**
@@ -57,6 +58,78 @@ export interface CopilotModalProps extends CopilotChatProps {
57
58
  Header?: React.ComponentType<HeaderProps>;
58
59
  }
59
60
 
61
+ // Inner component that has access to the Copilot context
62
+ const CopilotModalInner = ({
63
+ observabilityHooks,
64
+ onSetOpen,
65
+ clickOutsideToClose,
66
+ hitEscapeToClose,
67
+ shortcut,
68
+ className,
69
+ children,
70
+ Window,
71
+ Button,
72
+ Header,
73
+ ...chatProps
74
+ }: Omit<CopilotModalProps, "icons" | "labels" | "defaultOpen"> & {
75
+ Window: React.ComponentType<WindowProps>;
76
+ Button: React.ComponentType<ButtonProps>;
77
+ Header: React.ComponentType<HeaderProps>;
78
+ clickOutsideToClose: boolean;
79
+ hitEscapeToClose: boolean;
80
+ shortcut: string;
81
+ }) => {
82
+ const { copilotApiConfig } = useCopilotContext();
83
+
84
+ // Helper function to trigger event hooks only if publicApiKey is provided
85
+ const triggerObservabilityHook = useCallback(
86
+ (hookName: keyof CopilotObservabilityHooks, ...args: any[]) => {
87
+ if (copilotApiConfig.publicApiKey && observabilityHooks?.[hookName]) {
88
+ (observabilityHooks[hookName] as any)(...args);
89
+ }
90
+ },
91
+ [copilotApiConfig.publicApiKey, observabilityHooks],
92
+ );
93
+
94
+ const { open } = useChatContext();
95
+ const prevOpen = useRef(open);
96
+
97
+ // Monitor open state changes and trigger event hooks
98
+ useEffect(() => {
99
+ if (prevOpen.current !== open) {
100
+ onSetOpen?.(open);
101
+
102
+ // Trigger chat minimize/expand events
103
+ if (open) {
104
+ triggerObservabilityHook("onChatExpanded");
105
+ } else {
106
+ triggerObservabilityHook("onChatMinimized");
107
+ }
108
+ prevOpen.current = open;
109
+ }
110
+ }, [open, onSetOpen, triggerObservabilityHook]);
111
+
112
+ const memoizedHeader = useMemo(() => <Header />, [Header]);
113
+ const memoizedChildren = useMemo(() => children, [children]);
114
+
115
+ return (
116
+ <>
117
+ {memoizedChildren}
118
+ <div className={className}>
119
+ <Button></Button>
120
+ <Window
121
+ clickOutsideToClose={clickOutsideToClose}
122
+ shortcut={shortcut}
123
+ hitEscapeToClose={hitEscapeToClose}
124
+ >
125
+ {memoizedHeader}
126
+ <CopilotChat {...chatProps} observabilityHooks={observabilityHooks} />
127
+ </Window>
128
+ </div>
129
+ </>
130
+ );
131
+ };
132
+
60
133
  export const CopilotModal = ({
61
134
  instructions,
62
135
  defaultOpen = false,
@@ -85,49 +158,42 @@ export const CopilotModal = ({
85
158
  markdownTagRenderers,
86
159
  className,
87
160
  children,
161
+ observabilityHooks,
88
162
  ...props
89
163
  }: CopilotModalProps) => {
90
164
  const [openState, setOpenState] = React.useState(defaultOpen);
91
165
 
92
- const setOpen = (open: boolean) => {
93
- onSetOpen?.(open);
94
- setOpenState(open);
95
- };
96
-
97
- const memoizedHeader = useMemo(() => <Header />, [Header]);
98
- const memoizedChildren = useMemo(() => children, [children]);
99
-
100
166
  return (
101
- <ChatContextProvider icons={icons} labels={labels} open={openState} setOpen={setOpen}>
102
- {memoizedChildren}
103
- <div className={className}>
104
- <Button></Button>
105
- <Window
106
- clickOutsideToClose={clickOutsideToClose}
107
- shortcut={shortcut}
108
- hitEscapeToClose={hitEscapeToClose}
109
- >
110
- {memoizedHeader}
111
- <CopilotChat
112
- {...props}
113
- instructions={instructions}
114
- onSubmitMessage={onSubmitMessage}
115
- onStopGeneration={onStopGeneration}
116
- onReloadMessages={onReloadMessages}
117
- makeSystemMessage={makeSystemMessage}
118
- onInProgress={onInProgress}
119
- Messages={Messages}
120
- Input={Input}
121
- AssistantMessage={AssistantMessage}
122
- UserMessage={UserMessage}
123
- onThumbsUp={onThumbsUp}
124
- onThumbsDown={onThumbsDown}
125
- onCopy={onCopy}
126
- onRegenerate={onRegenerate}
127
- markdownTagRenderers={markdownTagRenderers}
128
- />
129
- </Window>
130
- </div>
167
+ <ChatContextProvider icons={icons} labels={labels} open={openState} setOpen={setOpenState}>
168
+ <CopilotModalInner
169
+ observabilityHooks={observabilityHooks}
170
+ onSetOpen={onSetOpen}
171
+ clickOutsideToClose={clickOutsideToClose ?? true}
172
+ hitEscapeToClose={hitEscapeToClose ?? true}
173
+ shortcut={shortcut ?? "/"}
174
+ className={className}
175
+ Window={Window}
176
+ Button={Button}
177
+ Header={Header}
178
+ instructions={instructions}
179
+ onSubmitMessage={onSubmitMessage}
180
+ onStopGeneration={onStopGeneration}
181
+ onReloadMessages={onReloadMessages}
182
+ makeSystemMessage={makeSystemMessage}
183
+ onInProgress={onInProgress}
184
+ Messages={Messages}
185
+ Input={Input}
186
+ AssistantMessage={AssistantMessage}
187
+ UserMessage={UserMessage}
188
+ onThumbsUp={onThumbsUp}
189
+ onThumbsDown={onThumbsDown}
190
+ onCopy={onCopy}
191
+ onRegenerate={onRegenerate}
192
+ markdownTagRenderers={markdownTagRenderers}
193
+ {...props}
194
+ >
195
+ {children}
196
+ </CopilotModalInner>
131
197
  </ChatContextProvider>
132
198
  );
133
199
  };
@@ -28,6 +28,26 @@
28
28
  * />
29
29
  * ```
30
30
  *
31
+ * ### With Observability Hooks
32
+ *
33
+ * To monitor user interactions, provide the `observabilityHooks` prop.
34
+ * **Note:** This requires a `publicApiKey` in the `<CopilotKit>` provider.
35
+ *
36
+ * ```tsx
37
+ * <CopilotKit publicApiKey="YOUR_PUBLIC_API_KEY">
38
+ * <CopilotPopup
39
+ * observabilityHooks={{
40
+ * onChatExpanded: () => {
41
+ * console.log("Popup opened");
42
+ * },
43
+ * onChatMinimized: () => {
44
+ * console.log("Popup closed");
45
+ * },
46
+ * }}
47
+ * />
48
+ * </CopilotKit>
49
+ * ```
50
+ *
31
51
  * ### Look & Feel
32
52
  *
33
53
  * By default, CopilotKit components do not have any styles. You can import CopilotKit's stylesheet at the root of your project:
@@ -30,6 +30,28 @@
30
30
  * </CopilotSidebar>
31
31
  * ```
32
32
  *
33
+ * ### With Observability Hooks
34
+ *
35
+ * To monitor user interactions, provide the `observabilityHooks` prop.
36
+ * **Note:** This requires a `publicApiKey` in the `<CopilotKit>` provider.
37
+ *
38
+ * ```tsx
39
+ * <CopilotKit publicApiKey="YOUR_PUBLIC_API_KEY">
40
+ * <CopilotSidebar
41
+ * observabilityHooks={{
42
+ * onChatExpanded: () => {
43
+ * console.log("Sidebar opened");
44
+ * },
45
+ * onChatMinimized: () => {
46
+ * console.log("Sidebar closed");
47
+ * },
48
+ * }}
49
+ * >
50
+ * <YourApp/>
51
+ * </CopilotSidebar>
52
+ * </CopilotKit>
53
+ * ```
54
+ *
33
55
  * ### Look & Feel
34
56
  *
35
57
  * By default, CopilotKit components do not have any styles. You can import CopilotKit's stylesheet at the root of your project:
@@ -1,4 +1,4 @@
1
- import { useCopilotChat } from "@copilotkit/react-core";
1
+ import { useCopilotChatInternal as useCopilotChat } from "@copilotkit/react-core";
2
2
  import { SmallSpinnerIcon } from "./Icons";
3
3
 
4
4
  interface SuggestionsProps {
@@ -3,6 +3,52 @@ import { CopilotChatSuggestion } from "../../types/suggestions";
3
3
  import { ReactNode } from "react";
4
4
  import { ImageData } from "@copilotkit/shared";
5
5
 
6
+ /**
7
+ * Event hooks for CopilotKit chat events.
8
+ * These hooks only work when publicApiKey is provided.
9
+ */
10
+ export interface CopilotObservabilityHooks {
11
+ /**
12
+ * Called when a message is sent by the user
13
+ */
14
+ onMessageSent?: (message: string) => void;
15
+
16
+ /**
17
+ * Called when the chat is minimized/closed
18
+ */
19
+ onChatMinimized?: () => void;
20
+
21
+ /**
22
+ * Called when the chat is expanded/opened
23
+ */
24
+ onChatExpanded?: () => void;
25
+
26
+ /**
27
+ * Called when a message is regenerated
28
+ */
29
+ onMessageRegenerated?: (messageId: string) => void;
30
+
31
+ /**
32
+ * Called when a message is copied
33
+ */
34
+ onMessageCopied?: (content: string) => void;
35
+
36
+ /**
37
+ * Called when feedback is given (thumbs up/down)
38
+ */
39
+ onFeedbackGiven?: (messageId: string, type: "thumbsUp" | "thumbsDown") => void;
40
+
41
+ /**
42
+ * Called when chat generation starts
43
+ */
44
+ onChatStarted?: () => void;
45
+
46
+ /**
47
+ * Called when chat generation stops
48
+ */
49
+ onChatStopped?: () => void;
50
+ }
51
+
6
52
  export interface ButtonProps {}
7
53
 
8
54
  export interface WindowProps {
@@ -4,12 +4,7 @@ import {
4
4
  defaultCopilotContextCategories,
5
5
  } from "@copilotkit/react-core";
6
6
  import { CopilotKitVersion } from "./types";
7
- import { ActionExecutionMessage, ResultMessage, TextMessage } from "@copilotkit/runtime-client-gql";
8
- import { AgentStateMessage } from "@copilotkit/runtime-client-gql";
9
-
10
- export function shouldShowDevConsole(showDevConsole: boolean): boolean {
11
- return showDevConsole;
12
- }
7
+ export { shouldShowDevConsole } from "@copilotkit/react-core";
13
8
 
14
9
  export async function getPublishedCopilotKitVersion(
15
10
  current: string,