@copilotkitnext/react 0.0.3 → 0.0.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 (48) hide show
  1. package/package.json +3 -3
  2. package/.turbo/turbo-build$colon$css.log +0 -9
  3. package/.turbo/turbo-build.log +0 -30
  4. package/.turbo/turbo-check-types.log +0 -7
  5. package/.turbo/turbo-lint.log +0 -78
  6. package/.turbo/turbo-test.log +0 -79
  7. package/postcss.config.js +0 -7
  8. package/src/__tests__/setup.ts +0 -2
  9. package/src/components/chat/CopilotChat.tsx +0 -90
  10. package/src/components/chat/CopilotChatAssistantMessage.tsx +0 -478
  11. package/src/components/chat/CopilotChatAudioRecorder.tsx +0 -157
  12. package/src/components/chat/CopilotChatInput.tsx +0 -596
  13. package/src/components/chat/CopilotChatMessageView.tsx +0 -85
  14. package/src/components/chat/CopilotChatToolCallsView.tsx +0 -43
  15. package/src/components/chat/CopilotChatUserMessage.tsx +0 -337
  16. package/src/components/chat/CopilotChatView.tsx +0 -385
  17. package/src/components/chat/__tests__/CopilotChatAssistantMessage.test.tsx +0 -684
  18. package/src/components/chat/__tests__/CopilotChatInput.test.tsx +0 -531
  19. package/src/components/chat/__tests__/setup.ts +0 -1
  20. package/src/components/chat/index.ts +0 -35
  21. package/src/components/index.ts +0 -4
  22. package/src/components/ui/button.tsx +0 -123
  23. package/src/components/ui/dropdown-menu.tsx +0 -257
  24. package/src/components/ui/tooltip.tsx +0 -59
  25. package/src/hooks/index.ts +0 -6
  26. package/src/hooks/use-agent-context.tsx +0 -17
  27. package/src/hooks/use-agent.tsx +0 -48
  28. package/src/hooks/use-frontend-tool.tsx +0 -46
  29. package/src/hooks/use-human-in-the-loop.tsx +0 -76
  30. package/src/hooks/use-render-tool-call.tsx +0 -81
  31. package/src/index.ts +0 -4
  32. package/src/lib/__tests__/completePartialMarkdown.test.ts +0 -495
  33. package/src/lib/__tests__/renderSlot.test.tsx +0 -610
  34. package/src/lib/slots.tsx +0 -55
  35. package/src/lib/utils.ts +0 -6
  36. package/src/providers/CopilotChatConfigurationProvider.tsx +0 -81
  37. package/src/providers/CopilotKitProvider.tsx +0 -269
  38. package/src/providers/__tests__/CopilotKitProvider.test.tsx +0 -487
  39. package/src/providers/__tests__/CopilotKitProvider.wildcard.test.tsx +0 -261
  40. package/src/providers/index.ts +0 -14
  41. package/src/styles/globals.css +0 -302
  42. package/src/types/frontend-tool.ts +0 -8
  43. package/src/types/human-in-the-loop.ts +0 -33
  44. package/src/types/index.ts +0 -3
  45. package/src/types/react-tool-call-render.ts +0 -29
  46. package/tailwind.config.js +0 -9
  47. package/tsconfig.json +0 -23
  48. package/tsup.config.ts +0 -19
