@copilotkit/react-core 1.9.2-next.21 → 1.9.2-next.22

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 (59) hide show
  1. package/CHANGELOG.md +10 -0
  2. package/dist/{chunk-MTAJI7HV.mjs → chunk-6ZLSC4KB.mjs} +20 -15
  3. package/dist/chunk-6ZLSC4KB.mjs.map +1 -0
  4. package/dist/{chunk-DGON3GZX.mjs → chunk-BSAVFYRQ.mjs} +4 -4
  5. package/dist/{chunk-RAQK4M64.mjs → chunk-CUAFWKTQ.mjs} +4 -4
  6. package/dist/{chunk-QKEH3O4S.mjs → chunk-GEE5AMYL.mjs} +8 -8
  7. package/dist/{chunk-N2M65NJ2.mjs → chunk-GIMSRCVW.mjs} +6 -6
  8. package/dist/{chunk-DDIBJUWK.mjs → chunk-KLENTCQV.mjs} +33 -7
  9. package/dist/{chunk-DDIBJUWK.mjs.map → chunk-KLENTCQV.mjs.map} +1 -1
  10. package/dist/{chunk-4URMLOBR.mjs → chunk-NGQN3JRJ.mjs} +2 -2
  11. package/dist/{chunk-SJJNFYGQ.mjs → chunk-SGF6C7I6.mjs} +4 -4
  12. package/dist/components/copilot-provider/copilot-messages.mjs +2 -2
  13. package/dist/components/copilot-provider/copilotkit.mjs +8 -8
  14. package/dist/components/copilot-provider/index.mjs +8 -8
  15. package/dist/components/error-boundary/error-boundary.mjs +2 -2
  16. package/dist/components/index.mjs +8 -8
  17. package/dist/context/index.mjs +4 -4
  18. package/dist/hooks/index.js +42 -11
  19. package/dist/hooks/index.js.map +1 -1
  20. package/dist/hooks/index.mjs +14 -14
  21. package/dist/hooks/use-chat.js +16 -11
  22. package/dist/hooks/use-chat.js.map +1 -1
  23. package/dist/hooks/use-chat.mjs +3 -3
  24. package/dist/hooks/use-coagent.js +42 -11
  25. package/dist/hooks/use-coagent.js.map +1 -1
  26. package/dist/hooks/use-coagent.mjs +13 -13
  27. package/dist/hooks/use-copilot-chat.js +16 -11
  28. package/dist/hooks/use-copilot-chat.js.map +1 -1
  29. package/dist/hooks/use-copilot-chat.mjs +12 -12
  30. package/dist/hooks/use-langgraph-interrupt-render.mjs +1 -1
  31. package/dist/hooks/use-langgraph-interrupt.js +16 -11
  32. package/dist/hooks/use-langgraph-interrupt.js.map +1 -1
  33. package/dist/hooks/use-langgraph-interrupt.mjs +13 -13
  34. package/dist/index.js +42 -11
  35. package/dist/index.js.map +1 -1
  36. package/dist/index.mjs +18 -18
  37. package/dist/lib/copilot-task.mjs +10 -10
  38. package/dist/lib/index.mjs +10 -10
  39. package/dist/setupTests.d.ts +2 -0
  40. package/dist/setupTests.js +26 -0
  41. package/dist/setupTests.js.map +1 -0
  42. package/dist/setupTests.mjs +24 -0
  43. package/dist/setupTests.mjs.map +1 -0
  44. package/dist/utils/extract.mjs +8 -8
  45. package/dist/utils/index.mjs +8 -8
  46. package/jest.config.js +4 -0
  47. package/package.json +6 -3
  48. package/src/hooks/__tests__/use-coagent-config.test.ts +284 -0
  49. package/src/hooks/use-chat.ts +2 -0
  50. package/src/hooks/use-coagent.ts +36 -0
  51. package/src/setupTests.ts +26 -0
  52. package/tsconfig.json +2 -2
  53. package/dist/chunk-MTAJI7HV.mjs.map +0 -1
  54. /package/dist/{chunk-DGON3GZX.mjs.map → chunk-BSAVFYRQ.mjs.map} +0 -0
  55. /package/dist/{chunk-RAQK4M64.mjs.map → chunk-CUAFWKTQ.mjs.map} +0 -0
  56. /package/dist/{chunk-QKEH3O4S.mjs.map → chunk-GEE5AMYL.mjs.map} +0 -0
  57. /package/dist/{chunk-N2M65NJ2.mjs.map → chunk-GIMSRCVW.mjs.map} +0 -0
  58. /package/dist/{chunk-4URMLOBR.mjs.map → chunk-NGQN3JRJ.mjs.map} +0 -0
  59. /package/dist/{chunk-SJJNFYGQ.mjs.map → chunk-SGF6C7I6.mjs.map} +0 -0
