@copilotkit/react-core 1.10.0-next.2 → 1.10.0-next.4

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 (190) hide show
  1. package/CHANGELOG.md +15 -0
  2. package/dist/{chunk-VOMGRGWT.mjs → chunk-2JAX6WE6.mjs} +7 -7
  3. package/dist/chunk-2JAX6WE6.mjs.map +1 -0
  4. package/dist/{chunk-WUORFPJ7.mjs → chunk-2WYJIO6D.mjs} +4 -4
  5. package/dist/chunk-373NOCJI.mjs +79 -0
  6. package/dist/chunk-373NOCJI.mjs.map +1 -0
  7. package/dist/{chunk-XGRBCWK6.mjs → chunk-47GMU44Z.mjs} +4 -1
  8. package/dist/chunk-47GMU44Z.mjs.map +1 -0
  9. package/dist/{chunk-DF4YG4PF.mjs → chunk-57MBVQPX.mjs} +2 -2
  10. package/dist/{chunk-JZQOCH4A.mjs → chunk-5JL5ELUS.mjs} +2 -2
  11. package/dist/{chunk-LNAQ7JG3.mjs → chunk-AC2GVFW6.mjs} +2 -2
  12. package/dist/{chunk-RGKZCCPA.mjs → chunk-AVMA2MCW.mjs} +3 -3
  13. package/dist/chunk-AWFAFFO5.mjs +221 -0
  14. package/dist/chunk-AWFAFFO5.mjs.map +1 -0
  15. package/dist/{chunk-4XVBXDCX.mjs → chunk-BBK7LXZ6.mjs} +5 -5
  16. package/dist/{chunk-YAF2LATQ.mjs → chunk-EFL5OBKN.mjs} +1 -1
  17. package/dist/chunk-EFL5OBKN.mjs.map +1 -0
  18. package/dist/{chunk-4CFY3CON.mjs → chunk-EQQSE6KM.mjs} +2 -2
  19. package/dist/{chunk-JWAXDYOW.mjs → chunk-FAUNHSQU.mjs} +3 -3
  20. package/dist/{chunk-NXCJELW7.mjs → chunk-G7J6NY5J.mjs} +3 -3
  21. package/dist/chunk-ICIK2BSB.mjs +17 -0
  22. package/dist/chunk-ICIK2BSB.mjs.map +1 -0
  23. package/dist/{chunk-PYULBXCD.mjs → chunk-JLQZVKFX.mjs} +4 -4
  24. package/dist/chunk-KDAZGZ24.mjs +1 -0
  25. package/dist/{chunk-OMVNJ7S3.mjs → chunk-L7CWMU4O.mjs} +34 -19
  26. package/dist/chunk-L7CWMU4O.mjs.map +1 -0
  27. package/dist/{chunk-3OQM3NEK.mjs → chunk-N4WEHORG.mjs} +2 -2
  28. package/dist/{chunk-Q6FZZJ5A.mjs → chunk-OL3VRQKU.mjs} +2 -2
  29. package/dist/chunk-PQ5IXT4Z.mjs +18 -0
  30. package/dist/chunk-PQ5IXT4Z.mjs.map +1 -0
  31. package/dist/{chunk-VM7CVIET.mjs → chunk-PRKL7T7P.mjs} +6 -6
  32. package/dist/chunk-PRKL7T7P.mjs.map +1 -0
  33. package/dist/{chunk-KV25ZRMH.mjs → chunk-XIHAYU6C.mjs} +4 -4
  34. package/dist/chunk-XIHAYU6C.mjs.map +1 -0
  35. package/dist/{chunk-SGF6C7I6.mjs → chunk-ZTZJIDRJ.mjs} +9 -14
  36. package/dist/chunk-ZTZJIDRJ.mjs.map +1 -0
  37. package/dist/components/copilot-provider/copilot-messages.js +12 -1
  38. package/dist/components/copilot-provider/copilot-messages.js.map +1 -1
  39. package/dist/components/copilot-provider/copilot-messages.mjs +4 -4
  40. package/dist/components/copilot-provider/copilotkit-props.d.ts +1 -1
  41. package/dist/components/copilot-provider/copilotkit.d.ts +1 -1
  42. package/dist/components/copilot-provider/copilotkit.js +307 -550
  43. package/dist/components/copilot-provider/copilotkit.js.map +1 -1
  44. package/dist/components/copilot-provider/copilotkit.mjs +9 -9
  45. package/dist/components/copilot-provider/index.d.ts +1 -1
  46. package/dist/components/copilot-provider/index.js +307 -550
  47. package/dist/components/copilot-provider/index.js.map +1 -1
  48. package/dist/components/copilot-provider/index.mjs +9 -9
  49. package/dist/components/error-boundary/error-boundary.js +172 -323
  50. package/dist/components/error-boundary/error-boundary.js.map +1 -1
  51. package/dist/components/error-boundary/error-boundary.mjs +4 -4
  52. package/dist/components/error-boundary/error-utils.js.map +1 -1
  53. package/dist/components/error-boundary/error-utils.mjs +2 -2
  54. package/dist/components/index.d.ts +1 -1
  55. package/dist/components/index.js +307 -550
  56. package/dist/components/index.js.map +1 -1
  57. package/dist/components/index.mjs +9 -9
  58. package/dist/components/toast/toast-provider.js.map +1 -1
  59. package/dist/components/toast/toast-provider.mjs +1 -1
  60. package/dist/components/usage-banner.d.ts +8 -3
  61. package/dist/components/usage-banner.js +172 -302
  62. package/dist/components/usage-banner.js.map +1 -1
  63. package/dist/components/usage-banner.mjs +3 -1
  64. package/dist/context/copilot-context.d.ts +1 -1
  65. package/dist/context/copilot-context.js +3 -0
  66. package/dist/context/copilot-context.js.map +1 -1
  67. package/dist/context/copilot-context.mjs +1 -1
  68. package/dist/context/index.d.ts +1 -1
  69. package/dist/context/index.js +3 -0
  70. package/dist/context/index.js.map +1 -1
  71. package/dist/context/index.mjs +1 -1
  72. package/dist/{copilot-context-bd88d30d.d.ts → copilot-context-78fc727c.d.ts} +3 -1
  73. package/dist/hooks/index.d.ts +5 -3
  74. package/dist/hooks/index.js +143 -57
  75. package/dist/hooks/index.js.map +1 -1
  76. package/dist/hooks/index.mjs +32 -24
  77. package/dist/hooks/use-chat.d.ts +1 -1
  78. package/dist/hooks/use-chat.js +12 -1
  79. package/dist/hooks/use-chat.js.map +1 -1
  80. package/dist/hooks/use-chat.mjs +6 -6
  81. package/dist/hooks/use-coagent-state-render.js +3 -0
  82. package/dist/hooks/use-coagent-state-render.js.map +1 -1
  83. package/dist/hooks/use-coagent-state-render.mjs +3 -3
  84. package/dist/hooks/use-coagent.d.ts +1 -1
  85. package/dist/hooks/use-coagent.js +15 -4
  86. package/dist/hooks/use-coagent.js.map +1 -1
  87. package/dist/hooks/use-coagent.mjs +13 -13
  88. package/dist/hooks/use-copilot-action.js +3 -0
  89. package/dist/hooks/use-copilot-action.js.map +1 -1
  90. package/dist/hooks/use-copilot-action.mjs +4 -4
  91. package/dist/hooks/use-copilot-additional-instructions.js +3 -0
  92. package/dist/hooks/use-copilot-additional-instructions.js.map +1 -1
  93. package/dist/hooks/use-copilot-additional-instructions.mjs +2 -2
  94. package/dist/hooks/use-copilot-authenticated-action.js +3 -0
  95. package/dist/hooks/use-copilot-authenticated-action.js.map +1 -1
  96. package/dist/hooks/use-copilot-authenticated-action.mjs +5 -5
  97. package/dist/hooks/use-copilot-chat-light.d.ts +211 -0
  98. package/dist/hooks/use-copilot-chat-light.js +1770 -0
  99. package/dist/hooks/use-copilot-chat-light.js.map +1 -0
  100. package/dist/hooks/use-copilot-chat-light.mjs +28 -0
  101. package/dist/hooks/use-copilot-chat-light.mjs.map +1 -0
  102. package/dist/hooks/use-copilot-chat.d.ts +9 -81
  103. package/dist/hooks/use-copilot-chat.js +77 -5
  104. package/dist/hooks/use-copilot-chat.js.map +1 -1
  105. package/dist/hooks/use-copilot-chat.mjs +15 -13
  106. package/dist/hooks/use-copilot-chat_internal.d.ts +91 -0
  107. package/dist/hooks/use-copilot-chat_internal.js +1760 -0
  108. package/dist/hooks/use-copilot-chat_internal.js.map +1 -0
  109. package/dist/hooks/use-copilot-chat_internal.mjs +29 -0
  110. package/dist/hooks/use-copilot-chat_internal.mjs.map +1 -0
  111. package/dist/hooks/use-copilot-readable.js +3 -0
  112. package/dist/hooks/use-copilot-readable.js.map +1 -1
  113. package/dist/hooks/use-copilot-readable.mjs +2 -2
  114. package/dist/hooks/use-copilot-runtime-client.js +9 -1
  115. package/dist/hooks/use-copilot-runtime-client.js.map +1 -1
  116. package/dist/hooks/use-copilot-runtime-client.mjs +3 -3
  117. package/dist/hooks/use-langgraph-interrupt-render.js +3 -0
  118. package/dist/hooks/use-langgraph-interrupt-render.js.map +1 -1
  119. package/dist/hooks/use-langgraph-interrupt-render.mjs +2 -2
  120. package/dist/hooks/use-langgraph-interrupt.d.ts +1 -1
  121. package/dist/hooks/use-langgraph-interrupt.js +15 -4
  122. package/dist/hooks/use-langgraph-interrupt.js.map +1 -1
  123. package/dist/hooks/use-langgraph-interrupt.mjs +13 -13
  124. package/dist/hooks/use-make-copilot-document-readable.js +3 -0
  125. package/dist/hooks/use-make-copilot-document-readable.js.map +1 -1
  126. package/dist/hooks/use-make-copilot-document-readable.mjs +2 -2
  127. package/dist/index.d.ts +4 -2
  128. package/dist/index.js +384 -449
  129. package/dist/index.js.map +1 -1
  130. package/dist/index.mjs +34 -26
  131. package/dist/lib/copilot-task.d.ts +1 -1
  132. package/dist/lib/copilot-task.js.map +1 -1
  133. package/dist/lib/copilot-task.mjs +10 -10
  134. package/dist/lib/index.d.ts +1 -1
  135. package/dist/lib/index.js.map +1 -1
  136. package/dist/lib/index.mjs +10 -10
  137. package/dist/types/interrupt-action.d.ts +1 -1
  138. package/dist/utils/dev-console.d.ts +1 -1
  139. package/dist/utils/dev-console.js +9 -1
  140. package/dist/utils/dev-console.js.map +1 -1
  141. package/dist/utils/dev-console.mjs +1 -1
  142. package/dist/utils/extract.d.ts +1 -1
  143. package/dist/utils/extract.js.map +1 -1
  144. package/dist/utils/extract.mjs +9 -9
  145. package/dist/utils/index.d.ts +1 -1
  146. package/dist/utils/index.js +9 -1
  147. package/dist/utils/index.js.map +1 -1
  148. package/dist/utils/index.mjs +9 -9
  149. package/dist/utils/suggestions.d.ts +1 -1
  150. package/dist/utils/suggestions.js.map +1 -1
  151. package/dist/utils/suggestions.mjs +9 -9
  152. package/package.json +3 -3
  153. package/src/components/copilot-provider/copilotkit.tsx +16 -5
  154. package/src/components/error-boundary/error-boundary.tsx +5 -15
  155. package/src/components/toast/toast-provider.tsx +1 -3
  156. package/src/components/usage-banner.tsx +187 -315
  157. package/src/context/copilot-context.tsx +12 -1
  158. package/src/hooks/__tests__/use-coagent-config.test.ts +1 -1
  159. package/src/hooks/index.ts +6 -0
  160. package/src/hooks/use-coagent.ts +1 -1
  161. package/src/hooks/use-copilot-chat-light.ts +219 -0
  162. package/src/hooks/use-copilot-chat.ts +89 -430
  163. package/src/hooks/use-copilot-chat_internal.ts +437 -0
  164. package/src/hooks/use-langgraph-interrupt.ts +1 -1
  165. package/src/utils/dev-console.ts +18 -2
  166. package/dist/chunk-57K2ZJ5F.mjs +0 -348
  167. package/dist/chunk-57K2ZJ5F.mjs.map +0 -1
  168. package/dist/chunk-CQPYJIBH.mjs +0 -1
  169. package/dist/chunk-GFJW4RIM.mjs +0 -9
  170. package/dist/chunk-GFJW4RIM.mjs.map +0 -1
  171. package/dist/chunk-KV25ZRMH.mjs.map +0 -1
  172. package/dist/chunk-OMVNJ7S3.mjs.map +0 -1
  173. package/dist/chunk-SGF6C7I6.mjs.map +0 -1
  174. package/dist/chunk-VM7CVIET.mjs.map +0 -1
  175. package/dist/chunk-VOMGRGWT.mjs.map +0 -1
  176. package/dist/chunk-XGRBCWK6.mjs.map +0 -1
  177. package/dist/chunk-YAF2LATQ.mjs.map +0 -1
  178. /package/dist/{chunk-WUORFPJ7.mjs.map → chunk-2WYJIO6D.mjs.map} +0 -0
  179. /package/dist/{chunk-DF4YG4PF.mjs.map → chunk-57MBVQPX.mjs.map} +0 -0
  180. /package/dist/{chunk-JZQOCH4A.mjs.map → chunk-5JL5ELUS.mjs.map} +0 -0
  181. /package/dist/{chunk-LNAQ7JG3.mjs.map → chunk-AC2GVFW6.mjs.map} +0 -0
  182. /package/dist/{chunk-RGKZCCPA.mjs.map → chunk-AVMA2MCW.mjs.map} +0 -0
  183. /package/dist/{chunk-4XVBXDCX.mjs.map → chunk-BBK7LXZ6.mjs.map} +0 -0
  184. /package/dist/{chunk-4CFY3CON.mjs.map → chunk-EQQSE6KM.mjs.map} +0 -0
  185. /package/dist/{chunk-JWAXDYOW.mjs.map → chunk-FAUNHSQU.mjs.map} +0 -0
  186. /package/dist/{chunk-NXCJELW7.mjs.map → chunk-G7J6NY5J.mjs.map} +0 -0
  187. /package/dist/{chunk-PYULBXCD.mjs.map → chunk-JLQZVKFX.mjs.map} +0 -0
  188. /package/dist/{chunk-CQPYJIBH.mjs.map → chunk-KDAZGZ24.mjs.map} +0 -0
  189. /package/dist/{chunk-3OQM3NEK.mjs.map → chunk-N4WEHORG.mjs.map} +0 -0
  190. /package/dist/{chunk-Q6FZZJ5A.mjs.map → chunk-OL3VRQKU.mjs.map} +0 -0
