@copilotkit/react-core 1.10.0-next.1 → 1.10.0-next.10

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (204) hide show
  1. package/CHANGELOG.md +87 -0
  2. package/dist/{chunk-KV25ZRMH.mjs → chunk-2TSNHEIS.mjs} +6 -6
  3. package/dist/chunk-2TSNHEIS.mjs.map +1 -0
  4. package/dist/{chunk-DF4YG4PF.mjs → chunk-3RHHNUVV.mjs} +2 -2
  5. package/dist/{chunk-LNAQ7JG3.mjs → chunk-6EKLRL7B.mjs} +2 -2
  6. package/dist/{chunk-JZQOCH4A.mjs → chunk-ADZDXHVC.mjs} +4 -4
  7. package/dist/{chunk-4CFY3CON.mjs → chunk-CLMDRYEN.mjs} +2 -2
  8. package/dist/{chunk-VM7CVIET.mjs → chunk-COEUPDRL.mjs} +20 -21
  9. package/dist/chunk-COEUPDRL.mjs.map +1 -0
  10. package/dist/{chunk-RGKZCCPA.mjs → chunk-DLEXVOQE.mjs} +5 -5
  11. package/dist/{chunk-YAF2LATQ.mjs → chunk-EFL5OBKN.mjs} +1 -1
  12. package/dist/chunk-EFL5OBKN.mjs.map +1 -0
  13. package/dist/{chunk-JWAXDYOW.mjs → chunk-FAUNHSQU.mjs} +3 -3
  14. package/dist/chunk-ICIK2BSB.mjs +17 -0
  15. package/dist/chunk-ICIK2BSB.mjs.map +1 -0
  16. package/dist/chunk-IHAZJF3V.mjs +34 -0
  17. package/dist/chunk-IHAZJF3V.mjs.map +1 -0
  18. package/dist/{chunk-Q6FZZJ5A.mjs → chunk-IN7GE4NO.mjs} +2 -2
  19. package/dist/{chunk-4XVBXDCX.mjs → chunk-JBLMXZ3O.mjs} +8 -8
  20. package/dist/{chunk-NXCJELW7.mjs → chunk-JJDXTTEN.mjs} +3 -3
  21. package/dist/chunk-KDAZGZ24.mjs +1 -0
  22. package/dist/{chunk-VOMGRGWT.mjs → chunk-L6HQIJ74.mjs} +33 -17
  23. package/dist/chunk-L6HQIJ74.mjs.map +1 -0
  24. package/dist/{chunk-OMVNJ7S3.mjs → chunk-LVWV62JZ.mjs} +37 -24
  25. package/dist/chunk-LVWV62JZ.mjs.map +1 -0
  26. package/dist/{chunk-3OQM3NEK.mjs → chunk-N4WEHORG.mjs} +2 -2
  27. package/dist/chunk-OKRZF3DD.mjs +225 -0
  28. package/dist/chunk-OKRZF3DD.mjs.map +1 -0
  29. package/dist/{chunk-SGF6C7I6.mjs → chunk-Q42NJFXR.mjs} +11 -16
  30. package/dist/chunk-Q42NJFXR.mjs.map +1 -0
  31. package/dist/chunk-QGE7U4NV.mjs +85 -0
  32. package/dist/chunk-QGE7U4NV.mjs.map +1 -0
  33. package/dist/{chunk-XGRBCWK6.mjs → chunk-TEMLWRRT.mjs} +3 -3
  34. package/dist/chunk-TEMLWRRT.mjs.map +1 -0
  35. package/dist/{chunk-PYULBXCD.mjs → chunk-TWYUYC4F.mjs} +44 -10
  36. package/dist/chunk-TWYUYC4F.mjs.map +1 -0
  37. package/dist/{chunk-WUORFPJ7.mjs → chunk-X2DNXTME.mjs} +6 -6
  38. package/dist/{chunk-DCTJZ742.mjs → chunk-ZLQVRPDS.mjs} +5 -2
  39. package/dist/chunk-ZLQVRPDS.mjs.map +1 -0
  40. package/dist/components/copilot-provider/copilot-messages.d.ts +17 -1
  41. package/dist/components/copilot-provider/copilot-messages.js +46 -7
  42. package/dist/components/copilot-provider/copilot-messages.js.map +1 -1
  43. package/dist/components/copilot-provider/copilot-messages.mjs +11 -7
  44. package/dist/components/copilot-provider/copilotkit-props.d.ts +5 -3
  45. package/dist/components/copilot-provider/copilotkit-props.js.map +1 -1
  46. package/dist/components/copilot-provider/copilotkit.d.ts +1 -2
  47. package/dist/components/copilot-provider/copilotkit.js +337 -555
  48. package/dist/components/copilot-provider/copilotkit.js.map +1 -1
  49. package/dist/components/copilot-provider/copilotkit.mjs +10 -10
  50. package/dist/components/copilot-provider/index.d.ts +1 -2
  51. package/dist/components/copilot-provider/index.js +337 -555
  52. package/dist/components/copilot-provider/index.js.map +1 -1
  53. package/dist/components/copilot-provider/index.mjs +10 -10
  54. package/dist/components/error-boundary/error-boundary.js +176 -323
  55. package/dist/components/error-boundary/error-boundary.js.map +1 -1
  56. package/dist/components/error-boundary/error-boundary.mjs +4 -4
  57. package/dist/components/error-boundary/error-utils.js.map +1 -1
  58. package/dist/components/error-boundary/error-utils.mjs +2 -2
  59. package/dist/components/index.d.ts +1 -2
  60. package/dist/components/index.js +337 -555
  61. package/dist/components/index.js.map +1 -1
  62. package/dist/components/index.mjs +10 -10
  63. package/dist/components/toast/toast-provider.js.map +1 -1
  64. package/dist/components/toast/toast-provider.mjs +1 -1
  65. package/dist/components/usage-banner.d.ts +10 -4
  66. package/dist/components/usage-banner.js +176 -302
  67. package/dist/components/usage-banner.js.map +1 -1
  68. package/dist/components/usage-banner.mjs +3 -1
  69. package/dist/context/copilot-context.d.ts +1 -2
  70. package/dist/context/copilot-context.js +2 -2
  71. package/dist/context/copilot-context.js.map +1 -1
  72. package/dist/context/copilot-context.mjs +1 -1
  73. package/dist/context/copilot-messages-context.d.ts +11 -15
  74. package/dist/context/copilot-messages-context.js +4 -1
  75. package/dist/context/copilot-messages-context.js.map +1 -1
  76. package/dist/context/copilot-messages-context.mjs +1 -1
  77. package/dist/context/index.d.ts +2 -2
  78. package/dist/context/index.js +6 -3
  79. package/dist/context/index.js.map +1 -1
  80. package/dist/context/index.mjs +5 -5
  81. package/dist/{copilot-context-bd88d30d.d.ts → copilot-context-256f9020.d.ts} +4 -22
  82. package/dist/hooks/index.d.ts +7 -5
  83. package/dist/hooks/index.js +250 -122
  84. package/dist/hooks/index.js.map +1 -1
  85. package/dist/hooks/index.mjs +42 -34
  86. package/dist/hooks/use-chat.d.ts +1 -2
  87. package/dist/hooks/use-chat.js +11 -3
  88. package/dist/hooks/use-chat.js.map +1 -1
  89. package/dist/hooks/use-chat.mjs +6 -6
  90. package/dist/hooks/use-coagent-state-render.js +2 -2
  91. package/dist/hooks/use-coagent-state-render.js.map +1 -1
  92. package/dist/hooks/use-coagent-state-render.mjs +3 -3
  93. package/dist/hooks/use-coagent.d.ts +3 -4
  94. package/dist/hooks/use-coagent.js +114 -81
  95. package/dist/hooks/use-coagent.js.map +1 -1
  96. package/dist/hooks/use-coagent.mjs +16 -16
  97. package/dist/hooks/use-copilot-action.js +2 -2
  98. package/dist/hooks/use-copilot-action.js.map +1 -1
  99. package/dist/hooks/use-copilot-action.mjs +4 -4
  100. package/dist/hooks/use-copilot-additional-instructions.js +2 -2
  101. package/dist/hooks/use-copilot-additional-instructions.js.map +1 -1
  102. package/dist/hooks/use-copilot-additional-instructions.mjs +2 -2
  103. package/dist/hooks/use-copilot-authenticated-action.js +2 -2
  104. package/dist/hooks/use-copilot-authenticated-action.js.map +1 -1
  105. package/dist/hooks/use-copilot-authenticated-action.mjs +5 -5
  106. package/dist/hooks/use-copilot-chat-headless_c.d.ts +33 -0
  107. package/dist/hooks/use-copilot-chat-headless_c.js +1837 -0
  108. package/dist/hooks/use-copilot-chat-headless_c.js.map +1 -0
  109. package/dist/hooks/use-copilot-chat-headless_c.mjs +31 -0
  110. package/dist/hooks/use-copilot-chat-headless_c.mjs.map +1 -0
  111. package/dist/hooks/use-copilot-chat.d.ts +52 -82
  112. package/dist/hooks/use-copilot-chat.js +60 -13
  113. package/dist/hooks/use-copilot-chat.js.map +1 -1
  114. package/dist/hooks/use-copilot-chat.mjs +16 -17
  115. package/dist/hooks/use-copilot-chat_internal.d.ts +177 -0
  116. package/dist/hooks/use-copilot-chat_internal.js +1770 -0
  117. package/dist/hooks/use-copilot-chat_internal.js.map +1 -0
  118. package/dist/hooks/use-copilot-chat_internal.mjs +29 -0
  119. package/dist/hooks/use-copilot-chat_internal.mjs.map +1 -0
  120. package/dist/hooks/use-copilot-readable.js +2 -2
  121. package/dist/hooks/use-copilot-readable.js.map +1 -1
  122. package/dist/hooks/use-copilot-readable.mjs +2 -2
  123. package/dist/hooks/use-copilot-runtime-client.js +9 -1
  124. package/dist/hooks/use-copilot-runtime-client.js.map +1 -1
  125. package/dist/hooks/use-copilot-runtime-client.mjs +3 -3
  126. package/dist/hooks/use-langgraph-interrupt-render.js +2 -2
  127. package/dist/hooks/use-langgraph-interrupt-render.js.map +1 -1
  128. package/dist/hooks/use-langgraph-interrupt-render.mjs +3 -3
  129. package/dist/hooks/use-langgraph-interrupt.d.ts +3 -4
  130. package/dist/hooks/use-langgraph-interrupt.js +32 -11
  131. package/dist/hooks/use-langgraph-interrupt.js.map +1 -1
  132. package/dist/hooks/use-langgraph-interrupt.mjs +16 -16
  133. package/dist/hooks/use-make-copilot-document-readable.js +2 -2
  134. package/dist/hooks/use-make-copilot-document-readable.js.map +1 -1
  135. package/dist/hooks/use-make-copilot-document-readable.mjs +2 -2
  136. package/dist/index-08c43df1.d.ts +36 -0
  137. package/dist/index.d.ts +5 -3
  138. package/dist/index.js +460 -471
  139. package/dist/index.js.map +1 -1
  140. package/dist/index.mjs +47 -39
  141. package/dist/lib/copilot-task.d.ts +1 -2
  142. package/dist/lib/copilot-task.js.map +1 -1
  143. package/dist/lib/copilot-task.mjs +12 -12
  144. package/dist/lib/index.d.ts +1 -2
  145. package/dist/lib/index.js.map +1 -1
  146. package/dist/lib/index.mjs +12 -12
  147. package/dist/types/interrupt-action.d.ts +2 -3
  148. package/dist/utils/dev-console.d.ts +1 -1
  149. package/dist/utils/dev-console.js +9 -1
  150. package/dist/utils/dev-console.js.map +1 -1
  151. package/dist/utils/dev-console.mjs +1 -1
  152. package/dist/utils/extract.d.ts +2 -2
  153. package/dist/utils/extract.js.map +1 -1
  154. package/dist/utils/extract.mjs +10 -10
  155. package/dist/utils/index.d.ts +3 -3
  156. package/dist/utils/index.js +9 -1
  157. package/dist/utils/index.js.map +1 -1
  158. package/dist/utils/index.mjs +11 -11
  159. package/dist/utils/suggestions.d.ts +2 -2
  160. package/dist/utils/suggestions.js.map +1 -1
  161. package/dist/utils/suggestions.mjs +10 -10
  162. package/package.json +3 -3
  163. package/src/components/copilot-provider/copilot-messages.tsx +57 -1
  164. package/src/components/copilot-provider/copilotkit-props.tsx +4 -1
  165. package/src/components/copilot-provider/copilotkit.tsx +20 -10
  166. package/src/components/error-boundary/error-boundary.tsx +5 -15
  167. package/src/components/toast/toast-provider.tsx +1 -3
  168. package/src/components/usage-banner.tsx +193 -316
  169. package/src/context/copilot-context.tsx +12 -6
  170. package/src/context/copilot-messages-context.tsx +7 -1
  171. package/src/hooks/__tests__/use-coagent-config.test.ts +8 -1
  172. package/src/hooks/index.ts +7 -2
  173. package/src/hooks/use-coagent.ts +17 -19
  174. package/src/hooks/use-copilot-chat-headless_c.ts +187 -0
  175. package/src/hooks/use-copilot-chat.ts +64 -495
  176. package/src/hooks/use-copilot-chat_internal.ts +543 -0
  177. package/src/hooks/use-langgraph-interrupt.ts +1 -1
  178. package/src/utils/dev-console.ts +18 -2
  179. package/dist/chunk-57K2ZJ5F.mjs +0 -348
  180. package/dist/chunk-57K2ZJ5F.mjs.map +0 -1
  181. package/dist/chunk-CQPYJIBH.mjs +0 -1
  182. package/dist/chunk-DCTJZ742.mjs.map +0 -1
  183. package/dist/chunk-GFJW4RIM.mjs +0 -9
  184. package/dist/chunk-GFJW4RIM.mjs.map +0 -1
  185. package/dist/chunk-KV25ZRMH.mjs.map +0 -1
  186. package/dist/chunk-OMVNJ7S3.mjs.map +0 -1
  187. package/dist/chunk-PYULBXCD.mjs.map +0 -1
  188. package/dist/chunk-SGF6C7I6.mjs.map +0 -1
  189. package/dist/chunk-VM7CVIET.mjs.map +0 -1
  190. package/dist/chunk-VOMGRGWT.mjs.map +0 -1
  191. package/dist/chunk-XGRBCWK6.mjs.map +0 -1
  192. package/dist/chunk-YAF2LATQ.mjs.map +0 -1
  193. /package/dist/{chunk-DF4YG4PF.mjs.map → chunk-3RHHNUVV.mjs.map} +0 -0
  194. /package/dist/{chunk-LNAQ7JG3.mjs.map → chunk-6EKLRL7B.mjs.map} +0 -0
  195. /package/dist/{chunk-JZQOCH4A.mjs.map → chunk-ADZDXHVC.mjs.map} +0 -0
  196. /package/dist/{chunk-4CFY3CON.mjs.map → chunk-CLMDRYEN.mjs.map} +0 -0
  197. /package/dist/{chunk-RGKZCCPA.mjs.map → chunk-DLEXVOQE.mjs.map} +0 -0
  198. /package/dist/{chunk-JWAXDYOW.mjs.map → chunk-FAUNHSQU.mjs.map} +0 -0
  199. /package/dist/{chunk-Q6FZZJ5A.mjs.map → chunk-IN7GE4NO.mjs.map} +0 -0
  200. /package/dist/{chunk-4XVBXDCX.mjs.map → chunk-JBLMXZ3O.mjs.map} +0 -0
  201. /package/dist/{chunk-NXCJELW7.mjs.map → chunk-JJDXTTEN.mjs.map} +0 -0
  202. /package/dist/{chunk-CQPYJIBH.mjs.map → chunk-KDAZGZ24.mjs.map} +0 -0
  203. /package/dist/{chunk-3OQM3NEK.mjs.map → chunk-N4WEHORG.mjs.map} +0 -0
  204. /package/dist/{chunk-WUORFPJ7.mjs.map → chunk-X2DNXTME.mjs.map} +0 -0
