@copilotkit/react-core 1.50.0-beta.0 → 1.50.0-beta.2
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 +7 -0
- package/dist/{chunk-IUSKVYUI.mjs → chunk-2CYJN455.mjs} +2 -1
- package/dist/{chunk-IUSKVYUI.mjs.map → chunk-2CYJN455.mjs.map} +1 -1
- package/dist/{chunk-UJBV5GAG.mjs → chunk-6F7Q6CPI.mjs} +17 -36
- package/dist/chunk-6F7Q6CPI.mjs.map +1 -0
- package/dist/{chunk-JRT5BJF3.mjs → chunk-6SK26J65.mjs} +2 -2
- package/dist/{chunk-3GURHDG7.mjs → chunk-BPJ6V4YX.mjs} +2 -2
- package/dist/{chunk-TXI72QHK.mjs → chunk-EG56H77V.mjs} +2 -2
- package/dist/{chunk-3R423LZT.mjs → chunk-EHXVGFWN.mjs} +2 -2
- package/dist/{chunk-CB7CRBDG.mjs → chunk-FBVI3LQ6.mjs} +11 -11
- package/dist/chunk-FBVI3LQ6.mjs.map +1 -0
- package/dist/chunk-I76HKHPJ.mjs +32 -0
- package/dist/chunk-I76HKHPJ.mjs.map +1 -0
- package/dist/{chunk-R4MR43UQ.mjs → chunk-ISNVEPPQ.mjs} +17 -3
- package/dist/chunk-ISNVEPPQ.mjs.map +1 -0
- package/dist/{chunk-FBD24VEH.mjs → chunk-LD3MGPZB.mjs} +1 -1
- package/dist/{chunk-FBD24VEH.mjs.map → chunk-LD3MGPZB.mjs.map} +1 -1
- package/dist/{chunk-GMI4KO4X.mjs → chunk-OAEX7G5G.mjs} +2 -2
- package/dist/{chunk-DCHSCK62.mjs → chunk-SD7TUPQM.mjs} +13 -14
- package/dist/chunk-SD7TUPQM.mjs.map +1 -0
- package/dist/{chunk-NG26QEGF.mjs → chunk-T2VBHAAP.mjs} +9 -3
- package/dist/chunk-T2VBHAAP.mjs.map +1 -0
- package/dist/{chunk-NROJOTQP.mjs → chunk-TGIWTM6S.mjs} +8 -5
- package/dist/chunk-TGIWTM6S.mjs.map +1 -0
- package/dist/{chunk-QU6NONOD.mjs → chunk-U2ZRVVKT.mjs} +2 -2
- package/dist/{chunk-5X5DJRQQ.mjs → chunk-WF65O6HX.mjs} +2 -7
- package/dist/chunk-WF65O6HX.mjs.map +1 -0
- package/dist/{chunk-24SCZAB4.mjs → chunk-ZYTXB6HH.mjs} +22 -14
- package/dist/chunk-ZYTXB6HH.mjs.map +1 -0
- package/dist/components/CopilotListeners.js +13 -146
- package/dist/components/CopilotListeners.js.map +1 -1
- package/dist/components/CopilotListeners.mjs +1 -6
- package/dist/components/copilot-provider/copilot-messages.js.map +1 -1
- package/dist/components/copilot-provider/copilot-messages.mjs +1 -1
- package/dist/components/copilot-provider/copilotkit-props.d.ts +1 -1
- package/dist/components/copilot-provider/copilotkit.d.ts +1 -1
- package/dist/components/copilot-provider/copilotkit.js +11 -11
- package/dist/components/copilot-provider/copilotkit.js.map +1 -1
- package/dist/components/copilot-provider/copilotkit.mjs +6 -6
- package/dist/components/copilot-provider/index.d.ts +1 -1
- package/dist/components/copilot-provider/index.js +11 -11
- package/dist/components/copilot-provider/index.js.map +1 -1
- package/dist/components/copilot-provider/index.mjs +6 -6
- package/dist/components/index.d.ts +1 -1
- package/dist/components/index.js +11 -11
- package/dist/components/index.js.map +1 -1
- package/dist/components/index.mjs +6 -6
- package/dist/context/copilot-context.d.ts +1 -1
- package/dist/context/index.d.ts +1 -1
- package/dist/{copilot-context-1cd70a3f.d.ts → copilot-context-81022020.d.ts} +1 -1
- package/dist/hooks/index.d.ts +1 -1
- package/dist/hooks/index.js +187 -155
- package/dist/hooks/index.js.map +1 -1
- package/dist/hooks/index.mjs +24 -23
- package/dist/hooks/use-agent-nodename.d.ts +3 -0
- package/dist/hooks/use-agent-nodename.js +56 -0
- package/dist/hooks/use-agent-nodename.js.map +1 -0
- package/dist/hooks/use-agent-nodename.mjs +8 -0
- package/dist/hooks/use-agent-nodename.mjs.map +1 -0
- package/dist/hooks/use-coagent-state-render-bridge.js +7 -4
- package/dist/hooks/use-coagent-state-render-bridge.js.map +1 -1
- package/dist/hooks/use-coagent-state-render-bridge.mjs +1 -1
- package/dist/hooks/use-coagent.js +58 -21
- package/dist/hooks/use-coagent.js.map +1 -1
- package/dist/hooks/use-coagent.mjs +2 -1
- package/dist/hooks/use-configure-chat-suggestions.js +13 -144
- package/dist/hooks/use-configure-chat-suggestions.js.map +1 -1
- package/dist/hooks/use-configure-chat-suggestions.mjs +1 -6
- package/dist/hooks/use-copilot-action.js +5 -1
- package/dist/hooks/use-copilot-action.js.map +1 -1
- package/dist/hooks/use-copilot-action.mjs +2 -2
- package/dist/hooks/use-copilot-authenticated-action.js +5 -1
- 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-headless_c.js +107 -84
- package/dist/hooks/use-copilot-chat-headless_c.js.map +1 -1
- package/dist/hooks/use-copilot-chat-headless_c.mjs +6 -5
- package/dist/hooks/use-copilot-chat.js +105 -82
- package/dist/hooks/use-copilot-chat.js.map +1 -1
- package/dist/hooks/use-copilot-chat.mjs +6 -5
- package/dist/hooks/use-copilot-chat_internal.d.ts +1 -1
- package/dist/hooks/use-copilot-chat_internal.js +105 -82
- package/dist/hooks/use-copilot-chat_internal.js.map +1 -1
- package/dist/hooks/use-copilot-chat_internal.mjs +5 -4
- package/dist/hooks/use-copilot-readable.d.ts +1 -1
- package/dist/hooks/use-copilot-readable.js +1 -0
- package/dist/hooks/use-copilot-readable.js.map +1 -1
- package/dist/hooks/use-copilot-readable.mjs +1 -1
- package/dist/hooks/use-default-tool.js +5 -1
- package/dist/hooks/use-default-tool.js.map +1 -1
- package/dist/hooks/use-default-tool.mjs +3 -3
- package/dist/hooks/use-frontend-tool.js +5 -1
- package/dist/hooks/use-frontend-tool.js.map +1 -1
- package/dist/hooks/use-frontend-tool.mjs +1 -1
- package/dist/hooks/use-langgraph-interrupt-render.js +61 -7
- package/dist/hooks/use-langgraph-interrupt-render.js.map +1 -1
- package/dist/hooks/use-langgraph-interrupt-render.mjs +2 -1
- package/dist/hooks/use-langgraph-interrupt.d.ts +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.js +184 -155
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +31 -30
- package/dist/lib/copilot-task.d.ts +1 -1
- package/dist/lib/copilot-task.js.map +1 -1
- package/dist/lib/copilot-task.mjs +7 -7
- package/dist/lib/index.d.ts +1 -1
- package/dist/lib/index.js.map +1 -1
- package/dist/lib/index.mjs +7 -7
- package/dist/types/index.d.ts +1 -1
- package/dist/types/index.mjs +1 -1
- package/dist/types/interrupt-action.d.ts +1 -1
- package/dist/types/interrupt-action.js.map +1 -1
- package/jest.config.js +12 -0
- package/package.json +22 -21
- package/src/components/CopilotListeners.tsx +1 -2
- package/src/components/copilot-provider/copilot-messages.tsx +0 -41
- package/src/components/copilot-provider/copilotkit.tsx +2 -2
- package/src/hooks/__tests__/use-coagent-config.test.ts +189 -129
- package/src/hooks/use-agent-nodename.ts +30 -0
- package/src/hooks/use-coagent-state-render-bridge.tsx +20 -20
- package/src/hooks/use-coagent.ts +22 -13
- package/src/hooks/use-configure-chat-suggestions.tsx +8 -7
- package/src/hooks/use-copilot-chat_internal.ts +44 -42
- package/src/hooks/use-copilot-readable.ts +2 -1
- package/src/hooks/use-frontend-tool.ts +10 -2
- package/src/hooks/use-langgraph-interrupt-render.ts +10 -2
- package/src/types/interrupt-action.ts +1 -1
- package/dist/chunk-24SCZAB4.mjs.map +0 -1
- package/dist/chunk-5X5DJRQQ.mjs.map +0 -1
- package/dist/chunk-CB7CRBDG.mjs.map +0 -1
- package/dist/chunk-DCHSCK62.mjs.map +0 -1
- package/dist/chunk-NG26QEGF.mjs.map +0 -1
- package/dist/chunk-NROJOTQP.mjs.map +0 -1
- package/dist/chunk-R4MR43UQ.mjs.map +0 -1
- package/dist/chunk-UJBV5GAG.mjs.map +0 -1
- /package/dist/{chunk-JRT5BJF3.mjs.map → chunk-6SK26J65.mjs.map} +0 -0
- /package/dist/{chunk-3GURHDG7.mjs.map → chunk-BPJ6V4YX.mjs.map} +0 -0
- /package/dist/{chunk-TXI72QHK.mjs.map → chunk-EG56H77V.mjs.map} +0 -0
- /package/dist/{chunk-3R423LZT.mjs.map → chunk-EHXVGFWN.mjs.map} +0 -0
- /package/dist/{chunk-GMI4KO4X.mjs.map → chunk-OAEX7G5G.mjs.map} +0 -0
- /package/dist/{chunk-QU6NONOD.mjs.map → chunk-U2ZRVVKT.mjs.map} +0 -0
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import '@copilotkit/runtime-client-gql';
|
|
2
|
-
export { f as LangGraphInterruptAction, h as LangGraphInterruptActionSetter, g as LangGraphInterruptActionSetterArgs, e as LangGraphInterruptRender, L as LangGraphInterruptRenderHandlerProps, d as LangGraphInterruptRenderProps, Q as QueuedInterruptEvent } from '../copilot-context-
|
|
2
|
+
export { f as LangGraphInterruptAction, h as LangGraphInterruptActionSetter, g as LangGraphInterruptActionSetterArgs, e as LangGraphInterruptRender, L as LangGraphInterruptRenderHandlerProps, d as LangGraphInterruptRenderProps, Q as QueuedInterruptEvent } from '../copilot-context-81022020.js';
|
|
3
3
|
import '@copilotkit/shared';
|
|
4
4
|
import './frontend-action.js';
|
|
5
5
|
import 'react';
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/types/interrupt-action.ts"],"sourcesContent":["import { LangGraphInterruptEvent } from \"@copilotkit/runtime-client-gql\";\nimport { AgentSession } from \"../context/copilot-context\";\n\nexport interface LangGraphInterruptRenderHandlerProps<TEventValue = any> {\n event: LangGraphInterruptEvent<TEventValue>;\n resolve: (resolution: string) => void;\n}\n\nexport interface LangGraphInterruptRenderProps<TEventValue = any> {\n result: unknown;\n event: LangGraphInterruptEvent<TEventValue>;\n resolve: (resolution: string) => void;\n}\n\nexport interface LangGraphInterruptRender<TEventValue = any> {\n id: string;\n /**\n * The handler function to handle the event.\n */\n handler?: (props: LangGraphInterruptRenderHandlerProps<TEventValue>) => any | Promise<any>;\n /**\n * The render function to handle the event.\n */\n render?: (props: LangGraphInterruptRenderProps<TEventValue>) => string | React.ReactElement;\n /**\n * Method that returns a boolean, indicating if the interrupt action should run\n * Useful when using multiple interrupts\n */\n enabled?: (args: { eventValue: TEventValue; agentMetadata: AgentSession
|
|
1
|
+
{"version":3,"sources":["../../src/types/interrupt-action.ts"],"sourcesContent":["import { LangGraphInterruptEvent } from \"@copilotkit/runtime-client-gql\";\nimport { AgentSession } from \"../context/copilot-context\";\n\nexport interface LangGraphInterruptRenderHandlerProps<TEventValue = any> {\n event: LangGraphInterruptEvent<TEventValue>;\n resolve: (resolution: string) => void;\n}\n\nexport interface LangGraphInterruptRenderProps<TEventValue = any> {\n result: unknown;\n event: LangGraphInterruptEvent<TEventValue>;\n resolve: (resolution: string) => void;\n}\n\nexport interface LangGraphInterruptRender<TEventValue = any> {\n id: string;\n /**\n * The handler function to handle the event.\n */\n handler?: (props: LangGraphInterruptRenderHandlerProps<TEventValue>) => any | Promise<any>;\n /**\n * The render function to handle the event.\n */\n render?: (props: LangGraphInterruptRenderProps<TEventValue>) => string | React.ReactElement;\n /**\n * Method that returns a boolean, indicating if the interrupt action should run\n * Useful when using multiple interrupts\n */\n enabled?: (args: { eventValue: TEventValue; agentMetadata: AgentSession }) => boolean;\n}\n\nexport type LangGraphInterruptAction = LangGraphInterruptRender & {\n event?: LangGraphInterruptEvent;\n};\n\nexport type LangGraphInterruptActionSetterArgs = Partial<LangGraphInterruptRender> | null;\nexport type LangGraphInterruptActionSetter = (\n threadId: string,\n action: LangGraphInterruptActionSetterArgs,\n) => void;\n\nexport interface QueuedInterruptEvent {\n eventId: string; // Generated unique ID for tracking\n threadId: string;\n event: LangGraphInterruptEvent;\n}\n"],"mappings":";;;;;;;;;;;;;;;;AAAA;AAAA;","names":[]}
|
package/jest.config.js
CHANGED
|
@@ -9,5 +9,17 @@ module.exports = {
|
|
|
9
9
|
setupFilesAfterEnv: ["<rootDir>/src/setupTests.ts"],
|
|
10
10
|
moduleNameMapper: {
|
|
11
11
|
"^@/(.*)$": "<rootDir>/src/$1",
|
|
12
|
+
"\\.(css|less|scss|sass)$": "identity-obj-proxy",
|
|
13
|
+
},
|
|
14
|
+
transformIgnorePatterns: [
|
|
15
|
+
"node_modules/(?!(react-markdown|streamdown|@copilotkitnext)/)",
|
|
16
|
+
],
|
|
17
|
+
transform: {
|
|
18
|
+
"^.+\\.(ts|tsx)$": "ts-jest",
|
|
19
|
+
"^.+\\.(js|jsx|mjs)$": ["ts-jest", {
|
|
20
|
+
tsconfig: {
|
|
21
|
+
allowJs: true,
|
|
22
|
+
},
|
|
23
|
+
}],
|
|
12
24
|
},
|
|
13
25
|
};
|
package/package.json
CHANGED
|
@@ -9,7 +9,7 @@
|
|
|
9
9
|
"publishConfig": {
|
|
10
10
|
"access": "public"
|
|
11
11
|
},
|
|
12
|
-
"version": "1.50.0-beta.
|
|
12
|
+
"version": "1.50.0-beta.2",
|
|
13
13
|
"sideEffects": false,
|
|
14
14
|
"main": "./dist/index.js",
|
|
15
15
|
"module": "./dist/index.mjs",
|
|
@@ -28,18 +28,9 @@
|
|
|
28
28
|
},
|
|
29
29
|
"types": "./dist/index.d.ts",
|
|
30
30
|
"license": "MIT",
|
|
31
|
-
"scripts": {
|
|
32
|
-
"build": "tsup --clean",
|
|
33
|
-
"dev": "tsup --watch",
|
|
34
|
-
"test": "jest",
|
|
35
|
-
"check-types": "tsc --noEmit",
|
|
36
|
-
"clean": "rm -rf .turbo && rm -rf node_modules && rm -rf dist && rm -rf .next",
|
|
37
|
-
"link:global": "pnpm link --global",
|
|
38
|
-
"unlink:global": "pnpm unlink --global"
|
|
39
|
-
},
|
|
40
31
|
"peerDependencies": {
|
|
41
|
-
"@copilotkitnext/core": "0.0.
|
|
42
|
-
"@copilotkitnext/react": "0.0.
|
|
32
|
+
"@copilotkitnext/core": "0.0.23",
|
|
33
|
+
"@copilotkitnext/react": "0.0.23",
|
|
43
34
|
"react": "^18 || ^19 || ^19.0.0-rc",
|
|
44
35
|
"react-dom": "^18 || ^19 || ^19.0.0-rc",
|
|
45
36
|
"zod": ">=3.0.0"
|
|
@@ -52,23 +43,24 @@
|
|
|
52
43
|
"@types/react": "^19.1.0",
|
|
53
44
|
"@types/react-dom": "^19.0.2",
|
|
54
45
|
"eslint": "^8.56.0",
|
|
55
|
-
"
|
|
46
|
+
"identity-obj-proxy": "^3.0.0",
|
|
56
47
|
"jest": "^29.6.4",
|
|
57
48
|
"jest-environment-jsdom": "^30.0.2",
|
|
58
49
|
"react": "^19.1.0",
|
|
59
|
-
"react-dom": "^19.0
|
|
50
|
+
"react-dom": "^19.2.0",
|
|
60
51
|
"ts-jest": "^29.1.1",
|
|
61
|
-
"tsconfig": "workspace:*",
|
|
62
52
|
"tsup": "^6.7.0",
|
|
63
53
|
"typescript": "^5.2.3",
|
|
64
|
-
"zod": ">=3.0.0"
|
|
54
|
+
"zod": ">=3.0.0",
|
|
55
|
+
"eslint-config-custom": "1.4.6",
|
|
56
|
+
"tsconfig": "1.4.6"
|
|
65
57
|
},
|
|
66
58
|
"dependencies": {
|
|
67
|
-
"@copilotkit/runtime-client-gql": "workspace:*",
|
|
68
|
-
"@copilotkit/shared": "workspace:*",
|
|
69
59
|
"@scarf/scarf": "^1.3.0",
|
|
70
60
|
"react-markdown": "^8.0.7",
|
|
71
|
-
"untruncate-json": "^0.0.1"
|
|
61
|
+
"untruncate-json": "^0.0.1",
|
|
62
|
+
"@copilotkit/runtime-client-gql": "1.50.0-beta.2",
|
|
63
|
+
"@copilotkit/shared": "1.50.0-beta.2"
|
|
72
64
|
},
|
|
73
65
|
"keywords": [
|
|
74
66
|
"copilotkit",
|
|
@@ -81,5 +73,14 @@
|
|
|
81
73
|
"javascript",
|
|
82
74
|
"automation",
|
|
83
75
|
"textarea"
|
|
84
|
-
]
|
|
85
|
-
|
|
76
|
+
],
|
|
77
|
+
"scripts": {
|
|
78
|
+
"build": "tsup --clean",
|
|
79
|
+
"dev": "tsup --watch",
|
|
80
|
+
"test": "jest",
|
|
81
|
+
"check-types": "tsc --noEmit",
|
|
82
|
+
"clean": "rm -rf .turbo && rm -rf node_modules && rm -rf dist && rm -rf .next",
|
|
83
|
+
"link:global": "pnpm link --global",
|
|
84
|
+
"unlink:global": "pnpm unlink --global"
|
|
85
|
+
}
|
|
86
|
+
}
|
|
@@ -55,9 +55,8 @@ const usePredictStateSubscription = (agent?: AbstractAgent) => {
|
|
|
55
55
|
|
|
56
56
|
export function CopilotListeners() {
|
|
57
57
|
const { copilotkit } = useCopilotKit();
|
|
58
|
-
const { agentSession } = useCopilotContext();
|
|
59
58
|
const existingConfig = useCopilotChatConfiguration();
|
|
60
|
-
const resolvedAgentId =
|
|
59
|
+
const resolvedAgentId = existingConfig?.agentId;
|
|
61
60
|
const { setBannerError } = useToast();
|
|
62
61
|
|
|
63
62
|
const { agent } = useAgent({ agentId: resolvedAgentId });
|
|
@@ -252,47 +252,6 @@ export function CopilotMessages({ children }: { children: ReactNode }) {
|
|
|
252
252
|
[setBannerError, showDevConsole, traceUIError],
|
|
253
253
|
);
|
|
254
254
|
|
|
255
|
-
// useEffect(() => {
|
|
256
|
-
// if (!threadId || threadId === lastLoadedThreadId.current) return;
|
|
257
|
-
// if (
|
|
258
|
-
// threadId === lastLoadedThreadId.current &&
|
|
259
|
-
// agentSession?.agentName === lastLoadedAgentName.current
|
|
260
|
-
// ) {
|
|
261
|
-
// return;
|
|
262
|
-
// }
|
|
263
|
-
//
|
|
264
|
-
// const fetchMessages = async () => {
|
|
265
|
-
// if (!agentSession?.agentName) return;
|
|
266
|
-
//
|
|
267
|
-
// const result = await runtimeClient.loadAgentState({
|
|
268
|
-
// threadId,
|
|
269
|
-
// agentName: agentSession?.agentName,
|
|
270
|
-
// });
|
|
271
|
-
//
|
|
272
|
-
// // Check for GraphQL errors and manually trigger error handling
|
|
273
|
-
// if (result.error) {
|
|
274
|
-
// // Update refs to prevent infinite retries of the same failed request
|
|
275
|
-
// lastLoadedThreadId.current = threadId;
|
|
276
|
-
// lastLoadedAgentName.current = agentSession?.agentName;
|
|
277
|
-
// handleGraphQLErrors(result.error);
|
|
278
|
-
// return; // Don't try to process the data if there's an error
|
|
279
|
-
// }
|
|
280
|
-
//
|
|
281
|
-
// const newMessages = result.data?.loadAgentState?.messages;
|
|
282
|
-
// if (newMessages === lastLoadedMessages.current) return;
|
|
283
|
-
//
|
|
284
|
-
// if (result.data?.loadAgentState) {
|
|
285
|
-
// lastLoadedMessages.current = newMessages;
|
|
286
|
-
// lastLoadedThreadId.current = threadId;
|
|
287
|
-
// lastLoadedAgentName.current = agentSession?.agentName;
|
|
288
|
-
//
|
|
289
|
-
// const messages = loadMessagesFromJsonRepresentation(JSON.parse(newMessages || "[]"));
|
|
290
|
-
// setMessages(messages);
|
|
291
|
-
// }
|
|
292
|
-
// };
|
|
293
|
-
// void fetchMessages();
|
|
294
|
-
// }, [threadId, agentSession?.agentName]);
|
|
295
|
-
|
|
296
255
|
useEffect(() => {
|
|
297
256
|
updateTapMessages(messages);
|
|
298
257
|
}, [messages, updateTapMessages]);
|
|
@@ -72,7 +72,7 @@ export function CopilotKit({ children, ...props }: CopilotKitProps) {
|
|
|
72
72
|
<CopilotErrorBoundary publicApiKey={publicApiKey} showUsageBanner={enabled}>
|
|
73
73
|
<ThreadsProvider threadId={props.threadId}>
|
|
74
74
|
<CopilotKitProvider
|
|
75
|
-
|
|
75
|
+
{...props}
|
|
76
76
|
renderCustomMessages={renderArr}
|
|
77
77
|
useSingleEndpoint={true}
|
|
78
78
|
>
|
|
@@ -519,7 +519,7 @@ export function CopilotKitInternal(cpkProps: CopilotKitProps) {
|
|
|
519
519
|
<CopilotChatConfigurationProvider
|
|
520
520
|
// labels={labels}
|
|
521
521
|
// isModalDefaultOpen={isModalDefaultOpen}
|
|
522
|
-
agentId={
|
|
522
|
+
agentId={props.agent ?? "default"}
|
|
523
523
|
threadId={threadId}
|
|
524
524
|
>
|
|
525
525
|
<CopilotContext.Provider
|
|
@@ -1,8 +1,43 @@
|
|
|
1
|
-
import { renderHook } from "@testing-library/react";
|
|
1
|
+
import { renderHook, waitFor } from "@testing-library/react";
|
|
2
2
|
import { useCoAgent } from "../use-coagent";
|
|
3
|
+
import type { AgentSubscriber } from "@ag-ui/client";
|
|
4
|
+
|
|
5
|
+
// Mock functions for @copilotkitnext/react
|
|
6
|
+
const mockSetState = jest.fn();
|
|
7
|
+
const mockRunAgent = jest.fn();
|
|
8
|
+
const mockAbortRun = jest.fn();
|
|
9
|
+
const mockSubscribe = jest.fn();
|
|
10
|
+
const mockSetProperties = jest.fn();
|
|
11
|
+
|
|
12
|
+
// Store the last subscriber for triggering events
|
|
13
|
+
let lastSubscriber: AgentSubscriber | null = null;
|
|
14
|
+
|
|
15
|
+
const mockAgent = {
|
|
16
|
+
agentId: "test-agent",
|
|
17
|
+
state: { count: 0 },
|
|
18
|
+
isRunning: false,
|
|
19
|
+
threadId: "thread-123",
|
|
20
|
+
setState: mockSetState,
|
|
21
|
+
runAgent: mockRunAgent,
|
|
22
|
+
abortRun: mockAbortRun,
|
|
23
|
+
subscribe: mockSubscribe.mockImplementation((subscriber: AgentSubscriber) => {
|
|
24
|
+
lastSubscriber = subscriber;
|
|
25
|
+
return {
|
|
26
|
+
unsubscribe: jest.fn(),
|
|
27
|
+
};
|
|
28
|
+
}),
|
|
29
|
+
};
|
|
3
30
|
|
|
4
|
-
|
|
5
|
-
|
|
31
|
+
jest.mock("@copilotkitnext/react", () => ({
|
|
32
|
+
useAgent: jest.fn(() => ({ agent: mockAgent })),
|
|
33
|
+
useCopilotKit: jest.fn(() => ({
|
|
34
|
+
copilotkit: {
|
|
35
|
+
setProperties: mockSetProperties,
|
|
36
|
+
},
|
|
37
|
+
})),
|
|
38
|
+
}));
|
|
39
|
+
|
|
40
|
+
// Mock other dependencies
|
|
6
41
|
const mockAppendMessage = jest.fn();
|
|
7
42
|
const mockRunChatCompletion = jest.fn();
|
|
8
43
|
|
|
@@ -27,7 +62,6 @@ jest.mock("../../context", () => ({
|
|
|
27
62
|
availableAgents: [],
|
|
28
63
|
coagentStates: {},
|
|
29
64
|
coagentStatesRef: { current: {} },
|
|
30
|
-
setCoagentStatesWithRef: mockSetCoagentStatesWithRef,
|
|
31
65
|
threadId: "test-thread",
|
|
32
66
|
copilotApiConfig: {
|
|
33
67
|
headers: {},
|
|
@@ -61,14 +95,10 @@ jest.mock("../../components/copilot-provider/copilot-messages", () => ({
|
|
|
61
95
|
describe("useCoAgent config synchronization", () => {
|
|
62
96
|
beforeEach(() => {
|
|
63
97
|
jest.clearAllMocks();
|
|
64
|
-
|
|
65
|
-
if (typeof updater === "function") {
|
|
66
|
-
updater({});
|
|
67
|
-
}
|
|
68
|
-
});
|
|
98
|
+
lastSubscriber = null;
|
|
69
99
|
});
|
|
70
100
|
|
|
71
|
-
it("should call
|
|
101
|
+
it("should call setProperties when config changes", async () => {
|
|
72
102
|
const { rerender } = renderHook(
|
|
73
103
|
({ config }) =>
|
|
74
104
|
useCoAgent({
|
|
@@ -82,16 +112,20 @@ describe("useCoAgent config synchronization", () => {
|
|
|
82
112
|
);
|
|
83
113
|
|
|
84
114
|
// Clear the initial calls
|
|
85
|
-
|
|
115
|
+
mockSetProperties.mockClear();
|
|
86
116
|
|
|
87
117
|
// Change config
|
|
88
118
|
rerender({ config: { configurable: { model: "gpt-4o" } } });
|
|
89
119
|
|
|
90
|
-
//
|
|
91
|
-
|
|
120
|
+
// Wait for effect to complete and verify setProperties was called
|
|
121
|
+
await waitFor(() => {
|
|
122
|
+
expect(mockSetProperties).toHaveBeenCalledWith({
|
|
123
|
+
configurable: { model: "gpt-4o" },
|
|
124
|
+
});
|
|
125
|
+
});
|
|
92
126
|
});
|
|
93
127
|
|
|
94
|
-
it("should not call
|
|
128
|
+
it("should not call setProperties when config is unchanged", () => {
|
|
95
129
|
const config = { configurable: { model: "gpt-4" } };
|
|
96
130
|
|
|
97
131
|
const { rerender } = renderHook(
|
|
@@ -107,16 +141,16 @@ describe("useCoAgent config synchronization", () => {
|
|
|
107
141
|
);
|
|
108
142
|
|
|
109
143
|
// Clear the initial calls
|
|
110
|
-
|
|
144
|
+
mockSetProperties.mockClear();
|
|
111
145
|
|
|
112
|
-
// Re-render with same config
|
|
146
|
+
// Re-render with same config reference
|
|
113
147
|
rerender({ config });
|
|
114
148
|
|
|
115
|
-
// Should not have called
|
|
116
|
-
expect(
|
|
149
|
+
// Should not have called setProperties
|
|
150
|
+
expect(mockSetProperties).not.toHaveBeenCalled();
|
|
117
151
|
});
|
|
118
152
|
|
|
119
|
-
it("should handle backward compatibility with configurable prop", () => {
|
|
153
|
+
it("should handle backward compatibility with configurable prop", async () => {
|
|
120
154
|
const { rerender } = renderHook(
|
|
121
155
|
({ configurable }) =>
|
|
122
156
|
useCoAgent({
|
|
@@ -130,23 +164,32 @@ describe("useCoAgent config synchronization", () => {
|
|
|
130
164
|
);
|
|
131
165
|
|
|
132
166
|
// Clear the initial calls
|
|
133
|
-
|
|
167
|
+
mockSetProperties.mockClear();
|
|
134
168
|
|
|
135
169
|
// Change configurable prop
|
|
136
170
|
rerender({ configurable: { model: "gpt-4o" } });
|
|
137
171
|
|
|
138
|
-
//
|
|
139
|
-
|
|
172
|
+
// Wait for effect to complete and verify setProperties was called
|
|
173
|
+
await waitFor(() => {
|
|
174
|
+
expect(mockSetProperties).toHaveBeenCalledWith({
|
|
175
|
+
configurable: { model: "gpt-4o" },
|
|
176
|
+
});
|
|
177
|
+
});
|
|
140
178
|
});
|
|
141
179
|
|
|
142
|
-
it("should
|
|
143
|
-
|
|
180
|
+
it("should not call setProperties when both config and configurable are undefined", () => {
|
|
181
|
+
renderHook(() =>
|
|
182
|
+
useCoAgent({
|
|
183
|
+
name: "test-agent",
|
|
184
|
+
initialState: { count: 0 },
|
|
185
|
+
}),
|
|
186
|
+
);
|
|
144
187
|
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
});
|
|
188
|
+
// Should not have called setProperties
|
|
189
|
+
expect(mockSetProperties).not.toHaveBeenCalled();
|
|
190
|
+
});
|
|
149
191
|
|
|
192
|
+
it("should handle deeply nested config changes", async () => {
|
|
150
193
|
const { rerender } = renderHook(
|
|
151
194
|
({ config }) =>
|
|
152
195
|
useCoAgent({
|
|
@@ -155,137 +198,154 @@ describe("useCoAgent config synchronization", () => {
|
|
|
155
198
|
config,
|
|
156
199
|
}),
|
|
157
200
|
{
|
|
158
|
-
initialProps: {
|
|
201
|
+
initialProps: {
|
|
202
|
+
config: {
|
|
203
|
+
configurable: {
|
|
204
|
+
model: "gpt-4",
|
|
205
|
+
settings: { temperature: 0.5 },
|
|
206
|
+
},
|
|
207
|
+
},
|
|
208
|
+
},
|
|
159
209
|
},
|
|
160
210
|
);
|
|
161
211
|
|
|
162
|
-
// Clear the initial calls
|
|
163
|
-
|
|
164
|
-
capturedUpdater = null;
|
|
165
|
-
|
|
166
|
-
// Change config
|
|
167
|
-
rerender({ config: { configurable: { model: "gpt-4o" } } });
|
|
168
|
-
|
|
169
|
-
// Should have called setCoagentStatesWithRef
|
|
170
|
-
expect(mockSetCoagentStatesWithRef).toHaveBeenCalledWith(expect.any(Function));
|
|
171
|
-
expect(capturedUpdater).toBeTruthy();
|
|
212
|
+
// Clear the initial calls
|
|
213
|
+
mockSetProperties.mockClear();
|
|
172
214
|
|
|
173
|
-
//
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
active: true,
|
|
181
|
-
threadId: "thread-123",
|
|
182
|
-
nodeName: "test-node",
|
|
183
|
-
runId: "run-456",
|
|
215
|
+
// Change nested config
|
|
216
|
+
rerender({
|
|
217
|
+
config: {
|
|
218
|
+
configurable: {
|
|
219
|
+
model: "gpt-4",
|
|
220
|
+
settings: { temperature: 0.7 }, // Only nested property changed
|
|
221
|
+
},
|
|
184
222
|
},
|
|
185
|
-
};
|
|
186
|
-
|
|
187
|
-
const newState = capturedUpdater(prevState);
|
|
223
|
+
});
|
|
188
224
|
|
|
189
|
-
//
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
threadId: "thread-123",
|
|
198
|
-
nodeName: "test-node",
|
|
199
|
-
runId: "run-456",
|
|
200
|
-
},
|
|
225
|
+
// Wait for effect to complete and verify setProperties was called
|
|
226
|
+
await waitFor(() => {
|
|
227
|
+
expect(mockSetProperties).toHaveBeenCalledWith({
|
|
228
|
+
configurable: {
|
|
229
|
+
model: "gpt-4",
|
|
230
|
+
settings: { temperature: 0.7 },
|
|
231
|
+
},
|
|
232
|
+
});
|
|
201
233
|
});
|
|
202
234
|
});
|
|
203
235
|
|
|
204
|
-
|
|
205
|
-
|
|
236
|
+
describe("State Management", () => {
|
|
237
|
+
// Helper to create mock subscriber params
|
|
238
|
+
const createMockParams = (stateOverride: any = {}) => ({
|
|
239
|
+
messages: [],
|
|
240
|
+
state: stateOverride,
|
|
241
|
+
agent: mockAgent as any,
|
|
242
|
+
input: {} as any,
|
|
243
|
+
});
|
|
244
|
+
|
|
245
|
+
it("should initialize agent state via onRunInitialized event", () => {
|
|
246
|
+
// Set agent to have NO state (empty object)
|
|
247
|
+
mockAgent.state = {} as any;
|
|
248
|
+
|
|
249
|
+
renderHook(() =>
|
|
250
|
+
useCoAgent({
|
|
251
|
+
name: "test-agent",
|
|
252
|
+
initialState: { count: 42 },
|
|
253
|
+
}),
|
|
254
|
+
);
|
|
255
|
+
|
|
256
|
+
// Verify subscription was created
|
|
257
|
+
expect(mockSubscribe).toHaveBeenCalled();
|
|
258
|
+
expect(lastSubscriber).toBeTruthy();
|
|
259
|
+
|
|
260
|
+
// Clear any initial state calls
|
|
261
|
+
mockSetState.mockClear();
|
|
262
|
+
|
|
263
|
+
// Trigger onRunInitialized with no run state
|
|
264
|
+
lastSubscriber?.onRunInitialized?.(createMockParams({}));
|
|
265
|
+
|
|
266
|
+
// Should set state to initialState
|
|
267
|
+
expect(mockSetState).toHaveBeenCalledWith({ count: 42 });
|
|
206
268
|
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
return updater;
|
|
269
|
+
// Reset agent state
|
|
270
|
+
mockAgent.state = { count: 0 };
|
|
210
271
|
});
|
|
211
272
|
|
|
212
|
-
|
|
213
|
-
|
|
273
|
+
it("should preserve existing agent state on onRunInitialized", () => {
|
|
274
|
+
// Set agent to have existing state
|
|
275
|
+
mockAgent.state = { count: 100 };
|
|
276
|
+
|
|
277
|
+
renderHook(() =>
|
|
214
278
|
useCoAgent({
|
|
215
279
|
name: "test-agent",
|
|
216
|
-
initialState: { count:
|
|
217
|
-
config,
|
|
280
|
+
initialState: { count: 42 },
|
|
218
281
|
}),
|
|
219
|
-
|
|
220
|
-
initialProps: { config: { configurable: { model: "gpt-4" } } },
|
|
221
|
-
},
|
|
222
|
-
);
|
|
282
|
+
);
|
|
223
283
|
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
capturedUpdater = null;
|
|
284
|
+
// Clear any initial state calls
|
|
285
|
+
mockSetState.mockClear();
|
|
227
286
|
|
|
228
|
-
|
|
229
|
-
|
|
287
|
+
// Trigger onRunInitialized with no new state
|
|
288
|
+
lastSubscriber?.onRunInitialized?.(createMockParams({}));
|
|
289
|
+
|
|
290
|
+
// Should NOT override existing state
|
|
291
|
+
expect(mockSetState).not.toHaveBeenCalled();
|
|
292
|
+
|
|
293
|
+
// Reset agent state
|
|
294
|
+
mockAgent.state = { count: 0 };
|
|
295
|
+
});
|
|
230
296
|
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
297
|
+
it("should prioritize run state over initialState", () => {
|
|
298
|
+
renderHook(() =>
|
|
299
|
+
useCoAgent({
|
|
300
|
+
name: "test-agent",
|
|
301
|
+
initialState: { count: 42 },
|
|
302
|
+
}),
|
|
303
|
+
);
|
|
234
304
|
|
|
235
|
-
|
|
236
|
-
|
|
305
|
+
// Clear any initial state calls
|
|
306
|
+
mockSetState.mockClear();
|
|
237
307
|
|
|
238
|
-
|
|
308
|
+
// Trigger onRunInitialized with state from the run
|
|
309
|
+
lastSubscriber?.onRunInitialized?.(createMockParams({ count: 999 }));
|
|
239
310
|
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
"test-agent": {
|
|
243
|
-
name: "test-agent",
|
|
244
|
-
state: { count: 0 }, // Uses initialState
|
|
245
|
-
config: { configurable: { model: "gpt-4o" } }, // New config
|
|
246
|
-
running: false, // Default values
|
|
247
|
-
active: false,
|
|
248
|
-
threadId: undefined,
|
|
249
|
-
nodeName: undefined,
|
|
250
|
-
runId: undefined,
|
|
251
|
-
},
|
|
311
|
+
// Should use run state, not initialState
|
|
312
|
+
expect(mockSetState).toHaveBeenCalledWith({ count: 999 });
|
|
252
313
|
});
|
|
253
|
-
});
|
|
254
314
|
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
({ config }) =>
|
|
315
|
+
it("should handle setState with object updates", () => {
|
|
316
|
+
const { result } = renderHook(() =>
|
|
258
317
|
useCoAgent({
|
|
259
318
|
name: "test-agent",
|
|
260
319
|
initialState: { count: 0 },
|
|
261
|
-
config,
|
|
262
320
|
}),
|
|
263
|
-
|
|
264
|
-
initialProps: {
|
|
265
|
-
config: {
|
|
266
|
-
configurable: {
|
|
267
|
-
model: "gpt-4",
|
|
268
|
-
settings: { temperature: 0.5 },
|
|
269
|
-
},
|
|
270
|
-
},
|
|
271
|
-
},
|
|
272
|
-
},
|
|
273
|
-
);
|
|
321
|
+
);
|
|
274
322
|
|
|
275
|
-
|
|
276
|
-
|
|
323
|
+
// Update state with object
|
|
324
|
+
result.current.setState({ count: 5 });
|
|
277
325
|
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
config: {
|
|
281
|
-
configurable: {
|
|
282
|
-
model: "gpt-4",
|
|
283
|
-
settings: { temperature: 0.7 }, // Only nested property changed
|
|
284
|
-
},
|
|
285
|
-
},
|
|
326
|
+
// Should merge with existing state
|
|
327
|
+
expect(mockSetState).toHaveBeenCalledWith({ count: 5 });
|
|
286
328
|
});
|
|
287
329
|
|
|
288
|
-
|
|
289
|
-
|
|
330
|
+
it("should handle setState with function updaters", () => {
|
|
331
|
+
// Set current agent state
|
|
332
|
+
mockAgent.state = { count: 10 };
|
|
333
|
+
|
|
334
|
+
const { result } = renderHook(() =>
|
|
335
|
+
useCoAgent({
|
|
336
|
+
name: "test-agent",
|
|
337
|
+
initialState: { count: 0 },
|
|
338
|
+
}),
|
|
339
|
+
);
|
|
340
|
+
|
|
341
|
+
// Update state with function
|
|
342
|
+
result.current.setState((prev) => ({ count: (prev?.count || 0) + 5 }));
|
|
343
|
+
|
|
344
|
+
// Should call function with current state and set result
|
|
345
|
+
expect(mockSetState).toHaveBeenCalledWith({ count: 15 });
|
|
346
|
+
|
|
347
|
+
// Reset agent state
|
|
348
|
+
mockAgent.state = { count: 0 };
|
|
349
|
+
});
|
|
290
350
|
});
|
|
291
351
|
});
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import { useEffect, useRef } from "react";
|
|
2
|
+
import type { AgentSubscriber } from "@ag-ui/client";
|
|
3
|
+
import { useAgent } from "@copilotkitnext/react";
|
|
4
|
+
|
|
5
|
+
export function useAgentNodeName(agentName?: string) {
|
|
6
|
+
const { agent } = useAgent({ agentId: agentName });
|
|
7
|
+
const nodeNameRef = useRef<string>("start");
|
|
8
|
+
|
|
9
|
+
useEffect(() => {
|
|
10
|
+
if (!agent) return;
|
|
11
|
+
const subscriber: AgentSubscriber = {
|
|
12
|
+
onStepStartedEvent: ({ event }) => {
|
|
13
|
+
nodeNameRef.current = event.stepName;
|
|
14
|
+
},
|
|
15
|
+
onRunStartedEvent: () => {
|
|
16
|
+
nodeNameRef.current = "start";
|
|
17
|
+
},
|
|
18
|
+
onRunFinishedEvent: () => {
|
|
19
|
+
nodeNameRef.current = "end";
|
|
20
|
+
},
|
|
21
|
+
};
|
|
22
|
+
|
|
23
|
+
const subscription = agent.subscribe(subscriber);
|
|
24
|
+
return () => {
|
|
25
|
+
subscription.unsubscribe();
|
|
26
|
+
};
|
|
27
|
+
}, [agent]);
|
|
28
|
+
|
|
29
|
+
return nodeNameRef.current;
|
|
30
|
+
}
|