package/dist/index.mjs CHANGED
@@ -4,14 +4,14 @@ import "./chunk-6YOKPWQ7.mjs";
4
4
  import "./chunk-LUGEI4YQ.mjs";
5
5
  import {
6
6
  CopilotTask
7
- } from "./chunk-RAQK4M64.mjs";
7
+ } from "./chunk-CUAFWKTQ.mjs";
8
8
  import "./chunk-CQPYJIBH.mjs";
9
9
  import {
10
10
  useLangGraphInterruptRender
11
11
  } from "./chunk-VDADWRS3.mjs";
12
12
  import {
13
13
  useLangGraphInterrupt
14
- } from "./chunk-4URMLOBR.mjs";
14
+ } from "./chunk-NGQN3JRJ.mjs";
15
15
  import {
16
16
  useMakeCopilotDocumentReadable
17
17
  } from "./chunk-36MGCCPZ.mjs";
@@ -23,7 +23,7 @@ import {
23
23
  startAgent,
24
24
  stopAgent,
25
25
  useCoAgent
26
- } from "./chunk-DDIBJUWK.mjs";
26
+ } from "./chunk-KLENTCQV.mjs";
27
27
  import {
28
28
  useCopilotAdditionalInstructions
29
29
  } from "./chunk-BVK7PLK6.mjs";
@@ -35,7 +35,9 @@ import {
35
35
  } from "./chunk-NJA5ZLAZ.mjs";
36
36
  import {
37
37
  useCopilotChat
38
- } from "./chunk-QKEH3O4S.mjs";
38
+ } from "./chunk-GEE5AMYL.mjs";
39
+ import "./chunk-6ZLSC4KB.mjs";
40
+ import "./chunk-4CEQJ2X6.mjs";
39
41
  import {
40
42
  useCopilotReadable
41
43
  } from "./chunk-5BSUSFHM.mjs";
@@ -43,33 +45,31 @@ import {
43
45
  CopilotKit,
44
46
  defaultCopilotContextCategories,
45
47
  extract
46
- } from "./chunk-N2M65NJ2.mjs";
47
- import "./chunk-SJJNFYGQ.mjs";
48
- import "./chunk-DGON3GZX.mjs";
48
+ } from "./chunk-GIMSRCVW.mjs";
49
+ import "./chunk-SGF6C7I6.mjs";
50
+ import "./chunk-BSAVFYRQ.mjs";
51
+ import "./chunk-PMAFHQ7P.mjs";
49
52
  import "./chunk-5FHSUKQL.mjs";
50
53
  import "./chunk-RKTVJRK7.mjs";
51
- import "./chunk-PMAFHQ7P.mjs";
52
- import "./chunk-57K2ZJ5F.mjs";
53
- import "./chunk-YPSGKPDA.mjs";
54
- import {
55
- CopilotMessagesContext,
56
- useCopilotMessagesContext
57
- } from "./chunk-DCTJZ742.mjs";
58
- import "./chunk-MTAJI7HV.mjs";
59
- import "./chunk-4CEQJ2X6.mjs";
60
- import "./chunk-3OQM3NEK.mjs";
61
- import "./chunk-O7ARI5CV.mjs";
62
54
  import {
63
55
  useCopilotRuntimeClient
64
56
  } from "./chunk-JWAXDYOW.mjs";