@@ -1,385 +0,0 @@
1
- import React, { useRef, useState, useEffect } from "react";
2
- import { WithSlots, renderSlot } from "@/lib/slots";
3
- import CopilotChatMessageView from "./CopilotChatMessageView";
4
- import CopilotChatInput from "./CopilotChatInput";
5
- import { Message } from "@ag-ui/core";
6
- import { twMerge } from "tailwind-merge";
7
- import { StickToBottom, useStickToBottom, useStickToBottomContext } from "use-stick-to-bottom";
8
- import { ChevronDown } from "lucide-react";
9
- import { Button } from "@/components/ui/button";
10
- import { cn } from "@/lib/utils";
11
- import { useCopilotChatConfiguration } from "@/providers/CopilotChatConfigurationProvider";
12
-
13
- export type CopilotChatViewProps = WithSlots<
14
- {
15
- messageView: typeof CopilotChatMessageView;
16
- scrollView: React.FC<React.HTMLAttributes<HTMLDivElement>>;
17
- scrollToBottomButton: React.FC<
18
- React.ButtonHTMLAttributes<HTMLButtonElement>
19
- >;
20
- input: typeof CopilotChatInput;
21
- inputContainer: React.FC<
22
- React.HTMLAttributes<HTMLDivElement> & { children: React.ReactNode }
23
- >;
24
- feather: React.FC<React.HTMLAttributes<HTMLDivElement>>;
25
- disclaimer: React.FC<React.HTMLAttributes<HTMLDivElement>>;
26
- },
27
- {
28
- messages?: Message[];
29
- autoScroll?: boolean;
30
- } & React.HTMLAttributes<HTMLDivElement>
31
- >;
32
-
33
- export function CopilotChatView({
34
- messageView,
35
- input,
36
- scrollView,
37
- scrollToBottomButton,
38
- feather,
39
- inputContainer,
40
- disclaimer,
41
- messages = [],
42
- autoScroll = true,
43
- children,
44
- className,
45
- ...props
46
- }: CopilotChatViewProps) {
47
- const inputContainerRef = useRef<HTMLDivElement>(null);
48
- const [inputContainerHeight, setInputContainerHeight] = useState(0);
49
- const [isResizing, setIsResizing] = useState(false);
50
- const resizeTimeoutRef = useRef<NodeJS.Timeout | null>(null);
51
-
52
- // Track input container height changes
53
- useEffect(() => {
54
- const element = inputContainerRef.current;
55
- if (!element) return;
56
-
57
- const resizeObserver = new ResizeObserver((entries) => {
58
- for (const entry of entries) {
59
- const newHeight = entry.contentRect.height;
60
-
61
- // Update height and set resizing state
62
- setInputContainerHeight((prevHeight) => {
63
- if (newHeight !== prevHeight) {
64
- setIsResizing(true);
65
-
66
- // Clear existing timeout
67
- if (resizeTimeoutRef.current) {
68
- clearTimeout(resizeTimeoutRef.current);
69
- }
70
-
71
- // Set isResizing to false after a short delay
72
- resizeTimeoutRef.current = setTimeout(() => {
73
- setIsResizing(false);
74
- }, 250);
75
-
76
- return newHeight;
77
- }
78
- return prevHeight;
79
- });
80
- }
81
- });
82
-
83
- resizeObserver.observe(element);
84
-
85
- // Set initial height
86
- setInputContainerHeight(element.offsetHeight);
87
-
88
- return () => {
89
- resizeObserver.disconnect();
90
- if (resizeTimeoutRef.current) {
91
- clearTimeout(resizeTimeoutRef.current);
92
- }
93
- };
94
- }, []);
95
-
96
- const BoundMessageView = renderSlot(messageView, CopilotChatMessageView, {
97
- messages,
98
- });
99
-
100
- const BoundInput = renderSlot(input, CopilotChatInput, {});
101
- const BoundFeather = renderSlot(feather, CopilotChatView.Feather, {});
102
- const BoundScrollView = renderSlot(scrollView, CopilotChatView.ScrollView, {
103
- autoScroll,
104
- scrollToBottomButton,
105
- inputContainerHeight,
106
- isResizing,
107
- children: (
108
- <div style={{ paddingBottom: `${inputContainerHeight + 32}px` }}>
109
- <div className="max-w-3xl mx-auto">{BoundMessageView}</div>
110
- </div>
111
- ),
112
- });
113
-
114
- const BoundScrollToBottomButton = renderSlot(
115
- scrollToBottomButton,
116
- CopilotChatView.ScrollToBottomButton,
117
- {}
118
- );
119
-
120
- const BoundDisclaimer = renderSlot(
121
- disclaimer,
122
- CopilotChatView.Disclaimer,
123
- {}
124
- );
125
-
126
- const BoundInputContainer = renderSlot(
127
- inputContainer,
128
- CopilotChatView.InputContainer,
129
- {
130
- ref: inputContainerRef,
131
- children: (
132
- <>
133
- <div className="max-w-3xl mx-auto py-0 px-4 sm:px-0">
134
- {BoundInput}
135
- </div>
136
- {BoundDisclaimer}
137
- </>
138
- ),
139
- }
140
- );
141
-
142
- if (children) {
143
- return children({
144
- messageView: BoundMessageView,
145
- input: BoundInput,
146
- scrollView: BoundScrollView,
147
- scrollToBottomButton: BoundScrollToBottomButton,
148
- feather: BoundFeather,
149
- inputContainer: BoundInputContainer,
150
- disclaimer: BoundDisclaimer,
151
- });
152
- }
153
-
154
- return (
155
- <div className={twMerge("relative h-full", className)} {...props}>
156
- {BoundScrollView}
157
-
158
- {BoundFeather}
159
-
160
- {BoundInputContainer}
161
- </div>
162
- );
163
- }
164
-
165
- export namespace CopilotChatView {
166
- // Inner component that has access to StickToBottom context
167
- const ScrollContent: React.FC<{
168
- children: React.ReactNode;
169
- scrollToBottomButton?: React.FC<React.ButtonHTMLAttributes<HTMLButtonElement>>;
170
- inputContainerHeight: number;
171
- isResizing: boolean;
172
- }> = ({ children, scrollToBottomButton, inputContainerHeight, isResizing }) => {
173
- const { isAtBottom, scrollToBottom } = useStickToBottomContext();
174
-
175
- return (
176
- <>
177
- <StickToBottom.Content className="overflow-y-scroll overflow-x-hidden">
178
- <div className="px-4 sm:px-0">{children}</div>
179
- </StickToBottom.Content>
180
-
181
- {/* Scroll to bottom button - hidden during resize */}
182
- {!isAtBottom && !isResizing && (
183
- <div
184
- className="absolute inset-x-0 flex justify-center z-10"
185
- style={{
186
- bottom: `${inputContainerHeight + 16}px`,
187
- }}
188
- >
189
- {renderSlot(
190
- scrollToBottomButton,
191
- CopilotChatView.ScrollToBottomButton,
192
- {
193
- onClick: () => scrollToBottom(),
194
- }
195
- )}
196
- </div>
197
- )}
198
- </>
199
- );
200
- };
201
-
202
- export const ScrollView: React.FC<
203
- React.HTMLAttributes<HTMLDivElement> & {
204
- autoScroll?: boolean;
205
- scrollToBottomButton?: React.FC<
206
- React.ButtonHTMLAttributes<HTMLButtonElement>
207
- >;
208
- inputContainerHeight?: number;
209
- isResizing?: boolean;
210
- }
211
- > = ({
212
- children,
213
- autoScroll = true,
214
- scrollToBottomButton,
215
- inputContainerHeight = 0,
216
- isResizing = false,
217
- className,
218
- ...props
219
- }) => {
220
- const [hasMounted, setHasMounted] = useState(false);
221
- const { scrollRef, contentRef, scrollToBottom } = useStickToBottom();
222
- const [showScrollButton, setShowScrollButton] = useState(false);
223
-
224
- useEffect(() => {
225
- setHasMounted(true);
226
- }, []);
227
-
228
- // Monitor scroll position for non-autoscroll mode
229
- useEffect(() => {
230
- if (autoScroll) return; // Skip for autoscroll mode
231
-
232
- const scrollElement = scrollRef.current;
233
- if (!scrollElement) return;
234
-
235
- const checkScroll = () => {
236
- const atBottom =
237
- (scrollElement.scrollHeight - scrollElement.scrollTop - scrollElement.clientHeight < 10);
238
- setShowScrollButton(!atBottom);
239
- };
240
-
241
- checkScroll();
242
- scrollElement.addEventListener('scroll', checkScroll);
243
-
244
- // Also check on resize
245
- const resizeObserver = new ResizeObserver(checkScroll);
246
- resizeObserver.observe(scrollElement);
247
-
248
- return () => {
249
- scrollElement.removeEventListener('scroll', checkScroll);
250
- resizeObserver.disconnect();
251
- };
252
- }, [scrollRef, autoScroll]);
253
-
254
- if (!hasMounted) {
255
- return (
256
- <div className="h-full max-h-full flex flex-col min-h-0 overflow-y-scroll overflow-x-hidden">
257
- <div className="px-4 sm:px-0">{children}</div>
258
- </div>
259
- );
260
- }
261
-
262
- // When autoScroll is false, we don't use StickToBottom
263
- if (!autoScroll) {
264
- return (
265
- <div
266
- ref={scrollRef}
267
- className={cn("h-full max-h-full flex flex-col min-h-0 overflow-y-scroll overflow-x-hidden relative", className)}
268
- {...props}
269
- >
270
- <div ref={contentRef} className="px-4 sm:px-0">
271
- {children}
272
- </div>
273
-
274
- {/* Scroll to bottom button for manual mode */}
275
- {showScrollButton && !isResizing && (
276
- <div
277
- className="absolute inset-x-0 flex justify-center z-10"
278
- style={{
279
- bottom: `${inputContainerHeight + 16}px`,
280
- }}
281
- >
282
- {renderSlot(
283
- scrollToBottomButton,
284
- CopilotChatView.ScrollToBottomButton,
285
- {
286
- onClick: () => scrollToBottom(),
287
- }
288
- )}
289
- </div>
290
- )}
291
- </div>
292
- );
293
- }
294
-
295
- return (
296
- <StickToBottom
297
- className={cn("h-full max-h-full flex flex-col min-h-0 relative", className)}
298
- resize="smooth"
299
- initial="smooth"
300
- {...props}
301
- >
302
- <ScrollContent
303
- scrollToBottomButton={scrollToBottomButton}
304
- inputContainerHeight={inputContainerHeight}
305
- isResizing={isResizing}
306
- >
307
- {children}
308
- </ScrollContent>
309
- </StickToBottom>
310
- );
311
- };
312
-
313
- export const ScrollToBottomButton: React.FC<
314
- React.ButtonHTMLAttributes<HTMLButtonElement>
315
- > = ({ className, ...props }) => (
316
- <Button
317
- variant="outline"
318
- size="sm"
319
- className={twMerge(
320
- "rounded-full w-10 h-10 p-0",
321
- "bg-white dark:bg-gray-900",
322
- "shadow-lg border border-gray-200 dark:border-gray-700",
323
- "hover:bg-gray-50 dark:hover:bg-gray-800",
324
- "flex items-center justify-center cursor-pointer",
325
- className
326
- )}
327
- {...props}
328
- >
329
- <ChevronDown className="w-4 h-4 text-gray-600 dark:text-white" />
330
- </Button>
331
- );
332
-
333
- export const Feather: React.FC<React.HTMLAttributes<HTMLDivElement>> = ({
334
- className,
335
- style,
336
- ...props
337
- }) => (
338
- <div
339
- className={cn(
340
- "absolute bottom-0 left-0 right-4 h-24 pointer-events-none z-10 bg-gradient-to-t",
341
- "from-white via-white to-transparent",
342
- "dark:from-[rgb(33,33,33)] dark:via-[rgb(33,33,33)]",
343
- className
344
- )}
345
- style={style}
346
- {...props}
347
- />
348
- );
349
-
350
- export const InputContainer = React.forwardRef<
351
- HTMLDivElement,
352
- React.HTMLAttributes<HTMLDivElement> & { children: React.ReactNode }
353
- >(({ children, className, ...props }, ref) => (
354
- <div
355
- ref={ref}
356
- className={cn("absolute bottom-0 left-0 right-0 z-20", className)}
357
- {...props}
358
- >
359
- {children}
360
- </div>
361
- ));
362
-
363
- InputContainer.displayName = "CopilotChatView.InputContainer";
364
-
365
- export const Disclaimer: React.FC<React.HTMLAttributes<HTMLDivElement>> = ({
366
- className,
367
- ...props
368
- }) => {
369
- const { labels } = useCopilotChatConfiguration();
370
-
371
- return (
372
- <div
373
- className={cn(
374
- "text-center text-xs text-muted-foreground py-3 px-4 max-w-3xl mx-auto",
375
- className
376
- )}
377
- {...props}
378
- >
379
- {labels.chatDisclaimerText}
380
- </div>
381
- );
382
- };
383
- }
384
-
385
- export default CopilotChatView;