@@ -1,9 +1,14 @@
1
- import { Severity, CopilotKitError, ERROR_NAMES, ErrorVisibility } from "@copilotkit/shared";
1
+ import {
2
+ Severity,
3
+ CopilotKitError,
4
+ ErrorVisibility,
5
+ CopilotKitErrorCode,
6
+ } from "@copilotkit/shared";
7
+ import React from "react";
2
8
 
3
9
  interface UsageBannerProps {
4
10
  severity?: Severity;
5
- message?: string;
6
- icon?: React.ReactNode;
11
+ message?: string | React.ReactNode;
7
12
  onClose?: () => void;
8
13
  actions?: {
9
14
  primary?: {
@@ -17,61 +22,9 @@ interface UsageBannerProps {
17
22
  };
18
23
  }
19
24
 
20
- const defaultIcons: Record<Severity, JSX.Element> = {
21
- [Severity.CRITICAL]: (
22
- <svg
23
- viewBox="0 0 24 24"
24
- width="16"
25
- height="16"
26
- stroke="currentColor"
27
- strokeWidth="2.5"
28
- fill="none"
29
- strokeLinecap="round"
30
- strokeLinejoin="round"
31
- >
32
- <circle cx="12" cy="12" r="10" />
33
- <line x1="15" y1="9" x2="9" y2="15" />
34
- <line x1="9" y1="9" x2="15" y2="15" />
35
- </svg>
36
- ),
37
- [Severity.WARNING]: (
38
- <svg
39
- viewBox="0 0 24 24"
40
- width="16"
41
- height="16"
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="16"
57
- height="16"
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
- ),
69
- };
70
-
71
25
  export function UsageBanner({
72
26
  severity = Severity.CRITICAL,
73
27
  message = "",
74
- icon,
75
28
  onClose,
76
29
  actions,
77
30
  }: UsageBannerProps) {
@@ -79,298 +32,222 @@ export function UsageBanner({
79
32
  return null;
80
33
  }
81
34
 
82
- // Enhanced message parsing to clean up technical details
83
- const parseMessage = (rawMessage: string) => {
84
- // console.log("Raw message:", rawMessage); // Debug
85
-
86
- // Super aggressive cleaning - handle common error patterns first
87
- if (
88
- rawMessage.toLowerCase().includes("authentication") ||
89
- rawMessage.toLowerCase().includes("api key")
90
- ) {
91
- return "Authentication failed. Please check your API key.";
92
- }
93
-
94
- if (rawMessage.toLowerCase().includes("rate limit")) {
95
- return "Rate limit exceeded. Please try again later.";
96
- }
97
-
98
- if (rawMessage.toLowerCase().includes("checkpointer")) {
99
- return "Agent configuration error. Please check your setup.";
100
- }
101
-
102
- // For any other error, extract just the main error type
103
- let cleanMessage = rawMessage;
104
-
105
- // Remove everything after the first " - " or ":" followed by technical details
106
- cleanMessage = cleanMessage.split(" - ")[0];
107
- cleanMessage = cleanMessage.split(": Error code")[0];
108
- cleanMessage = cleanMessage.split(": 401")[0];
109
- cleanMessage = cleanMessage.split(": 403")[0];
110
- cleanMessage = cleanMessage.split(": 404")[0];
111
- cleanMessage = cleanMessage.split(": 500")[0];
112
-
113
- // Remove "See more" links
114
- cleanMessage = cleanMessage.replace(/See more:.*$/g, "").trim();
115
-
116
- // If still too technical, just show a generic message
117
- if (cleanMessage.includes("{") || cleanMessage.includes("'") || cleanMessage.length > 60) {
118
- return "Configuration error. Please check your setup.";
119
- }
120
-
121
- return cleanMessage || "An error occurred. Please check your configuration.";
122
- };
123
-
124
- const cleanMessage = parseMessage(message);
125
- const Icon = icon || defaultIcons[severity];
126
-
127
- const themeConfigs = {
35
+ const themes = {
128
36
  [Severity.INFO]: {
129
- bg: "rgba(239, 246, 255, 0.95)",
130
- border: "#93c5fd",
131
- text: "#1e40af",
132
- icon: "#3b82f6",
133
- primaryBtn: "#3b82f6",
134
- primaryBtnHover: "#2563eb",
37
+ bg: "#f8fafc",
38
+ border: "#e2e8f0",
39
+ text: "#475569",
40
+ accent: "#3b82f6",
135
41
  },
136
42
  [Severity.WARNING]: {
137
- bg: "rgba(255, 251, 235, 0.95)",
43
+ bg: "#fffbeb",
138
44
  border: "#fbbf24",
139
45
  text: "#92400e",
140
- icon: "#f59e0b",
141
- primaryBtn: "#f59e0b",
142
- primaryBtnHover: "#d97706",
46
+ accent: "#f59e0b",
143
47
  },
144
48
  [Severity.CRITICAL]: {
145
- bg: "rgba(254, 242, 242, 0.95)",
146
- border: "#f87171",
147
- text: "#991b1b",
148
- icon: "#ef4444",
149
- primaryBtn: "#ef4444",
150
- primaryBtnHover: "#dc2626",
49
+ bg: "#fef2f2",
50
+ border: "#fecaca",
51
+ text: "#dc2626",
52
+ accent: "#ef4444",
151
53
  },
152
54
  };
153
55
 
154
- const themeConfig = themeConfigs[severity] || themeConfigs[Severity.CRITICAL];
56
+ const theme = themes[severity];
155
57
 
156
58
  return (
157
- <div
158
- style={{
159
- position: "fixed",
160
- bottom: "24px",
161
- left: "50%",
162
- transform: "translateX(-50%)",
163
- width: "400px",
164
- maxWidth: "90vw",
165
- zIndex: 10000,
166
- animation: "bannerSlideIn 0.3s cubic-bezier(0.16, 1, 0.3, 1)",
167
- }}
168
- >
59
+ <>
169
60
  <style>
170
61
  {`
171
- @keyframes bannerSlideIn {
172
- from {
173
- opacity: 0;
174
- transform: translateX(-50%) translateY(20px);
175
- scale: 0.95;
62
+ @keyframes slideUp {
63
+ from { opacity: 0; transform: translateX(-50%) translateY(8px); }
64
+ to { opacity: 1; transform: translateX(-50%) translateY(0); }
65
+ }
66
+
67
+ .usage-banner {
68
+ position: fixed;
69
+ bottom: 24px;
70
+ left: 50%;
71
+ transform: translateX(-50%);
72
+ width: min(600px, calc(100vw - 32px));
73
+ z-index: 10000;
74
+ animation: slideUp 0.2s cubic-bezier(0.16, 1, 0.3, 1);
75
+ }
76
+
77
+ .banner-content {
78
+ background: linear-gradient(135deg, ${theme.bg} 0%, ${theme.bg}f5 100%);
79
+ border: 1px solid ${theme.border};
80
+ border-radius: 12px;
81
+ padding: 18px 20px;
82
+ box-shadow:
83
+ 0 4px 24px rgba(0, 0, 0, 0.08),
84
+ 0 2px 8px rgba(0, 0, 0, 0.04),
85
+ inset 0 1px 0 rgba(255, 255, 255, 0.7);
86
+ display: flex;
87
+ align-items: center;
88
+ gap: 16px;
89
+ font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', system-ui, sans-serif;
90
+ backdrop-filter: blur(12px);
91
+ position: relative;
92
+ overflow: hidden;
93
+ }
94
+
95
+ .banner-content::before {
96
+ content: '';
97
+ position: absolute;
98
+ top: 0;
99
+ left: 0;
100
+ right: 0;
101
+ height: 1px;
102
+ background: linear-gradient(90deg, transparent, ${theme.accent}40, transparent);
103
+ }
104
+
105
+ .banner-message {
106
+ color: ${theme.text};
107
+ font-size: 14px;
108
+ line-height: 1.5;
109
+ font-weight: 500;
110
+ flex: 1;
111
+ letter-spacing: -0.01em;
112
+ }
113
+
114
+ .close-btn {
115
+ background: rgba(0, 0, 0, 0.05);
116
+ border: none;
117
+ color: ${theme.text};
118
+ cursor: pointer;
119
+ padding: 0;
120
+ border-radius: 6px;
121
+ opacity: 0.6;
122
+ transition: all 0.15s cubic-bezier(0.16, 1, 0.3, 1);
123
+ font-size: 14px;
124
+ line-height: 1;
125
+ flex-shrink: 0;
126
+ width: 24px;
127
+ height: 24px;
128
+ display: flex;
129
+ align-items: center;
130
+ justify-content: center;
131
+ }
132
+
133
+ .close-btn:hover {
134
+ opacity: 1;
135
+ background: rgba(0, 0, 0, 0.08);
136
+ transform: scale(1.05);
137
+ }
138
+
139
+ .btn-primary {
140
+ background: linear-gradient(135deg, ${theme.accent} 0%, ${theme.accent}e6 100%);
141
+ color: white;
142
+ border: none;
143
+ border-radius: 8px;
144
+ padding: 10px 18px;
145
+ font-size: 13px;
146
+ font-weight: 600;
147
+ cursor: pointer;
148
+ transition: all 0.15s cubic-bezier(0.16, 1, 0.3, 1);
149
+ font-family: inherit;
150
+ flex-shrink: 0;
151
+ box-shadow:
152
+ 0 2px 8px ${theme.accent}30,
153
+ inset 0 1px 0 rgba(255, 255, 255, 0.2);
154
+ letter-spacing: -0.01em;
155
+ }
156
+
157
+ .btn-primary:hover {
158
+ transform: translateY(-1px) scale(1.02);
159
+ box-shadow:
160
+ 0 4px 12px ${theme.accent}40,
161
+ inset 0 1px 0 rgba(255, 255, 255, 0.25);
162
+ }
163
+
164
+ .btn-primary:active {
165
+ transform: translateY(0) scale(0.98);
166
+ transition: all 0.08s cubic-bezier(0.16, 1, 0.3, 1);
167
+ }
168
+
169
+ @media (max-width: 640px) {
170
+ .usage-banner {
171
+ width: calc(100vw - 24px);
172
+ }
173
+
174
+ .banner-content {
175
+ padding: 16px;
176
+ gap: 12px;
177
+ }
178
+
179
+ .banner-message {
180
+ font-size: 13px;
181
+ line-height: 1.45;
182
+ }
183
+
184
+ .btn-primary {
185
+ padding: 8px 14px;
186
+ font-size: 12px;
176
187
  }
177
- to {
178
- opacity: 1;
179
- transform: translateX(-50%) translateY(0);
180
- scale: 1;
188
+
189
+ .close-btn {
190
+ width: 22px;
191
+ height: 22px;
192
+ font-size: 12px;
181
193
  }
182
194
  }
183
195
  `}
184
196
  </style>
185
- <div
186
- style={{
187
- borderRadius: "12px",
188
- border: `1px solid ${themeConfig.border}`,
189
- background: themeConfig.bg,
190
- padding: "14px",
191
- boxShadow: "0 8px 32px rgba(0, 0, 0, 0.12), 0 2px 8px rgba(0, 0, 0, 0.08)",
192
- position: "relative",
193
- backdropFilter: "blur(12px)",
194
- WebkitBackdropFilter: "blur(12px)",
195
- boxSizing: "border-box",
196
- overflow: "hidden",
197
- }}
198
- >
199
- {/* Close button */}
200
- {onClose && (
201
- <button
202
- onClick={onClose}
203
- style={{
204
- position: "absolute",
205
- top: "8px",
206
- right: "8px",
207
- background: "rgba(255, 255, 255, 0.9)",
208
- border: "none",
209
- color: themeConfig.text,
210
- cursor: "pointer",
211
- fontSize: "16px",
212
- lineHeight: "1",
213
- padding: "4px",
214
- borderRadius: "4px",
215
- width: "20px",
216
- height: "20px",
217
- display: "flex",
218
- alignItems: "center",
219
- justifyContent: "center",
220
- }}
221
- title="Close"
222
- >
223
- ×
224
- </button>
225
- )}
226
197
 
227
- {/* Message */}
228
- <div
229
- style={{
230
- fontSize: "14px",
231
- fontWeight: 500,
232
- color: themeConfig.text,
233
- lineHeight: "1.4",
234
- fontFamily: "-apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif",
235
- paddingRight: onClose ? "30px" : "0",
236
- marginBottom: actions ? "12px" : "0",
237
- wordBreak: "break-word",
238
- overflow: "hidden",
239
- textOverflow: "ellipsis",
240
- display: "-webkit-box",
241
- WebkitLineClamp: 2,
242
- WebkitBoxOrient: "vertical",
243
- }}
244
- >
245
- {cleanMessage}
198
+ <div className="usage-banner">
199
+ <div className="banner-content">
200
+ <div className="banner-message">{message}</div>
201
+ {actions?.primary && (
202
+ <button className="btn-primary" onClick={actions.primary.onClick}>
203
+ {actions.primary.label}
204
+ </button>
205
+ )}
206
+ {onClose && (
207
+ <button className="close-btn" onClick={onClose} title="Close">
208
+ ×
209
+ </button>
210
+ )}
246
211
  </div>
247
-
248
- {/* Actions */}
249
- {actions && (
250
- <div
251
- style={{
252
- display: "flex",
253
- gap: "8px",
254
- flexWrap: "wrap",
255
- }}
256
- >
257
- {actions.secondary && (
258
- <button
259
- onClick={actions.secondary.onClick}
260
- style={{
261
- borderRadius: "8px",
262
- padding: "6px 12px",
263
- fontSize: "13px",
264
- fontWeight: 500,
265
- color: themeConfig.text,
266
- backgroundColor: "rgba(255, 255, 255, 0.9)",
267
- border: `1px 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
- }}
276
- onMouseOut={(e) => {
277
- e.currentTarget.style.backgroundColor = "rgba(255, 255, 255, 0.9)";
278
- e.currentTarget.style.transform = "translateY(0)";
279
- }}
280
- >
281
- {actions.secondary.label}
282
- </button>
283
- )}
284
- {actions.primary && (
285
- <button
286
- onClick={actions.primary.onClick}
287
- style={{
288
- borderRadius: "8px",
289
- padding: "6px 12px",
290
- fontSize: "13px",
291
- fontWeight: 600,
292
- color: "#fff",
293
- backgroundColor: themeConfig.primaryBtn,
294
- border: "none",
295
- cursor: "pointer",
296
- transition: "all 0.2s ease",
297
- boxShadow: "0 2px 8px rgba(0, 0, 0, 0.15)",
298
- fontFamily: "-apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif",
299
- }}
300
- onMouseOver={(e) => {
301
- e.currentTarget.style.backgroundColor = themeConfig.primaryBtnHover;
302
- e.currentTarget.style.transform = "translateY(-1px)";
303
- e.currentTarget.style.boxShadow = "0 4px 12px rgba(0, 0, 0, 0.2)";
304
- }}
305
- onMouseOut={(e) => {
306
- e.currentTarget.style.backgroundColor = themeConfig.primaryBtn;
307
- e.currentTarget.style.transform = "translateY(0)";
308
- e.currentTarget.style.boxShadow = "0 2px 8px rgba(0, 0, 0, 0.15)";
309
- }}
310
- >
311
- {actions.primary.label}
312
- </button>
313
- )}
314
- </div>
315
- )}
316
212
  </div>
317
- </div>
213
+ </>
318
214
  );
319
215
  }
320
216
 
217
+ // Get action button based on error type
218
+ export const getErrorActions = (error: CopilotKitError) => {
219
+ switch (error.code) {
220
+ case CopilotKitErrorCode.MISSING_PUBLIC_API_KEY_ERROR:
221
+ return {
222
+ primary: {
223
+ label: "Show me how",
224
+ onClick: () =>
225
+ window.open(
226
+ "https://docs.copilotkit.ai/docs/guides/subscription",
227
+ "_blank",
228
+ "noopener,noreferrer",
229
+ ),
230
+ },
231
+ };
232
+ case CopilotKitErrorCode.UPGRADE_REQUIRED_ERROR:
233
+ return {
234
+ primary: {
235
+ label: "Upgrade",
236
+ onClick: () =>
237
+ window.open("https://cloud.copilotkit.ai", "_blank", "noopener,noreferrer"),
238
+ },
239
+ };
240
+ default:
241
+ return undefined;
242
+ }
243
+ };
244
+
321
245
  export function renderCopilotKitUsage(error: CopilotKitError, onClose?: () => void) {
322
246
  // Route based on error visibility level
323
247
  if (error.visibility !== ErrorVisibility.BANNER) {
324
248
  return null;
325
249
  }
326
250
 
327
- // Extract URL from markdown links in the message
328
- const extractUrlFromMessage = (message: string): string | null => {
329
- const linkRegex = /\[([^\]]+)\]\(([^)]+)\)/g;
330
- const match = linkRegex.exec(message);
331
- return match ? match[2] : null;
332
- };
333
-
334
- // Get action button based on error type
335
- const getErrorActions = (error: CopilotKitError) => {
336
- switch (error.name) {
337
- case ERROR_NAMES.MISSING_PUBLIC_API_KEY_ERROR:
338
- return {
339
- primary: {
340
- label: "Sign In",
341
- onClick: () => (window.location.href = "https://cloud.copilotkit.ai"),
342
- },
343
- };
344
- case ERROR_NAMES.UPGRADE_REQUIRED_ERROR:
345
- return {
346
- primary: {
347
- label: "Upgrade",
348
- onClick: () => (window.location.href = "https://copilotkit.ai/"),
349
- },
350
- };
351
- case ERROR_NAMES.COPILOT_API_DISCOVERY_ERROR:
352
- case ERROR_NAMES.COPILOT_REMOTE_ENDPOINT_DISCOVERY_ERROR:
353
- case ERROR_NAMES.COPILOT_KIT_AGENT_DISCOVERY_ERROR:
354
- return {
355
- primary: {
356
- label: "View Docs",
357
- onClick: () => {
358
- // Try to get URL from the error message first, then extensions, then default
359
- const urlFromMessage = extractUrlFromMessage(error.message);
360
- const urlFromExtensions = (error.extensions as any)?.troubleshootingUrl;
361
- const url =
362
- urlFromMessage ||
363
- urlFromExtensions ||
364
- "https://docs.copilotkit.ai/troubleshooting/common-issues";
365
- window.open(url, "_blank");
366
- },
367
- },
368
- };
369
- default:
370
- return undefined;
371
- }
372
- };
373
-
374
251
  return (
375
252
  <UsageBanner
376
253
  severity={error.severity || Severity.CRITICAL}
@@ -1,4 +1,9 @@
1
- import { CopilotCloudConfig, FunctionCallHandler, CopilotErrorHandler } from "@copilotkit/shared";
1
+ import {
2
+ CopilotCloudConfig,
3
+ FunctionCallHandler,
4
+ CopilotErrorHandler,
5
+ CopilotKitError,
6
+ } from "@copilotkit/shared";
2
7
  import {
3
8
  ActionRenderProps,
4
9
  CatchAllActionRenderProps,
@@ -224,9 +229,10 @@ export interface CopilotContextParams {
224
229
  * Optional trace handler for comprehensive debugging and observability.
225
230
  */
226
231
  onError?: CopilotErrorHandler;
227
- // suggestions state
228
- suggestions: SuggestionItem[];
229
- setSuggestions: React.Dispatch<React.SetStateAction<SuggestionItem[]>>;
232
+
233
+ // banner error state
234
+ bannerError: CopilotKitError | null;
235
+ setBannerError: React.Dispatch<React.SetStateAction<CopilotKitError | null>>;
230
236
  }
231
237
 
232
238
  const emptyCopilotContext: CopilotContextParams = {
@@ -298,8 +304,8 @@ const emptyCopilotContext: CopilotContextParams = {
298
304
  setLangGraphInterruptAction: () => null,
299
305
  removeLangGraphInterruptAction: () => null,
300
306
  onError: undefined,
301
- suggestions: [],
302
- setSuggestions: () => {},
307
+ bannerError: null,
308
+ setBannerError: () => {},
303
309
  };
304
310
 
305
311
  export const CopilotContext = React.createContext<CopilotContextParams>(emptyCopilotContext);
@@ -4,15 +4,21 @@
4
4
 
5
5
  import { Message } from "@copilotkit/runtime-client-gql";
6
6
  import React from "react";
7
+ import { SuggestionItem } from "../utils/suggestions";
7
8
 
8
9
  export interface CopilotMessagesContextParams {
9
10
  messages: Message[];
10
- setMessages: React.Dispatch<React.SetStateAction<Message[]>>;
11
+ setMessages: React.Dispatch<React.SetStateAction<Message[]>>; // suggestions state
12
+ suggestions: SuggestionItem[];
13
+ setSuggestions: React.Dispatch<React.SetStateAction<SuggestionItem[]>>;
11
14
  }
12
15
 
13
16
  const emptyCopilotContext: CopilotMessagesContextParams = {
14
17
  messages: [],
15
18
  setMessages: () => [],
19
+ // suggestions state
20
+ suggestions: [],
21
+ setSuggestions: () => [],
16
22
  };
17
23
 
18
24
  export const CopilotMessagesContext =
@@ -6,7 +6,7 @@ const mockSetCoagentStatesWithRef = jest.fn();
6
6
  const mockAppendMessage = jest.fn();
7
7
  const mockRunChatCompletion = jest.fn();
8
8
 
9
- jest.mock("../use-copilot-chat", () => ({
9
+ jest.mock("../use-copilot-chat_internal", () => ({
10
10
  useCopilotChat: () => ({
11
11
  appendMessage: mockAppendMessage,
12
12
  runChatCompletion: mockRunChatCompletion,
@@ -51,6 +51,13 @@ jest.mock("../../components/error-boundary/error-utils", () => ({
51
51
  useAsyncCallback: (fn: any) => fn,
52
52
  }));
53
53
 
54
+ jest.mock("../../components/copilot-provider/copilot-messages", () => ({
55
+ useMessagesTap: () => ({
56
+ getMessagesFromTap: jest.fn(() => []),
57
+ updateTapMessages: jest.fn(),
58
+ }),
59
+ }));
60
+
54
61
  describe("useCoAgent config synchronization", () => {
55
62
  beforeEach(() => {
56
63
  jest.clearAllMocks();
@@ -1,7 +1,12 @@
1
1
  export { useCopilotChat } from "./use-copilot-chat";
2
- export type { UseCopilotChatOptions } from "./use-copilot-chat";
3
2
  export type { UseCopilotChatReturn } from "./use-copilot-chat";
4
-
3
+ export type { UseCopilotChatOptions } from "./use-copilot-chat_internal";
4
+ export {
5
+ type UseCopilotChatReturn_c,
6
+ type UseCopilotChatOptions_c,
7
+ useCopilotChatHeadless_c,
8
+ } from "./use-copilot-chat-headless_c";
9
+ export { useCopilotChat as useCopilotChatInternal } from "./use-copilot-chat_internal";
5
10
  export { useCopilotAction } from "./use-copilot-action";
6
11
  export { useCoAgentStateRender } from "./use-coagent-state-render";
7
12
  export { useMakeCopilotDocumentReadable } from "./use-make-copilot-document-readable";