@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.
- package/package.json +3 -3
- package/.turbo/turbo-build$colon$css.log +0 -9
- package/.turbo/turbo-build.log +0 -30
- package/.turbo/turbo-check-types.log +0 -7
- package/.turbo/turbo-lint.log +0 -78
- package/.turbo/turbo-test.log +0 -79
- package/postcss.config.js +0 -7
- package/src/__tests__/setup.ts +0 -2
- package/src/components/chat/CopilotChat.tsx +0 -90
- package/src/components/chat/CopilotChatAssistantMessage.tsx +0 -478
- package/src/components/chat/CopilotChatAudioRecorder.tsx +0 -157
- package/src/components/chat/CopilotChatInput.tsx +0 -596
- package/src/components/chat/CopilotChatMessageView.tsx +0 -85
- package/src/components/chat/CopilotChatToolCallsView.tsx +0 -43
- package/src/components/chat/CopilotChatUserMessage.tsx +0 -337
- package/src/components/chat/CopilotChatView.tsx +0 -385
- package/src/components/chat/__tests__/CopilotChatAssistantMessage.test.tsx +0 -684
- package/src/components/chat/__tests__/CopilotChatInput.test.tsx +0 -531
- package/src/components/chat/__tests__/setup.ts +0 -1
- package/src/components/chat/index.ts +0 -35
- package/src/components/index.ts +0 -4
- package/src/components/ui/button.tsx +0 -123
- package/src/components/ui/dropdown-menu.tsx +0 -257
- package/src/components/ui/tooltip.tsx +0 -59
- package/src/hooks/index.ts +0 -6
- package/src/hooks/use-agent-context.tsx +0 -17
- package/src/hooks/use-agent.tsx +0 -48
- package/src/hooks/use-frontend-tool.tsx +0 -46
- package/src/hooks/use-human-in-the-loop.tsx +0 -76
- package/src/hooks/use-render-tool-call.tsx +0 -81
- package/src/index.ts +0 -4
- package/src/lib/__tests__/completePartialMarkdown.test.ts +0 -495
- package/src/lib/__tests__/renderSlot.test.tsx +0 -610
- package/src/lib/slots.tsx +0 -55
- package/src/lib/utils.ts +0 -6
- package/src/providers/CopilotChatConfigurationProvider.tsx +0 -81
- package/src/providers/CopilotKitProvider.tsx +0 -269
- package/src/providers/__tests__/CopilotKitProvider.test.tsx +0 -487
- package/src/providers/__tests__/CopilotKitProvider.wildcard.test.tsx +0 -261
- package/src/providers/index.ts +0 -14
- package/src/styles/globals.css +0 -302
- package/src/types/frontend-tool.ts +0 -8
- package/src/types/human-in-the-loop.ts +0 -33
- package/src/types/index.ts +0 -3
- package/src/types/react-tool-call-render.ts +0 -29
- package/tailwind.config.js +0 -9
- package/tsconfig.json +0 -23
- package/tsup.config.ts +0 -19
|
@@ -1,487 +0,0 @@
|
|
|
1
|
-
import React from "react";
|
|
2
|
-
import { render, renderHook, waitFor } from "@testing-library/react";
|
|
3
|
-
import { describe, it, expect, vi, beforeEach, afterEach } from "vitest";
|
|
4
|
-
import { CopilotKitProvider, useCopilotKit } from "../CopilotKitProvider";
|
|
5
|
-
import { ReactFrontendTool } from "../../types/frontend-tool";
|
|
6
|
-
import { ReactHumanInTheLoop } from "../../types/human-in-the-loop";
|
|
7
|
-
import { z } from "zod";
|
|
8
|
-
|
|
9
|
-
// Mock console methods
|
|
10
|
-
const originalConsoleError = console.error;
|
|
11
|
-
const originalConsoleWarn = console.warn;
|
|
12
|
-
|
|
13
|
-
describe("CopilotKitProvider", () => {
|
|
14
|
-
let consoleErrorSpy: ReturnType<typeof vi.spyOn>;
|
|
15
|
-
let consoleWarnSpy: ReturnType<typeof vi.spyOn>;
|
|
16
|
-
|
|
17
|
-
beforeEach(() => {
|
|
18
|
-
consoleErrorSpy = vi.spyOn(console, "error").mockImplementation(() => {});
|
|
19
|
-
consoleWarnSpy = vi.spyOn(console, "warn").mockImplementation(() => {});
|
|
20
|
-
});
|
|
21
|
-
|
|
22
|
-
afterEach(() => {
|
|
23
|
-
consoleErrorSpy.mockRestore();
|
|
24
|
-
consoleWarnSpy.mockRestore();
|
|
25
|
-
});
|
|
26
|
-
|
|
27
|
-
describe("Basic functionality", () => {
|
|
28
|
-
it("provides context to children", () => {
|
|
29
|
-
const { result } = renderHook(() => useCopilotKit(), {
|
|
30
|
-
wrapper: ({ children }) => (
|
|
31
|
-
<CopilotKitProvider>{children}</CopilotKitProvider>
|
|
32
|
-
),
|
|
33
|
-
});
|
|
34
|
-
|
|
35
|
-
expect(result.current).toBeDefined();
|
|
36
|
-
expect(result.current.copilotkit).toBeDefined();
|
|
37
|
-
expect(result.current.renderToolCalls).toBeDefined();
|
|
38
|
-
expect(result.current.currentRenderToolCalls).toBeDefined();
|
|
39
|
-
expect(result.current.setCurrentRenderToolCalls).toBeDefined();
|
|
40
|
-
});
|
|
41
|
-
|
|
42
|
-
it("throws error when used outside provider", () => {
|
|
43
|
-
// Temporarily restore console.error for this test
|
|
44
|
-
consoleErrorSpy.mockRestore();
|
|
45
|
-
const errorSpy = vi.spyOn(console, "error").mockImplementation(() => {});
|
|
46
|
-
|
|
47
|
-
expect(() => {
|
|
48
|
-
renderHook(() => useCopilotKit());
|
|
49
|
-
}).toThrow();
|
|
50
|
-
|
|
51
|
-
errorSpy.mockRestore();
|
|
52
|
-
consoleErrorSpy = vi.spyOn(console, "error").mockImplementation(() => {});
|
|
53
|
-
});
|
|
54
|
-
});
|
|
55
|
-
|
|
56
|
-
describe("frontendTools prop", () => {
|
|
57
|
-
it("registers frontend tools with CopilotKitCore", () => {
|
|
58
|
-
const mockHandler = vi.fn();
|
|
59
|
-
const frontendTools: ReactFrontendTool[] = [
|
|
60
|
-
{
|
|
61
|
-
name: "testTool",
|
|
62
|
-
description: "A test tool",
|
|
63
|
-
parameters: z.object({
|
|
64
|
-
input: z.string(),
|
|
65
|
-
}),
|
|
66
|
-
handler: mockHandler,
|
|
67
|
-
},
|
|
68
|
-
];
|
|
69
|
-
|
|
70
|
-
const { result } = renderHook(() => useCopilotKit(), {
|
|
71
|
-
wrapper: ({ children }) => (
|
|
72
|
-
<CopilotKitProvider frontendTools={frontendTools}>
|
|
73
|
-
{children}
|
|
74
|
-
</CopilotKitProvider>
|
|
75
|
-
),
|
|
76
|
-
});
|
|
77
|
-
|
|
78
|
-
expect(result.current.copilotkit.tools["testTool"]).toBeDefined();
|
|
79
|
-
expect(result.current.copilotkit.tools["testTool"]?.name).toBe("testTool");
|
|
80
|
-
expect(result.current.copilotkit.tools["testTool"]?.handler).toBe(mockHandler);
|
|
81
|
-
});
|
|
82
|
-
|
|
83
|
-
it("includes render components from frontend tools", () => {
|
|
84
|
-
const TestComponent: React.FC<any> = () => <div>Test</div>;
|
|
85
|
-
const frontendTools: ReactFrontendTool[] = [
|
|
86
|
-
{
|
|
87
|
-
name: "renderTool",
|
|
88
|
-
description: "A tool with render",
|
|
89
|
-
parameters: z.object({
|
|
90
|
-
input: z.string(),
|
|
91
|
-
}),
|
|
92
|
-
render: TestComponent,
|
|
93
|
-
},
|
|
94
|
-
];
|
|
95
|
-
|
|
96
|
-
const { result } = renderHook(() => useCopilotKit(), {
|
|
97
|
-
wrapper: ({ children }) => (
|
|
98
|
-
<CopilotKitProvider frontendTools={frontendTools}>
|
|
99
|
-
{children}
|
|
100
|
-
</CopilotKitProvider>
|
|
101
|
-
),
|
|
102
|
-
});
|
|
103
|
-
|
|
104
|
-
const renderTool = result.current.renderToolCalls.find(rc => rc.name === "renderTool");
|
|
105
|
-
expect(renderTool).toBeDefined();
|
|
106
|
-
expect(renderTool?.render).toBe(TestComponent);
|
|
107
|
-
});
|
|
108
|
-
|
|
109
|
-
it("warns when frontendTools prop changes", async () => {
|
|
110
|
-
const initialTools: ReactFrontendTool[] = [
|
|
111
|
-
{
|
|
112
|
-
name: "tool1",
|
|
113
|
-
description: "Tool 1",
|
|
114
|
-
},
|
|
115
|
-
];
|
|
116
|
-
|
|
117
|
-
const { rerender } = render(
|
|
118
|
-
<CopilotKitProvider frontendTools={initialTools}>
|
|
119
|
-
<div>Test</div>
|
|
120
|
-
</CopilotKitProvider>
|
|
121
|
-
);
|
|
122
|
-
|
|
123
|
-
const newTools: ReactFrontendTool[] = [
|
|
124
|
-
{
|
|
125
|
-
name: "tool2",
|
|
126
|
-
description: "Tool 2",
|
|
127
|
-
},
|
|
128
|
-
];
|
|
129
|
-
|
|
130
|
-
rerender(
|
|
131
|
-
<CopilotKitProvider frontendTools={newTools}>
|
|
132
|
-
<div>Test</div>
|
|
133
|
-
</CopilotKitProvider>
|
|
134
|
-
);
|
|
135
|
-
|
|
136
|
-
await waitFor(() => {
|
|
137
|
-
expect(consoleErrorSpy).toHaveBeenCalledWith(
|
|
138
|
-
expect.stringContaining("frontendTools must be a stable array")
|
|
139
|
-
);
|
|
140
|
-
});
|
|
141
|
-
});
|
|
142
|
-
});
|
|
143
|
-
|
|
144
|
-
describe("humanInTheLoop prop", () => {
|
|
145
|
-
it("processes humanInTheLoop tools and creates handlers", () => {
|
|
146
|
-
const TestComponent: React.FC<any> = () => <div>Test</div>;
|
|
147
|
-
const humanInTheLoopTools: ReactHumanInTheLoop[] = [
|
|
148
|
-
{
|
|
149
|
-
name: "approvalTool",
|
|
150
|
-
description: "Requires human approval",
|
|
151
|
-
parameters: z.object({
|
|
152
|
-
question: z.string(),
|
|
153
|
-
}),
|
|
154
|
-
render: TestComponent,
|
|
155
|
-
},
|
|
156
|
-
];
|
|
157
|
-
|
|
158
|
-
const { result } = renderHook(() => useCopilotKit(), {
|
|
159
|
-
wrapper: ({ children }) => (
|
|
160
|
-
<CopilotKitProvider humanInTheLoop={humanInTheLoopTools}>
|
|
161
|
-
{children}
|
|
162
|
-
</CopilotKitProvider>
|
|
163
|
-
),
|
|
164
|
-
});
|
|
165
|
-
|
|
166
|
-
// Check that the tool is registered
|
|
167
|
-
expect(result.current.copilotkit.tools["approvalTool"]).toBeDefined();
|
|
168
|
-
expect(result.current.copilotkit.tools["approvalTool"]?.name).toBe("approvalTool");
|
|
169
|
-
expect(result.current.copilotkit.tools["approvalTool"]?.handler).toBeDefined();
|
|
170
|
-
|
|
171
|
-
// Check that render component is registered
|
|
172
|
-
const approvalTool = result.current.renderToolCalls.find(rc => rc.name === "approvalTool");
|
|
173
|
-
expect(approvalTool).toBeDefined();
|
|
174
|
-
expect(approvalTool?.render).toBe(TestComponent);
|
|
175
|
-
});
|
|
176
|
-
|
|
177
|
-
it("creates placeholder handlers for humanInTheLoop tools", async () => {
|
|
178
|
-
const TestComponent: React.FC<any> = () => <div>Test</div>;
|
|
179
|
-
const humanInTheLoopTools: ReactHumanInTheLoop[] = [
|
|
180
|
-
{
|
|
181
|
-
name: "interactiveTool",
|
|
182
|
-
description: "Interactive tool",
|
|
183
|
-
parameters: z.object({
|
|
184
|
-
data: z.string(),
|
|
185
|
-
}),
|
|
186
|
-
render: TestComponent,
|
|
187
|
-
},
|
|
188
|
-
];
|
|
189
|
-
|
|
190
|
-
const { result } = renderHook(() => useCopilotKit(), {
|
|
191
|
-
wrapper: ({ children }) => (
|
|
192
|
-
<CopilotKitProvider humanInTheLoop={humanInTheLoopTools}>
|
|
193
|
-
{children}
|
|
194
|
-
</CopilotKitProvider>
|
|
195
|
-
),
|
|
196
|
-
});
|
|
197
|
-
|
|
198
|
-
const handler = result.current.copilotkit.tools["interactiveTool"]?.handler;
|
|
199
|
-
expect(handler).toBeDefined();
|
|
200
|
-
|
|
201
|
-
// Call the handler and check for warning
|
|
202
|
-
const handlerPromise = handler!({ data: "test" });
|
|
203
|
-
|
|
204
|
-
await waitFor(() => {
|
|
205
|
-
expect(consoleWarnSpy).toHaveBeenCalledWith(
|
|
206
|
-
expect.stringContaining("Human-in-the-loop tool 'interactiveTool' called")
|
|
207
|
-
);
|
|
208
|
-
});
|
|
209
|
-
|
|
210
|
-
const result2 = await handlerPromise;
|
|
211
|
-
expect(result2).toBeUndefined();
|
|
212
|
-
});
|
|
213
|
-
|
|
214
|
-
it("warns when humanInTheLoop prop changes", async () => {
|
|
215
|
-
const TestComponent: React.FC<any> = () => <div>Test</div>;
|
|
216
|
-
const initialTools: ReactHumanInTheLoop[] = [
|
|
217
|
-
{
|
|
218
|
-
name: "tool1",
|
|
219
|
-
description: "Tool 1",
|
|
220
|
-
render: TestComponent,
|
|
221
|
-
},
|
|
222
|
-
];
|
|
223
|
-
|
|
224
|
-
const { rerender } = render(
|
|
225
|
-
<CopilotKitProvider humanInTheLoop={initialTools}>
|
|
226
|
-
<div>Test</div>
|
|
227
|
-
</CopilotKitProvider>
|
|
228
|
-
);
|
|
229
|
-
|
|
230
|
-
const newTools: ReactHumanInTheLoop[] = [
|
|
231
|
-
{
|
|
232
|
-
name: "tool2",
|
|
233
|
-
description: "Tool 2",
|
|
234
|
-
render: TestComponent,
|
|
235
|
-
},
|
|
236
|
-
];
|
|
237
|
-
|
|
238
|
-
rerender(
|
|
239
|
-
<CopilotKitProvider humanInTheLoop={newTools}>
|
|
240
|
-
<div>Test</div>
|
|
241
|
-
</CopilotKitProvider>
|
|
242
|
-
);
|
|
243
|
-
|
|
244
|
-
await waitFor(() => {
|
|
245
|
-
expect(consoleErrorSpy).toHaveBeenCalledWith(
|
|
246
|
-
expect.stringContaining("humanInTheLoop must be a stable array")
|
|
247
|
-
);
|
|
248
|
-
});
|
|
249
|
-
});
|
|
250
|
-
});
|
|
251
|
-
|
|
252
|
-
describe("Combined tools functionality", () => {
|
|
253
|
-
it("registers both frontendTools and humanInTheLoop tools", () => {
|
|
254
|
-
const TestComponent: React.FC<any> = () => <div>Test</div>;
|
|
255
|
-
const frontendTools: ReactFrontendTool[] = [
|
|
256
|
-
{
|
|
257
|
-
name: "frontendTool",
|
|
258
|
-
description: "Frontend tool",
|
|
259
|
-
handler: vi.fn(),
|
|
260
|
-
},
|
|
261
|
-
];
|
|
262
|
-
const humanInTheLoopTools: ReactHumanInTheLoop[] = [
|
|
263
|
-
{
|
|
264
|
-
name: "humanTool",
|
|
265
|
-
description: "Human tool",
|
|
266
|
-
render: TestComponent,
|
|
267
|
-
},
|
|
268
|
-
];
|
|
269
|
-
|
|
270
|
-
const { result } = renderHook(() => useCopilotKit(), {
|
|
271
|
-
wrapper: ({ children }) => (
|
|
272
|
-
<CopilotKitProvider
|
|
273
|
-
frontendTools={frontendTools}
|
|
274
|
-
humanInTheLoop={humanInTheLoopTools}
|
|
275
|
-
>
|
|
276
|
-
{children}
|
|
277
|
-
</CopilotKitProvider>
|
|
278
|
-
),
|
|
279
|
-
});
|
|
280
|
-
|
|
281
|
-
expect(result.current.copilotkit.tools["frontendTool"]).toBeDefined();
|
|
282
|
-
expect(result.current.copilotkit.tools["humanTool"]).toBeDefined();
|
|
283
|
-
});
|
|
284
|
-
|
|
285
|
-
it("should handle agentId in frontend tools", () => {
|
|
286
|
-
const handler1 = vi.fn();
|
|
287
|
-
const handler2 = vi.fn();
|
|
288
|
-
|
|
289
|
-
const frontendTools: ReactFrontendTool[] = [
|
|
290
|
-
{
|
|
291
|
-
name: "globalTool",
|
|
292
|
-
description: "Global tool",
|
|
293
|
-
handler: handler1,
|
|
294
|
-
},
|
|
295
|
-
{
|
|
296
|
-
name: "agentSpecificTool",
|
|
297
|
-
description: "Agent specific tool",
|
|
298
|
-
handler: handler2,
|
|
299
|
-
agentId: "specificAgent",
|
|
300
|
-
},
|
|
301
|
-
];
|
|
302
|
-
|
|
303
|
-
const { result } = renderHook(() => useCopilotKit(), {
|
|
304
|
-
wrapper: ({ children }) => (
|
|
305
|
-
<CopilotKitProvider frontendTools={frontendTools}>
|
|
306
|
-
{children}
|
|
307
|
-
</CopilotKitProvider>
|
|
308
|
-
),
|
|
309
|
-
});
|
|
310
|
-
|
|
311
|
-
expect(result.current.copilotkit.tools["globalTool"]).toBeDefined();
|
|
312
|
-
expect(result.current.copilotkit.tools["globalTool"]?.agentId).toBeUndefined();
|
|
313
|
-
expect(result.current.copilotkit.tools["agentSpecificTool"]).toBeDefined();
|
|
314
|
-
expect(result.current.copilotkit.tools["agentSpecificTool"]?.agentId).toBe("specificAgent");
|
|
315
|
-
});
|
|
316
|
-
|
|
317
|
-
it("combines render components from all sources", () => {
|
|
318
|
-
const TestComponent1: React.FC<any> = () => <div>Test1</div>;
|
|
319
|
-
const TestComponent2: React.FC<any> = () => <div>Test2</div>;
|
|
320
|
-
const TestComponent3: React.FC<any> = () => <div>Test3</div>;
|
|
321
|
-
|
|
322
|
-
const frontendTools: ReactFrontendTool[] = [
|
|
323
|
-
{
|
|
324
|
-
name: "frontendRenderTool",
|
|
325
|
-
description: "Frontend render tool",
|
|
326
|
-
parameters: z.object({ a: z.string() }),
|
|
327
|
-
render: TestComponent1,
|
|
328
|
-
},
|
|
329
|
-
];
|
|
330
|
-
|
|
331
|
-
const humanInTheLoopTools: ReactHumanInTheLoop[] = [
|
|
332
|
-
{
|
|
333
|
-
name: "humanRenderTool",
|
|
334
|
-
description: "Human render tool",
|
|
335
|
-
parameters: z.object({ b: z.string() }),
|
|
336
|
-
render: TestComponent2,
|
|
337
|
-
},
|
|
338
|
-
];
|
|
339
|
-
|
|
340
|
-
const renderToolCalls = [
|
|
341
|
-
{
|
|
342
|
-
name: "directRenderTool",
|
|
343
|
-
args: z.object({ c: z.string() }),
|
|
344
|
-
render: TestComponent3,
|
|
345
|
-
},
|
|
346
|
-
];
|
|
347
|
-
|
|
348
|
-
const { result } = renderHook(() => useCopilotKit(), {
|
|
349
|
-
wrapper: ({ children }) => (
|
|
350
|
-
<CopilotKitProvider
|
|
351
|
-
frontendTools={frontendTools}
|
|
352
|
-
humanInTheLoop={humanInTheLoopTools}
|
|
353
|
-
renderToolCalls={renderToolCalls}
|
|
354
|
-
>
|
|
355
|
-
{children}
|
|
356
|
-
</CopilotKitProvider>
|
|
357
|
-
),
|
|
358
|
-
});
|
|
359
|
-
|
|
360
|
-
const frontendRenderTool = result.current.renderToolCalls.find(rc => rc.name === "frontendRenderTool");
|
|
361
|
-
const humanRenderTool = result.current.renderToolCalls.find(rc => rc.name === "humanRenderTool");
|
|
362
|
-
const directRenderTool = result.current.renderToolCalls.find(rc => rc.name === "directRenderTool");
|
|
363
|
-
|
|
364
|
-
expect(frontendRenderTool).toBeDefined();
|
|
365
|
-
expect(humanRenderTool).toBeDefined();
|
|
366
|
-
expect(directRenderTool).toBeDefined();
|
|
367
|
-
|
|
368
|
-
expect(frontendRenderTool?.render).toBe(TestComponent1);
|
|
369
|
-
expect(humanRenderTool?.render).toBe(TestComponent2);
|
|
370
|
-
expect(directRenderTool?.render).toBe(TestComponent3);
|
|
371
|
-
});
|
|
372
|
-
});
|
|
373
|
-
|
|
374
|
-
describe("currentRenderToolCalls state", () => {
|
|
375
|
-
it("initializes currentRenderToolCalls with all render tools", async () => {
|
|
376
|
-
const TestComponent: React.FC<any> = () => <div>Test</div>;
|
|
377
|
-
const frontendTools: ReactFrontendTool[] = [
|
|
378
|
-
{
|
|
379
|
-
name: "tool1",
|
|
380
|
-
description: "Tool 1",
|
|
381
|
-
parameters: z.object({ a: z.string() }),
|
|
382
|
-
render: TestComponent,
|
|
383
|
-
},
|
|
384
|
-
];
|
|
385
|
-
|
|
386
|
-
const { result } = renderHook(() => useCopilotKit(), {
|
|
387
|
-
wrapper: ({ children }) => (
|
|
388
|
-
<CopilotKitProvider frontendTools={frontendTools}>
|
|
389
|
-
{children}
|
|
390
|
-
</CopilotKitProvider>
|
|
391
|
-
),
|
|
392
|
-
});
|
|
393
|
-
|
|
394
|
-
await waitFor(() => {
|
|
395
|
-
const tool1 = result.current.currentRenderToolCalls.find(rc => rc.name === "tool1");
|
|
396
|
-
expect(tool1).toBeDefined();
|
|
397
|
-
});
|
|
398
|
-
});
|
|
399
|
-
|
|
400
|
-
it("allows updating currentRenderToolCalls", async () => {
|
|
401
|
-
const TestComponent: React.FC<any> = () => <div>Test</div>;
|
|
402
|
-
const NewComponent: React.FC<any> = () => <div>New</div>;
|
|
403
|
-
|
|
404
|
-
const { result } = renderHook(() => useCopilotKit(), {
|
|
405
|
-
wrapper: ({ children }) => (
|
|
406
|
-
<CopilotKitProvider>{children}</CopilotKitProvider>
|
|
407
|
-
),
|
|
408
|
-
});
|
|
409
|
-
|
|
410
|
-
const newRenderToolCall = [
|
|
411
|
-
{
|
|
412
|
-
name: "dynamicTool",
|
|
413
|
-
args: z.object({ x: z.string() }),
|
|
414
|
-
render: NewComponent,
|
|
415
|
-
},
|
|
416
|
-
];
|
|
417
|
-
|
|
418
|
-
result.current.setCurrentRenderToolCalls(newRenderToolCall);
|
|
419
|
-
|
|
420
|
-
await waitFor(() => {
|
|
421
|
-
const dynamicTool = result.current.currentRenderToolCalls.find(rc => rc.name === "dynamicTool");
|
|
422
|
-
expect(dynamicTool).toBeDefined();
|
|
423
|
-
expect(dynamicTool?.render).toBe(NewComponent);
|
|
424
|
-
});
|
|
425
|
-
});
|
|
426
|
-
});
|
|
427
|
-
|
|
428
|
-
describe("Edge cases", () => {
|
|
429
|
-
it("handles empty arrays for tools", () => {
|
|
430
|
-
const { result } = renderHook(() => useCopilotKit(), {
|
|
431
|
-
wrapper: ({ children }) => (
|
|
432
|
-
<CopilotKitProvider frontendTools={[]} humanInTheLoop={[]}>
|
|
433
|
-
{children}
|
|
434
|
-
</CopilotKitProvider>
|
|
435
|
-
),
|
|
436
|
-
});
|
|
437
|
-
|
|
438
|
-
expect(Object.keys(result.current.copilotkit.tools)).toHaveLength(0);
|
|
439
|
-
expect(Object.keys(result.current.renderToolCalls)).toHaveLength(0);
|
|
440
|
-
});
|
|
441
|
-
|
|
442
|
-
it("handles tools without render components", () => {
|
|
443
|
-
const frontendTools: ReactFrontendTool[] = [
|
|
444
|
-
{
|
|
445
|
-
name: "noRenderTool",
|
|
446
|
-
description: "Tool without render",
|
|
447
|
-
handler: vi.fn(),
|
|
448
|
-
},
|
|
449
|
-
];
|
|
450
|
-
|
|
451
|
-
const { result } = renderHook(() => useCopilotKit(), {
|
|
452
|
-
wrapper: ({ children }) => (
|
|
453
|
-
<CopilotKitProvider frontendTools={frontendTools}>
|
|
454
|
-
{children}
|
|
455
|
-
</CopilotKitProvider>
|
|
456
|
-
),
|
|
457
|
-
});
|
|
458
|
-
|
|
459
|
-
expect(result.current.copilotkit.tools["noRenderTool"]).toBeDefined();
|
|
460
|
-
const noRenderTool = result.current.renderToolCalls.find(rc => rc.name === "noRenderTool");
|
|
461
|
-
expect(noRenderTool).toBeUndefined();
|
|
462
|
-
});
|
|
463
|
-
|
|
464
|
-
it("handles humanInTheLoop tools with followUp flag", () => {
|
|
465
|
-
const TestComponent: React.FC<any> = () => <div>Test</div>;
|
|
466
|
-
const humanInTheLoopTools: ReactHumanInTheLoop[] = [
|
|
467
|
-
{
|
|
468
|
-
name: "followUpTool",
|
|
469
|
-
description: "Tool with followUp",
|
|
470
|
-
parameters: z.object({ a: z.string() }),
|
|
471
|
-
followUp: false,
|
|
472
|
-
render: TestComponent,
|
|
473
|
-
},
|
|
474
|
-
];
|
|
475
|
-
|
|
476
|
-
const { result } = renderHook(() => useCopilotKit(), {
|
|
477
|
-
wrapper: ({ children }) => (
|
|
478
|
-
<CopilotKitProvider humanInTheLoop={humanInTheLoopTools}>
|
|
479
|
-
{children}
|
|
480
|
-
</CopilotKitProvider>
|
|
481
|
-
),
|
|
482
|
-
});
|
|
483
|
-
|
|
484
|
-
expect(result.current.copilotkit.tools["followUpTool"]?.followUp).toBe(false);
|
|
485
|
-
});
|
|
486
|
-
});
|
|
487
|
-
});
|