65
57
  import {
66
58
  shouldShowDevConsole
67
59
  } from "./chunk-GFJW4RIM.mjs";
60
+ import "./chunk-3OQM3NEK.mjs";
61
+ import "./chunk-O7ARI5CV.mjs";
68
62
  import "./chunk-YAF2LATQ.mjs";
63
+ import "./chunk-57K2ZJ5F.mjs";
64
+ import "./chunk-YPSGKPDA.mjs";
69
65
  import {
70
66
  CopilotContext,
71
67
  useCopilotContext
72
68
  } from "./chunk-DKZTPL66.mjs";
69
+ import {
70
+ CopilotMessagesContext,
71
+ useCopilotMessagesContext
72
+ } from "./chunk-DCTJZ742.mjs";
73
73
  import "./chunk-SKC7AJIV.mjs";
74
74
  export {
75
75
  CopilotContext,
@@ -1,21 +1,21 @@
1
1
  import {
2
2
  CopilotTask
3
- } from "../chunk-RAQK4M64.mjs";
4
- import "../chunk-N2M65NJ2.mjs";
5
- import "../chunk-SJJNFYGQ.mjs";
6
- import "../chunk-DGON3GZX.mjs";
3
+ } from "../chunk-CUAFWKTQ.mjs";
4
+ import "../chunk-4CEQJ2X6.mjs";
5
+ import "../chunk-GIMSRCVW.mjs";
6
+ import "../chunk-SGF6C7I6.mjs";
7
+ import "../chunk-BSAVFYRQ.mjs";
8
+ import "../chunk-PMAFHQ7P.mjs";
7
9
  import "../chunk-5FHSUKQL.mjs";
8
10
  import "../chunk-RKTVJRK7.mjs";
9
- import "../chunk-PMAFHQ7P.mjs";
10
- import "../chunk-57K2ZJ5F.mjs";
11
- import "../chunk-DCTJZ742.mjs";
12
- import "../chunk-4CEQJ2X6.mjs";
13
- import "../chunk-3OQM3NEK.mjs";
14
- import "../chunk-O7ARI5CV.mjs";
15
11
  import "../chunk-JWAXDYOW.mjs";
16
12
  import "../chunk-GFJW4RIM.mjs";
13
+ import "../chunk-3OQM3NEK.mjs";
14
+ import "../chunk-O7ARI5CV.mjs";
17
15
  import "../chunk-YAF2LATQ.mjs";
16
+ import "../chunk-57K2ZJ5F.mjs";
18
17
  import "../chunk-DKZTPL66.mjs";
18
+ import "../chunk-DCTJZ742.mjs";
19
19
  import "../chunk-SKC7AJIV.mjs";
20
20
  export {
21
21
  CopilotTask
@@ -1,22 +1,22 @@
1
1
  import "../chunk-LUGEI4YQ.mjs";
2
2
  import {
3
3
  CopilotTask
4
- } from "../chunk-RAQK4M64.mjs";
5
- import "../chunk-N2M65NJ2.mjs";
6
- import "../chunk-SJJNFYGQ.mjs";
7
- import "../chunk-DGON3GZX.mjs";
4
+ } from "../chunk-CUAFWKTQ.mjs";
5
+ import "../chunk-4CEQJ2X6.mjs";
6
+ import "../chunk-GIMSRCVW.mjs";
7
+ import "../chunk-SGF6C7I6.mjs";
8
+ import "../chunk-BSAVFYRQ.mjs";
9
+ import "../chunk-PMAFHQ7P.mjs";
8
10
  import "../chunk-5FHSUKQL.mjs";
9
11
  import "../chunk-RKTVJRK7.mjs";
