@copilotkit/react-core 1.9.1-next.0 → 1.9.2-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 (180) hide show
  1. package/CHANGELOG.md +17 -0
  2. package/dist/{chunk-B5UA5G3E.mjs → chunk-2FW7HH6W.mjs} +12 -8
  3. package/dist/chunk-2FW7HH6W.mjs.map +1 -0
  4. package/dist/{chunk-ERFA53MG.mjs → chunk-6KGEF242.mjs} +2 -2
  5. package/dist/chunk-6KGEF242.mjs.map +1 -0
  6. package/dist/{chunk-2J3SMMGW.mjs → chunk-C6F6EQNA.mjs} +2 -2
  7. package/dist/chunk-CCESTGAM.mjs +102 -0
  8. package/dist/chunk-CCESTGAM.mjs.map +1 -0
  9. package/dist/chunk-GFJW4RIM.mjs +9 -0
  10. package/dist/chunk-GFJW4RIM.mjs.map +1 -0
  11. package/dist/chunk-HD2GE3DK.mjs +359 -0
  12. package/dist/chunk-HD2GE3DK.mjs.map +1 -0
  13. package/dist/{chunk-74AJEJTV.mjs → chunk-HJP2RX5R.mjs} +11 -6
  14. package/dist/chunk-HJP2RX5R.mjs.map +1 -0
  15. package/dist/{chunk-EQ4XLLT4.mjs → chunk-LDACFA2B.mjs} +3 -3
  16. package/dist/{chunk-FGBRHBRR.mjs → chunk-LZDDYZEY.mjs} +2 -2
  17. package/dist/chunk-NNSXCFQO.mjs +154 -0
  18. package/dist/chunk-NNSXCFQO.mjs.map +1 -0
  19. package/dist/{chunk-WZAEVHLK.mjs → chunk-Q5D5XQFA.mjs} +2 -2
  20. package/dist/{chunk-534J55RX.mjs → chunk-QQZLIEXK.mjs} +9 -7
  21. package/dist/chunk-QQZLIEXK.mjs.map +1 -0
  22. package/dist/chunk-RUY6MLHA.mjs +119 -0
  23. package/dist/chunk-RUY6MLHA.mjs.map +1 -0
  24. package/dist/{chunk-MDIIRGJD.mjs → chunk-SGLWMQ2J.mjs} +25 -17
  25. package/dist/chunk-SGLWMQ2J.mjs.map +1 -0
  26. package/dist/{chunk-G27C5EFO.mjs → chunk-T42PN5VN.mjs} +7 -5
  27. package/dist/{chunk-G27C5EFO.mjs.map → chunk-T42PN5VN.mjs.map} +1 -1
  28. package/dist/{chunk-VQ3VTO26.mjs → chunk-UHQMV2CE.mjs} +2 -2
  29. package/dist/{chunk-4DVPRMVH.mjs → chunk-UIT6QMUJ.mjs} +7 -7
  30. package/dist/chunk-VRXANACV.mjs +277 -0
  31. package/dist/chunk-VRXANACV.mjs.map +1 -0
  32. package/dist/{chunk-2FLZLANO.mjs → chunk-XY5BN4HZ.mjs} +19 -12
  33. package/dist/chunk-XY5BN4HZ.mjs.map +1 -0
  34. package/dist/{chunk-7HDYPEWS.mjs → chunk-YDENFEKA.mjs} +2 -2
  35. package/dist/{chunk-4VWM6JNK.mjs → chunk-YZDRMIOM.mjs} +6 -6
  36. package/dist/components/copilot-provider/copilot-messages.js +105 -11
  37. package/dist/components/copilot-provider/copilot-messages.js.map +1 -1
  38. package/dist/components/copilot-provider/copilot-messages.mjs +4 -2
  39. package/dist/components/copilot-provider/copilotkit-props.d.ts +4 -3
  40. package/dist/components/copilot-provider/copilotkit-props.js.map +1 -1
  41. package/dist/components/copilot-provider/copilotkit.d.ts +1 -1
  42. package/dist/components/copilot-provider/copilotkit.js +863 -441
  43. package/dist/components/copilot-provider/copilotkit.js.map +1 -1
  44. package/dist/components/copilot-provider/copilotkit.mjs +10 -9
  45. package/dist/components/copilot-provider/index.d.ts +1 -1
  46. package/dist/components/copilot-provider/index.js +863 -441
  47. package/dist/components/copilot-provider/index.js.map +1 -1
  48. package/dist/components/copilot-provider/index.mjs +10 -9
  49. package/dist/components/error-boundary/error-boundary.js +320 -159
  50. package/dist/components/error-boundary/error-boundary.js.map +1 -1
  51. package/dist/components/error-boundary/error-boundary.mjs +4 -3
  52. package/dist/components/error-boundary/error-utils.js +2 -1
  53. package/dist/components/error-boundary/error-utils.js.map +1 -1
  54. package/dist/components/error-boundary/error-utils.mjs +2 -1
  55. package/dist/components/index.d.ts +1 -1
  56. package/dist/components/index.js +863 -441
  57. package/dist/components/index.js.map +1 -1
  58. package/dist/components/index.mjs +10 -9
  59. package/dist/components/toast/toast-provider.d.ts +9 -12
  60. package/dist/components/toast/toast-provider.js +218 -191
  61. package/dist/components/toast/toast-provider.js.map +1 -1
  62. package/dist/components/toast/toast-provider.mjs +1 -2
  63. package/dist/components/usage-banner.d.ts +3 -2
  64. package/dist/components/usage-banner.js +311 -153
  65. package/dist/components/usage-banner.js.map +1 -1
  66. package/dist/components/usage-banner.mjs +1 -1
  67. package/dist/context/copilot-context.d.ts +1 -1
  68. package/dist/context/copilot-context.js +1 -1
  69. package/dist/context/copilot-context.js.map +1 -1
  70. package/dist/context/copilot-context.mjs +1 -1
  71. package/dist/context/index.d.ts +1 -1
  72. package/dist/context/index.js +1 -1
  73. package/dist/context/index.js.map +1 -1
  74. package/dist/context/index.mjs +1 -1
  75. package/dist/{copilot-context-309906bb.d.ts → copilot-context-f9b2b4c3.d.ts} +1 -1
  76. package/dist/hooks/index.d.ts +1 -1
  77. package/dist/hooks/index.js +160 -75
  78. package/dist/hooks/index.js.map +1 -1
  79. package/dist/hooks/index.mjs +33 -32
  80. package/dist/hooks/use-chat.d.ts +1 -1
  81. package/dist/hooks/use-chat.js +243 -68
  82. package/dist/hooks/use-chat.js.map +1 -1
  83. package/dist/hooks/use-chat.mjs +6 -3
  84. package/dist/hooks/use-coagent-state-render.js +10 -5
  85. package/dist/hooks/use-coagent-state-render.js.map +1 -1
  86. package/dist/hooks/use-coagent-state-render.mjs +3 -4
  87. package/dist/hooks/use-coagent.d.ts +1 -1
  88. package/dist/hooks/use-coagent.js +148 -67
  89. package/dist/hooks/use-coagent.js.map +1 -1
  90. package/dist/hooks/use-coagent.mjs +14 -13
  91. package/dist/hooks/use-copilot-action.js +5 -4
  92. package/dist/hooks/use-copilot-action.js.map +1 -1
  93. package/dist/hooks/use-copilot-action.mjs +4 -3
  94. package/dist/hooks/use-copilot-additional-instructions.js +1 -1
  95. package/dist/hooks/use-copilot-additional-instructions.js.map +1 -1
  96. package/dist/hooks/use-copilot-additional-instructions.mjs +2 -2
  97. package/dist/hooks/use-copilot-authenticated-action.js +5 -4
  98. package/dist/hooks/use-copilot-authenticated-action.js.map +1 -1
  99. package/dist/hooks/use-copilot-authenticated-action.mjs +5 -4
  100. package/dist/hooks/use-copilot-chat.d.ts +1 -1
  101. package/dist/hooks/use-copilot-chat.js +138 -62
  102. package/dist/hooks/use-copilot-chat.js.map +1 -1
  103. package/dist/hooks/use-copilot-chat.mjs +13 -12
  104. package/dist/hooks/use-copilot-readable.js +1 -1
  105. package/dist/hooks/use-copilot-readable.js.map +1 -1
  106. package/dist/hooks/use-copilot-readable.mjs +2 -2
  107. package/dist/hooks/use-copilot-runtime-client.d.ts +5 -2
  108. package/dist/hooks/use-copilot-runtime-client.js +101 -128
  109. package/dist/hooks/use-copilot-runtime-client.js.map +1 -1
  110. package/dist/hooks/use-copilot-runtime-client.mjs +3 -3
  111. package/dist/hooks/use-langgraph-interrupt-render.js +1 -1
  112. package/dist/hooks/use-langgraph-interrupt-render.js.map +1 -1
  113. package/dist/hooks/use-langgraph-interrupt-render.mjs +2 -2
  114. package/dist/hooks/use-langgraph-interrupt.d.ts +1 -1
  115. package/dist/hooks/use-langgraph-interrupt.js +140 -64
  116. package/dist/hooks/use-langgraph-interrupt.js.map +1 -1
  117. package/dist/hooks/use-langgraph-interrupt.mjs +14 -13
  118. package/dist/hooks/use-make-copilot-document-readable.js +1 -1
  119. package/dist/hooks/use-make-copilot-document-readable.js.map +1 -1
  120. package/dist/hooks/use-make-copilot-document-readable.mjs +2 -2
  121. package/dist/index.d.ts +1 -1
  122. package/dist/index.js +913 -480
  123. package/dist/index.js.map +1 -1
  124. package/dist/index.mjs +35 -34
  125. package/dist/lib/copilot-task.d.ts +1 -1
  126. package/dist/lib/copilot-task.js.map +1 -1
  127. package/dist/lib/copilot-task.mjs +11 -10
  128. package/dist/lib/index.d.ts +1 -1
  129. package/dist/lib/index.js.map +1 -1
  130. package/dist/lib/index.mjs +11 -10
  131. package/dist/types/interrupt-action.d.ts +1 -1
  132. package/dist/utils/dev-console.d.ts +1 -1
  133. package/dist/utils/dev-console.js +1 -10
  134. package/dist/utils/dev-console.js.map +1 -1
  135. package/dist/utils/dev-console.mjs +1 -1
  136. package/dist/utils/extract.d.ts +1 -1
  137. package/dist/utils/extract.js.map +1 -1
  138. package/dist/utils/extract.mjs +10 -9
  139. package/dist/utils/index.d.ts +1 -1
  140. package/dist/utils/index.js +7 -14
  141. package/dist/utils/index.js.map +1 -1
  142. package/dist/utils/index.mjs +12 -11
  143. package/package.json +3 -3
  144. package/src/components/copilot-provider/copilot-messages.tsx +163 -4
  145. package/src/components/copilot-provider/copilotkit-props.tsx +3 -2
  146. package/src/components/copilot-provider/copilotkit.tsx +8 -2
  147. package/src/components/error-boundary/error-boundary.tsx +6 -5
  148. package/src/components/error-boundary/error-utils.tsx +1 -1
  149. package/src/components/toast/toast-provider.tsx +260 -93
  150. package/src/components/usage-banner.tsx +311 -131
  151. package/src/context/copilot-context.tsx +2 -2
  152. package/src/hooks/use-chat.ts +4 -0
  153. package/src/hooks/use-coagent-state-render.ts +9 -3
  154. package/src/hooks/use-coagent.ts +10 -3
  155. package/src/hooks/use-copilot-runtime-client.ts +153 -12
  156. package/src/utils/dev-console.ts +2 -17
  157. package/dist/chunk-22ENANUU.mjs +0 -250
  158. package/dist/chunk-22ENANUU.mjs.map +0 -1
  159. package/dist/chunk-2FLZLANO.mjs.map +0 -1
  160. package/dist/chunk-534J55RX.mjs.map +0 -1
  161. package/dist/chunk-6PK72HMH.mjs +0 -63
  162. package/dist/chunk-6PK72HMH.mjs.map +0 -1
  163. package/dist/chunk-74AJEJTV.mjs.map +0 -1
  164. package/dist/chunk-B5UA5G3E.mjs.map +0 -1
  165. package/dist/chunk-BKTARDXX.mjs +0 -40
  166. package/dist/chunk-BKTARDXX.mjs.map +0 -1
  167. package/dist/chunk-D34OH4VN.mjs +0 -201
  168. package/dist/chunk-D34OH4VN.mjs.map +0 -1
  169. package/dist/chunk-ERFA53MG.mjs.map +0 -1
  170. package/dist/chunk-MDIIRGJD.mjs.map +0 -1
  171. package/dist/chunk-MLAS4QUR.mjs +0 -18
  172. package/dist/chunk-MLAS4QUR.mjs.map +0 -1
  173. /package/dist/{chunk-2J3SMMGW.mjs.map → chunk-C6F6EQNA.mjs.map} +0 -0
  174. /package/dist/{chunk-EQ4XLLT4.mjs.map → chunk-LDACFA2B.mjs.map} +0 -0
  175. /package/dist/{chunk-FGBRHBRR.mjs.map → chunk-LZDDYZEY.mjs.map} +0 -0
  176. /package/dist/{chunk-WZAEVHLK.mjs.map → chunk-Q5D5XQFA.mjs.map} +0 -0
  177. /package/dist/{chunk-VQ3VTO26.mjs.map → chunk-UHQMV2CE.mjs.map} +0 -0
  178. /package/dist/{chunk-4DVPRMVH.mjs.map → chunk-UIT6QMUJ.mjs.map} +0 -0
  179. /package/dist/{chunk-7HDYPEWS.mjs.map → chunk-YDENFEKA.mjs.map} +0 -0
  180. /package/dist/{chunk-4VWM6JNK.mjs.map → chunk-YZDRMIOM.mjs.map} +0 -0
