@copilotkit/react-ui 1.9.3 → 1.10.0-next.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.
Files changed (178) hide show
  1. package/CHANGELOG.md +30 -0
  2. package/dist/{chunk-KENCH7RN.mjs → chunk-B5IFB5YJ.mjs} +1 -1
  3. package/dist/chunk-B5IFB5YJ.mjs.map +1 -0
  4. package/dist/chunk-DBKRAOH7.mjs +34 -0
  5. package/dist/chunk-DBKRAOH7.mjs.map +1 -0
  6. package/dist/{chunk-4HUXYD3B.mjs → chunk-DTRPPNSA.mjs} +2 -2
  7. package/dist/{chunk-YTXEWDNC.mjs → chunk-E6MQUIZW.mjs} +15 -4
  8. package/dist/chunk-E6MQUIZW.mjs.map +1 -0
  9. package/dist/{chunk-L3GZ7TXC.mjs → chunk-GCKKSSBU.mjs} +21 -24
  10. package/dist/chunk-GCKKSSBU.mjs.map +1 -0
  11. package/dist/{chunk-KN2GCKBE.mjs → chunk-GJ3MFNBX.mjs} +6 -6
  12. package/dist/{chunk-32MUWKL3.mjs → chunk-JHUTTP5C.mjs} +21 -17
  13. package/dist/chunk-JHUTTP5C.mjs.map +1 -0
  14. package/dist/{chunk-HKTWKCPS.mjs → chunk-LXCD3K7B.mjs} +127 -92
  15. package/dist/chunk-LXCD3K7B.mjs.map +1 -0
  16. package/dist/{chunk-S5MBUNGN.mjs → chunk-O72ZB5V3.mjs} +4 -4
  17. package/dist/chunk-O72ZB5V3.mjs.map +1 -0
  18. package/dist/{chunk-QGSPTXOV.mjs → chunk-O7KTFUAN.mjs} +2 -2
  19. package/dist/chunk-O7KTFUAN.mjs.map +1 -0
  20. package/dist/chunk-Q2467VHZ.mjs +30 -0
  21. package/dist/chunk-Q2467VHZ.mjs.map +1 -0
  22. package/dist/{chunk-H3EM63WS.mjs → chunk-VLNT34X3.mjs} +2 -2
  23. package/dist/chunk-VVL6JFCJ.mjs +16 -0
  24. package/dist/chunk-VVL6JFCJ.mjs.map +1 -0
  25. package/dist/chunk-WHDNKXMP.mjs +135 -0
  26. package/dist/chunk-WHDNKXMP.mjs.map +1 -0
  27. package/dist/{chunk-ALIBUJML.mjs → chunk-WPVTPQ7X.mjs} +2 -2
  28. package/dist/components/chat/Button.d.ts +1 -1
  29. package/dist/components/chat/Chat.d.ts +119 -28
  30. package/dist/components/chat/Chat.js +298 -658
  31. package/dist/components/chat/Chat.js.map +1 -1
  32. package/dist/components/chat/Chat.mjs +12 -15
  33. package/dist/components/chat/CodeBlock.js.map +1 -1
  34. package/dist/components/chat/CodeBlock.mjs +1 -1
  35. package/dist/components/chat/Header.d.ts +1 -1
  36. package/dist/components/chat/Input.d.ts +1 -1
  37. package/dist/components/chat/Input.js +3 -3
  38. package/dist/components/chat/Input.js.map +1 -1
  39. package/dist/components/chat/Input.mjs +2 -2
  40. package/dist/components/chat/Markdown.js +13 -2
  41. package/dist/components/chat/Markdown.js.map +1 -1
  42. package/dist/components/chat/Markdown.mjs +2 -2
  43. package/dist/components/chat/Messages.d.ts +3 -3
  44. package/dist/components/chat/Messages.js +40 -116
  45. package/dist/components/chat/Messages.js.map +1 -1
  46. package/dist/components/chat/Messages.mjs +1 -1
  47. package/dist/components/chat/Modal.d.ts +7 -2
  48. package/dist/components/chat/Modal.js +308 -668
  49. package/dist/components/chat/Modal.js.map +1 -1
  50. package/dist/components/chat/Modal.mjs +13 -16
  51. package/dist/components/chat/Popup.d.ts +7 -2
  52. package/dist/components/chat/Popup.js +310 -670
  53. package/dist/components/chat/Popup.js.map +1 -1
  54. package/dist/components/chat/Popup.mjs +14 -17
  55. package/dist/components/chat/Sidebar.d.ts +7 -2
  56. package/dist/components/chat/Sidebar.js +312 -672
  57. package/dist/components/chat/Sidebar.js.map +1 -1
  58. package/dist/components/chat/Sidebar.mjs +14 -17
  59. package/dist/components/chat/Suggestion.d.ts +2 -9
  60. package/dist/components/chat/Suggestion.js +6 -96
  61. package/dist/components/chat/Suggestion.js.map +1 -1
  62. package/dist/components/chat/Suggestion.mjs +3 -5
  63. package/dist/components/chat/Suggestions.d.ts +1 -1
  64. package/dist/components/chat/Suggestions.js +4 -3
  65. package/dist/components/chat/Suggestions.js.map +1 -1
  66. package/dist/components/chat/Suggestions.mjs +2 -2
  67. package/dist/components/chat/Window.d.ts +1 -1
  68. package/dist/components/chat/index.d.ts +8 -3
  69. package/dist/components/chat/index.js +316 -676
  70. package/dist/components/chat/index.js.map +1 -1
  71. package/dist/components/chat/index.mjs +18 -21
  72. package/dist/components/chat/messages/AssistantMessage.d.ts +1 -1
  73. package/dist/components/chat/messages/AssistantMessage.js +32 -24
  74. package/dist/components/chat/messages/AssistantMessage.js.map +1 -1
  75. package/dist/components/chat/messages/AssistantMessage.mjs +3 -3
  76. package/dist/components/chat/messages/ImageRenderer.d.ts +12 -0
  77. package/dist/components/chat/messages/ImageRenderer.js +58 -0
  78. package/dist/components/chat/messages/ImageRenderer.js.map +1 -0
  79. package/dist/components/chat/messages/ImageRenderer.mjs +8 -0
  80. package/dist/components/chat/messages/RenderMessage.d.ts +9 -0
  81. package/dist/components/chat/messages/{RenderTextMessage.js → RenderMessage.js} +92 -47
  82. package/dist/components/chat/messages/RenderMessage.js.map +1 -0
  83. package/dist/components/chat/messages/RenderMessage.mjs +16 -0
  84. package/dist/components/chat/messages/UserMessage.d.ts +1 -1
  85. package/dist/components/chat/messages/UserMessage.js +7 -1
  86. package/dist/components/chat/messages/UserMessage.js.map +1 -1
  87. package/dist/components/chat/messages/UserMessage.mjs +1 -1
  88. package/dist/components/chat/props.d.ts +32 -27
  89. package/dist/components/chat/props.js.map +1 -1
  90. package/dist/components/index.d.ts +8 -3
  91. package/dist/components/index.js +316 -676
  92. package/dist/components/index.js.map +1 -1
  93. package/dist/components/index.mjs +18 -21
  94. package/dist/hooks/use-push-to-talk.d.ts +1 -1
  95. package/dist/hooks/use-push-to-talk.js +3 -3
  96. package/dist/hooks/use-push-to-talk.js.map +1 -1
  97. package/dist/hooks/use-push-to-talk.mjs +1 -1
  98. package/dist/index.css +59 -3
  99. package/dist/index.css.map +1 -1
  100. package/dist/index.d.ts +8 -3
  101. package/dist/index.js +322 -682
  102. package/dist/index.js.map +1 -1
  103. package/dist/index.mjs +18 -21
  104. package/dist/types/css.d.ts +3 -0
  105. package/dist/types/css.js.map +1 -1
  106. package/package.json +4 -4
  107. package/src/components/chat/Chat.tsx +193 -105
  108. package/src/components/chat/CodeBlock.tsx +1 -1
  109. package/src/components/chat/Markdown.tsx +12 -2
  110. package/src/components/chat/Messages.tsx +43 -122
  111. package/src/components/chat/Suggestion.tsx +5 -108
  112. package/src/components/chat/Suggestions.tsx +0 -1
  113. package/src/components/chat/index.tsx +1 -1
  114. package/src/components/chat/messages/AssistantMessage.tsx +15 -23
  115. package/src/components/chat/messages/ImageRenderer.tsx +37 -0
  116. package/src/components/chat/messages/{RenderTextMessage.tsx → RenderMessage.tsx} +10 -9
  117. package/src/components/chat/messages/UserMessage.tsx +16 -5
  118. package/src/components/chat/props.ts +36 -28
  119. package/src/css/colors.css +10 -0
  120. package/src/css/markdown.css +8 -0
  121. package/src/css/messages.css +54 -5
  122. package/src/css/suggestions.css +1 -1
  123. package/src/hooks/use-push-to-talk.tsx +6 -5
  124. package/src/styles.css +1 -1
  125. package/src/types/css.ts +3 -0
  126. package/dist/chunk-2II3Q27P.mjs +0 -112
  127. package/dist/chunk-2II3Q27P.mjs.map +0 -1
  128. package/dist/chunk-32MUWKL3.mjs.map +0 -1
  129. package/dist/chunk-53CVDVS5.mjs +0 -127
  130. package/dist/chunk-53CVDVS5.mjs.map +0 -1
  131. package/dist/chunk-B3D7U7TJ.mjs +0 -211
  132. package/dist/chunk-B3D7U7TJ.mjs.map +0 -1
  133. package/dist/chunk-C7OB63U5.mjs +0 -36
  134. package/dist/chunk-C7OB63U5.mjs.map +0 -1
  135. package/dist/chunk-HKTWKCPS.mjs.map +0 -1
  136. package/dist/chunk-HWMFMBJC.mjs +0 -10
  137. package/dist/chunk-HWMFMBJC.mjs.map +0 -1
  138. package/dist/chunk-IMBPSLL4.mjs +0 -104
  139. package/dist/chunk-IMBPSLL4.mjs.map +0 -1
  140. package/dist/chunk-KENCH7RN.mjs.map +0 -1
  141. package/dist/chunk-L3GZ7TXC.mjs.map +0 -1
  142. package/dist/chunk-QGSPTXOV.mjs.map +0 -1
  143. package/dist/chunk-S5MBUNGN.mjs.map +0 -1
  144. package/dist/chunk-ULDQXCED.mjs +0 -78
  145. package/dist/chunk-ULDQXCED.mjs.map +0 -1
  146. package/dist/chunk-YTXEWDNC.mjs.map +0 -1
  147. package/dist/components/chat/messages/RenderActionExecutionMessage.d.ts +0 -9
  148. package/dist/components/chat/messages/RenderActionExecutionMessage.js +0 -869
  149. package/dist/components/chat/messages/RenderActionExecutionMessage.js.map +0 -1
  150. package/dist/components/chat/messages/RenderActionExecutionMessage.mjs +0 -14
  151. package/dist/components/chat/messages/RenderAgentStateMessage.d.ts +0 -9
  152. package/dist/components/chat/messages/RenderAgentStateMessage.js +0 -854
  153. package/dist/components/chat/messages/RenderAgentStateMessage.js.map +0 -1
  154. package/dist/components/chat/messages/RenderAgentStateMessage.mjs +0 -14
  155. package/dist/components/chat/messages/RenderImageMessage.d.ts +0 -9
  156. package/dist/components/chat/messages/RenderImageMessage.js +0 -823
  157. package/dist/components/chat/messages/RenderImageMessage.js.map +0 -1
  158. package/dist/components/chat/messages/RenderImageMessage.mjs +0 -15
  159. package/dist/components/chat/messages/RenderImageMessage.mjs.map +0 -1
  160. package/dist/components/chat/messages/RenderResultMessage.d.ts +0 -9
  161. package/dist/components/chat/messages/RenderResultMessage.js +0 -778
  162. package/dist/components/chat/messages/RenderResultMessage.js.map +0 -1
  163. package/dist/components/chat/messages/RenderResultMessage.mjs +0 -14
  164. package/dist/components/chat/messages/RenderResultMessage.mjs.map +0 -1
  165. package/dist/components/chat/messages/RenderTextMessage.d.ts +0 -9
  166. package/dist/components/chat/messages/RenderTextMessage.js.map +0 -1
  167. package/dist/components/chat/messages/RenderTextMessage.mjs +0 -15
  168. package/dist/components/chat/messages/RenderTextMessage.mjs.map +0 -1
  169. package/src/components/chat/messages/RenderActionExecutionMessage.tsx +0 -127
  170. package/src/components/chat/messages/RenderAgentStateMessage.tsx +0 -116
  171. package/src/components/chat/messages/RenderImageMessage.tsx +0 -64
  172. package/src/components/chat/messages/RenderResultMessage.tsx +0 -26
  173. /package/dist/{chunk-4HUXYD3B.mjs.map → chunk-DTRPPNSA.mjs.map} +0 -0
  174. /package/dist/{chunk-KN2GCKBE.mjs.map → chunk-GJ3MFNBX.mjs.map} +0 -0
  175. /package/dist/{chunk-H3EM63WS.mjs.map → chunk-VLNT34X3.mjs.map} +0 -0
  176. /package/dist/{chunk-ALIBUJML.mjs.map → chunk-WPVTPQ7X.mjs.map} +0 -0
  177. /package/dist/components/chat/messages/{RenderActionExecutionMessage.mjs.map → ImageRenderer.mjs.map} +0 -0
  178. /package/dist/components/chat/messages/{RenderAgentStateMessage.mjs.map → RenderMessage.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-ALIBUJML.mjs";
7
+ } from "./chunk-WPVTPQ7X.mjs";
8
8
  import "./chunk-WB3YULQ4.mjs";