10
- import "../chunk-PMAFHQ7P.mjs";
11
- import "../chunk-57K2ZJ5F.mjs";
12
- import "../chunk-DCTJZ742.mjs";
13
- import "../chunk-4CEQJ2X6.mjs";
14
- import "../chunk-3OQM3NEK.mjs";
15
- import "../chunk-O7ARI5CV.mjs";
16
12
  import "../chunk-JWAXDYOW.mjs";
17
13
  import "../chunk-GFJW4RIM.mjs";
14
+ import "../chunk-3OQM3NEK.mjs";
15
+ import "../chunk-O7ARI5CV.mjs";
18
16
  import "../chunk-YAF2LATQ.mjs";
17
+ import "../chunk-57K2ZJ5F.mjs";
19
18
  import "../chunk-DKZTPL66.mjs";
19
+ import "../chunk-DCTJZ742.mjs";
20
20
  import "../chunk-SKC7AJIV.mjs";
21
21
  export {
22
22
  CopilotTask
@@ -0,0 +1,2 @@
1
+
2
+ export { }
@@ -0,0 +1,26 @@
1
+ "use strict";
2
+
3
+ // src/setupTests.ts
4
+ jest.mock("@segment/analytics-node", () => ({
5
+ Analytics: jest.fn().mockImplementation(() => ({
6
+ track: jest.fn(),
7
+ identify: jest.fn(),
8
+ page: jest.fn(),
9
+ group: jest.fn(),
10
+ alias: jest.fn()
11
+ }))
12
+ }));
13
+ jest.mock("@copilotkit/shared", () => ({
14
+ parseJson: jest.fn((jsonString, defaultValue) => {
15
+ try {
16
+ return JSON.parse(jsonString);
17
+ } catch (e) {
18
+ return defaultValue;
19
+ }
20
+ }),
21
+ CopilotKitAgentDiscoveryError: jest.fn()
22
+ }));
23
+ jest.mock("react-dom/test-utils", () => ({
24
+ act: jest.fn((fn) => fn())
25
+ }));
26
+ //# sourceMappingURL=setupTests.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/setupTests.ts"],"sourcesContent":["// Mock modules that cause ES module issues\njest.mock(\"@segment/analytics-node\", () => ({\n Analytics: jest.fn().mockImplementation(() => ({\n track: jest.fn(),\n identify: jest.fn(),\n page: jest.fn(),\n group: jest.fn(),\n alias: jest.fn(),\n })),\n}));\n\njest.mock(\"@copilotkit/shared\", () => ({\n parseJson: jest.fn((jsonString, defaultValue) => {\n try {\n return JSON.parse(jsonString);\n } catch {\n return defaultValue;\n }\n }),\n CopilotKitAgentDiscoveryError: jest.fn(),\n}));\n\n// Mock react-dom/test-utils to avoid compatibility issues\njest.mock(\"react-dom/test-utils\", () => ({\n act: jest.fn((fn) => fn()),\n}));\n"],"mappings":";;;AACA,KAAK,KAAK,2BAA2B,OAAO;AAAA,EAC1C,WAAW,KAAK,GAAG,EAAE,mBAAmB,OAAO;AAAA,IAC7C,OAAO,KAAK,GAAG;AAAA,IACf,UAAU,KAAK,GAAG;AAAA,IAClB,MAAM,KAAK,GAAG;AAAA,IACd,OAAO,KAAK,GAAG;AAAA,IACf,OAAO,KAAK,GAAG;AAAA,EACjB,EAAE;AACJ,EAAE;AAEF,KAAK,KAAK,sBAAsB,OAAO;AAAA,EACrC,WAAW,KAAK,GAAG,CAAC,YAAY,iBAAiB;AAC/C,QAAI;AACF,aAAO,KAAK,MAAM,UAAU;AAAA,IAC9B,SAAQ,GAAN;AACA,aAAO;AAAA,IACT;AAAA,EACF,CAAC;AAAA,EACD,+BAA+B,KAAK,GAAG;AACzC,EAAE;AAGF,KAAK,KAAK,wBAAwB,OAAO;AAAA,EACvC,KAAK,KAAK,GAAG,CAAC,OAAO,GAAG,CAAC;AAC3B,EAAE;","names":[]}
@@ -0,0 +1,24 @@
1
+ // src/setupTests.ts
2
+ jest.mock("@segment/analytics-node", () => ({
3
+ Analytics: jest.fn().mockImplementation(() => ({
4
+ track: jest.fn(),
5
+ identify: jest.fn(),
6
+ page: jest.fn(),
7
+ group: jest.fn(),
8
+ alias: jest.fn()
9
+ }))
10
+ }));
11
+ jest.mock("@copilotkit/shared", () => ({
12
+ parseJson: jest.fn((jsonString, defaultValue) => {
13
+ try {
14
+ return JSON.parse(jsonString);
15
+ } catch (e) {
16
+ return defaultValue;
17
+ }
18
+ }),
19
+ CopilotKitAgentDiscoveryError: jest.fn()
20
+ }));
21
+ jest.mock("react-dom/test-utils", () => ({
22
+ act: jest.fn((fn) => fn())
23
+ }));
24
+ //# sourceMappingURL=setupTests.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/setupTests.ts"],"sourcesContent":["// Mock modules that cause ES module issues\njest.mock(\"@segment/analytics-node\", () => ({\n Analytics: jest.fn().mockImplementation(() => ({\n track: jest.fn(),\n identify: jest.fn(),\n page: jest.fn(),\n group: jest.fn(),\n alias: jest.fn(),\n })),\n}));\n\njest.mock(\"@copilotkit/shared\", () => ({\n parseJson: jest.fn((jsonString, defaultValue) => {\n try {\n return JSON.parse(jsonString);\n } catch {\n return defaultValue;\n }\n }),\n CopilotKitAgentDiscoveryError: jest.fn(),\n}));\n\n// Mock react-dom/test-utils to avoid compatibility issues\njest.mock(\"react-dom/test-utils\", () => ({\n act: jest.fn((fn) => fn()),\n}));\n"],"mappings":";AACA,KAAK,KAAK,2BAA2B,OAAO;AAAA,EAC1C,WAAW,KAAK,GAAG,EAAE,mBAAmB,OAAO;AAAA,IAC7C,OAAO,KAAK,GAAG;AAAA,IACf,UAAU,KAAK,GAAG;AAAA,IAClB,MAAM,KAAK,GAAG;AAAA,IACd,OAAO,KAAK,GAAG;AAAA,IACf,OAAO,KAAK,GAAG;AAAA,EACjB,EAAE;AACJ,EAAE;AAEF,KAAK,KAAK,sBAAsB,OAAO;AAAA,EACrC,WAAW,KAAK,GAAG,CAAC,YAAY,iBAAiB;AAC/C,QAAI;AACF,aAAO,KAAK,MAAM,UAAU;AAAA,IAC9B,SAAQ,GAAN;AACA,aAAO;AAAA,IACT;AAAA,EACF,CAAC;AAAA,EACD,+BAA+B,KAAK,GAAG;AACzC,EAAE;AAGF,KAAK,KAAK,wBAAwB,OAAO;AAAA,EACvC,KAAK,KAAK,GAAG,CAAC,OAAO,GAAG,CAAC;AAC3B,EAAE;","names":[]}
@@ -1,19 +1,19 @@
1
1
  import {
2
2
  extract
3
- } from "../chunk-N2M65NJ2.mjs";
4
- import "../chunk-SJJNFYGQ.mjs";
5
- import "../chunk-DGON3GZX.mjs";
3
+ } from "../chunk-GIMSRCVW.mjs";
4
+ import "../chunk-SGF6C7I6.mjs";
5
+ import "../chunk-BSAVFYRQ.mjs";
6
+ import "../chunk-PMAFHQ7P.mjs";
6
7
  import "../chunk-5FHSUKQL.mjs";
