@copilotkitnext/react 0.0.2 → 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 +5 -5
- package/.turbo/turbo-build$colon$css.log +0 -9
- package/.turbo/turbo-build.log +0 -30
- package/.turbo/turbo-check-types.log +0 -0
- 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,81 +0,0 @@
|
|
|
1
|
-
import React, { createContext, useContext, ReactNode } from "react";
|
|
2
|
-
|
|
3
|
-
// Default labels
|
|
4
|
-
export const CopilotChatDefaultLabels = {
|
|
5
|
-
chatInputPlaceholder: "Type a message...",
|
|
6
|
-
chatInputToolbarStartTranscribeButtonLabel: "Transcribe",
|
|
7
|
-
chatInputToolbarCancelTranscribeButtonLabel: "Cancel",
|
|
8
|
-
chatInputToolbarFinishTranscribeButtonLabel: "Finish",
|
|
9
|
-
chatInputToolbarAddButtonLabel: "Add photos or files",
|
|
10
|
-
chatInputToolbarToolsButtonLabel: "Tools",
|
|
11
|
-
assistantMessageToolbarCopyCodeLabel: "Copy",
|
|
12
|
-
assistantMessageToolbarCopyCodeCopiedLabel: "Copied",
|
|
13
|
-
assistantMessageToolbarCopyMessageLabel: "Copy",
|
|
14
|
-
assistantMessageToolbarThumbsUpLabel: "Good response",
|
|
15
|
-
assistantMessageToolbarThumbsDownLabel: "Bad response",
|
|
16
|
-
assistantMessageToolbarReadAloudLabel: "Read aloud",
|
|
17
|
-
assistantMessageToolbarRegenerateLabel: "Regenerate",
|
|
18
|
-
userMessageToolbarCopyMessageLabel: "Copy",
|
|
19
|
-
userMessageToolbarEditMessageLabel: "Edit",
|
|
20
|
-
chatDisclaimerText:
|
|
21
|
-
"AI can make mistakes. Please verify important information.",
|
|
22
|
-
};
|
|
23
|
-
|
|
24
|
-
export type CopilotChatLabels = typeof CopilotChatDefaultLabels;
|
|
25
|
-
|
|
26
|
-
// Define the full configuration interface
|
|
27
|
-
export interface CopilotChatConfigurationValue {
|
|
28
|
-
labels: CopilotChatLabels;
|
|
29
|
-
inputValue?: string;
|
|
30
|
-
onSubmitInput?: (value: string) => void;
|
|
31
|
-
onChangeInput?: (value: string) => void;
|
|
32
|
-
}
|
|
33
|
-
|
|
34
|
-
// Create the configuration context
|
|
35
|
-
const CopilotChatConfiguration =
|
|
36
|
-
createContext<CopilotChatConfigurationValue | null>(null);
|
|
37
|
-
|
|
38
|
-
// Provider props interface
|
|
39
|
-
export interface CopilotChatConfigurationProviderProps {
|
|
40
|
-
children: ReactNode;
|
|
41
|
-
labels?: Partial<CopilotChatLabels>;
|
|
42
|
-
inputValue?: string;
|
|
43
|
-
onSubmitInput?: (value: string) => void;
|
|
44
|
-
onChangeInput?: (value: string) => void;
|
|
45
|
-
}
|
|
46
|
-
|
|
47
|
-
// Provider component
|
|
48
|
-
export const CopilotChatConfigurationProvider: React.FC<
|
|
49
|
-
CopilotChatConfigurationProviderProps
|
|
50
|
-
> = ({ children, labels = {}, inputValue, onSubmitInput, onChangeInput }) => {
|
|
51
|
-
// Merge default labels with provided labels
|
|
52
|
-
const mergedLabels: CopilotChatLabels = {
|
|
53
|
-
...CopilotChatDefaultLabels,
|
|
54
|
-
...labels,
|
|
55
|
-
};
|
|
56
|
-
|
|
57
|
-
const configurationValue: CopilotChatConfigurationValue = {
|
|
58
|
-
labels: mergedLabels,
|
|
59
|
-
inputValue,
|
|
60
|
-
onSubmitInput,
|
|
61
|
-
onChangeInput,
|
|
62
|
-
};
|
|
63
|
-
|
|
64
|
-
return (
|
|
65
|
-
<CopilotChatConfiguration.Provider value={configurationValue}>
|
|
66
|
-
{children}
|
|
67
|
-
</CopilotChatConfiguration.Provider>
|
|
68
|
-
);
|
|
69
|
-
};
|
|
70
|
-
|
|
71
|
-
// Hook to use the full configuration
|
|
72
|
-
export const useCopilotChatConfiguration =
|
|
73
|
-
(): CopilotChatConfigurationValue => {
|
|
74
|
-
const configuration = useContext(CopilotChatConfiguration);
|
|
75
|
-
if (!configuration) {
|
|
76
|
-
throw new Error(
|
|
77
|
-
"useCopilotChatConfiguration must be used within CopilotChatConfigurationProvider"
|
|
78
|
-
);
|
|
79
|
-
}
|
|
80
|
-
return configuration;
|
|
81
|
-
};
|
|
@@ -1,269 +0,0 @@
|
|
|
1
|
-
"use client";
|
|
2
|
-
|
|
3
|
-
import React, {
|
|
4
|
-
createContext,
|
|
5
|
-
useContext,
|
|
6
|
-
ReactNode,
|
|
7
|
-
useMemo,
|
|
8
|
-
useEffect,
|
|
9
|
-
useState,
|
|
10
|
-
useReducer,
|
|
11
|
-
useRef,
|
|
12
|
-
} from "react";
|
|
13
|
-
import { ReactToolCallRender } from "../types/react-tool-call-render";
|
|
14
|
-
import { ReactFrontendTool } from "../types/frontend-tool";
|
|
15
|
-
import { ReactHumanInTheLoop } from "../types/human-in-the-loop";
|
|
16
|
-
import {
|
|
17
|
-
CopilotKitCore,
|
|
18
|
-
CopilotKitCoreConfig,
|
|
19
|
-
FrontendTool,
|
|
20
|
-
} from "@copilotkitnext/core";
|
|
21
|
-
import { AbstractAgent } from "@ag-ui/client";
|
|
22
|
-
|
|
23
|
-
// Define the context value interface - idiomatic React naming
|
|
24
|
-
export interface CopilotKitContextValue {
|
|
25
|
-
copilotkit: CopilotKitCore;
|
|
26
|
-
renderToolCalls: ReactToolCallRender<unknown>[];
|
|
27
|
-
currentRenderToolCalls: ReactToolCallRender<unknown>[];
|
|
28
|
-
setCurrentRenderToolCalls: React.Dispatch<
|
|
29
|
-
React.SetStateAction<ReactToolCallRender<unknown>[]>
|
|
30
|
-
>;
|
|
31
|
-
}
|
|
32
|
-
|
|
33
|
-
// Create the CopilotKit context
|
|
34
|
-
const CopilotKitContext = createContext<CopilotKitContextValue>({
|
|
35
|
-
copilotkit: null!,
|
|
36
|
-
renderToolCalls: [],
|
|
37
|
-
currentRenderToolCalls: [],
|
|
38
|
-
setCurrentRenderToolCalls: () => {},
|
|
39
|
-
});
|
|
40
|
-
|
|
41
|
-
// Provider props interface
|
|
42
|
-
export interface CopilotKitProviderProps {
|
|
43
|
-
children: ReactNode;
|
|
44
|
-
runtimeUrl?: string;
|
|
45
|
-
headers?: Record<string, string>;
|
|
46
|
-
properties?: Record<string, unknown>;
|
|
47
|
-
agents?: Record<string, AbstractAgent>;
|
|
48
|
-
renderToolCalls?: ReactToolCallRender<unknown>[];
|
|
49
|
-
frontendTools?: ReactFrontendTool[];
|
|
50
|
-
humanInTheLoop?: ReactHumanInTheLoop[];
|
|
51
|
-
}
|
|
52
|
-
|
|
53
|
-
// Small helper to normalize array props to a stable reference and warn
|
|
54
|
-
function useStableArrayProp<T>(
|
|
55
|
-
prop: T[] | undefined,
|
|
56
|
-
warningMessage?: string,
|
|
57
|
-
isMeaningfulChange?: (initial: T[], next: T[]) => boolean
|
|
58
|
-
): T[] {
|
|
59
|
-
const empty = useMemo<T[]>(() => [], []);
|
|
60
|
-
const value = prop ?? empty;
|
|
61
|
-
const initial = useRef(value);
|
|
62
|
-
|
|
63
|
-
useEffect(() => {
|
|
64
|
-
if (
|
|
65
|
-
warningMessage &&
|
|
66
|
-
value !== initial.current &&
|
|
67
|
-
(isMeaningfulChange ? isMeaningfulChange(initial.current, value) : true)
|
|
68
|
-
) {
|
|
69
|
-
console.error(warningMessage);
|
|
70
|
-
}
|
|
71
|
-
}, [value, warningMessage]);
|
|
72
|
-
|
|
73
|
-
return value;
|
|
74
|
-
}
|
|
75
|
-
|
|
76
|
-
// Provider component
|
|
77
|
-
export const CopilotKitProvider: React.FC<CopilotKitProviderProps> = ({
|
|
78
|
-
children,
|
|
79
|
-
runtimeUrl,
|
|
80
|
-
headers = {},
|
|
81
|
-
properties = {},
|
|
82
|
-
agents = {},
|
|
83
|
-
renderToolCalls,
|
|
84
|
-
frontendTools,
|
|
85
|
-
humanInTheLoop,
|
|
86
|
-
}) => {
|
|
87
|
-
// Normalize array props to stable references with clear dev warnings
|
|
88
|
-
const renderToolCallsList = useStableArrayProp<ReactToolCallRender<unknown>>(
|
|
89
|
-
renderToolCalls,
|
|
90
|
-
"renderToolCalls must be a stable array. If you want to dynamically add or remove tools, use `useFrontendTool` instead.",
|
|
91
|
-
(initial, next) => {
|
|
92
|
-
// Only warn if the shape (names+agentId) changed. Allow identity changes
|
|
93
|
-
// to support updated closures from parents (e.g., Storybook state).
|
|
94
|
-
const key = (rc?: ReactToolCallRender<unknown>) =>
|
|
95
|
-
`${rc?.agentId ?? ""}:${rc?.name ?? ""}`;
|
|
96
|
-
const setFrom = (arr: ReactToolCallRender<unknown>[]) =>
|
|
97
|
-
new Set(arr.map(key));
|
|
98
|
-
const a = setFrom(initial);
|
|
99
|
-
const b = setFrom(next);
|
|
100
|
-
if (a.size !== b.size) return true;
|
|
101
|
-
for (const k of a) if (!b.has(k)) return true;
|
|
102
|
-
return false;
|
|
103
|
-
}
|
|
104
|
-
);
|
|
105
|
-
const frontendToolsList = useStableArrayProp<ReactFrontendTool>(
|
|
106
|
-
frontendTools,
|
|
107
|
-
"frontendTools must be a stable array. If you want to dynamically add or remove tools, use `useFrontendTool` instead."
|
|
108
|
-
);
|
|
109
|
-
const humanInTheLoopList = useStableArrayProp<ReactHumanInTheLoop>(
|
|
110
|
-
humanInTheLoop,
|
|
111
|
-
"humanInTheLoop must be a stable array. If you want to dynamically add or remove human-in-the-loop tools, use `useHumanInTheLoop` instead."
|
|
112
|
-
);
|
|
113
|
-
|
|
114
|
-
const initialRenderToolCalls = useMemo(() => renderToolCallsList, []);
|
|
115
|
-
const [currentRenderToolCalls, setCurrentRenderToolCalls] = useState<
|
|
116
|
-
ReactToolCallRender<unknown>[]
|
|
117
|
-
>([]);
|
|
118
|
-
|
|
119
|
-
// Note: warnings for array identity changes are handled by useStableArrayProp
|
|
120
|
-
|
|
121
|
-
// Process humanInTheLoop tools to create handlers and add render components
|
|
122
|
-
const processedHumanInTheLoopTools = useMemo(() => {
|
|
123
|
-
const processedTools: FrontendTool[] = [];
|
|
124
|
-
const processedRenderToolCalls: ReactToolCallRender<unknown>[] = [];
|
|
125
|
-
|
|
126
|
-
humanInTheLoopList.forEach((tool) => {
|
|
127
|
-
// Create a promise-based handler for each human-in-the-loop tool
|
|
128
|
-
const frontendTool: FrontendTool = {
|
|
129
|
-
name: tool.name,
|
|
130
|
-
description: tool.description,
|
|
131
|
-
parameters: tool.parameters,
|
|
132
|
-
followUp: tool.followUp,
|
|
133
|
-
...(tool.agentId && { agentId: tool.agentId }),
|
|
134
|
-
handler: async () => {
|
|
135
|
-
// This handler will be replaced by the hook when it runs
|
|
136
|
-
// For provider-level tools, we create a basic handler that waits for user interaction
|
|
137
|
-
return new Promise((resolve) => {
|
|
138
|
-
// The actual implementation will be handled by the render component
|
|
139
|
-
// This is a placeholder that the hook will override
|
|
140
|
-
console.warn(
|
|
141
|
-
`Human-in-the-loop tool '${tool.name}' called but no interactive handler is set up.`
|
|
142
|
-
);
|
|
143
|
-
resolve(undefined);
|
|
144
|
-
});
|
|
145
|
-
},
|
|
146
|
-
};
|
|
147
|
-
processedTools.push(frontendTool);
|
|
148
|
-
|
|
149
|
-
// Add the render component to renderToolCalls
|
|
150
|
-
if (tool.render) {
|
|
151
|
-
processedRenderToolCalls.push({
|
|
152
|
-
name: tool.name,
|
|
153
|
-
args: tool.parameters!,
|
|
154
|
-
render: tool.render,
|
|
155
|
-
...(tool.agentId && { agentId: tool.agentId }),
|
|
156
|
-
} as ReactToolCallRender<unknown>);
|
|
157
|
-
}
|
|
158
|
-
});
|
|
159
|
-
|
|
160
|
-
return { tools: processedTools, renderToolCalls: processedRenderToolCalls };
|
|
161
|
-
}, [humanInTheLoopList]);
|
|
162
|
-
|
|
163
|
-
// Combine all tools for CopilotKitCore
|
|
164
|
-
const allTools = useMemo(() => {
|
|
165
|
-
const tools: Record<string, FrontendTool> = {};
|
|
166
|
-
|
|
167
|
-
// Add frontend tools
|
|
168
|
-
frontendToolsList.forEach((tool) => {
|
|
169
|
-
tools[tool.name] = tool;
|
|
170
|
-
});
|
|
171
|
-
|
|
172
|
-
// Add processed human-in-the-loop tools
|
|
173
|
-
processedHumanInTheLoopTools.tools.forEach((tool) => {
|
|
174
|
-
tools[tool.name] = tool;
|
|
175
|
-
});
|
|
176
|
-
|
|
177
|
-
return tools;
|
|
178
|
-
}, [frontendToolsList, processedHumanInTheLoopTools]);
|
|
179
|
-
|
|
180
|
-
// Combine all render tool calls
|
|
181
|
-
const allRenderToolCalls = useMemo(() => {
|
|
182
|
-
const combined: ReactToolCallRender<unknown>[] = [...renderToolCallsList];
|
|
183
|
-
|
|
184
|
-
// Add render components from frontend tools
|
|
185
|
-
frontendToolsList.forEach((tool) => {
|
|
186
|
-
if (tool.render && tool.parameters) {
|
|
187
|
-
combined.push({
|
|
188
|
-
name: tool.name,
|
|
189
|
-
args: tool.parameters,
|
|
190
|
-
render: tool.render,
|
|
191
|
-
} as ReactToolCallRender<unknown>);
|
|
192
|
-
}
|
|
193
|
-
});
|
|
194
|
-
|
|
195
|
-
// Add render components from human-in-the-loop tools
|
|
196
|
-
combined.push(...processedHumanInTheLoopTools.renderToolCalls);
|
|
197
|
-
|
|
198
|
-
return combined;
|
|
199
|
-
}, [renderToolCallsList, frontendToolsList, processedHumanInTheLoopTools]);
|
|
200
|
-
|
|
201
|
-
const copilotkit = useMemo(() => {
|
|
202
|
-
const config: CopilotKitCoreConfig = {
|
|
203
|
-
// Don't set runtimeUrl during initialization to prevent server-side fetching
|
|
204
|
-
runtimeUrl: undefined,
|
|
205
|
-
headers,
|
|
206
|
-
properties,
|
|
207
|
-
agents,
|
|
208
|
-
tools: allTools,
|
|
209
|
-
};
|
|
210
|
-
const copilotkit = new CopilotKitCore(config);
|
|
211
|
-
|
|
212
|
-
return copilotkit;
|
|
213
|
-
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
214
|
-
}, [allTools]);
|
|
215
|
-
|
|
216
|
-
// Keep currentRenderToolCalls in sync with computed render tool calls
|
|
217
|
-
// so that updates to the render functions/closures propagate.
|
|
218
|
-
useEffect(() => {
|
|
219
|
-
setCurrentRenderToolCalls((prev) =>
|
|
220
|
-
prev === allRenderToolCalls ? prev : allRenderToolCalls
|
|
221
|
-
);
|
|
222
|
-
}, [allRenderToolCalls]);
|
|
223
|
-
|
|
224
|
-
useEffect(() => {
|
|
225
|
-
copilotkit.setRuntimeUrl(runtimeUrl);
|
|
226
|
-
copilotkit.setHeaders(headers);
|
|
227
|
-
copilotkit.setProperties(properties);
|
|
228
|
-
copilotkit.setAgents(agents);
|
|
229
|
-
}, [runtimeUrl, headers, properties, agents]);
|
|
230
|
-
|
|
231
|
-
return (
|
|
232
|
-
<CopilotKitContext.Provider
|
|
233
|
-
value={{
|
|
234
|
-
copilotkit,
|
|
235
|
-
renderToolCalls: allRenderToolCalls,
|
|
236
|
-
currentRenderToolCalls,
|
|
237
|
-
setCurrentRenderToolCalls,
|
|
238
|
-
}}
|
|
239
|
-
>
|
|
240
|
-
{children}
|
|
241
|
-
</CopilotKitContext.Provider>
|
|
242
|
-
);
|
|
243
|
-
};
|
|
244
|
-
|
|
245
|
-
// Hook to use the CopilotKit instance - returns the full context value
|
|
246
|
-
export const useCopilotKit = (): CopilotKitContextValue => {
|
|
247
|
-
const context = useContext(CopilotKitContext);
|
|
248
|
-
const [, forceUpdate] = useReducer((x) => x + 1, 0);
|
|
249
|
-
|
|
250
|
-
if (!context) {
|
|
251
|
-
throw new Error("useCopilotKit must be used within CopilotKitProvider");
|
|
252
|
-
}
|
|
253
|
-
useEffect(() => {
|
|
254
|
-
const unsubscribe = context.copilotkit.subscribe({
|
|
255
|
-
onRuntimeLoaded: () => {
|
|
256
|
-
forceUpdate();
|
|
257
|
-
},
|
|
258
|
-
onRuntimeLoadError: () => {
|
|
259
|
-
forceUpdate();
|
|
260
|
-
},
|
|
261
|
-
});
|
|
262
|
-
return () => {
|
|
263
|
-
unsubscribe();
|
|
264
|
-
};
|
|
265
|
-
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
266
|
-
}, []);
|
|
267
|
-
|
|
268
|
-
return context;
|
|
269
|
-
};
|