9
9
  import {
10
10
  CopilotPopup
11
- } from "./chunk-H3EM63WS.mjs";
12
- import "./chunk-KN2GCKBE.mjs";
11
+ } from "./chunk-VLNT34X3.mjs";
12
+ import "./chunk-GJ3MFNBX.mjs";
13
13
  import "./chunk-C3GSYRC3.mjs";
14
14
  import "./chunk-GVKA7RQQ.mjs";
15
15
  import "./chunk-V7W6IM2V.mjs";
@@ -26,38 +26,35 @@ import "./chunk-BH6PCAAL.mjs";
26
26
  import "./chunk-UFN2VWSR.mjs";
27
27
  import {
28
28
  CopilotChat
29
- } from "./chunk-HKTWKCPS.mjs";
30
- import "./chunk-53CVDVS5.mjs";
31
- import "./chunk-2II3Q27P.mjs";
32
- import {
33
- RenderImageMessage
34
- } from "./chunk-ULDQXCED.mjs";
35
- import "./chunk-C7OB63U5.mjs";
36
- import "./chunk-32MUWKL3.mjs";
29
+ } from "./chunk-LXCD3K7B.mjs";
30
+ import "./chunk-JHUTTP5C.mjs";
37
31
  import {
38
32
  AssistantMessage
39
- } from "./chunk-L3GZ7TXC.mjs";
33
+ } from "./chunk-GCKKSSBU.mjs";
34
+ import {
35
+ ImageRenderer
36
+ } from "./chunk-DBKRAOH7.mjs";
40
37
  import {
41
38
  UserMessage
42
- } from "./chunk-HWMFMBJC.mjs";
39
+ } from "./chunk-VVL6JFCJ.mjs";
43
40
  import {
44
41
  Suggestions
45
- } from "./chunk-QGSPTXOV.mjs";
42
+ } from "./chunk-O7KTFUAN.mjs";
46
43
  import {
47
44
  Suggestion
48
- } from "./chunk-IMBPSLL4.mjs";
45
+ } from "./chunk-Q2467VHZ.mjs";
49
46
  import "./chunk-PLHTVHUW.mjs";