7
8
  import "../chunk-RKTVJRK7.mjs";
8
- import "../chunk-PMAFHQ7P.mjs";
9
- import "../chunk-57K2ZJ5F.mjs";
10
- import "../chunk-DCTJZ742.mjs";
11
- import "../chunk-3OQM3NEK.mjs";
12
- import "../chunk-O7ARI5CV.mjs";
13
9
  import "../chunk-JWAXDYOW.mjs";
14
10
  import "../chunk-GFJW4RIM.mjs";
11
+ import "../chunk-3OQM3NEK.mjs";
12
+ import "../chunk-O7ARI5CV.mjs";
15
13
  import "../chunk-YAF2LATQ.mjs";
14
+ import "../chunk-57K2ZJ5F.mjs";
16
15
  import "../chunk-DKZTPL66.mjs";
16
+ import "../chunk-DCTJZ742.mjs";
17
17
  import "../chunk-SKC7AJIV.mjs";
18
18
  export {
19
19
  extract
@@ -1,21 +1,21 @@
1
1
  import {
2
2
  extract
3
- } from "../chunk-N2M65NJ2.mjs";
4
- import "../chunk-SJJNFYGQ.mjs";
5
- import "../chunk-DGON3GZX.mjs";
3
+ } from "../chunk-GIMSRCVW.mjs";
4
+ import "../chunk-SGF6C7I6.mjs";
5
+ import "../chunk-BSAVFYRQ.mjs";
6
+ import "../chunk-PMAFHQ7P.mjs";
6
7
  import "../chunk-5FHSUKQL.mjs";