@@ -1,9 +1,10 @@
1
- import { Severity, CopilotKitError, ERROR_NAMES } from "@copilotkit/shared";
1
+ import { Severity, CopilotKitError, ERROR_NAMES, ErrorVisibility } from "@copilotkit/shared";
2
2
 
3
3
  interface UsageBannerProps {
4
4
  severity?: Severity;
5
5
  message?: string;
6
6
  icon?: React.ReactNode;
7
+ onClose?: () => void;
7
8
  actions?: {
8
9
  primary?: {
9
10
  label: string;
@@ -17,13 +18,13 @@ interface UsageBannerProps {
17
18
  }
18
19
 
19
20
  const defaultIcons: Record<Severity, JSX.Element> = {
20
- [Severity.Error]: (
21
+ [Severity.CRITICAL]: (
21
22
  <svg
22
23
  viewBox="0 0 24 24"
23
- width="20"
24
- height="20"
24
+ width="18"
25
+ height="18"
25
26
  stroke="currentColor"
26
- strokeWidth="2"
27
+ strokeWidth="2.5"
27
28
  fill="none"
28
29
  strokeLinecap="round"
29
30
  strokeLinejoin="round"
@@ -33,133 +34,286 @@ const defaultIcons: Record<Severity, JSX.Element> = {
33
34
  <line x1="9" y1="9" x2="15" y2="15" />
34
35
  </svg>
35
36
  ),
37
+ [Severity.WARNING]: (
38
+ <svg
39
+ viewBox="0 0 24 24"
40
+ width="18"
41
+ height="18"
42
+ stroke="currentColor"
43
+ strokeWidth="2.5"
44
+ fill="none"
45
+ strokeLinecap="round"
46
+ strokeLinejoin="round"
47
+ >
48
+ <path d="m21.73 18-8-14a2 2 0 0 0-3.48 0l-8 14A2 2 0 0 0 4 21h16a2 2 0 0 0 1.73-3Z" />
49
+ <line x1="12" y1="9" x2="12" y2="13" />
50
+ <line x1="12" y1="17" x2="12.01" y2="17" />
51
+ </svg>
52
+ ),
53
+ [Severity.INFO]: (
54
+ <svg
55
+ viewBox="0 0 24 24"
56
+ width="18"
57
+ height="18"
58
+ stroke="currentColor"
59
+ strokeWidth="2.5"
60
+ fill="none"
61
+ strokeLinecap="round"
62
+ strokeLinejoin="round"
63
+ >
64
+ <circle cx="12" cy="12" r="10" />
65
+ <line x1="12" y1="16" x2="12" y2="12" />
66
+ <line x1="12" y1="8" x2="12.01" y2="8" />
67
+ </svg>
68
+ ),
36
69
  };
37
70
 
38
71
  export function UsageBanner({
39
- severity = Severity.Error,
72
+ severity = Severity.CRITICAL,
40
73
  message = "",
41
74
  icon,
75
+ onClose,
42
76
  actions,
43
77
  }: UsageBannerProps) {
44
78
  if (!message || !severity) {
45
79
  return null;
46
80
  }
47
81
 
82
+ // Parse markdown links from message and clean it up
83
+ const parseMessage = (rawMessage: string) => {
84
+ // Extract markdown links: [text](url)
85
+ const linkRegex = /\[([^\]]+)\]\(([^)]+)\)/g;
86
+ const matches = Array.from(rawMessage.matchAll(linkRegex));
87
+
88
+ if (matches.length > 0) {
89
+ // Remove "See more:" and markdown links from the main message
90
+ let cleanMessage = rawMessage
91
+ .replace(/\.\s*See more:\s*\[([^\]]+)\]\(([^)]+)\)/g, ".")
92
+ .replace(/See more:\s*\[([^\]]+)\]\(([^)]+)\)/g, "")
93
+ .trim();
94
+
95
+ return cleanMessage;
96
+ }
97
+
98
+ return rawMessage;
99
+ };
100
+
101
+ const cleanMessage = parseMessage(message);
48
102
  const Icon = icon || defaultIcons[severity];
