@copilotkit/react-core 1.9.2-next.9 → 1.9.3-next.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 +191 -0
- package/dist/{chunk-ERXWDCY6.mjs → chunk-36MGCCPZ.mjs} +2 -2
- package/dist/{chunk-UBNRUXEK.mjs → chunk-5BSUSFHM.mjs} +2 -2
- package/dist/{chunk-G7LYGERN.mjs → chunk-6ZLSC4KB.mjs} +124 -73
- package/dist/chunk-6ZLSC4KB.mjs.map +1 -0
- package/dist/{chunk-JDEWNLNP.mjs → chunk-BSAVFYRQ.mjs} +11 -11
- package/dist/{chunk-JDEWNLNP.mjs.map → chunk-BSAVFYRQ.mjs.map} +1 -1
- package/dist/{chunk-JPMIAGI6.mjs → chunk-BVK7PLK6.mjs} +2 -2
- package/dist/{chunk-FXK6RQIN.mjs → chunk-CUAFWKTQ.mjs} +4 -4
- package/dist/{chunk-XFOTNHYA.mjs → chunk-DKZTPL66.mjs} +2 -2
- package/dist/{chunk-XFOTNHYA.mjs.map → chunk-DKZTPL66.mjs.map} +1 -1
- package/dist/{chunk-EF5BNM34.mjs → chunk-FN3UA2ZE.mjs} +3 -3
- package/dist/{chunk-EXU7GWLC.mjs → chunk-GEE5AMYL.mjs} +9 -9
- package/dist/{chunk-WOGURSAL.mjs → chunk-GIMSRCVW.mjs} +64 -23
- package/dist/chunk-GIMSRCVW.mjs.map +1 -0
- package/dist/{chunk-55QZ2SVJ.mjs → chunk-JWAXDYOW.mjs} +8 -8
- package/dist/chunk-JWAXDYOW.mjs.map +1 -0
- package/dist/{chunk-3YHYWAHK.mjs → chunk-KIXKBJUV.mjs} +2 -2
- package/dist/{chunk-ADIITPD2.mjs → chunk-KLENTCQV.mjs} +34 -8
- package/dist/{chunk-ADIITPD2.mjs.map → chunk-KLENTCQV.mjs.map} +1 -1
- package/dist/{chunk-OF4SZTLL.mjs → chunk-NGQN3JRJ.mjs} +3 -3
- package/dist/{chunk-NQVCZQ5T.mjs → chunk-NJA5ZLAZ.mjs} +27 -8
- package/dist/chunk-NJA5ZLAZ.mjs.map +1 -0
- package/dist/{chunk-SJJNFYGQ.mjs → chunk-SGF6C7I6.mjs} +4 -4
- package/dist/{chunk-CMQV4XNY.mjs → chunk-VDADWRS3.mjs} +2 -2
- package/dist/components/copilot-provider/copilot-messages.js +7 -7
- package/dist/components/copilot-provider/copilot-messages.js.map +1 -1
- package/dist/components/copilot-provider/copilot-messages.mjs +3 -3
- package/dist/components/copilot-provider/copilotkit-props.d.ts +14 -9
- package/dist/components/copilot-provider/copilotkit-props.js.map +1 -1
- package/dist/components/copilot-provider/copilotkit.d.ts +1 -1
- package/dist/components/copilot-provider/copilotkit.js +70 -29
- package/dist/components/copilot-provider/copilotkit.js.map +1 -1
- package/dist/components/copilot-provider/copilotkit.mjs +9 -9
- package/dist/components/copilot-provider/index.d.ts +1 -1
- package/dist/components/copilot-provider/index.js +70 -29
- package/dist/components/copilot-provider/index.js.map +1 -1
- package/dist/components/copilot-provider/index.mjs +9 -9
- package/dist/components/error-boundary/error-boundary.mjs +2 -2
- package/dist/components/index.d.ts +1 -1
- package/dist/components/index.js +70 -29
- package/dist/components/index.js.map +1 -1
- package/dist/components/index.mjs +9 -9
- package/dist/context/copilot-context.d.ts +1 -1
- package/dist/context/copilot-context.js +1 -1
- package/dist/context/copilot-context.js.map +1 -1
- package/dist/context/copilot-context.mjs +1 -1
- package/dist/context/index.d.ts +1 -1
- package/dist/context/index.js +1 -1
- package/dist/context/index.js.map +1 -1
- package/dist/context/index.mjs +4 -4
- package/dist/{copilot-context-3da805ab.d.ts → copilot-context-3ab4fdf5.d.ts} +3 -3
- package/dist/hooks/index.d.ts +1 -1
- package/dist/hooks/index.js +179 -83
- package/dist/hooks/index.js.map +1 -1
- package/dist/hooks/index.mjs +23 -23
- package/dist/hooks/use-chat.d.ts +1 -1
- package/dist/hooks/use-chat.js +220 -169
- package/dist/hooks/use-chat.js.map +1 -1
- package/dist/hooks/use-chat.mjs +4 -4
- package/dist/hooks/use-coagent-state-render.js +1 -1
- package/dist/hooks/use-coagent-state-render.js.map +1 -1
- package/dist/hooks/use-coagent-state-render.mjs +2 -2
- package/dist/hooks/use-coagent.d.ts +1 -1
- package/dist/hooks/use-coagent.js +154 -77
- package/dist/hooks/use-coagent.js.map +1 -1
- package/dist/hooks/use-coagent.mjs +14 -14
- package/dist/hooks/use-copilot-action.js +26 -7
- package/dist/hooks/use-copilot-action.js.map +1 -1
- package/dist/hooks/use-copilot-action.mjs +2 -2
- package/dist/hooks/use-copilot-additional-instructions.js +1 -1
- package/dist/hooks/use-copilot-additional-instructions.js.map +1 -1
- package/dist/hooks/use-copilot-additional-instructions.mjs +2 -2
- package/dist/hooks/use-copilot-authenticated-action.js +26 -7
- package/dist/hooks/use-copilot-authenticated-action.js.map +1 -1
- package/dist/hooks/use-copilot-authenticated-action.mjs +3 -3
- package/dist/hooks/use-copilot-chat.d.ts +1 -1
- package/dist/hooks/use-copilot-chat.js +128 -77
- package/dist/hooks/use-copilot-chat.js.map +1 -1
- package/dist/hooks/use-copilot-chat.mjs +13 -13
- package/dist/hooks/use-copilot-readable.js +1 -1
- package/dist/hooks/use-copilot-readable.js.map +1 -1
- package/dist/hooks/use-copilot-readable.mjs +2 -2
- package/dist/hooks/use-copilot-runtime-client.d.ts +2 -2
- package/dist/hooks/use-copilot-runtime-client.js +7 -7
- package/dist/hooks/use-copilot-runtime-client.js.map +1 -1
- package/dist/hooks/use-copilot-runtime-client.mjs +1 -1
- package/dist/hooks/use-langgraph-interrupt-render.js +1 -1
- package/dist/hooks/use-langgraph-interrupt-render.js.map +1 -1
- package/dist/hooks/use-langgraph-interrupt-render.mjs +2 -2
- package/dist/hooks/use-langgraph-interrupt.d.ts +1 -1
- package/dist/hooks/use-langgraph-interrupt.js +128 -77
- package/dist/hooks/use-langgraph-interrupt.js.map +1 -1
- package/dist/hooks/use-langgraph-interrupt.mjs +14 -14
- package/dist/hooks/use-make-copilot-document-readable.js +1 -1
- package/dist/hooks/use-make-copilot-document-readable.js.map +1 -1
- package/dist/hooks/use-make-copilot-document-readable.mjs +2 -2
- package/dist/index.d.ts +1 -1
- package/dist/index.js +240 -103
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +27 -27
- package/dist/lib/copilot-task.d.ts +1 -1
- package/dist/lib/copilot-task.js.map +1 -1
- package/dist/lib/copilot-task.mjs +11 -11
- package/dist/lib/index.d.ts +1 -1
- package/dist/lib/index.js.map +1 -1
- package/dist/lib/index.mjs +11 -11
- package/dist/setupTests.d.ts +2 -0
- package/dist/setupTests.js +26 -0
- package/dist/setupTests.js.map +1 -0
- package/dist/setupTests.mjs +24 -0
- package/dist/setupTests.mjs.map +1 -0
- package/dist/types/interrupt-action.d.ts +1 -1
- package/dist/utils/extract.d.ts +1 -1
- package/dist/utils/extract.js.map +1 -1
- package/dist/utils/extract.mjs +9 -9
- package/dist/utils/index.d.ts +1 -1
- package/dist/utils/index.js.map +1 -1
- package/dist/utils/index.mjs +10 -10
- package/jest.config.js +4 -0
- package/package.json +6 -3
- package/src/components/copilot-provider/__tests__/{copilotkit-trace.test.tsx → copilotkit-error.test.tsx} +17 -17
- package/src/components/copilot-provider/copilot-messages.tsx +7 -7
- package/src/components/copilot-provider/copilotkit-props.tsx +13 -8
- package/src/components/copilot-provider/copilotkit.tsx +61 -19
- package/src/context/copilot-context.tsx +4 -4
- package/src/hooks/__tests__/use-coagent-config.test.ts +284 -0
- package/src/hooks/use-chat.ts +149 -61
- package/src/hooks/use-coagent.ts +36 -0
- package/src/hooks/use-copilot-action.ts +51 -9
- package/src/hooks/use-copilot-runtime-client.ts +11 -12
- package/src/setupTests.ts +26 -0
- package/tsconfig.json +5 -2
- package/dist/chunk-55QZ2SVJ.mjs.map +0 -1
- package/dist/chunk-G7LYGERN.mjs.map +0 -1
- package/dist/chunk-NQVCZQ5T.mjs.map +0 -1
- package/dist/chunk-WOGURSAL.mjs.map +0 -1
- /package/dist/{chunk-ERXWDCY6.mjs.map → chunk-36MGCCPZ.mjs.map} +0 -0
- /package/dist/{chunk-UBNRUXEK.mjs.map → chunk-5BSUSFHM.mjs.map} +0 -0
- /package/dist/{chunk-JPMIAGI6.mjs.map → chunk-BVK7PLK6.mjs.map} +0 -0
- /package/dist/{chunk-FXK6RQIN.mjs.map → chunk-CUAFWKTQ.mjs.map} +0 -0
- /package/dist/{chunk-EF5BNM34.mjs.map → chunk-FN3UA2ZE.mjs.map} +0 -0
- /package/dist/{chunk-EXU7GWLC.mjs.map → chunk-GEE5AMYL.mjs.map} +0 -0
- /package/dist/{chunk-3YHYWAHK.mjs.map → chunk-KIXKBJUV.mjs.map} +0 -0
- /package/dist/{chunk-OF4SZTLL.mjs.map → chunk-NGQN3JRJ.mjs.map} +0 -0
- /package/dist/{chunk-SJJNFYGQ.mjs.map → chunk-SGF6C7I6.mjs.map} +0 -0
- /package/dist/{chunk-CMQV4XNY.mjs.map → chunk-VDADWRS3.mjs.map} +0 -0
|
@@ -272,26 +272,29 @@ export function CopilotKitInternal(cpkProps: CopilotKitProps) {
|
|
|
272
272
|
headers,
|
|
273
273
|
credentials: copilotApiConfig.credentials,
|
|
274
274
|
showDevConsole: props.showDevConsole ?? false,
|
|
275
|
-
|
|
275
|
+
onError: props.onError,
|
|
276
276
|
});
|
|
277
277
|
|
|
278
278
|
const [chatSuggestionConfiguration, setChatSuggestionConfiguration] = useState<{
|
|
279
279
|
[key: string]: CopilotChatSuggestionConfiguration;
|
|
280
280
|
}>({});
|
|
281
281
|
|
|
282
|
-
const addChatSuggestionConfiguration = (
|
|
283
|
-
id: string,
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
setChatSuggestionConfiguration
|
|
287
|
-
|
|
282
|
+
const addChatSuggestionConfiguration = useCallback(
|
|
283
|
+
(id: string, suggestion: CopilotChatSuggestionConfiguration) => {
|
|
284
|
+
setChatSuggestionConfiguration((prev) => ({ ...prev, [id]: suggestion }));
|
|
285
|
+
},
|
|
286
|
+
[setChatSuggestionConfiguration],
|
|
287
|
+
);
|
|
288
288
|
|
|
289
|
-
const removeChatSuggestionConfiguration = (
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
289
|
+
const removeChatSuggestionConfiguration = useCallback(
|
|
290
|
+
(id: string) => {
|
|
291
|
+
setChatSuggestionConfiguration((prev) => {
|
|
292
|
+
const { [id]: _, ...rest } = prev;
|
|
293
|
+
return rest;
|
|
294
|
+
});
|
|
295
|
+
},
|
|
296
|
+
[setChatSuggestionConfiguration],
|
|
297
|
+
);
|
|
295
298
|
|
|
296
299
|
const [availableAgents, setAvailableAgents] = useState<Agent[]>([]);
|
|
297
300
|
const [coagentStates, setCoagentStates] = useState<Record<string, CoagentState>>({});
|
|
@@ -389,6 +392,45 @@ export function CopilotKitInternal(cpkProps: CopilotKitProps) {
|
|
|
389
392
|
|
|
390
393
|
const memoizedChildren = useMemo(() => children, [children]);
|
|
391
394
|
|
|
395
|
+
const agentLock = useMemo(() => props.agent ?? null, [props.agent]);
|
|
396
|
+
|
|
397
|
+
const forwardedParameters = useMemo(
|
|
398
|
+
() => props.forwardedParameters ?? {},
|
|
399
|
+
[props.forwardedParameters],
|
|
400
|
+
);
|
|
401
|
+
|
|
402
|
+
const updateExtensions = useCallback(
|
|
403
|
+
(newExtensions: SetStateAction<ExtensionsInput>) => {
|
|
404
|
+
setExtensions((prev: ExtensionsInput) => {
|
|
405
|
+
const resolved = typeof newExtensions === "function" ? newExtensions(prev) : newExtensions;
|
|
406
|
+
const isSameLength = Object.keys(resolved).length === Object.keys(prev).length;
|
|
407
|
+
const isEqual =
|
|
408
|
+
isSameLength &&
|
|
409
|
+
// @ts-ignore
|
|
410
|
+
Object.entries(resolved).every(([key, value]) => prev[key] === value);
|
|
411
|
+
|
|
412
|
+
return isEqual ? prev : resolved;
|
|
413
|
+
});
|
|
414
|
+
},
|
|
415
|
+
[setExtensions],
|
|
416
|
+
);
|
|
417
|
+
|
|
418
|
+
const updateAuthStates = useCallback(
|
|
419
|
+
(newAuthStates: SetStateAction<Record<string, AuthState>>) => {
|
|
420
|
+
setAuthStates((prev) => {
|
|
421
|
+
const resolved = typeof newAuthStates === "function" ? newAuthStates(prev) : newAuthStates;
|
|
422
|
+
const isSameLength = Object.keys(resolved).length === Object.keys(prev).length;
|
|
423
|
+
const isEqual =
|
|
424
|
+
isSameLength &&
|
|
425
|
+
// @ts-ignore
|
|
426
|
+
Object.entries(resolved).every(([key, value]) => prev[key] === value);
|
|
427
|
+
|
|
428
|
+
return isEqual ? prev : resolved;
|
|
429
|
+
});
|
|
430
|
+
},
|
|
431
|
+
[setAuthStates],
|
|
432
|
+
);
|
|
433
|
+
|
|
392
434
|
return (
|
|
393
435
|
<CopilotContext.Provider
|
|
394
436
|
value={{
|
|
@@ -425,8 +467,8 @@ export function CopilotKitInternal(cpkProps: CopilotKitProps) {
|
|
|
425
467
|
agentSession,
|
|
426
468
|
setAgentSession,
|
|
427
469
|
runtimeClient,
|
|
428
|
-
forwardedParameters
|
|
429
|
-
agentLock
|
|
470
|
+
forwardedParameters,
|
|
471
|
+
agentLock,
|
|
430
472
|
threadId: internalThreadId,
|
|
431
473
|
setThreadId,
|
|
432
474
|
runId,
|
|
@@ -435,13 +477,13 @@ export function CopilotKitInternal(cpkProps: CopilotKitProps) {
|
|
|
435
477
|
availableAgents,
|
|
436
478
|
authConfig_c: props.authConfig_c,
|
|
437
479
|
authStates_c: authStates,
|
|
438
|
-
setAuthStates_c:
|
|
480
|
+
setAuthStates_c: updateAuthStates,
|
|
439
481
|
extensions,
|
|
440
|
-
setExtensions,
|
|
482
|
+
setExtensions: updateExtensions,
|
|
441
483
|
langGraphInterruptAction,
|
|
442
484
|
setLangGraphInterruptAction,
|
|
443
485
|
removeLangGraphInterruptAction,
|
|
444
|
-
|
|
486
|
+
onError: props.onError,
|
|
445
487
|
}}
|
|
446
488
|
>
|
|
447
489
|
<CopilotMessages>{memoizedChildren}</CopilotMessages>
|
|
@@ -452,7 +494,7 @@ export function CopilotKitInternal(cpkProps: CopilotKitProps) {
|
|
|
452
494
|
export const defaultCopilotContextCategories = ["global"];
|
|
453
495
|
|
|
454
496
|
function entryPointsToFunctionCallHandler(actions: FrontendAction<any>[]): FunctionCallHandler {
|
|
455
|
-
return async ({ name, args }) => {
|
|
497
|
+
return async ({ name, args }: { name: string; args: Record<string, any> }) => {
|
|
456
498
|
let actionsByFunctionName: Record<string, FrontendAction<any>> = {};
|
|
457
499
|
for (let action of actions) {
|
|
458
500
|
actionsByFunctionName[action.name] = action;
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { CopilotCloudConfig, FunctionCallHandler,
|
|
1
|
+
import { CopilotCloudConfig, FunctionCallHandler, CopilotErrorHandler } from "@copilotkit/shared";
|
|
2
2
|
import {
|
|
3
3
|
ActionRenderProps,
|
|
4
4
|
CatchAllActionRenderProps,
|
|
@@ -195,7 +195,7 @@ export interface CopilotContextParams {
|
|
|
195
195
|
/**
|
|
196
196
|
* The forwarded parameters to use for the task.
|
|
197
197
|
*/
|
|
198
|
-
forwardedParameters?: Pick<ForwardedParametersInput, "temperature"
|
|
198
|
+
forwardedParameters?: Partial<Pick<ForwardedParametersInput, "temperature">>;
|
|
199
199
|
availableAgents: Agent[];
|
|
200
200
|
|
|
201
201
|
/**
|
|
@@ -222,7 +222,7 @@ export interface CopilotContextParams {
|
|
|
222
222
|
/**
|
|
223
223
|
* Optional trace handler for comprehensive debugging and observability.
|
|
224
224
|
*/
|
|
225
|
-
|
|
225
|
+
onError?: CopilotErrorHandler;
|
|
226
226
|
}
|
|
227
227
|
|
|
228
228
|
const emptyCopilotContext: CopilotContextParams = {
|
|
@@ -293,7 +293,7 @@ const emptyCopilotContext: CopilotContextParams = {
|
|
|
293
293
|
langGraphInterruptAction: null,
|
|
294
294
|
setLangGraphInterruptAction: () => null,
|
|
295
295
|
removeLangGraphInterruptAction: () => null,
|
|
296
|
-
|
|
296
|
+
onError: undefined,
|
|
297
297
|
};
|
|
298
298
|
|
|
299
299
|
export const CopilotContext = React.createContext<CopilotContextParams>(emptyCopilotContext);
|
|
@@ -0,0 +1,284 @@
|
|
|
1
|
+
import { renderHook } from "@testing-library/react";
|
|
2
|
+
import { useCoAgent } from "../use-coagent";
|
|
3
|
+
|
|
4
|
+
// Mock the dependencies
|
|
5
|
+
const mockSetCoagentStatesWithRef = jest.fn();
|
|
6
|
+
const mockAppendMessage = jest.fn();
|
|
7
|
+
const mockRunChatCompletion = jest.fn();
|
|
8
|
+
|
|
9
|
+
jest.mock("../use-copilot-chat", () => ({
|
|
10
|
+
useCopilotChat: () => ({
|
|
11
|
+
appendMessage: mockAppendMessage,
|
|
12
|
+
runChatCompletion: mockRunChatCompletion,
|
|
13
|
+
}),
|
|
14
|
+
}));
|
|
15
|
+
|
|
16
|
+
jest.mock("../use-copilot-runtime-client", () => ({
|
|
17
|
+
useCopilotRuntimeClient: () => ({
|
|
18
|
+
loadAgentState: jest.fn().mockResolvedValue({
|
|
19
|
+
data: { loadAgentState: { state: "{}", threadExists: false } },
|
|
20
|
+
error: null,
|
|
21
|
+
}),
|
|
22
|
+
}),
|
|
23
|
+
}));
|
|
24
|
+
|
|
25
|
+
jest.mock("../../context", () => ({
|
|
26
|
+
useCopilotContext: () => ({
|
|
27
|
+
availableAgents: [],
|
|
28
|
+
coagentStates: {},
|
|
29
|
+
coagentStatesRef: { current: {} },
|
|
30
|
+
setCoagentStatesWithRef: mockSetCoagentStatesWithRef,
|
|
31
|
+
threadId: "test-thread",
|
|
32
|
+
copilotApiConfig: {
|
|
33
|
+
headers: {},
|
|
34
|
+
chatApiEndpoint: "test-endpoint",
|
|
35
|
+
publicApiKey: "test-key",
|
|
36
|
+
},
|
|
37
|
+
showDevConsole: false,
|
|
38
|
+
}),
|
|
39
|
+
useCopilotMessagesContext: () => ({
|
|
40
|
+
messages: [],
|
|
41
|
+
}),
|
|
42
|
+
}));
|
|
43
|
+
|
|
44
|
+
jest.mock("../../components/toast/toast-provider", () => ({
|
|
45
|
+
useToast: () => ({
|
|
46
|
+
setBannerError: jest.fn(),
|
|
47
|
+
}),
|
|
48
|
+
}));
|
|
49
|
+
|
|
50
|
+
jest.mock("../../components/error-boundary/error-utils", () => ({
|
|
51
|
+
useAsyncCallback: (fn: any) => fn,
|
|
52
|
+
}));
|
|
53
|
+
|
|
54
|
+
describe("useCoAgent config synchronization", () => {
|
|
55
|
+
beforeEach(() => {
|
|
56
|
+
jest.clearAllMocks();
|
|
57
|
+
mockSetCoagentStatesWithRef.mockImplementation((updater) => {
|
|
58
|
+
if (typeof updater === "function") {
|
|
59
|
+
updater({});
|
|
60
|
+
}
|
|
61
|
+
});
|
|
62
|
+
});
|
|
63
|
+
|
|
64
|
+
it("should call setCoagentStatesWithRef when config changes", () => {
|
|
65
|
+
const { rerender } = renderHook(
|
|
66
|
+
({ config }) =>
|
|
67
|
+
useCoAgent({
|
|
68
|
+
name: "test-agent",
|
|
69
|
+
initialState: { count: 0 },
|
|
70
|
+
config,
|
|
71
|
+
}),
|
|
72
|
+
{
|
|
73
|
+
initialProps: { config: { configurable: { model: "gpt-4" } } },
|
|
74
|
+
},
|
|
75
|
+
);
|
|
76
|
+
|
|
77
|
+
// Clear the initial calls
|
|
78
|
+
mockSetCoagentStatesWithRef.mockClear();
|
|
79
|
+
|
|
80
|
+
// Change config
|
|
81
|
+
rerender({ config: { configurable: { model: "gpt-4o" } } });
|
|
82
|
+
|
|
83
|
+
// Should have called setCoagentStatesWithRef with new config
|
|
84
|
+
expect(mockSetCoagentStatesWithRef).toHaveBeenCalledWith(expect.any(Function));
|
|
85
|
+
});
|
|
86
|
+
|
|
87
|
+
it("should not call setCoagentStatesWithRef when config is unchanged", () => {
|
|
88
|
+
const config = { configurable: { model: "gpt-4" } };
|
|
89
|
+
|
|
90
|
+
const { rerender } = renderHook(
|
|
91
|
+
({ config }) =>
|
|
92
|
+
useCoAgent({
|
|
93
|
+
name: "test-agent",
|
|
94
|
+
initialState: { count: 0 },
|
|
95
|
+
config,
|
|
96
|
+
}),
|
|
97
|
+
{
|
|
98
|
+
initialProps: { config },
|
|
99
|
+
},
|
|
100
|
+
);
|
|
101
|
+
|
|
102
|
+
// Clear the initial calls
|
|
103
|
+
mockSetCoagentStatesWithRef.mockClear();
|
|
104
|
+
|
|
105
|
+
// Re-render with same config
|
|
106
|
+
rerender({ config });
|
|
107
|
+
|
|
108
|
+
// Should not have called setCoagentStatesWithRef
|
|
109
|
+
expect(mockSetCoagentStatesWithRef).not.toHaveBeenCalled();
|
|
110
|
+
});
|
|
111
|
+
|
|
112
|
+
it("should handle backward compatibility with configurable prop", () => {
|
|
113
|
+
const { rerender } = renderHook(
|
|
114
|
+
({ configurable }) =>
|
|
115
|
+
useCoAgent({
|
|
116
|
+
name: "test-agent",
|
|
117
|
+
initialState: { count: 0 },
|
|
118
|
+
configurable,
|
|
119
|
+
}),
|
|
120
|
+
{
|
|
121
|
+
initialProps: { configurable: { model: "gpt-4" } },
|
|
122
|
+
},
|
|
123
|
+
);
|
|
124
|
+
|
|
125
|
+
// Clear the initial calls
|
|
126
|
+
mockSetCoagentStatesWithRef.mockClear();
|
|
127
|
+
|
|
128
|
+
// Change configurable prop
|
|
129
|
+
rerender({ configurable: { model: "gpt-4o" } });
|
|
130
|
+
|
|
131
|
+
// Should have called setCoagentStatesWithRef
|
|
132
|
+
expect(mockSetCoagentStatesWithRef).toHaveBeenCalledWith(expect.any(Function));
|
|
133
|
+
});
|
|
134
|
+
|
|
135
|
+
it("should update config while preserving other state properties", () => {
|
|
136
|
+
let capturedUpdater: any = null;
|
|
137
|
+
|
|
138
|
+
mockSetCoagentStatesWithRef.mockImplementation((updater) => {
|
|
139
|
+
capturedUpdater = updater;
|
|
140
|
+
return updater;
|
|
141
|
+
});
|
|
142
|
+
|
|
143
|
+
const { rerender } = renderHook(
|
|
144
|
+
({ config }) =>
|
|
145
|
+
useCoAgent({
|
|
146
|
+
name: "test-agent",
|
|
147
|
+
initialState: { count: 0 },
|
|
148
|
+
config,
|
|
149
|
+
}),
|
|
150
|
+
{
|
|
151
|
+
initialProps: { config: { configurable: { model: "gpt-4" } } },
|
|
152
|
+
},
|
|
153
|
+
);
|
|
154
|
+
|
|
155
|
+
// Clear the initial calls and reset captured updater
|
|
156
|
+
mockSetCoagentStatesWithRef.mockClear();
|
|
157
|
+
capturedUpdater = null;
|
|
158
|
+
|
|
159
|
+
// Change config
|
|
160
|
+
rerender({ config: { configurable: { model: "gpt-4o" } } });
|
|
161
|
+
|
|
162
|
+
// Should have called setCoagentStatesWithRef
|
|
163
|
+
expect(mockSetCoagentStatesWithRef).toHaveBeenCalledWith(expect.any(Function));
|
|
164
|
+
expect(capturedUpdater).toBeTruthy();
|
|
165
|
+
|
|
166
|
+
// Test the updater function behavior
|
|
167
|
+
const prevState = {
|
|
168
|
+
"test-agent": {
|
|
169
|
+
name: "test-agent",
|
|
170
|
+
state: { count: 5 },
|
|
171
|
+
config: { configurable: { model: "gpt-4" } },
|
|
172
|
+
running: true,
|
|
173
|
+
active: true,
|
|
174
|
+
threadId: "thread-123",
|
|
175
|
+
nodeName: "test-node",
|
|
176
|
+
runId: "run-456",
|
|
177
|
+
},
|
|
178
|
+
};
|
|
179
|
+
|
|
180
|
+
const newState = capturedUpdater(prevState);
|
|
181
|
+
|
|
182
|
+
// Verify the state is updated correctly
|
|
183
|
+
expect(newState).toEqual({
|
|
184
|
+
"test-agent": {
|
|
185
|
+
name: "test-agent",
|
|
186
|
+
state: { count: 5 }, // State preserved
|
|
187
|
+
config: { configurable: { model: "gpt-4o" } }, // Config updated
|
|
188
|
+
running: true, // Other properties preserved
|
|
189
|
+
active: true,
|
|
190
|
+
threadId: "thread-123",
|
|
191
|
+
nodeName: "test-node",
|
|
192
|
+
runId: "run-456",
|
|
193
|
+
},
|
|
194
|
+
});
|
|
195
|
+
});
|
|
196
|
+
|
|
197
|
+
it("should create new agent state when agent doesn't exist", () => {
|
|
198
|
+
let capturedUpdater: any = null;
|
|
199
|
+
|
|
200
|
+
mockSetCoagentStatesWithRef.mockImplementation((updater) => {
|
|
201
|
+
capturedUpdater = updater;
|
|
202
|
+
return updater;
|
|
203
|
+
});
|
|
204
|
+
|
|
205
|
+
const { rerender } = renderHook(
|
|
206
|
+
({ config }) =>
|
|
207
|
+
useCoAgent({
|
|
208
|
+
name: "test-agent",
|
|
209
|
+
initialState: { count: 0 },
|
|
210
|
+
config,
|
|
211
|
+
}),
|
|
212
|
+
{
|
|
213
|
+
initialProps: { config: { configurable: { model: "gpt-4" } } },
|
|
214
|
+
},
|
|
215
|
+
);
|
|
216
|
+
|
|
217
|
+
// Clear the initial calls and reset captured updater
|
|
218
|
+
mockSetCoagentStatesWithRef.mockClear();
|
|
219
|
+
capturedUpdater = null;
|
|
220
|
+
|
|
221
|
+
// Change config
|
|
222
|
+
rerender({ config: { configurable: { model: "gpt-4o" } } });
|
|
223
|
+
|
|
224
|
+
// Should have called setCoagentStatesWithRef
|
|
225
|
+
expect(mockSetCoagentStatesWithRef).toHaveBeenCalledWith(expect.any(Function));
|
|
226
|
+
expect(capturedUpdater).toBeTruthy();
|
|
227
|
+
|
|
228
|
+
// Test the updater function behavior with empty previous state
|
|
229
|
+
const prevState = {}; // No existing agent state
|
|
230
|
+
|
|
231
|
+
const newState = capturedUpdater(prevState);
|
|
232
|
+
|
|
233
|
+
// Verify the state creates a new agent state with default values
|
|
234
|
+
expect(newState).toEqual({
|
|
235
|
+
"test-agent": {
|
|
236
|
+
name: "test-agent",
|
|
237
|
+
state: { count: 0 }, // Uses initialState
|
|
238
|
+
config: { configurable: { model: "gpt-4o" } }, // New config
|
|
239
|
+
running: false, // Default values
|
|
240
|
+
active: false,
|
|
241
|
+
threadId: undefined,
|
|
242
|
+
nodeName: undefined,
|
|
243
|
+
runId: undefined,
|
|
244
|
+
},
|
|
245
|
+
});
|
|
246
|
+
});
|
|
247
|
+
|
|
248
|
+
it("should handle deeply nested config changes", () => {
|
|
249
|
+
const { rerender } = renderHook(
|
|
250
|
+
({ config }) =>
|
|
251
|
+
useCoAgent({
|
|
252
|
+
name: "test-agent",
|
|
253
|
+
initialState: { count: 0 },
|
|
254
|
+
config,
|
|
255
|
+
}),
|
|
256
|
+
{
|
|
257
|
+
initialProps: {
|
|
258
|
+
config: {
|
|
259
|
+
configurable: {
|
|
260
|
+
model: "gpt-4",
|
|
261
|
+
settings: { temperature: 0.5 },
|
|
262
|
+
},
|
|
263
|
+
},
|
|
264
|
+
},
|
|
265
|
+
},
|
|
266
|
+
);
|
|
267
|
+
|
|
268
|
+
// Clear the initial calls
|
|
269
|
+
mockSetCoagentStatesWithRef.mockClear();
|
|
270
|
+
|
|
271
|
+
// Change nested config
|
|
272
|
+
rerender({
|
|
273
|
+
config: {
|
|
274
|
+
configurable: {
|
|
275
|
+
model: "gpt-4",
|
|
276
|
+
settings: { temperature: 0.7 }, // Only nested property changed
|
|
277
|
+
},
|
|
278
|
+
},
|
|
279
|
+
});
|
|
280
|
+
|
|
281
|
+
// Should detect the nested change
|
|
282
|
+
expect(mockSetCoagentStatesWithRef).toHaveBeenCalledWith(expect.any(Function));
|
|
283
|
+
});
|
|
284
|
+
});
|