7
8
  import "../chunk-RKTVJRK7.mjs";
8
- import "../chunk-PMAFHQ7P.mjs";
9
- import "../chunk-57K2ZJ5F.mjs";
10
- import "../chunk-DCTJZ742.mjs";
11
- import "../chunk-3OQM3NEK.mjs";
12
- import "../chunk-O7ARI5CV.mjs";
13
9
  import "../chunk-JWAXDYOW.mjs";
14
10
  import {
15
11
  shouldShowDevConsole
16
12
  } from "../chunk-GFJW4RIM.mjs";
13
+ import "../chunk-3OQM3NEK.mjs";
14
+ import "../chunk-O7ARI5CV.mjs";
17
15
  import "../chunk-YAF2LATQ.mjs";
16
+ import "../chunk-57K2ZJ5F.mjs";
18
17
  import "../chunk-DKZTPL66.mjs";
18
+ import "../chunk-DCTJZ742.mjs";
19
19
  import "../chunk-SKC7AJIV.mjs";
20
20
  export {
21
21
  extract,
package/jest.config.js CHANGED
@@ -6,4 +6,8 @@ module.exports = {
6
6
  "<rootDir>/src/**/__tests__/**/*.(ts|tsx)",
7
7
  "<rootDir>/src/**/*.(test|spec).(ts|tsx)",
8
8
  ],
9
+ setupFilesAfterEnv: ["<rootDir>/src/setupTests.ts"],
10
+ moduleNameMapper: {
11
+ "^@/(.*)$": "<rootDir>/src/$1",
12
+ },
9
13
  };
package/package.json CHANGED
@@ -9,7 +9,7 @@
9
9
  "publishConfig": {
10
10
  "access": "public"
11
11
  },
12
- "version": "1.9.2-next.21",
12
+ "version": "1.9.2-next.22",
13
13
  "sideEffects": false,
14
14
  "main": "./dist/index.js",
15
15
  "module": "./dist/index.mjs",
@@ -27,6 +27,8 @@
27
27
  "react-dom": "^18 || ^19 || ^19.0.0-rc"
28
28
  },