49
103
 
50
- const bgColor = {
51
- info: "#dbeafe",
52
- warning: "#fef3c7",
53
- error: "#fee2e2",
54
- }[severity];
55
-
56
- const textColor = {
57
- info: "#1e40af",
58
- warning: "#854d0e",
59
- error: "#991b1b",
60
- }[severity];
61
-
62
- const iconColor = {
63
- info: "#3b82f6",
64
- warning: "#eab308",
65
- error: "#ef4444",
66
- }[severity];
67
-
68
- const primaryButtonColor = {
69
- info: "#3b82f6",
70
- warning: "#eab308",
71
- error: "#ef4444",
72
- }[severity];
73
-
74
- const primaryButtonHoverColor = {
75
- info: "#2563eb",
76
- warning: "#ca8a04",
77
- error: "#dc2626",
78
- }[severity];
104
+ const themeConfigs = {
105
+ [Severity.INFO]: {
106
+ bg: "linear-gradient(135deg, #eff6ff 0%, #dbeafe 100%)",
107
+ border: "#93c5fd",
108
+ text: "#1e40af",
109
+ icon: "#3b82f6",
110
+ primaryBtn: "#3b82f6",
111
+ primaryBtnHover: "#2563eb",
112
+ },
113
+ [Severity.WARNING]: {
114
+ bg: "linear-gradient(135deg, #fffbeb 0%, #fef3c7 100%)",
115
+ border: "#fbbf24",
116
+ text: "#92400e",
117
+ icon: "#f59e0b",
118
+ primaryBtn: "#f59e0b",
119
+ primaryBtnHover: "#d97706",
120
+ },
121
+ [Severity.CRITICAL]: {
122
+ bg: "linear-gradient(135deg, #fef2f2 0%, #fecaca 100%)",
123
+ border: "#f87171",
124
+ text: "#991b1b",
125
+ icon: "#ef4444",
126
+ primaryBtn: "#ef4444",
127
+ primaryBtnHover: "#dc2626",
128
+ },
129
+ };
130
+
131
+ const themeConfig = themeConfigs[severity] || themeConfigs[Severity.CRITICAL];
79
132
 