50
- import "./chunk-4HUXYD3B.mjs";
47
+ import "./chunk-DTRPPNSA.mjs";
51
48
  import "./chunk-CGEAG65D.mjs";
52
49
  import "./chunk-QIOJXTIQ.mjs";
53
50
  import {
54
51
  Markdown
55
- } from "./chunk-YTXEWDNC.mjs";
56
- import "./chunk-B3D7U7TJ.mjs";
52
+ } from "./chunk-E6MQUIZW.mjs";
53
+ import "./chunk-WHDNKXMP.mjs";
57
54
  import {
58
55
  useChatContext
59
56
  } from "./chunk-IEMQ2SQW.mjs";
60
- import "./chunk-KENCH7RN.mjs";
57
+ import "./chunk-B5IFB5YJ.mjs";
61
58
  import "./chunk-XWG3L6QC.mjs";
62
59
  import "./chunk-IU3WTXLQ.mjs";
63
60
  import "./chunk-T26KLXLH.mjs";
@@ -66,7 +63,7 @@ import {
66
63
  } from "./chunk-Z4XPPVZT.mjs";
67
64
  import "./chunk-54JAUBUJ.mjs";
68
65
  import "./chunk-JGMFJZMG.mjs";
69
- import "./chunk-S5MBUNGN.mjs";
66
+ import "./chunk-O72ZB5V3.mjs";
70
67
  import "./chunk-MRXNTQOX.mjs";
