@copilotkit/react-core 1.55.0-next.8 → 1.55.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +48 -5
- package/dist/{copilotkit-DNYSFuz5.mjs → copilotkit-BY5S1-0P.mjs} +2772 -858
- package/dist/copilotkit-BY5S1-0P.mjs.map +1 -0
- package/dist/{copilotkit-Dy5w3qEV.d.mts → copilotkit-BuhSUZHb.d.mts} +230 -17
- package/dist/copilotkit-BuhSUZHb.d.mts.map +1 -0
- package/dist/{copilotkit-B3Mb1yVE.cjs → copilotkit-Bz5-ImDl.cjs} +2776 -832
- package/dist/copilotkit-Bz5-ImDl.cjs.map +1 -0
- package/dist/{copilotkit-DBzgOMby.d.cts → copilotkit-dwDWYpya.d.cts} +230 -17
- package/dist/copilotkit-dwDWYpya.d.cts.map +1 -0
- package/dist/index.cjs +9 -4
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +1 -1
- package/dist/index.d.mts +1 -1
- package/dist/index.mjs +9 -4
- package/dist/index.mjs.map +1 -1
- package/dist/index.umd.js +1624 -396
- package/dist/index.umd.js.map +1 -1
- package/dist/v2/index.cjs +13 -1
- package/dist/v2/index.css +1 -1
- package/dist/v2/index.d.cts +3 -3
- package/dist/v2/index.d.mts +3 -3
- package/dist/v2/index.mjs +3 -2
- package/dist/v2/index.umd.js +2746 -790
- package/dist/v2/index.umd.js.map +1 -1
- package/package.json +62 -54
- package/scripts/scope-preflight.mjs +1 -2
- package/src/components/CopilotListeners.tsx +41 -8
- package/src/components/copilot-provider/__tests__/copilot-messages-key.test.tsx +92 -0
- package/src/components/copilot-provider/copilotkit-props.tsx +4 -2
- package/src/components/copilot-provider/copilotkit.tsx +3 -3
- package/src/components/toast/toast-provider.tsx +269 -194
- package/src/hooks/__tests__/use-copilot-chat-internal-connect.test.tsx +27 -16
- package/src/hooks/use-copilot-chat_internal.ts +15 -4
- package/src/v2/__tests__/A2UIMessageRenderer.test.tsx +86 -22
- package/src/v2/__tests__/utils/test-helpers.tsx +107 -7
- package/src/v2/a2ui/A2UICatalogContext.tsx +79 -0
- package/src/v2/a2ui/A2UIMessageRenderer.tsx +125 -37
- package/src/v2/a2ui/A2UIToolCallRenderer.tsx +290 -0
- package/src/v2/components/CopilotKitInspector.tsx +2 -0
- package/src/v2/components/OpenGenerativeUIRenderer.tsx +598 -0
- package/src/v2/components/__tests__/OpenGenerativeUIRenderer.test.tsx +665 -0
- package/src/v2/components/chat/CopilotChat.tsx +197 -52
- package/src/v2/components/chat/CopilotChatAssistantMessage.tsx +17 -2
- package/src/v2/components/chat/CopilotChatAttachmentQueue.tsx +481 -0
- package/src/v2/components/chat/CopilotChatAttachmentRenderer.tsx +139 -0
- package/src/v2/components/chat/CopilotChatInput.tsx +146 -77
- package/src/v2/components/chat/CopilotChatMessageView.tsx +260 -151
- package/src/v2/components/chat/CopilotChatSuggestionView.tsx +1 -0
- package/src/v2/components/chat/CopilotChatUserMessage.tsx +54 -0
- package/src/v2/components/chat/CopilotChatView.tsx +179 -66
- package/src/v2/components/chat/__tests__/CopilotChat.attachments.test.tsx +168 -0
- package/src/v2/components/chat/__tests__/CopilotChatActivityRendering.e2e.test.tsx +63 -2
- package/src/v2/components/chat/__tests__/CopilotChatInput.test.tsx +544 -1
- package/src/v2/components/chat/__tests__/CopilotChatPerf.e2e.test.tsx +268 -0
- package/src/v2/components/chat/__tests__/CopilotChatPropsRerender.e2e.test.tsx +249 -0
- package/src/v2/components/chat/__tests__/CopilotChatToolRendering.e2e.test.tsx +5 -2
- package/src/v2/components/chat/__tests__/CopilotChatToolRerenders.e2e.test.tsx +5 -2
- package/src/v2/components/chat/__tests__/MCPAppsActivityRenderer.e2e.test.tsx +60 -3
- package/src/v2/components/chat/__tests__/copilot-chat-throttle.test.tsx +138 -0
- package/src/v2/components/chat/index.ts +9 -0
- package/src/v2/components/chat/scroll-element-context.ts +13 -0
- package/src/v2/hooks/__tests__/use-agent-context-timing.e2e.test.tsx +8 -0
- package/src/v2/hooks/__tests__/use-agent-thread-isolation.test.tsx +327 -0
- package/src/v2/hooks/__tests__/use-agent-throttle.test.tsx +1003 -0
- package/src/v2/hooks/__tests__/use-agent.e2e.test.tsx +13 -2
- package/src/v2/hooks/__tests__/use-attachments.test.tsx +169 -0
- package/src/v2/hooks/__tests__/use-frontend-tool.e2e.test.tsx +23 -4
- package/src/v2/hooks/__tests__/use-threads.test.tsx +54 -0
- package/src/v2/hooks/index.ts +5 -0
- package/src/v2/hooks/use-agent.tsx +220 -15
- package/src/v2/hooks/use-attachments.tsx +269 -0
- package/src/v2/hooks/use-frontend-tool.tsx +5 -2
- package/src/v2/hooks/use-render-activity-message.tsx +9 -2
- package/src/v2/hooks/use-render-custom-messages.tsx +6 -1
- package/src/v2/hooks/use-threads.tsx +35 -15
- package/src/v2/index.ts +5 -1
- package/src/v2/lib/__tests__/processPartialHtml.test.ts +112 -0
- package/src/v2/lib/__tests__/slots.test.ts +56 -0
- package/src/v2/lib/processPartialHtml.ts +45 -0
- package/src/v2/lib/slots.tsx +42 -1
- package/src/v2/providers/CopilotChatConfigurationProvider.tsx +9 -3
- package/src/v2/providers/CopilotKitProvider.tsx +268 -32
- package/src/v2/providers/SandboxFunctionsContext.ts +10 -0
- package/src/v2/providers/__tests__/CopilotKitProvider.sandboxFunctions.test.tsx +198 -0
- package/src/v2/providers/__tests__/CopilotKitProvider.test.tsx +71 -0
- package/src/v2/providers/index.ts +7 -0
- package/src/v2/styles/globals.css +2 -1
- package/src/v2/types/index.ts +1 -0
- package/src/v2/types/sandbox-function.ts +11 -0
- package/dist/copilotkit-B3Mb1yVE.cjs.map +0 -1
- package/dist/copilotkit-DBzgOMby.d.cts.map +0 -1
- package/dist/copilotkit-DNYSFuz5.mjs.map +0 -1
- package/dist/copilotkit-Dy5w3qEV.d.mts.map +0 -1
- package/src/v2/components/__tests__/license-warning-banner.test.tsx +0 -46
|
@@ -0,0 +1,198 @@
|
|
|
1
|
+
import { renderHook } from "@testing-library/react";
|
|
2
|
+
import React from "react";
|
|
3
|
+
import { afterEach, beforeEach, describe, expect, it, vi } from "vitest";
|
|
4
|
+
import { z } from "zod";
|
|
5
|
+
import { CopilotKitProvider, useCopilotKit } from "../CopilotKitProvider";
|
|
6
|
+
import { useSandboxFunctions } from "../SandboxFunctionsContext";
|
|
7
|
+
import type { SandboxFunction } from "../../types/sandbox-function";
|
|
8
|
+
|
|
9
|
+
describe("CopilotKitProvider — openGenerativeUI.sandboxFunctions", () => {
|
|
10
|
+
beforeEach(() => {
|
|
11
|
+
vi.spyOn(console, "error").mockImplementation(() => {});
|
|
12
|
+
vi.spyOn(console, "warn").mockImplementation(() => {});
|
|
13
|
+
});
|
|
14
|
+
|
|
15
|
+
afterEach(() => {
|
|
16
|
+
vi.restoreAllMocks();
|
|
17
|
+
});
|
|
18
|
+
|
|
19
|
+
const makeSandboxFunction = (
|
|
20
|
+
name: string,
|
|
21
|
+
overrides?: Partial<SandboxFunction>,
|
|
22
|
+
): SandboxFunction => ({
|
|
23
|
+
name,
|
|
24
|
+
description: `${name} description`,
|
|
25
|
+
parameters: z.object({ value: z.string() }),
|
|
26
|
+
handler: vi.fn().mockResolvedValue(undefined),
|
|
27
|
+
...overrides,
|
|
28
|
+
});
|
|
29
|
+
|
|
30
|
+
/** Helper: find the sandbox-functions context entry from the context record */
|
|
31
|
+
function findSandboxContext(
|
|
32
|
+
ctx: Record<string, { description: string; value: string }>,
|
|
33
|
+
) {
|
|
34
|
+
return Object.values(ctx).find((c) =>
|
|
35
|
+
c.description.includes("Sandbox functions"),
|
|
36
|
+
);
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
describe("SandboxFunctionsContext", () => {
|
|
40
|
+
it("provides sandbox functions to children via context", () => {
|
|
41
|
+
const fns = [makeSandboxFunction("myFn")];
|
|
42
|
+
|
|
43
|
+
const { result } = renderHook(() => useSandboxFunctions(), {
|
|
44
|
+
wrapper: ({ children }) => (
|
|
45
|
+
<CopilotKitProvider openGenerativeUI={{ sandboxFunctions: fns }}>
|
|
46
|
+
{children}
|
|
47
|
+
</CopilotKitProvider>
|
|
48
|
+
),
|
|
49
|
+
});
|
|
50
|
+
|
|
51
|
+
expect(result.current).toHaveLength(1);
|
|
52
|
+
expect(result.current[0].name).toBe("myFn");
|
|
53
|
+
});
|
|
54
|
+
|
|
55
|
+
it("provides empty array when openGenerativeUI is not set", () => {
|
|
56
|
+
const { result } = renderHook(() => useSandboxFunctions(), {
|
|
57
|
+
wrapper: ({ children }) => (
|
|
58
|
+
<CopilotKitProvider>{children}</CopilotKitProvider>
|
|
59
|
+
),
|
|
60
|
+
});
|
|
61
|
+
|
|
62
|
+
expect(result.current).toHaveLength(0);
|
|
63
|
+
});
|
|
64
|
+
|
|
65
|
+
it("provides empty array when sandboxFunctions is not set", () => {
|
|
66
|
+
const { result } = renderHook(() => useSandboxFunctions(), {
|
|
67
|
+
wrapper: ({ children }) => (
|
|
68
|
+
<CopilotKitProvider openGenerativeUI={{}}>
|
|
69
|
+
{children}
|
|
70
|
+
</CopilotKitProvider>
|
|
71
|
+
),
|
|
72
|
+
});
|
|
73
|
+
|
|
74
|
+
expect(result.current).toHaveLength(0);
|
|
75
|
+
});
|
|
76
|
+
});
|
|
77
|
+
|
|
78
|
+
describe("agent context registration", () => {
|
|
79
|
+
it("registers agent context when sandbox functions are provided", () => {
|
|
80
|
+
const fns = [makeSandboxFunction("addToCart")];
|
|
81
|
+
|
|
82
|
+
const { result } = renderHook(() => useCopilotKit(), {
|
|
83
|
+
wrapper: ({ children }) => (
|
|
84
|
+
<CopilotKitProvider openGenerativeUI={{ sandboxFunctions: fns }}>
|
|
85
|
+
{children}
|
|
86
|
+
</CopilotKitProvider>
|
|
87
|
+
),
|
|
88
|
+
});
|
|
89
|
+
|
|
90
|
+
const sandboxContext = findSandboxContext(
|
|
91
|
+
result.current.copilotkit.context,
|
|
92
|
+
);
|
|
93
|
+
expect(sandboxContext).toBeDefined();
|
|
94
|
+
|
|
95
|
+
const parsed = JSON.parse(sandboxContext!.value);
|
|
96
|
+
expect(parsed).toHaveLength(1);
|
|
97
|
+
expect(parsed[0].name).toBe("addToCart");
|
|
98
|
+
expect(parsed[0].description).toBe("addToCart description");
|
|
99
|
+
expect(parsed[0].parameters).toBeDefined();
|
|
100
|
+
expect(parsed[0].parameters.type).toBe("object");
|
|
101
|
+
});
|
|
102
|
+
|
|
103
|
+
it("does not register agent context when sandbox functions are empty", () => {
|
|
104
|
+
const { result } = renderHook(() => useCopilotKit(), {
|
|
105
|
+
wrapper: ({ children }) => (
|
|
106
|
+
<CopilotKitProvider openGenerativeUI={{ sandboxFunctions: [] }}>
|
|
107
|
+
{children}
|
|
108
|
+
</CopilotKitProvider>
|
|
109
|
+
),
|
|
110
|
+
});
|
|
111
|
+
|
|
112
|
+
const sandboxContext = findSandboxContext(
|
|
113
|
+
result.current.copilotkit.context,
|
|
114
|
+
);
|
|
115
|
+
expect(sandboxContext).toBeUndefined();
|
|
116
|
+
});
|
|
117
|
+
|
|
118
|
+
it("does not register agent context when openGenerativeUI is omitted", () => {
|
|
119
|
+
const { result } = renderHook(() => useCopilotKit(), {
|
|
120
|
+
wrapper: ({ children }) => (
|
|
121
|
+
<CopilotKitProvider>{children}</CopilotKitProvider>
|
|
122
|
+
),
|
|
123
|
+
});
|
|
124
|
+
|
|
125
|
+
const sandboxContext = findSandboxContext(
|
|
126
|
+
result.current.copilotkit.context,
|
|
127
|
+
);
|
|
128
|
+
expect(sandboxContext).toBeUndefined();
|
|
129
|
+
});
|
|
130
|
+
|
|
131
|
+
it("includes multiple functions in agent context", () => {
|
|
132
|
+
const fns = [makeSandboxFunction("fnA"), makeSandboxFunction("fnB")];
|
|
133
|
+
|
|
134
|
+
const { result } = renderHook(() => useCopilotKit(), {
|
|
135
|
+
wrapper: ({ children }) => (
|
|
136
|
+
<CopilotKitProvider openGenerativeUI={{ sandboxFunctions: fns }}>
|
|
137
|
+
{children}
|
|
138
|
+
</CopilotKitProvider>
|
|
139
|
+
),
|
|
140
|
+
});
|
|
141
|
+
|
|
142
|
+
const sandboxContext = findSandboxContext(
|
|
143
|
+
result.current.copilotkit.context,
|
|
144
|
+
);
|
|
145
|
+
const parsed = JSON.parse(sandboxContext!.value);
|
|
146
|
+
expect(parsed).toHaveLength(2);
|
|
147
|
+
expect(parsed.map((f: any) => f.name)).toEqual(["fnA", "fnB"]);
|
|
148
|
+
});
|
|
149
|
+
|
|
150
|
+
it("converts parameters to JSON Schema in agent context", () => {
|
|
151
|
+
const fns = [
|
|
152
|
+
makeSandboxFunction("myFn", {
|
|
153
|
+
parameters: z.object({
|
|
154
|
+
itemId: z.string(),
|
|
155
|
+
quantity: z.number(),
|
|
156
|
+
}),
|
|
157
|
+
}),
|
|
158
|
+
];
|
|
159
|
+
|
|
160
|
+
const { result } = renderHook(() => useCopilotKit(), {
|
|
161
|
+
wrapper: ({ children }) => (
|
|
162
|
+
<CopilotKitProvider openGenerativeUI={{ sandboxFunctions: fns }}>
|
|
163
|
+
{children}
|
|
164
|
+
</CopilotKitProvider>
|
|
165
|
+
),
|
|
166
|
+
});
|
|
167
|
+
|
|
168
|
+
const sandboxContext = findSandboxContext(
|
|
169
|
+
result.current.copilotkit.context,
|
|
170
|
+
);
|
|
171
|
+
const parsed = JSON.parse(sandboxContext!.value);
|
|
172
|
+
const params = parsed[0].parameters;
|
|
173
|
+
|
|
174
|
+
expect(params.type).toBe("object");
|
|
175
|
+
expect(params.properties.itemId).toEqual({ type: "string" });
|
|
176
|
+
expect(params.properties.quantity).toEqual({ type: "number" });
|
|
177
|
+
});
|
|
178
|
+
|
|
179
|
+
it("removes agent context on unmount", () => {
|
|
180
|
+
const fns = [makeSandboxFunction("myFn")];
|
|
181
|
+
|
|
182
|
+
const { result, unmount } = renderHook(() => useCopilotKit(), {
|
|
183
|
+
wrapper: ({ children }) => (
|
|
184
|
+
<CopilotKitProvider openGenerativeUI={{ sandboxFunctions: fns }}>
|
|
185
|
+
{children}
|
|
186
|
+
</CopilotKitProvider>
|
|
187
|
+
),
|
|
188
|
+
});
|
|
189
|
+
|
|
190
|
+
const copilotkit = result.current.copilotkit;
|
|
191
|
+
expect(findSandboxContext(copilotkit.context)).toBeDefined();
|
|
192
|
+
|
|
193
|
+
unmount();
|
|
194
|
+
|
|
195
|
+
expect(findSandboxContext(copilotkit.context)).toBeUndefined();
|
|
196
|
+
});
|
|
197
|
+
});
|
|
198
|
+
});
|
|
@@ -573,6 +573,76 @@ describe("CopilotKitProvider", () => {
|
|
|
573
573
|
});
|
|
574
574
|
});
|
|
575
575
|
|
|
576
|
+
describe("useSingleEndpoint → runtimeTransport mapping", () => {
|
|
577
|
+
it("maps useSingleEndpoint=true to 'single' transport", () => {
|
|
578
|
+
const { result } = renderHook(() => useCopilotKit(), {
|
|
579
|
+
wrapper: ({ children }) => (
|
|
580
|
+
<CopilotKitProvider useSingleEndpoint={true}>
|
|
581
|
+
{children}
|
|
582
|
+
</CopilotKitProvider>
|
|
583
|
+
),
|
|
584
|
+
});
|
|
585
|
+
|
|
586
|
+
expect(result.current.copilotkit.runtimeTransport).toBe("single");
|
|
587
|
+
});
|
|
588
|
+
|
|
589
|
+
it("maps useSingleEndpoint=false to 'rest' transport", () => {
|
|
590
|
+
const { result } = renderHook(() => useCopilotKit(), {
|
|
591
|
+
wrapper: ({ children }) => (
|
|
592
|
+
<CopilotKitProvider useSingleEndpoint={false}>
|
|
593
|
+
{children}
|
|
594
|
+
</CopilotKitProvider>
|
|
595
|
+
),
|
|
596
|
+
});
|
|
597
|
+
|
|
598
|
+
expect(result.current.copilotkit.runtimeTransport).toBe("rest");
|
|
599
|
+
});
|
|
600
|
+
|
|
601
|
+
it("maps omitted useSingleEndpoint to 'auto' transport", () => {
|
|
602
|
+
const { result } = renderHook(() => useCopilotKit(), {
|
|
603
|
+
wrapper: ({ children }) => (
|
|
604
|
+
<CopilotKitProvider>{children}</CopilotKitProvider>
|
|
605
|
+
),
|
|
606
|
+
});
|
|
607
|
+
|
|
608
|
+
expect(result.current.copilotkit.runtimeTransport).toBe("auto");
|
|
609
|
+
});
|
|
610
|
+
|
|
611
|
+
it("updates transport when useSingleEndpoint prop changes", () => {
|
|
612
|
+
let capturedCopilotkit: ReturnType<typeof useCopilotKit>["copilotkit"];
|
|
613
|
+
|
|
614
|
+
function Collector({ children }: { children?: React.ReactNode }) {
|
|
615
|
+
const { copilotkit } = useCopilotKit();
|
|
616
|
+
capturedCopilotkit = copilotkit;
|
|
617
|
+
return <>{children}</>;
|
|
618
|
+
}
|
|
619
|
+
|
|
620
|
+
const { rerender } = render(
|
|
621
|
+
<CopilotKitProvider useSingleEndpoint={false}>
|
|
622
|
+
<Collector />
|
|
623
|
+
</CopilotKitProvider>,
|
|
624
|
+
);
|
|
625
|
+
|
|
626
|
+
expect(capturedCopilotkit!.runtimeTransport).toBe("rest");
|
|
627
|
+
|
|
628
|
+
rerender(
|
|
629
|
+
<CopilotKitProvider useSingleEndpoint={true}>
|
|
630
|
+
<Collector />
|
|
631
|
+
</CopilotKitProvider>,
|
|
632
|
+
);
|
|
633
|
+
|
|
634
|
+
expect(capturedCopilotkit!.runtimeTransport).toBe("single");
|
|
635
|
+
|
|
636
|
+
rerender(
|
|
637
|
+
<CopilotKitProvider>
|
|
638
|
+
<Collector />
|
|
639
|
+
</CopilotKitProvider>,
|
|
640
|
+
);
|
|
641
|
+
|
|
642
|
+
expect(capturedCopilotkit!.runtimeTransport).toBe("auto");
|
|
643
|
+
});
|
|
644
|
+
});
|
|
645
|
+
|
|
576
646
|
describe("Edge cases", () => {
|
|
577
647
|
it("handles empty arrays for tools", () => {
|
|
578
648
|
const { result } = renderHook(() => useCopilotKit(), {
|
|
@@ -583,6 +653,7 @@ describe("CopilotKitProvider", () => {
|
|
|
583
653
|
),
|
|
584
654
|
});
|
|
585
655
|
|
|
656
|
+
// No built-in tools when openGenerativeUI is not configured
|
|
586
657
|
expect(result.current.copilotkit.tools).toHaveLength(0);
|
|
587
658
|
expect(result.current.copilotkit.renderToolCalls).toHaveLength(0);
|
|
588
659
|
});
|
|
@@ -12,3 +12,10 @@ export {
|
|
|
12
12
|
type CopilotKitProviderProps,
|
|
13
13
|
type CopilotKitContextValue,
|
|
14
14
|
} from "./CopilotKitProvider";
|
|
15
|
+
|
|
16
|
+
export type { Anchor as InspectorAnchor } from "@copilotkit/web-inspector";
|
|
17
|
+
|
|
18
|
+
export {
|
|
19
|
+
SandboxFunctionsContext,
|
|
20
|
+
useSandboxFunctions,
|
|
21
|
+
} from "./SandboxFunctionsContext";
|
package/src/v2/types/index.ts
CHANGED
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import type { StandardSchemaV1 } from "@copilotkit/shared";
|
|
2
|
+
|
|
3
|
+
export type SandboxFunction<
|
|
4
|
+
TParams extends StandardSchemaV1 = StandardSchemaV1,
|
|
5
|
+
> = {
|
|
6
|
+
name: string;
|
|
7
|
+
description: string;
|
|
8
|
+
parameters: TParams;
|
|
9
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
10
|
+
handler: (args: any) => Promise<unknown>;
|
|
11
|
+
};
|