@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,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
- };