71
68
  export {
72
69
  AssistantMessage,
@@ -74,8 +71,8 @@ export {
74
71
  CopilotDevConsole,
75
72
  CopilotPopup,
76
73
  CopilotSidebar,
74
+ ImageRenderer,
77
75
  Markdown,
78
- RenderImageMessage,
79
76
  Suggestion as RenderSuggestion,
80
77
  Suggestions as RenderSuggestionsList,
81
78
  UserMessage,
@@ -9,6 +9,9 @@ interface CopilotKitCSSProperties extends CSSProperties {
9
9
  "--copilot-kit-secondary-contrast-color"?: string;
10
10
  "--copilot-kit-separator-color"?: string;
11
11
  "--copilot-kit-muted-color"?: string;
12
+ "--copilot-kit-error-background"?: string;
13
+ "--copilot-kit-error-border"?: string;
14
+ "--copilot-kit-error-text"?: string;
12
15
  "--copilot-kit-shadow-sm"?: string;
13
16
  "--copilot-kit-shadow-md"?: string;
14
17
  "--copilot-kit-shadow-lg"?: string;
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/types/css.ts"],"sourcesContent":["// autogenerated (see postcss.config.js) - do not edit\nimport { CSSProperties } from \"react\";\n\nexport interface CopilotKitCSSProperties extends CSSProperties {\n \"--copilot-kit-primary-color\"?: string;\n \"--copilot-kit-contrast-color\"?: string;\n \"--copilot-kit-background-color\"?: string;\n \"--copilot-kit-input-background-color\"?: string;\n \"--copilot-kit-secondary-color\"?: string;\n \"--copilot-kit-secondary-contrast-color\"?: string;\n \"--copilot-kit-separator-color\"?: string;\n \"--copilot-kit-muted-color\"?: string;\n \"--copilot-kit-shadow-sm\"?: string;\n \"--copilot-kit-shadow-md\"?: string;\n \"--copilot-kit-shadow-lg\"?: string;\n \"--copilot-kit-dev-console-bg\"?: string;\n \"--copilot-kit-dev-console-text\"?: string;\n}\n"],"mappings":";;;;;;;;;;;;;;;;AAAA;AAAA;","names":[]}
1
+ {"version":3,"sources":["../../src/types/css.ts"],"sourcesContent":["// autogenerated (see postcss.config.js) - do not edit\nimport { CSSProperties } from \"react\";\n\nexport interface CopilotKitCSSProperties extends CSSProperties {\n \"--copilot-kit-primary-color\"?: string;\n \"--copilot-kit-contrast-color\"?: string;\n \"--copilot-kit-background-color\"?: string;\n \"--copilot-kit-input-background-color\"?: string;\n \"--copilot-kit-secondary-color\"?: string;\n \"--copilot-kit-secondary-contrast-color\"?: string;\n \"--copilot-kit-separator-color\"?: string;\n \"--copilot-kit-muted-color\"?: string;\n \"--copilot-kit-error-background\"?: string;\n \"--copilot-kit-error-border\"?: string;\n \"--copilot-kit-error-text\"?: string;\n \"--copilot-kit-shadow-sm\"?: string;\n \"--copilot-kit-shadow-md\"?: string;\n \"--copilot-kit-shadow-lg\"?: string;\n \"--copilot-kit-dev-console-bg\"?: string;\n \"--copilot-kit-dev-console-text\"?: string;\n}\n"],"mappings":";;;;;;;;;;;;;;;;AAAA;AAAA;","names":[]}
package/package.json CHANGED
@@ -9,7 +9,7 @@
9
9
  "publishConfig": {
10
10
  "access": "public"
11
11
  },
12
- "version": "1.9.3",
12
+ "version": "1.10.0-next.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.9.3",
55
- "@copilotkit/runtime-client-gql": "1.9.3",
56
- "@copilotkit/shared": "1.9.3"
54
+ "@copilotkit/react-core": "1.10.0-next.0",
55
+ "@copilotkit/runtime-client-gql": "1.10.0-next.0",
56
+ "@copilotkit/shared": "1.10.0-next.0"
57
57
  },
58
58
  "keywords": [
59
59
  "copilotkit",
@@ -53,27 +53,24 @@ import {
53
53
  } from "./ChatContext";
54
54
  import { Messages as DefaultMessages } from "./Messages";
55
55
  import { Input as DefaultInput } from "./Input";
56
- import { RenderTextMessage as DefaultRenderTextMessage } from "./messages/RenderTextMessage";
57
- import { RenderActionExecutionMessage as DefaultRenderActionExecutionMessage } from "./messages/RenderActionExecutionMessage";
58
- import { RenderResultMessage as DefaultRenderResultMessage } from "./messages/RenderResultMessage";
59
- import { RenderAgentStateMessage as DefaultRenderAgentStateMessage } from "./messages/RenderAgentStateMessage";
60
- import { RenderImageMessage as DefaultRenderImageMessage } from "./messages/RenderImageMessage";
56
+ import { RenderMessage as DefaultRenderMessage } from "./messages/RenderMessage";
61
57
  import { AssistantMessage as DefaultAssistantMessage } from "./messages/AssistantMessage";
62
58
  import { UserMessage as DefaultUserMessage } from "./messages/UserMessage";
63
- import React, { useEffect, useRef, useState } from "react";
59
+ import { ImageRenderer as DefaultImageRenderer } from "./messages/ImageRenderer";
60
+ import React, { useEffect, useRef, useState, useCallback, useMemo } from "react";
64
61
  import {
65
62
  SystemMessageFunction,
66
63
  useCopilotChat,
67
64
  useCopilotContext,
68
65
  useCopilotMessagesContext,
69
66
  } from "@copilotkit/react-core";
70
- import { reloadSuggestions } from "./Suggestion";
71
- import { CopilotChatSuggestion } from "../../types/suggestions";
72
- import { Message, Role, TextMessage, ImageMessage } from "@copilotkit/runtime-client-gql";
67
+ import type { SuggestionItem } from "@copilotkit/react-core";
68
+ import { Message } from "@copilotkit/shared";
73
69
  import { randomId } from "@copilotkit/shared";
74
70
  import {
75
71
  AssistantMessageProps,
76
72
  ComponentsMap,
73
+ ImageRendererProps,
77
74
  InputProps,
78
75
  MessagesProps,
79
76
  RenderMessageProps,
@@ -85,6 +82,15 @@ import { HintFunction, runAgent, stopAgent } from "@copilotkit/react-core";
85
82
  import { ImageUploadQueue } from "./ImageUploadQueue";
86
83
  import { Suggestions as DefaultRenderSuggestionsList } from "./Suggestions";
87
84
 
85
+ /**
86
+ * The type of suggestions to use in the chat.
87
+ *
88
+ * `auto` - Suggestions are generated automatically.
89
+ * `manual` - Suggestions are controlled programmatically.
90
+ * `SuggestionItem[]` - Static suggestions array.
91
+ */
92
+ export type ChatSuggestions = "auto" | "manual" | SuggestionItem[];
93
+
88
94
  /**
89
95
  * Props for CopilotChat component.
90
96
  */
@@ -99,6 +105,25 @@ export interface CopilotChatProps {
99
105
  */
100
106
  instructions?: string;
101
107
 
108
+ /**
109
+ * Controls the behavior of suggestions in the chat interface.
110
+ *
111
+ * `auto` (default) - Suggestions are generated automatically:
112
+ * - When the chat is first opened (empty state)
113
+ * - After each message exchange completes
114
+ * - Uses configuration from `useCopilotChatSuggestions` hooks
115
+ *
116
+ * `manual` - Suggestions are controlled programmatically:
117
+ * - Use `setSuggestions()` to set custom suggestions
118
+ * - Use `generateSuggestions()` to trigger AI generation
119
+ * - Access via `useCopilotChat` hook
120
+ *
121
+ * `SuggestionItem[]` - Static suggestions array:
122
+ * - Always shows the same suggestions
123
+ * - No AI generation involved
124
+ */
125
+ suggestions?: ChatSuggestions;
126
+
102
127
  /**
103
128
  * A callback that gets called when the in progress state changes.
104
129
  */
@@ -132,12 +157,12 @@ export interface CopilotChatProps {
132
157
  /**
133
158
  * A callback function for thumbs up feedback
134
159
  */
135
- onThumbsUp?: (message: TextMessage) => void;
160
+ onThumbsUp?: (message: Message) => void;
136
161
 
137
162
  /**
138
163
  * A callback function for thumbs down feedback
139
164
  */
140
- onThumbsDown?: (message: TextMessage) => void;
165
+ onThumbsDown?: (message: Message) => void;
141
166
 
142
167
  /**
143
168
  * A list of markdown components to render in assistant message.
@@ -190,29 +215,14 @@ export interface CopilotChatProps {
190
215
  Messages?: React.ComponentType<MessagesProps>;
191
216
 
192
217
  /**
193
- * A custom RenderTextMessage component to use instead of the default.
194
- */
195
- RenderTextMessage?: React.ComponentType<RenderMessageProps>;
196
-
197
- /**
198
- * A custom RenderActionExecutionMessage component to use instead of the default.
199
- */
200
- RenderActionExecutionMessage?: React.ComponentType<RenderMessageProps>;
201
-
202
- /**
203
- * A custom RenderAgentStateMessage component to use instead of the default.
204
- */
205
- RenderAgentStateMessage?: React.ComponentType<RenderMessageProps>;
206
-
207
- /**
208
- * A custom RenderResultMessage component to use instead of the default.
209
- */
210
- RenderResultMessage?: React.ComponentType<RenderMessageProps>;
211
-
212
- /**
213
- * A custom RenderImageMessage component to use instead of the default.
218
+ * A custom RenderMessage component to use instead of the default.
219
+ *
220
+ * **Warning**: This is a break-glass solution to allow for custom
221
+ * rendering of messages. You are most likely looking to swap out
222
+ * the AssistantMessage and UserMessage components instead which
223
+ * are also props.
214
224
  */
215
- RenderImageMessage?: React.ComponentType<RenderMessageProps>;
225
+ RenderMessage?: React.ComponentType<RenderMessageProps>;
216
226
 
217
227
  /**
218
228
  * A custom suggestions list component to use instead of the default.
@@ -224,6 +234,11 @@ export interface CopilotChatProps {
224
234
  */
225
235
  Input?: React.ComponentType<InputProps>;
226
236
 
237
+ /**
238
+ * A custom image rendering component to use instead of the default.
239
+ */
240
+ ImageRenderer?: React.ComponentType<ImageRendererProps>;
241
+
227
242
  /**
228
243
  * A class name to apply to the root element.
229
244
  */
@@ -297,6 +312,7 @@ export type ImageUpload = {
297
312
 
298
313
  export function CopilotChat({
299
314
  instructions,
315
+ suggestions = "auto",
300
316
  onSubmitMessage,
301
317
  makeSystemMessage,
302
318
  onInProgress,
@@ -308,11 +324,7 @@ export function CopilotChat({
308
324
  onThumbsDown,
309
325
  markdownTagRenderers,
310
326
  Messages = DefaultMessages,
311
- RenderTextMessage = DefaultRenderTextMessage,
312
- RenderActionExecutionMessage = DefaultRenderActionExecutionMessage,
313
- RenderAgentStateMessage = DefaultRenderAgentStateMessage,
314
- RenderResultMessage = DefaultRenderResultMessage,
315
- RenderImageMessage = DefaultRenderImageMessage,
327
+ RenderMessage = DefaultRenderMessage,
316
328
  RenderSuggestionsList = DefaultRenderSuggestionsList,
317
329
  Input = DefaultInput,
318
330
  className,
@@ -320,6 +332,7 @@ export function CopilotChat({
320
332
  labels,
321
333
  AssistantMessage = DefaultAssistantMessage,
322
334
  UserMessage = DefaultUserMessage,
335
+ ImageRenderer = DefaultImageRenderer,
323
336
  imageUploadsEnabled,
324
337
  inputFileAccept = "image/*",
325
338
  hideStopButton,
@@ -398,19 +411,18 @@ export function CopilotChat({
398
411
  ...additionalInstructions.map((instruction) => `- ${instruction}`),
399
412
  ];
400
413
 
401
- console.log("combinedAdditionalInstructions", combinedAdditionalInstructions);
402
-
403
414
  setChatInstructions(combinedAdditionalInstructions.join("\n") || "");
404
415
  }, [instructions, additionalInstructions]);
405
416
 
406
417
  const {
407
418
  visibleMessages,
408
419
  isLoading,
409
- currentSuggestions,
410
420
  sendMessage,
411
421
  stopGeneration,
412
422
  reloadMessages,
423
+ suggestions: currentSuggestions,
413
424
  } = useCopilotChatLogic(
425
+ suggestions,
414
426
  makeSystemMessage,
415
427
  onInProgress,
416
428
  onSubmitMessage,
@@ -489,11 +501,7 @@ export function CopilotChat({
489
501
  <Messages
490
502
  AssistantMessage={AssistantMessage}
491
503
  UserMessage={UserMessage}
492
- RenderTextMessage={RenderTextMessage}
493
- RenderActionExecutionMessage={RenderActionExecutionMessage}
494
- RenderAgentStateMessage={RenderAgentStateMessage}
495
- RenderResultMessage={RenderResultMessage}
496
- RenderImageMessage={RenderImageMessage}
504
+ RenderMessage={RenderMessage}
497
505
  messages={visibleMessages}
498
506
  inProgress={isLoading}
499
507
  onRegenerate={handleRegenerate}
@@ -501,6 +509,7 @@ export function CopilotChat({
501
509
  onThumbsUp={onThumbsUp}
502
510
  onThumbsDown={onThumbsDown}
503
511
  markdownTagRenderers={markdownTagRenderers}
512
+ ImageRenderer={ImageRenderer}
504
513
  >
505
514
  {currentSuggestions.length > 0 && (
506
515
  <RenderSuggestionsList
@@ -523,7 +532,6 @@ export function CopilotChat({
523
532
  />
524
533
  </>
525
534
  )}
526
-
527
535
  <Input
528
536
  inProgress={isLoading}
529
537
  onSend={handleSendMessage}
@@ -558,9 +566,8 @@ export function WrappedCopilotChat({
558
566
  return <>{children}</>;
559
567
  }
560
568
 
561
- const SUGGESTIONS_DEBOUNCE_TIMEOUT = 1000;
562
-
563
569
  export const useCopilotChatLogic = (
570
+ chatSuggestions: ChatSuggestions,
564
571
  makeSystemMessage?: SystemMessageFunction,
565
572
  onInProgress?: (isLoading: boolean) => void,
566
573
  onSubmitMessage?: (messageContent: string) => Promise<void> | void,
@@ -570,88 +577,160 @@ export const useCopilotChatLogic = (
570
577
  const {
571
578
  visibleMessages,
572
579
  appendMessage,
580
+ setMessages,
573
581
  reloadMessages: defaultReloadMessages,
574
582
  stopGeneration: defaultStopGeneration,
575
583
  runChatCompletion,
576
584
  isLoading,
585
+ suggestions,
586
+ setSuggestions,
587
+ generateSuggestions,
588
+ resetSuggestions: resetSuggestionsFromHook,
589
+ isLoadingSuggestions,
577
590
  } = useCopilotChat({
578
- id: randomId(),
579
591
  makeSystemMessage,
580
592
  });
581
593
 
582
- const [currentSuggestions, setCurrentSuggestions] = useState<CopilotChatSuggestion[]>([]);
583
- const suggestionsAbortControllerRef = useRef<AbortController | null>(null);
584
- const debounceTimerRef = useRef<any>();
585
-
586
- const abortSuggestions = () => {
587
- suggestionsAbortControllerRef.current?.abort();
588
- suggestionsAbortControllerRef.current = null;
589
- };
590
-
591
594
  const generalContext = useCopilotContext();
592
595
  const messagesContext = useCopilotMessagesContext();
593
- const context = { ...generalContext, ...messagesContext };
594
596
 
597
+ // Get actions from context for message conversion
598
+ const { actions } = generalContext;
599
+
600
+ // Suggestion state management
601
+ const [suggestionsFailed, setSuggestionsFailed] = useState(false);
602
+ const hasGeneratedInitialSuggestions = useRef<boolean>(false);
603
+
604
+ // Handle static suggestions (when suggestions prop is an array)
595
605
  useEffect(() => {
596
- onInProgress?.(isLoading);
606
+ if (Array.isArray(chatSuggestions)) {
607
+ setSuggestions(chatSuggestions);
608
+ hasGeneratedInitialSuggestions.current = true;
609
+ }
610
+ }, [JSON.stringify(chatSuggestions), setSuggestions]);
597
611
 
598
- abortSuggestions();
599
-
600
- debounceTimerRef.current = setTimeout(
601
- () => {
602
- if (!isLoading && Object.keys(context.chatSuggestionConfiguration).length !== 0) {
603
- suggestionsAbortControllerRef.current = new AbortController();
604
- reloadSuggestions(
605
- context,
606
- context.chatSuggestionConfiguration,
607
- setCurrentSuggestions,
608
- suggestionsAbortControllerRef,
609
- );
610
- }
611
- },
612
- currentSuggestions.length == 0 ? 0 : SUGGESTIONS_DEBOUNCE_TIMEOUT,
613
- );
612
+ // Error handling wrapper
613
+ const generateSuggestionsWithErrorHandling = useCallback(
614
+ async (context: string) => {
615
+ try {
616
+ await generateSuggestions();
617
+ } catch (error) {
618
+ console.error("Failed to generate suggestions:", error);
619
+ setSuggestionsFailed(true);
620
+ }
621
+ },
622
+ [generateSuggestions],
623
+ );
614
624
 
615
- return () => {
616
- clearTimeout(debounceTimerRef.current);
617
- };
625
+ // Automatic suggestion generation logic
626
+ useEffect(() => {
627
+ // Only proceed if in auto mode, not currently loading, and not failed
628
+ if (chatSuggestions !== "auto" || isLoadingSuggestions || suggestionsFailed) {
629
+ return;
630
+ }
631
+
632
+ // Don't run during chat loading (when the assistant is responding)
633
+ if (isLoading) {
634
+ return;
635
+ }
636
+
637
+ // Check if we have any configurations
638
+ if (Object.keys(generalContext.chatSuggestionConfiguration).length === 0) {
639
+ return;
640
+ }
641
+
642
+ // Generate initial suggestions when chat is empty
643
+ if (visibleMessages.length === 0 && !hasGeneratedInitialSuggestions.current) {
644
+ hasGeneratedInitialSuggestions.current = true;
645
+ generateSuggestionsWithErrorHandling("initial");
646
+ return;
647
+ }
648
+
649
+ // Generate post-message suggestions after assistant responds
650
+ if (visibleMessages.length > 0 && suggestions.length === 0) {
651
+ generateSuggestionsWithErrorHandling("post-message");
652
+ return;
653
+ }
618
654
  }, [
655
+ chatSuggestions,
656
+ isLoadingSuggestions,
657
+ suggestionsFailed,
658
+ visibleMessages.length,
619
659
  isLoading,
620
- context.chatSuggestionConfiguration,
621
- // hackish way to trigger suggestions reload on reset, but better than moving suggestions to the
622
- // global context
623
- visibleMessages.length == 0,
660
+ suggestions.length,
661
+ Object.keys(generalContext.chatSuggestionConfiguration).join(","), // Use stable string instead of object reference
662
+ generateSuggestionsWithErrorHandling,
624
663
  ]);
625
664
 
665
+ // Reset suggestion state when switching away from auto mode
666
+ useEffect(() => {
667
+ if (chatSuggestions !== "auto") {
668
+ hasGeneratedInitialSuggestions.current = false;
669
+ setSuggestionsFailed(false);
670
+ }
671
+ }, [chatSuggestions]);
672
+
673
+ // Memoize context to prevent infinite re-renders
674
+ const stableContext = useMemo(
675
+ () => ({
676
+ ...generalContext,
677
+ ...messagesContext,
678
+ }),
679
+ [
680
+ // Only include stable dependencies
681
+ generalContext.actions,
682
+ messagesContext.messages.length,
683
+ generalContext.isLoading,
684
+ ],
685
+ );
686
+
687
+ // Wrapper for resetSuggestions that also resets local state
688
+ const resetSuggestions = useCallback(() => {
689
+ resetSuggestionsFromHook();
690
+ setSuggestionsFailed(false);
691
+ hasGeneratedInitialSuggestions.current = false;
692
+ }, [resetSuggestionsFromHook]);
693
+
694
+ useEffect(() => {
695
+ onInProgress?.(isLoading);
696
+ }, [onInProgress, isLoading]);
697
+
626
698
  const sendMessage = async (
627
699
  messageContent: string,
628
700
  imagesToUse?: Array<{ contentType: string; bytes: string }>,
629
701
  ) => {
630
- // Use images passed in the call OR the ones from the state (passed via props)
631
702
  const images = imagesToUse || [];
632
703
 
633
- abortSuggestions();
634
- setCurrentSuggestions([]);
704
+ // Clear existing suggestions when user sends a message
705
+ // This prevents stale suggestions from remaining visible during new conversation flow
706
+ if (chatSuggestions === "auto" || chatSuggestions === "manual") {
707
+ setSuggestions([]);
708
+ }
635
709
 
636
710
  let firstMessage: Message | null = null;
637
711
 
638
- // If there's text content, send a text message first
712
+ // Send text message if content provided
639
713
  if (messageContent.trim().length > 0) {
640
- const textMessage = new TextMessage({
714
+ const textMessage: Message = {
715
+ id: randomId(),
716
+ role: "user",
641
717
  content: messageContent,
642
- role: Role.User,
643
- });
718
+ };
644
719
 
720
+ // Call user-provided submit handler if available
645
721
  if (onSubmitMessage) {
646
722
  try {
647
- // Call onSubmitMessage only with text, as image handling is internal right now
648
723
  await onSubmitMessage(messageContent);
649
724
  } catch (error) {
650
725
  console.error("Error in onSubmitMessage:", error);
651
726
  }
652
727
  }
653
728
 
654
- await appendMessage(textMessage, { followUp: images.length === 0 });
729
+ // Send the message and clear suggestions for auto/manual modes
730
+ await appendMessage(textMessage, {
731
+ followUp: images.length === 0,
732
+ clearSuggestions: chatSuggestions === "auto" || chatSuggestions === "manual",
733
+ });
655
734
 
656
735
  if (!firstMessage) {
657
736
  firstMessage = textMessage;
@@ -661,11 +740,14 @@ export const useCopilotChatLogic = (
661
740
  // Send image messages
662
741
  if (images.length > 0) {
663
742
  for (let i = 0; i < images.length; i++) {
664
- const imageMessage = new ImageMessage({
665
- format: images[i].contentType.replace("image/", ""),
666
- bytes: images[i].bytes,
667
- role: Role.User,
668
- });
743
+ const imageMessage = {
744
+ id: randomId(),
745
+ role: "user" as const,
746
+ image: {
747
+ format: images[i].contentType.replace("image/", ""),
748
+ bytes: images[i].bytes,
749
+ },
750
+ } as unknown as Message;
669
751
  await appendMessage(imageMessage, { followUp: i === images.length - 1 });
670
752
  if (!firstMessage) {
671
753
  firstMessage = imageMessage;
@@ -675,7 +757,7 @@ export const useCopilotChatLogic = (
675
757
 
676
758
  if (!firstMessage) {
677
759
  // Should not happen if send button is properly disabled, but handle just in case
678
- return new TextMessage({ content: "", role: Role.User }); // Return a dummy message
760
+ return { role: "user", content: "", id: randomId() } as Message; // Return a dummy message
679
761
  }
680
762
 
681
763
  // The hook implicitly triggers API call on appendMessage.
@@ -684,7 +766,6 @@ export const useCopilotChatLogic = (
684
766
  };
685
767
 
686
768
  const messages = visibleMessages;
687
- const { setMessages } = messagesContext;
688
769
  const currentAgentName = generalContext.agentSession?.agentName;
689
770
  const restartCurrentAgent = async (hint?: HintFunction) => {
690
771
  if (generalContext.agentSession) {
@@ -710,7 +791,7 @@ export const useCopilotChatLogic = (
710
791
  if (generalContext.agentSession) {
711
792
  await runAgent(
712
793
  generalContext.agentSession.agentName,
713
- context,
794
+ stableContext,
714
795
  appendMessage,
715
796
  runChatCompletion,
716
797
  hint,
@@ -719,7 +800,7 @@ export const useCopilotChatLogic = (
719
800
  };
720
801
  const stopCurrentAgent = () => {
721
802
  if (generalContext.agentSession) {
722
- stopAgent(generalContext.agentSession.agentName, context);
803
+ stopAgent(generalContext.agentSession.agentName, stableContext);
723
804
  }
724
805
  };
725
806
  const setCurrentAgentState = (state: any) => {
@@ -736,9 +817,12 @@ export const useCopilotChatLogic = (
736
817
  };
737
818
 
738
819
  function stopGeneration() {
820
+ // Clear suggestions when stopping generation
821
+ setSuggestions([]);
822
+
739
823
  if (onStopGeneration) {
740
824
  onStopGeneration({
741
- messages,
825
+ messages: messages,
742
826
  setMessages,
743
827
  stopGeneration: defaultStopGeneration,
744
828
  currentAgentName,
@@ -754,7 +838,7 @@ export const useCopilotChatLogic = (
754
838
  function reloadMessages(messageId: string) {
755
839
  if (onReloadMessages) {
756
840
  onReloadMessages({
757
- messages,
841
+ messages: messages,
758
842
  setMessages,
759
843
  stopGeneration: defaultStopGeneration,
760
844
  currentAgentName,
@@ -770,11 +854,15 @@ export const useCopilotChatLogic = (
770
854
  }
771
855
 
772
856
  return {
857
+ messages,
773
858
  visibleMessages,
774
859
  isLoading,
775
- currentSuggestions,
860
+ suggestions,
776
861
  sendMessage,
777
862
  stopGeneration,
778
863
  reloadMessages,
864
+ resetSuggestions,
865
+ context: stableContext,
866
+ actions,
779
867
  };
780
868
  };
@@ -62,7 +62,7 @@ const CodeBlock: FC<Props> = memo(({ language, value }) => {
62
62
  }
63
63
  const fileExtension = programmingLanguages[language] || ".file";
64
64
  const suggestedFileName = `file-${generateRandomString(3, true)}${fileExtension}`;
65
- const fileName = window.prompt("Enter file name" || "", suggestedFileName);
65
+ const fileName = window.prompt("Enter file name", suggestedFileName);
66
66
 
67
67
  if (!fileName) {
68
68
  // User pressed cancel on prompt.
@@ -34,9 +34,19 @@ const defaultComponents: Components = {
34
34
 
35
35
  const match = /language-(\w+)/.exec(className || "");
36
36
 
37
- if (inline) {
37
+ // Detect inline code: if it has a language class or contains newlines, it's likely a code block
38
+ // Otherwise, treat it as inline code
39
+ const hasLanguage = match && match[1];
40
+ const content = String(children);
41
+ const hasNewlines = content.includes("\n");
42
+ const isInline = !hasLanguage && !hasNewlines;
43
+
44
+ if (isInline) {
38
45
  return (
39
- <code className={className} {...props}>
46
+ <code
47
+ className={`copilotKitMarkdownElement copilotKitInlineCode ${className || ""}`}
48
+ {...props}
49
+ >
40
50
  {children}
41
51
  </code>
42
52
  );