@@ -1,9 +1,13 @@
1
- import { Severity, CopilotKitError, ERROR_NAMES, ErrorVisibility } from "@copilotkit/shared";
1
+ import {
2
+ Severity,
3
+ CopilotKitError,
4
+ ErrorVisibility,
5
+ CopilotKitErrorCode,
6
+ } from "@copilotkit/shared";
2
7
 
3
8
  interface UsageBannerProps {
4
9
  severity?: Severity;
5
10
  message?: string;
6
- icon?: React.ReactNode;
7
11
  onClose?: () => void;
8
12
  actions?: {
9
13
  primary?: {
@@ -17,61 +21,9 @@ interface UsageBannerProps {
17
21
  };
18
22
  }
19
23
 
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
24
  export function UsageBanner({
72
25
  severity = Severity.CRITICAL,
73
26
  message = "",
74
- icon,
75
27
  onClose,
76
28
  actions,
77
29
  }: UsageBannerProps) {
@@ -79,298 +31,218 @@ export function UsageBanner({
79
31
  return null;
80
32
  }
81
33
 
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 = {
34
+ const themes = {
128
35
  [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",
36
+ bg: "#f8fafc",
37
+ border: "#e2e8f0",
38
+ text: "#475569",
39
+ accent: "#3b82f6",
135
40
  },
136
41
  [Severity.WARNING]: {
137
- bg: "rgba(255, 251, 235, 0.95)",
42
+ bg: "#fffbeb",
138
43
  border: "#fbbf24",
139
44
  text: "#92400e",
140
- icon: "#f59e0b",
141
- primaryBtn: "#f59e0b",
142
- primaryBtnHover: "#d97706",
45
+ accent: "#f59e0b",
143
46
  },
144
47
  [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",
48
+ bg: "#fef2f2",
49
+ border: "#fecaca",
50
+ text: "#dc2626",
51
+ accent: "#ef4444",
151
52
  },
152
53
  };
153
54
 
154
- const themeConfig = themeConfigs[severity] || themeConfigs[Severity.CRITICAL];
55
+ const theme = themes[severity];
155
56
 
156
57
  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
- >
58
+ <>
169
59
  <style>
170
60
  {`
171
- @keyframes bannerSlideIn {
172
- from {
173
- opacity: 0;
174
- transform: translateX(-50%) translateY(20px);
175
- scale: 0.95;
61
+ @keyframes slideUp {
62
+ from { opacity: 0; transform: translateX(-50%) translateY(8px); }
63
+ to { opacity: 1; transform: translateX(-50%) translateY(0); }
64
+ }
65
+
66
+ .usage-banner {
67
+ position: fixed;
68
+ bottom: 24px;
69
+ left: 50%;
70
+ transform: translateX(-50%);
71
+ width: min(600px, calc(100vw - 32px));
72
+ z-index: 10000;
73
+ animation: slideUp 0.2s cubic-bezier(0.16, 1, 0.3, 1);
74
+ }
75
+
76
+ .banner-content {
77
+ background: linear-gradient(135deg, ${theme.bg} 0%, ${theme.bg}f5 100%);
78
+ border: 1px solid ${theme.border};
79
+ border-radius: 12px;
80
+ padding: 18px 20px;
81
+ box-shadow:
82
+ 0 4px 24px rgba(0, 0, 0, 0.08),
83
+ 0 2px 8px rgba(0, 0, 0, 0.04),
84
+ inset 0 1px 0 rgba(255, 255, 255, 0.7);
85
+ display: flex;
86
+ align-items: center;
87
+ gap: 16px;
88
+ font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', system-ui, sans-serif;
89
+ backdrop-filter: blur(12px);
90
+ position: relative;
91
+ overflow: hidden;
92
+ }
93
+
94
+ .banner-content::before {
95
+ content: '';
96
+ position: absolute;
97
+ top: 0;
98
+ left: 0;
99
+ right: 0;
100
+ height: 1px;
101
+ background: linear-gradient(90deg, transparent, ${theme.accent}40, transparent);
102
+ }
103
+
104
+ .banner-message {
105
+ color: ${theme.text};
106
+ font-size: 14px;
107
+ line-height: 1.5;
108
+ font-weight: 500;
109
+ flex: 1;
110
+ letter-spacing: -0.01em;
111
+ }
112
+
113
+ .close-btn {
114
+ background: rgba(0, 0, 0, 0.05);
115
+ border: none;
116
+ color: ${theme.text};
117
+ cursor: pointer;
118
+ padding: 0;
119
+ border-radius: 6px;
120
+ opacity: 0.6;
121
+ transition: all 0.15s cubic-bezier(0.16, 1, 0.3, 1);
122
+ font-size: 14px;
123
+ line-height: 1;
124
+ flex-shrink: 0;
125
+ width: 24px;
126
+ height: 24px;
127
+ display: flex;
128
+ align-items: center;
129
+ justify-content: center;
130
+ }
131
+
132
+ .close-btn:hover {
133
+ opacity: 1;
134
+ background: rgba(0, 0, 0, 0.08);
135
+ transform: scale(1.05);
136
+ }
137
+
138
+ .btn-primary {
139
+ background: linear-gradient(135deg, ${theme.accent} 0%, ${theme.accent}e6 100%);
140
+ color: white;
141
+ border: none;
142
+ border-radius: 8px;
143
+ padding: 10px 18px;
144
+ font-size: 13px;
145
+ font-weight: 600;
146
+ cursor: pointer;
147
+ transition: all 0.15s cubic-bezier(0.16, 1, 0.3, 1);
148
+ font-family: inherit;
149
+ flex-shrink: 0;
150
+ box-shadow:
151
+ 0 2px 8px ${theme.accent}30,
152
+ inset 0 1px 0 rgba(255, 255, 255, 0.2);
153
+ letter-spacing: -0.01em;
154
+ }
155
+
156
+ .btn-primary:hover {
157
+ transform: translateY(-1px) scale(1.02);
158
+ box-shadow:
159
+ 0 4px 12px ${theme.accent}40,
160
+ inset 0 1px 0 rgba(255, 255, 255, 0.25);
161
+ }
162
+
163
+ .btn-primary:active {
164
+ transform: translateY(0) scale(0.98);
165
+ transition: all 0.08s cubic-bezier(0.16, 1, 0.3, 1);
166
+ }
167
+
168
+ @media (max-width: 640px) {
169
+ .usage-banner {
170
+ width: calc(100vw - 24px);
171
+ }
172
+
173
+ .banner-content {
174
+ padding: 16px;
175
+ gap: 12px;
176
+ }
177
+
178
+ .banner-message {
179
+ font-size: 13px;
180
+ line-height: 1.45;
181
+ }
182
+
183
+ .btn-primary {
184
+ padding: 8px 14px;
185
+ font-size: 12px;
176
186
  }
177
- to {
178
- opacity: 1;
179
- transform: translateX(-50%) translateY(0);
180
- scale: 1;
187
+
188
+ .close-btn {
189
+ width: 22px;
190
+ height: 22px;
191
+ font-size: 12px;
181
192
  }
182
193
  }
183
194
  `}
184
195
  </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
196
 
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}
197
+ <div className="usage-banner">
198
+ <div className="banner-content">
199
+ <div className="banner-message">{message}</div>
200
+ {actions?.primary && (
201
+ <button className="btn-primary" onClick={actions.primary.onClick}>
202
+ {actions.primary.label}
203
+ </button>
204
+ )}
205
+ {onClose && (
206
+ <button className="close-btn" onClick={onClose} title="Close">
207
+ ×
208
+ </button>
209
+ )}
246
210
  </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
211
  </div>
317
- </div>
212
+ </>
318
213
  );
319
214
  }
320
215
 
216
+ // Get action button based on error type
217
+ export const getErrorActions = (error: CopilotKitError) => {
218
+ switch (error.code) {
219
+ case CopilotKitErrorCode.MISSING_PUBLIC_API_KEY_ERROR:
220
+ return {
221
+ primary: {
222
+ label: "Get Free API Key",
223
+ onClick: () =>
224
+ window.open("https://cloud.copilotkit.ai", "_blank", "noopener,noreferrer"),
225
+ },
226
+ };
227
+ case CopilotKitErrorCode.UPGRADE_REQUIRED_ERROR:
228
+ return {
229
+ primary: {
230
+ label: "Upgrade",
231
+ onClick: () =>
232
+ window.open("https://cloud.copilotkit.ai", "_blank", "noopener,noreferrer"),
233
+ },
234
+ };
235
+ default:
236
+ return undefined;
237
+ }
238
+ };
239
+
321
240
  export function renderCopilotKitUsage(error: CopilotKitError, onClose?: () => void) {
322
241
  // Route based on error visibility level
323
242
  if (error.visibility !== ErrorVisibility.BANNER) {
324
243
  return null;
325
244
  }
326
245
 
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
246
  return (
375
247
  <UsageBanner
376
248
  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,
@@ -226,6 +231,10 @@ export interface CopilotContextParams {
226
231
  onError?: CopilotErrorHandler;
227
232
  // suggestions state
228
233
  suggestions: SuggestionItem[];
234
+
235
+ // banner error state
236
+ bannerError: CopilotKitError | null;
237
+ setBannerError: React.Dispatch<React.SetStateAction<CopilotKitError | null>>;
229
238
  setSuggestions: React.Dispatch<React.SetStateAction<SuggestionItem[]>>;
230
239
  }
231
240
 
@@ -299,6 +308,8 @@ const emptyCopilotContext: CopilotContextParams = {
299
308
  removeLangGraphInterruptAction: () => null,
300
309
  onError: undefined,
301
310
  suggestions: [],
311
+ bannerError: null,
312
+ setBannerError: () => {},
302
313
  setSuggestions: () => {},
303
314
  };
304
315
 
@@ -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,
@@ -2,6 +2,12 @@ export { useCopilotChat } from "./use-copilot-chat";
2
2
  export type { UseCopilotChatOptions } from "./use-copilot-chat";
3
3
  export type { UseCopilotChatReturn } from "./use-copilot-chat";
4
4
 
5
+ export { useCopilotChatLight } from "./use-copilot-chat-light";
6
+ export type {
7
+ UseCopilotChatLightOptions,
8
+ UseCopilotChatLightReturn,
9
+ } from "./use-copilot-chat-light";
10
+ export { useCopilotChat as useCopilotChatInternal } from "./use-copilot-chat_internal";
5
11
  export { useCopilotAction } from "./use-copilot-action";
6
12
  export { useCoAgentStateRender } from "./use-coagent-state-render";
7
13
  export { useMakeCopilotDocumentReadable } from "./use-make-copilot-document-readable";
@@ -96,7 +96,7 @@ import {
96
96
  useCopilotMessagesContext,
97
97
  } from "../context";
98
98
  import { CoagentState } from "../types/coagent-state";
99
- import { useCopilotChat } from "./use-copilot-chat";
99
+ import { useCopilotChat } from "./use-copilot-chat_internal";
100
100
  import { Message } from "@copilotkit/shared";
101
101
  import { useAsyncCallback } from "../components/error-boundary/error-utils";
102
102
  import { useToast } from "../components/toast/toast-provider";