80
133
  return (
81
134
  <div
82
135
  style={{
83
136
  position: "fixed",
84
- bottom: "16px",
137
+ bottom: "20px",
85
138
  left: "50%",
86
139
  transform: "translateX(-50%)",
87
- maxWidth: "90%",
88
- zIndex: 9999,
140
+ maxWidth: "min(95vw, 680px)",
141
+ width: "100%",
142
+ zIndex: 10000,
143
+ animation: "bannerSlideIn 0.4s cubic-bezier(0.16, 1, 0.3, 1)",
89
144
  }}
90
145
  >
146
+ <style>
147
+ {`
148
+ @keyframes bannerSlideIn {
149
+ from {
150
+ opacity: 0;
151
+ transform: translateX(-50%) translateY(10px);
152
+ }
153
+ to {
154
+ opacity: 1;
155
+ transform: translateX(-50%) translateY(0);
156
+ }
157
+ }
158
+ `}
159
+ </style>
91
160
  <div
92
161
  style={{
93
162
  display: "flex",
94
- flexWrap: "wrap",
95
- alignItems: "center",
96
- gap: "12px",
97
- borderRadius: "9999px",
98
- border: "1px solid #e5e7eb",
99
- backgroundColor: bgColor,
100
- padding: "8px 16px",
101
- boxShadow: "0 4px 6px -1px rgba(0, 0, 0, 0.1)",
163
+ alignItems: "flex-start",
164
+ gap: "14px",
165
+ borderRadius: "16px",
166
+ border: `1px solid ${themeConfig.border}`,
167
+ background: themeConfig.bg,
168
+ padding: "18px 20px",
169
+ boxShadow: "0 10px 25px -5px rgba(0, 0, 0, 0.1), 0 8px 10px -6px rgba(0, 0, 0, 0.1)",
170
+ position: "relative",
171
+ backdropFilter: "blur(10px)",
172
+ WebkitBackdropFilter: "blur(10px)",
102
173
  }}
103
174
  >
104
- <div style={{ color: iconColor }}>{Icon}</div>
105
- <span
106
- style={{
107
- flex: 1,
108
- fontSize: "14px",
109
- fontWeight: 500,
110
- color: textColor,
111
- whiteSpace: "normal",
112
- wordBreak: "break-word",
113
- }}
114
- >
115
- {message}
116
- </span>
175
+ {/* Close button */}
176
+ {onClose && (
177
+ <button
178
+ onClick={onClose}
179
+ style={{
180
+ position: "absolute",
181
+ top: "12px",
182
+ right: "12px",
183
+ background: "rgba(255, 255, 255, 0.8)",
184
+ border: "none",
185
+ color: themeConfig.text,
186
+ cursor: "pointer",
187
+ fontSize: "18px",
188
+ lineHeight: "1",
189
+ padding: "6px",
190
+ borderRadius: "8px",
191
+ opacity: 0.7,
192
+ transition: "all 0.2s ease",
193
+ display: "flex",
194
+ alignItems: "center",
195
+ justifyContent: "center",
196
+ width: "28px",
197
+ height: "28px",
198
+ }}
199
+ title="Close"
200
+ onMouseOver={(e) => {
201
+ e.currentTarget.style.opacity = "1";
202
+ e.currentTarget.style.background = "rgba(255, 255, 255, 1)";
203
+ e.currentTarget.style.transform = "scale(1.05)";
204
+ }}
205
+ onMouseOut={(e) => {
206
+ e.currentTarget.style.opacity = "0.7";
207
+ e.currentTarget.style.background = "rgba(255, 255, 255, 0.8)";
208
+ e.currentTarget.style.transform = "scale(1)";
209
+ }}
210
+ >
211
+ ×
212
+ </button>
213
+ )}
214
+
215
+ {/* Icon */}
117
216
  <div
118
217
  style={{
218
+ color: themeConfig.icon,
219
+ flexShrink: 0,
220
+ marginTop: "1px",
221
+ padding: "6px",
222
+ borderRadius: "10px",
223
+ background: "rgba(255, 255, 255, 0.7)",
119
224
  display: "flex",
120
- gap: "8px",
121
- flexWrap: "wrap",
225
+ alignItems: "center",
226
+ justifyContent: "center",
122
227
  }}
123
228
  >
124
- {actions?.secondary && (
125
- <button
126
- onClick={actions.secondary.onClick}
127
- style={{
128
- borderRadius: "9999px",
129
- padding: "4px 12px",
130
- fontSize: "14px",
131
- fontWeight: 500,
132
- color: textColor,
133
- backgroundColor: "transparent",
134
- border: "none",
135
- cursor: "pointer",
136
- transition: "background-color 0.2s",
137
- }}
138
- onMouseOver={(e) => (e.currentTarget.style.backgroundColor = "rgba(255,255,255,0.5)")}
139
- onMouseOut={(e) => (e.currentTarget.style.backgroundColor = "transparent")}
140
- >
141
- {actions.secondary.label}
142
- </button>
143
- )}
144
- {actions?.primary && (
145
- <button
146
- onClick={actions.primary.onClick}
229
+ {Icon}
230
+ </div>
231
+
232
+ {/* Content */}
233
+ <div style={{ flex: 1, paddingRight: onClose ? "40px" : "0" }}>
234
+ {/* Message */}
235
+ <div
236
+ style={{
237
+ fontSize: "15px",
238
+ fontWeight: 600,
239
+ color: themeConfig.text,
240
+ lineHeight: "1.5",
241
+ marginBottom: actions ? "12px" : "0",
242
+ fontFamily: "-apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif",
243
+ }}
244
+ >
245
+ {cleanMessage}
246
+ </div>
247
+
248
+ {/* Actions */}
249
+ {actions && (
250
+ <div
147
251
  style={{
148
- borderRadius: "9999px",
149
- padding: "4px 12px",
150
- fontSize: "14px",
151
- fontWeight: 500,
152
- color: "#fff",
153
- backgroundColor: primaryButtonColor,
154
- border: "none",
155
- cursor: "pointer",
156
- transition: "background-color 0.2s",
252
+ display: "flex",
253
+ gap: "10px",
254
+ flexWrap: "wrap",
157
255
  }}
158
- onMouseOver={(e) => (e.currentTarget.style.backgroundColor = primaryButtonHoverColor)}
159
- onMouseOut={(e) => (e.currentTarget.style.backgroundColor = primaryButtonColor)}
160
256
  >
161
- {actions.primary.label}
162
- </button>
257
+ {actions.secondary && (
258
+ <button
259
+ onClick={actions.secondary.onClick}
260
+ style={{
261
+ borderRadius: "10px",
262
+ padding: "8px 16px",
263
+ fontSize: "14px",
264
+ fontWeight: 500,
265
+ color: themeConfig.text,
266
+ backgroundColor: "rgba(255, 255, 255, 0.8)",
267
+ border: `1.5px solid ${themeConfig.border}`,
268
+ cursor: "pointer",
269
+ transition: "all 0.2s ease",
270
+ fontFamily: "-apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif",
271
+ }}
272
+ onMouseOver={(e) => {
273
+ e.currentTarget.style.backgroundColor = "rgba(255, 255, 255, 1)";
274
+ e.currentTarget.style.transform = "translateY(-1px)";
275
+ e.currentTarget.style.boxShadow = "0 4px 12px rgba(0, 0, 0, 0.15)";
276
+ }}
277
+ onMouseOut={(e) => {
278
+ e.currentTarget.style.backgroundColor = "rgba(255, 255, 255, 0.8)";
279
+ e.currentTarget.style.transform = "translateY(0)";
280
+ e.currentTarget.style.boxShadow = "none";
281
+ }}
282
+ >
283
+ {actions.secondary.label}
284
+ </button>
285
+ )}
286
+ {actions.primary && (
287
+ <button
288
+ onClick={actions.primary.onClick}
289
+ style={{
290
+ borderRadius: "10px",
291
+ padding: "8px 16px",
292
+ fontSize: "14px",
293
+ fontWeight: 600,
294
+ color: "#fff",
295
+ backgroundColor: themeConfig.primaryBtn,
296
+ border: "none",
297
+ cursor: "pointer",
298
+ transition: "all 0.2s ease",
299
+ boxShadow: "0 4px 12px rgba(0, 0, 0, 0.15)",
300
+ fontFamily: "-apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif",
301
+ }}
302
+ onMouseOver={(e) => {
303
+ e.currentTarget.style.backgroundColor = themeConfig.primaryBtnHover;
304
+ e.currentTarget.style.transform = "translateY(-1px)";
305
+ e.currentTarget.style.boxShadow = "0 6px 16px rgba(0, 0, 0, 0.2)";
306
+ }}
307
+ onMouseOut={(e) => {
308
+ e.currentTarget.style.backgroundColor = themeConfig.primaryBtn;
309
+ e.currentTarget.style.transform = "translateY(0)";
310
+ e.currentTarget.style.boxShadow = "0 4px 12px rgba(0, 0, 0, 0.15)";
311
+ }}
312
+ >
313
+ {actions.primary.label}
314
+ </button>
315
+ )}
316
+ </div>
163
317
  )}
164
318
  </div>
165
319
  </div>
@@ -167,39 +321,65 @@ export function UsageBanner({
167
321
  );
168
322
  }
169
323
 
170
- export function renderCopilotKitUsage(error: CopilotKitError) {
171
- switch (error.name) {
172
- case ERROR_NAMES.CONFIGURATION_ERROR:
173
- return <UsageBanner severity={error.severity} message={error.message} />;
174
- case ERROR_NAMES.MISSING_PUBLIC_API_KEY_ERROR:
175
- return (
176
- <UsageBanner
177
- severity={error.severity}
178
- message={error.message}
179
- actions={{
180
- primary: {
181
- label: "Sign In",
182
- onClick: () => {
183
- window.location.href = "https://cloud.copilotkit.ai";
184
- },
185
- },
186
- }}
187
- />
188
- );
189
- case ERROR_NAMES.UPGRADE_REQUIRED_ERROR:
190
- return (
191
- <UsageBanner
192
- severity={error.severity}
193
- message={error.message}
194
- actions={{
195
- primary: {
196
- label: "Upgrade",
197
- onClick: () => {
198
- window.location.href = "https://copilotkit.ai/";
199
- },
200
- },
201
- }}
202
- />
203
- );
324
+ export function renderCopilotKitUsage(error: CopilotKitError, onClose?: () => void) {
325
+ // Route based on error visibility level
326
+ if (error.visibility !== ErrorVisibility.BANNER) {
327
+ return null;
204
328
  }
329
+
330
+ // Extract URL from markdown links in the message
331
+ const extractUrlFromMessage = (message: string): string | null => {
332
+ const linkRegex = /\[([^\]]+)\]\(([^)]+)\)/g;
333
+ const match = linkRegex.exec(message);
334
+ return match ? match[2] : null;
335
+ };
336
+
337
+ // Get action button based on error type
338
+ const getErrorActions = (error: CopilotKitError) => {
339
+ switch (error.name) {
340
+ case ERROR_NAMES.MISSING_PUBLIC_API_KEY_ERROR:
341
+ return {
342
+ primary: {
343
+ label: "Sign In",
344
+ onClick: () => (window.location.href = "https://cloud.copilotkit.ai"),
345
+ },
346
+ };
347
+ case ERROR_NAMES.UPGRADE_REQUIRED_ERROR:
348
+ return {
349
+ primary: {
350
+ label: "Upgrade",
351
+ onClick: () => (window.location.href = "https://copilotkit.ai/"),
352
+ },
353
+ };
354
+ case ERROR_NAMES.COPILOT_API_DISCOVERY_ERROR:
355
+ case ERROR_NAMES.COPILOT_REMOTE_ENDPOINT_DISCOVERY_ERROR:
356
+ case ERROR_NAMES.COPILOT_KIT_AGENT_DISCOVERY_ERROR:
357
+ return {
358
+ primary: {
359
+ label: "View Docs",
360
+ onClick: () => {
361
+ // Try to get URL from the error message first, then extensions, then default
362
+ const urlFromMessage = extractUrlFromMessage(error.message);
363
+ const urlFromExtensions = (error.extensions as any)?.troubleshootingUrl;
364
+ const url =
365
+ urlFromMessage ||
366
+ urlFromExtensions ||
367
+ "https://docs.copilotkit.ai/troubleshooting/common-issues";
368
+ window.open(url, "_blank");
369
+ },
370
+ },
371
+ };
372
+ default:
373
+ return undefined;
374
+ }
375
+ };
376
+
377
+ return (
378
+ <UsageBanner
379
+ severity={error.severity || Severity.CRITICAL}
380
+ message={error.message}
381
+ onClose={onClose}
382
+ actions={getErrorActions(error)}
383
+ />
384
+ );
205
385
  }
@@ -162,7 +162,7 @@ export interface CopilotContextParams {
162
162
  // api endpoints
163
163
  copilotApiConfig: CopilotApiConfig;
164
164
 
165
- showDevConsole: boolean | "auto";
165
+ showDevConsole: boolean;
166
166
 
167
167
  // agents
168
168
  coagentStates: Record<string, CoagentState>;
@@ -268,7 +268,7 @@ const emptyCopilotContext: CopilotContextParams = {
268
268
  chatSuggestionConfiguration: {},
269
269
  addChatSuggestionConfiguration: () => {},
270
270
  removeChatSuggestionConfiguration: () => {},
271
- showDevConsole: "auto",
271
+ showDevConsole: false,
272
272
  coagentStates: {},
273
273
  setCoagentStates: () => {},
274
274
  coagentStatesRef: { current: {} },
@@ -37,6 +37,7 @@ import { FrontendAction, processActionsForRuntimeRequest } from "../types/fronte
37
37
  import { CoagentState } from "../types/coagent-state";
38
38
  import { AgentSession } from "../context/copilot-context";
39
39
  import { useCopilotRuntimeClient } from "./use-copilot-runtime-client";
40
+ import { useCopilotContext } from "../context/copilot-context";
40
41
  import { useAsyncCallback, useErrorToast } from "../components/error-boundary/error-utils";
41
42
  import {
42
43
  LangGraphInterruptAction,
@@ -235,11 +236,14 @@ export function useChat(options: UseChatOptions): UseChatHelpers {
235
236
  ...(publicApiKey ? { [COPILOT_CLOUD_PUBLIC_API_KEY_HEADER]: publicApiKey } : {}),
236
237
  };
237
238
 
239
+ const { showDevConsole } = useCopilotContext();
240
+
238
241
  const runtimeClient = useCopilotRuntimeClient({
239
242
  url: copilotConfig.chatApiEndpoint,
240
243
  publicApiKey: copilotConfig.publicApiKey,
241
244
  headers,
242
245
  credentials: copilotConfig.credentials,
246
+ showDevConsole,
243
247
  });
244
248
 
245
249
  const pendingAppendsRef = useRef<{ message: Message; followUp: boolean }[]>([]);
@@ -43,7 +43,7 @@
43
43
 
44
44
  import { useRef, useContext, useEffect } from "react";
45
45
  import { CopilotContext } from "../context/copilot-context";
46
- import { randomId } from "@copilotkit/shared";
46
+ import { randomId, CopilotKitAgentDiscoveryError } from "@copilotkit/shared";
47
47
  import { CoAgentStateRender } from "../types/coagent-action";
48
48
  import { useToast } from "../components/toast/toast-provider";
49
49
 
@@ -70,12 +70,18 @@ export function useCoAgentStateRender<T = any>(
70
70
  availableAgents,
71
71
  } = useContext(CopilotContext);
72
72
  const idRef = useRef<string>(randomId());
73
- const { addToast } = useToast();
73
+ const { setBannerError, addToast } = useToast();
74
74
 
75
75
  useEffect(() => {
76
76
  if (availableAgents?.length && !availableAgents.some((a) => a.name === action.name)) {
77
77
  const message = `(useCoAgentStateRender): Agent "${action.name}" not found. Make sure the agent exists and is properly configured.`;
78
- addToast({ type: "warning", message });
78
+
79
+ // Route to banner instead of toast for consistency
80
+ const agentError = new CopilotKitAgentDiscoveryError({
81
+ agentName: action.name,
82
+ availableAgents: availableAgents.map((a) => ({ name: a.name, id: a.id })),
83
+ });
84
+ setBannerError(agentError);
79
85
  }
80
86
  }, [availableAgents]);
81
87
 
@@ -101,7 +101,7 @@ import { Message } from "@copilotkit/runtime-client-gql";
101
101
  import { useAsyncCallback } from "../components/error-boundary/error-utils";
102
102
  import { useToast } from "../components/toast/toast-provider";
103
103
  import { useCopilotRuntimeClient } from "./use-copilot-runtime-client";
104
- import { parseJson } from "@copilotkit/shared";
104
+ import { parseJson, CopilotKitAgentDiscoveryError } from "@copilotkit/shared";
105
105
 
106
106
  interface UseCoagentOptionsBase {
107
107
  /**
@@ -214,7 +214,7 @@ export type HintFunction = (params: HintFunctionParams) => Message | undefined;
214
214
  export function useCoAgent<T = any>(options: UseCoagentOptions<T>): UseCoagentReturnType<T> {
215
215
  const generalContext = useCopilotContext();
216
216
  const { availableAgents } = generalContext;
217
- const { addToast } = useToast();
217
+ const { setBannerError } = useToast();
218
218
  const lastLoadedThreadId = useRef<string>();
219
219
  const lastLoadedState = useRef<any>();
220
220
 
@@ -223,7 +223,13 @@ export function useCoAgent<T = any>(options: UseCoagentOptions<T>): UseCoagentRe
223
223
  if (availableAgents?.length && !availableAgents.some((a) => a.name === name)) {
224
224
  const message = `(useCoAgent): Agent "${name}" not found. Make sure the agent exists and is properly configured.`;
225
225
  console.warn(message);
226
- addToast({ type: "warning", message });
226
+
227
+ // Route to banner instead of toast for consistency
228
+ const agentError = new CopilotKitAgentDiscoveryError({
229
+ agentName: name,
230
+ availableAgents: availableAgents.map((a) => ({ name: a.name, id: a.id })),
231
+ });
232
+ setBannerError(agentError);
227
233
  }
228
234
  }, [availableAgents]);
229
235
 
@@ -241,6 +247,7 @@ export function useCoAgent<T = any>(options: UseCoagentOptions<T>): UseCoagentRe
241
247
  publicApiKey: copilotApiConfig.publicApiKey,
242
248
  headers,
243
249
  credentials: copilotApiConfig.credentials,
250
+ showDevConsole: context.showDevConsole,
244
251
  });
245
252
 
246
253
  // if we manage state internally, we need to provide a function to set the state