29
29
  "devDependencies": {
30
+ "@testing-library/react": "^16.3.0",
31
+ "@testing-library/react-hooks": "^8.0.1",
30
32
  "@types/jest": "^29.5.4",
31
33
  "@types/react": "^18.2.5",
32
34
  "@types/react-dom": "^18.2.4",
@@ -34,6 +36,7 @@
34
36
  "jest": "^29.6.4",
35
37
  "jest-environment-jsdom": "^30.0.2",
36
38
  "react": "^18.2.0",
39
+ "react-dom": "^18.2.0",
37
40
  "ts-jest": "^29.1.1",
38
41
  "tsup": "^6.7.0",
39
42
  "typescript": "^5.2.3",
@@ -44,8 +47,8 @@
44
47
  "@scarf/scarf": "^1.3.0",
45
48
  "react-markdown": "^8.0.7",
46
49
  "untruncate-json": "^0.0.1",
47
- "@copilotkit/shared": "1.9.2-next.21",
48
- "@copilotkit/runtime-client-gql": "1.9.2-next.21"
50
+ "@copilotkit/runtime-client-gql": "1.9.2-next.22",
51
+ "@copilotkit/shared": "1.9.2-next.22"
49
52
  },
50
53
  "keywords": [
51
54
  "copilotkit",
@@ -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
+ });
@@ -623,6 +623,8 @@ export function useChat(options: UseChatOptions): UseChatHelpers {
623
623
  threadId: lastAgentStateMessage.threadId,
624
624
  nodeName: lastAgentStateMessage.nodeName,
625
625
  runId: lastAgentStateMessage.runId,
626
+ // Preserve existing config from previous state
627
+ config: prevAgentStates[lastAgentStateMessage.agentName]?.config,
626
628
  },
627
629
  }));
628
630
  if (lastAgentStateMessage.running) {
@@ -311,6 +311,42 @@ export function useCoAgent<T = any>(options: UseCoagentOptions<T>): UseCoagentRe
311
311
  coagentStates[name] === undefined,
312
312
  ]);
313
313
 
314
+ // Sync config when runtime configuration changes
315
+ useEffect(() => {
316
+ const newConfig = options.config
317
+ ? options.config
318
+ : options.configurable
319
+ ? { configurable: options.configurable }
320
+ : undefined;
321
+
322
+ if (newConfig === undefined) return;
323
+
324
+ setCoagentStatesWithRef((prev) => {
325
+ const existing = prev[name] ?? {
326
+ name,
327
+ state: isInternalStateManagementWithInitial(options) ? options.initialState : {},
328
+ config: {},
329
+ running: false,
330
+ active: false,
331
+ threadId: undefined,
332
+ nodeName: undefined,
333
+ runId: undefined,
334
+ };
335
+
336
+ if (JSON.stringify(existing.config) === JSON.stringify(newConfig)) {
337
+ return prev;
338
+ }
339
+
340
+ return {
341
+ ...prev,
342
+ [name]: {
343
+ ...existing,
344
+ config: newConfig,
345
+ },
346
+ };
347
+ });
348
+ }, [JSON.stringify(options.config), JSON.stringify(options.configurable)]);
349
+
314
350
  const runAgentCallback = useAsyncCallback(
315
351
  async (hint?: HintFunction) => {
316
352
  await runAgent(name, context, appendMessage, runChatCompletion, hint);
@@ -0,0 +1,26 @@
1
+ // Mock modules that cause ES module issues
2
+ jest.mock("@segment/analytics-node", () => ({
3
+ Analytics: jest.fn().mockImplementation(() => ({
4
+ track: jest.fn(),
5
+ identify: jest.fn(),
6
+ page: jest.fn(),
7
+ group: jest.fn(),
8
+ alias: jest.fn(),
9
+ })),
10
+ }));
11
+
12
+ jest.mock("@copilotkit/shared", () => ({
13
+ parseJson: jest.fn((jsonString, defaultValue) => {
14
+ try {
15
+ return JSON.parse(jsonString);
16
+ } catch {
17
+ return defaultValue;
18
+ }
19
+ }),
20
+ CopilotKitAgentDiscoveryError: jest.fn(),
21
+ }));
22
+
23
+ // Mock react-dom/test-utils to avoid compatibility issues
24
+ jest.mock("react-dom/test-utils", () => ({
25
+ act: jest.fn((fn) => fn()),
26
+ }));