@copilotkit/react-core 1.50.0-beta.1 → 1.50.0-beta.11

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 (201) hide show
  1. package/CHANGELOG.md +105 -0
  2. package/dist/{chunk-UJBV5GAG.mjs → chunk-3775VM7Y.mjs} +32 -65
  3. package/dist/chunk-3775VM7Y.mjs.map +1 -0
  4. package/dist/{chunk-3GURHDG7.mjs → chunk-4HRUQH6U.mjs} +3 -3
  5. package/dist/{chunk-7BYHZLPL.mjs → chunk-4RRMC7L2.mjs} +4 -4
  6. package/dist/chunk-4RRMC7L2.mjs.map +1 -0
  7. package/dist/{chunk-D3QSYDJR.mjs → chunk-7IBF6RBW.mjs} +2 -2
  8. package/dist/{chunk-GMI4KO4X.mjs → chunk-7SHWECGN.mjs} +2 -2
  9. package/dist/{chunk-OVYFRPSN.mjs → chunk-ABWT4DRT.mjs} +2 -2
  10. package/dist/{chunk-WVLHXIFP.mjs → chunk-AFNWX62Q.mjs} +2 -2
  11. package/dist/{chunk-WVLHXIFP.mjs.map → chunk-AFNWX62Q.mjs.map} +1 -1
  12. package/dist/{chunk-JRT5BJF3.mjs → chunk-B5ELMVT7.mjs} +2 -2
  13. package/dist/{chunk-TXI72QHK.mjs → chunk-EG56H77V.mjs} +2 -2
  14. package/dist/{chunk-DCHSCK62.mjs → chunk-FYMZKPOL.mjs} +36 -42
  15. package/dist/chunk-FYMZKPOL.mjs.map +1 -0
  16. package/dist/{chunk-FBD24VEH.mjs → chunk-HE22TZMF.mjs} +2 -2
  17. package/dist/{chunk-FBD24VEH.mjs.map → chunk-HE22TZMF.mjs.map} +1 -1
  18. package/dist/chunk-I76HKHPJ.mjs +32 -0
  19. package/dist/chunk-I76HKHPJ.mjs.map +1 -0
  20. package/dist/{chunk-LHKZJ2ND.mjs → chunk-PMWUKW3Z.mjs} +3 -3
  21. package/dist/{chunk-NROJOTQP.mjs → chunk-QNUAXSDP.mjs} +9 -6
  22. package/dist/chunk-QNUAXSDP.mjs.map +1 -0
  23. package/dist/{chunk-NG26QEGF.mjs → chunk-T2VBHAAP.mjs} +9 -3
  24. package/dist/chunk-T2VBHAAP.mjs.map +1 -0
  25. package/dist/{chunk-QU6NONOD.mjs → chunk-U2ZRVVKT.mjs} +2 -2
  26. package/dist/{chunk-R4MR43UQ.mjs → chunk-VV56AVPB.mjs} +33 -9
  27. package/dist/chunk-VV56AVPB.mjs.map +1 -0
  28. package/dist/{chunk-5X5DJRQQ.mjs → chunk-WF65O6HX.mjs} +2 -7
  29. package/dist/chunk-WF65O6HX.mjs.map +1 -0
  30. package/dist/chunk-XDFVCQD3.mjs +27 -0
  31. package/dist/chunk-XDFVCQD3.mjs.map +1 -0
  32. package/dist/{chunk-WMJVBMUX.mjs → chunk-YCG6SNAU.mjs} +2 -2
  33. package/dist/{chunk-3R423LZT.mjs → chunk-YJGPIN3R.mjs} +3 -3
  34. package/dist/{chunk-BR5YEYZJ.mjs → chunk-YTQHRJUA.mjs} +2 -2
  35. package/dist/chunk-Z6JV2LRY.mjs +37 -0
  36. package/dist/chunk-Z6JV2LRY.mjs.map +1 -0
  37. package/dist/{chunk-24SCZAB4.mjs → chunk-ZYTXB6HH.mjs} +22 -14
  38. package/dist/chunk-ZYTXB6HH.mjs.map +1 -0
  39. package/dist/components/CopilotListeners.js +13 -146
  40. package/dist/components/CopilotListeners.js.map +1 -1
  41. package/dist/components/CopilotListeners.mjs +1 -6
  42. package/dist/components/copilot-provider/copilot-messages.js +1 -1
  43. package/dist/components/copilot-provider/copilot-messages.js.map +1 -1
  44. package/dist/components/copilot-provider/copilot-messages.mjs +2 -2
  45. package/dist/components/copilot-provider/copilotkit-props.d.ts +1 -1
  46. package/dist/components/copilot-provider/copilotkit.d.ts +1 -1
  47. package/dist/components/copilot-provider/copilotkit.js +35 -40
  48. package/dist/components/copilot-provider/copilotkit.js.map +1 -1
  49. package/dist/components/copilot-provider/copilotkit.mjs +9 -9
  50. package/dist/components/copilot-provider/index.d.ts +1 -1
  51. package/dist/components/copilot-provider/index.js +35 -40
  52. package/dist/components/copilot-provider/index.js.map +1 -1
  53. package/dist/components/copilot-provider/index.mjs +9 -9
  54. package/dist/components/dev-console/console-trigger.js +1 -1
  55. package/dist/components/dev-console/console-trigger.js.map +1 -1
  56. package/dist/components/dev-console/console-trigger.mjs +3 -3
  57. package/dist/components/dev-console/developer-console-modal.js +1 -1
  58. package/dist/components/dev-console/developer-console-modal.js.map +1 -1
  59. package/dist/components/dev-console/developer-console-modal.mjs +2 -2
  60. package/dist/components/index.d.ts +1 -1
  61. package/dist/components/index.js +35 -40
  62. package/dist/components/index.js.map +1 -1
  63. package/dist/components/index.mjs +9 -9
  64. package/dist/context/copilot-context.d.ts +1 -1
  65. package/dist/context/copilot-context.js +1 -1
  66. package/dist/context/copilot-context.js.map +1 -1
  67. package/dist/context/copilot-context.mjs +1 -1
  68. package/dist/context/index.d.ts +1 -1
  69. package/dist/context/index.js +1 -1
  70. package/dist/context/index.js.map +1 -1
  71. package/dist/context/index.mjs +1 -1
  72. package/dist/{copilot-context-1cd70a3f.d.ts → copilot-context-ec77e921.d.ts} +3 -3
  73. package/dist/hooks/index.d.ts +2 -2
  74. package/dist/hooks/index.js +254 -219
  75. package/dist/hooks/index.js.map +1 -1
  76. package/dist/hooks/index.mjs +24 -23
  77. package/dist/hooks/use-agent-nodename.d.ts +3 -0
  78. package/dist/hooks/use-agent-nodename.js +56 -0
  79. package/dist/hooks/use-agent-nodename.js.map +1 -0
  80. package/dist/hooks/use-agent-nodename.mjs +8 -0
  81. package/dist/hooks/use-coagent-state-render-bridge.js +8 -5
  82. package/dist/hooks/use-coagent-state-render-bridge.js.map +1 -1
  83. package/dist/hooks/use-coagent-state-render-bridge.mjs +2 -2
  84. package/dist/hooks/use-coagent-state-render.js +1 -1
  85. package/dist/hooks/use-coagent-state-render.js.map +1 -1
  86. package/dist/hooks/use-coagent-state-render.mjs +2 -2
  87. package/dist/hooks/use-coagent.js +58 -21
  88. package/dist/hooks/use-coagent.js.map +1 -1
  89. package/dist/hooks/use-coagent.mjs +2 -1
  90. package/dist/hooks/use-copilot-action.js +5 -1
  91. package/dist/hooks/use-copilot-action.js.map +1 -1
  92. package/dist/hooks/use-copilot-action.mjs +2 -2
  93. package/dist/hooks/use-copilot-additional-instructions.js +1 -1
  94. package/dist/hooks/use-copilot-additional-instructions.js.map +1 -1
  95. package/dist/hooks/use-copilot-additional-instructions.mjs +2 -2
  96. package/dist/hooks/use-copilot-authenticated-action.js +6 -2
  97. package/dist/hooks/use-copilot-authenticated-action.js.map +1 -1
  98. package/dist/hooks/use-copilot-authenticated-action.mjs +4 -4
  99. package/dist/hooks/use-copilot-chat-headless_c.js +128 -140
  100. package/dist/hooks/use-copilot-chat-headless_c.js.map +1 -1
  101. package/dist/hooks/use-copilot-chat-headless_c.mjs +6 -6
  102. package/dist/hooks/{use-configure-chat-suggestions.d.ts → use-copilot-chat-suggestions.d.ts} +2 -3
  103. package/dist/hooks/use-copilot-chat-suggestions.js +60 -0
  104. package/dist/hooks/use-copilot-chat-suggestions.js.map +1 -0
  105. package/dist/hooks/use-copilot-chat-suggestions.mjs +8 -0
  106. package/dist/hooks/use-copilot-chat-suggestions.mjs.map +1 -0
  107. package/dist/hooks/use-copilot-chat.js +126 -138
  108. package/dist/hooks/use-copilot-chat.js.map +1 -1
  109. package/dist/hooks/use-copilot-chat.mjs +6 -6
  110. package/dist/hooks/use-copilot-chat_internal.d.ts +18 -1
  111. package/dist/hooks/use-copilot-chat_internal.js +126 -138
  112. package/dist/hooks/use-copilot-chat_internal.js.map +1 -1
  113. package/dist/hooks/use-copilot-chat_internal.mjs +5 -5
  114. package/dist/hooks/use-copilot-readable.d.ts +1 -1
  115. package/dist/hooks/use-copilot-readable.js +29 -5
  116. package/dist/hooks/use-copilot-readable.js.map +1 -1
  117. package/dist/hooks/use-copilot-readable.mjs +1 -1
  118. package/dist/hooks/use-default-tool.js +5 -1
  119. package/dist/hooks/use-default-tool.js.map +1 -1
  120. package/dist/hooks/use-default-tool.mjs +3 -3
  121. package/dist/hooks/use-frontend-tool.js +5 -1
  122. package/dist/hooks/use-frontend-tool.js.map +1 -1
  123. package/dist/hooks/use-frontend-tool.mjs +1 -1
  124. package/dist/hooks/use-langgraph-interrupt-render.js +77 -13
  125. package/dist/hooks/use-langgraph-interrupt-render.js.map +1 -1
  126. package/dist/hooks/use-langgraph-interrupt-render.mjs +3 -2
  127. package/dist/hooks/use-langgraph-interrupt.d.ts +1 -1
  128. package/dist/hooks/use-langgraph-interrupt.js +3 -3
  129. package/dist/hooks/use-langgraph-interrupt.js.map +1 -1
  130. package/dist/hooks/use-langgraph-interrupt.mjs +2 -2
  131. package/dist/hooks/use-make-copilot-document-readable.js +1 -1
  132. package/dist/hooks/use-make-copilot-document-readable.js.map +1 -1
  133. package/dist/hooks/use-make-copilot-document-readable.mjs +2 -2
  134. package/dist/index.d.ts +2 -2
  135. package/dist/index.js +273 -246
  136. package/dist/index.js.map +1 -1
  137. package/dist/index.mjs +34 -33
  138. package/dist/lib/copilot-task.d.ts +1 -1
  139. package/dist/lib/copilot-task.js.map +1 -1
  140. package/dist/lib/copilot-task.mjs +10 -10
  141. package/dist/lib/index.d.ts +1 -1
  142. package/dist/lib/index.js.map +1 -1
  143. package/dist/lib/index.mjs +10 -10
  144. package/dist/types/index.d.ts +1 -1
  145. package/dist/types/interrupt-action.d.ts +1 -1
  146. package/dist/types/interrupt-action.js.map +1 -1
  147. package/dist/utils/index.mjs +3 -3
  148. package/dist/v2/index.css +4 -0
  149. package/dist/v2/index.css.map +1 -0
  150. package/dist/v2/index.js.map +1 -1
  151. package/dist/v2/index.mjs +2 -0
  152. package/dist/v2/index.mjs.map +1 -1
  153. package/jest.config.js +12 -0
  154. package/package.json +12 -9
  155. package/src/components/CopilotListeners.tsx +1 -2
  156. package/src/components/copilot-provider/copilot-messages.tsx +0 -41
  157. package/src/components/copilot-provider/copilotkit.tsx +31 -31
  158. package/src/context/copilot-context.tsx +2 -2
  159. package/src/hooks/__tests__/use-coagent-config.test.ts +189 -129
  160. package/src/hooks/index.ts +2 -2
  161. package/src/hooks/use-agent-nodename.ts +30 -0
  162. package/src/hooks/use-coagent-state-render-bridge.tsx +22 -22
  163. package/src/hooks/use-coagent.ts +22 -13
  164. package/src/hooks/use-copilot-chat-suggestions.tsx +124 -0
  165. package/src/hooks/use-copilot-chat_internal.ts +78 -78
  166. package/src/hooks/use-copilot-readable.ts +30 -12
  167. package/src/hooks/use-frontend-tool.ts +10 -2
  168. package/src/hooks/use-langgraph-interrupt-render.ts +25 -7
  169. package/src/hooks/use-langgraph-interrupt.ts +2 -3
  170. package/src/types/interrupt-action.ts +2 -5
  171. package/src/v2/index.ts +2 -0
  172. package/tsup.config.ts +1 -1
  173. package/dist/chunk-24SCZAB4.mjs.map +0 -1
  174. package/dist/chunk-5X5DJRQQ.mjs.map +0 -1
  175. package/dist/chunk-7BYHZLPL.mjs.map +0 -1
  176. package/dist/chunk-CB7CRBDG.mjs +0 -48
  177. package/dist/chunk-CB7CRBDG.mjs.map +0 -1
  178. package/dist/chunk-DCHSCK62.mjs.map +0 -1
  179. package/dist/chunk-IUSKVYUI.mjs +0 -13
  180. package/dist/chunk-IUSKVYUI.mjs.map +0 -1
  181. package/dist/chunk-NG26QEGF.mjs.map +0 -1
  182. package/dist/chunk-NROJOTQP.mjs.map +0 -1
  183. package/dist/chunk-R4MR43UQ.mjs.map +0 -1
  184. package/dist/chunk-UJBV5GAG.mjs.map +0 -1
  185. package/dist/hooks/use-configure-chat-suggestions.js +0 -210
  186. package/dist/hooks/use-configure-chat-suggestions.js.map +0 -1
  187. package/dist/hooks/use-configure-chat-suggestions.mjs +0 -13
  188. package/src/hooks/use-configure-chat-suggestions.tsx +0 -85
  189. /package/dist/{chunk-3GURHDG7.mjs.map → chunk-4HRUQH6U.mjs.map} +0 -0
  190. /package/dist/{chunk-D3QSYDJR.mjs.map → chunk-7IBF6RBW.mjs.map} +0 -0
  191. /package/dist/{chunk-GMI4KO4X.mjs.map → chunk-7SHWECGN.mjs.map} +0 -0
  192. /package/dist/{chunk-OVYFRPSN.mjs.map → chunk-ABWT4DRT.mjs.map} +0 -0
  193. /package/dist/{chunk-JRT5BJF3.mjs.map → chunk-B5ELMVT7.mjs.map} +0 -0
  194. /package/dist/{chunk-TXI72QHK.mjs.map → chunk-EG56H77V.mjs.map} +0 -0
  195. /package/dist/{chunk-LHKZJ2ND.mjs.map → chunk-PMWUKW3Z.mjs.map} +0 -0
  196. /package/dist/{chunk-QU6NONOD.mjs.map → chunk-U2ZRVVKT.mjs.map} +0 -0
  197. /package/dist/{chunk-WMJVBMUX.mjs.map → chunk-YCG6SNAU.mjs.map} +0 -0
  198. /package/dist/{chunk-3R423LZT.mjs.map → chunk-YJGPIN3R.mjs.map} +0 -0
  199. /package/dist/{chunk-BR5YEYZJ.mjs.map → chunk-YTQHRJUA.mjs.map} +0 -0
  200. /package/dist/hooks/{use-configure-chat-suggestions.mjs.map → use-agent-nodename.mjs.map} +0 -0
  201. /package/src/v2/{styles.css → index.css} +0 -0
@@ -0,0 +1,124 @@
1
+ /**
2
+ * <Callout type="warning">
3
+ * useCopilotChatSuggestions is experimental. The interface is not final and
4
+ * can change without notice.
5
+ * </Callout>
6
+ *
7
+ * `useCopilotReadable` is a React hook that provides app-state and other information
8
+ * to the Copilot. Optionally, the hook can also handle hierarchical state within your
9
+ * application, passing these parent-child relationships to the Copilot.
10
+ *
11
+ * <br/>
12
+ * <img src="https://cdn.copilotkit.ai/docs/copilotkit/images/use-copilot-chat-suggestions/use-copilot-chat-suggestions.gif" width="500" />
13
+ *
14
+ * ## Usage
15
+ *
16
+ * ### Install Dependencies
17
+ *
18
+ * This component is part of the [@copilotkit/react-ui](https://npmjs.com/package/@copilotkit/react-ui) package.
19
+ *
20
+ * ```shell npm2yarn \"@copilotkit/react-ui"\
21
+ * npm install @copilotkit/react-core @copilotkit/react-ui
22
+ * ```
23
+ *
24
+ * ### Simple Usage
25
+ *
26
+ * ```tsx
27
+ * import { useCopilotChatSuggestions } from "@copilotkit/react-ui";
28
+ *
29
+ * export function MyComponent() {
30
+ * const [employees, setEmployees] = useState([]);
31
+ *
32
+ * useCopilotChatSuggestions({
33
+ * instructions: `The following employees are on duty: ${JSON.stringify(employees)}`,
34
+ * });
35
+ * }
36
+ * ```
37
+ *
38
+ * ### Dependency Management
39
+ *
40
+ * ```tsx
41
+ * import { useCopilotChatSuggestions } from "@copilotkit/react-ui";
42
+ *
43
+ * export function MyComponent() {
44
+ * useCopilotChatSuggestions(
45
+ * {
46
+ * instructions: "Suggest the most relevant next actions.",
47
+ * },
48
+ * [appState],
49
+ * );
50
+ * }
51
+ * ```
52
+ *
53
+ * In the example above, the suggestions are generated based on the given instructions.
54
+ * The hook monitors `appState`, and updates suggestions accordingly whenever it changes.
55
+ *
56
+ * ### Behavior and Lifecycle
57
+ *
58
+ * The hook registers the configuration with the chat context upon component mount and
59
+ * removes it on unmount, ensuring a clean and efficient lifecycle management.
60
+ */
61
+ import {
62
+ useConfigureSuggestions,
63
+ useCopilotChatConfiguration,
64
+ useCopilotKit,
65
+ useSuggestions,
66
+ } from "@copilotkitnext/react";
67
+ import { useEffect } from "react";
68
+ import { StaticSuggestionsConfig, Suggestion } from "@copilotkitnext/core";
69
+
70
+ type StaticSuggestionInput = Omit<Suggestion, "isLoading"> & Partial<Pick<Suggestion, "isLoading">>;
71
+
72
+ type StaticSuggestionsConfigInput = Omit<StaticSuggestionsConfig, "suggestions"> & {
73
+ suggestions: StaticSuggestionInput[];
74
+ };
75
+
76
+ type DynamicSuggestionsConfigInput = {
77
+ /**
78
+ * A prompt or instructions for the GPT to generate suggestions.
79
+ */
80
+ instructions: string;
81
+ /**
82
+ * The minimum number of suggestions to generate. Defaults to `1`.
83
+ * @default 1
84
+ */
85
+ minSuggestions?: number;
86
+ /**
87
+ * The maximum number of suggestions to generate. Defaults to `3`.
88
+ * @default 1
89
+ */
90
+ maxSuggestions?: number;
91
+
92
+ /**
93
+ * Whether the suggestions are available. Defaults to `enabled`.
94
+ * @default enabled
95
+ */
96
+ available?: "enabled" | "disabled" | "always" | "before-first-message" | "after-first-message";
97
+
98
+ /**
99
+ * An optional class name to apply to the suggestions.
100
+ */
101
+ className?: string;
102
+ };
103
+
104
+ export type UseCopilotChatSuggestionsConfiguration =
105
+ | DynamicSuggestionsConfigInput
106
+ | StaticSuggestionsConfigInput;
107
+
108
+ export function useCopilotChatSuggestions(
109
+ config: UseCopilotChatSuggestionsConfiguration,
110
+ dependencies: any[] = [],
111
+ ) {
112
+ const existingConfig = useCopilotChatConfiguration();
113
+ const resolvedAgentId = existingConfig?.agentId ?? "default";
114
+
115
+ const available =
116
+ (config.available === "enabled" ? "always" : config.available) ?? "before-first-message";
117
+
118
+ const finalSuggestionConfig = {
119
+ ...config,
120
+ available,
121
+ consumerAgentId: resolvedAgentId, // Use chatConfig.agentId here
122
+ };
123
+ useConfigureSuggestions(finalSuggestionConfig, dependencies);
124
+ }
@@ -14,10 +14,6 @@ import {
14
14
  } from "@copilotkitnext/react";
15
15
  import { Suggestion } from "@copilotkitnext/core";
16
16
  import { useLazyToolRenderer } from "./use-lazy-tool-renderer";
17
- import {
18
- useConfigureChatSuggestions,
19
- UseCopilotChatSuggestionsConfiguration,
20
- } from "./use-configure-chat-suggestions";
21
17
  import { AbstractAgent, AGUIConnectNotImplementedError } from "@ag-ui/client";
22
18
  import {
23
19
  CoAgentStateRenderBridge,
@@ -71,7 +67,23 @@ export interface UseCopilotChatOptions {
71
67
  * Disables inclusion of CopilotKit’s default system message. When true, no system message is sent (this also suppresses any custom message from <code>makeSystemMessage</code>).
72
68
  */
73
69
  disableSystemMessage?: boolean;
74
-
70
+ /**
71
+ * Controls the behavior of suggestions in the chat interface.
72
+ *
73
+ * `auto` (default) - Suggestions are generated automatically:
74
+ * - When the chat is first opened (empty state)
75
+ * - After each message exchange completes
76
+ * - Uses configuration from `useCopilotChatSuggestions` hooks
77
+ *
78
+ * `manual` - Suggestions are controlled programmatically:
79
+ * - Use `setSuggestions()` to set custom suggestions
80
+ * - Use `generateSuggestions()` to trigger AI generation
81
+ * - Access via `useCopilotChat` hook
82
+ *
83
+ * `SuggestionItem[]` - Static suggestions array:
84
+ * - Always shows the same suggestions
85
+ * - No AI generation involved
86
+ */
75
87
  suggestions?: ChatSuggestions;
76
88
  }
77
89
 
@@ -227,7 +239,7 @@ export interface UseCopilotChatReturn {
227
239
  * Manually set suggestions
228
240
  * Useful for manual mode or custom suggestion workflows
229
241
  */
230
- setSuggestions: (suggestions: Suggestion[]) => void;
242
+ setSuggestions: (suggestions: Omit<Suggestion, "isLoading">[]) => void;
231
243
 
232
244
  /**
233
245
  * Trigger AI-powered suggestion generation
@@ -258,27 +270,6 @@ export interface UseCopilotChatReturn {
258
270
  threadId?: string;
259
271
  }
260
272
 
261
- function useConfigureSuggestions(suggestions?: UseCopilotChatOptions["suggestions"]) {
262
- let suggestionsConfig: UseCopilotChatSuggestionsConfiguration;
263
-
264
- if (Array.isArray(suggestions)) {
265
- suggestionsConfig = {
266
- suggestions,
267
- available: "always",
268
- };
269
- } else if (suggestions === "auto") {
270
- suggestionsConfig = {
271
- available: suggestions === "auto" ? "always" : "disabled",
272
- instructions:
273
- "Suggest what the user could say next. Provide clear, highly relevant suggestions. Do not literally suggest function calls.",
274
- };
275
- } else {
276
- suggestionsConfig = { available: "disabled" } as UseCopilotChatSuggestionsConfiguration;
277
- }
278
-
279
- useConfigureChatSuggestions(suggestionsConfig);
280
- }
281
-
282
273
  export function useCopilotChatInternal({
283
274
  suggestions,
284
275
  }: UseCopilotChatOptions = {}): UseCopilotChatReturn {
@@ -286,10 +277,9 @@ export function useCopilotChatInternal({
286
277
  const { threadId, agentSession } = useCopilotContext();
287
278
  const existingConfig = useCopilotChatConfiguration();
288
279
  const [agentAvailable, setAgentAvailable] = useState(false);
289
- useConfigureSuggestions(suggestions);
290
280
 
291
281
  // Apply priority: props > existing config > defaults
292
- const resolvedAgentId = agentSession?.agentName ?? existingConfig?.agentId ?? "default";
282
+ const resolvedAgentId = existingConfig?.agentId ?? "default";
293
283
  const { agent } = useAgent({ agentId: resolvedAgentId });
294
284
 
295
285
  useEffect(() => {
@@ -419,15 +409,14 @@ export function useCopilotChatInternal({
419
409
  [latestSendMessageFunc],
420
410
  );
421
411
 
422
- const latestSetMessages = useUpdatedRef(agent?.setMessages);
423
412
  const latestSetMessagesFunc = useCallback(
424
413
  (messages: Message[] | DeprecatedGqlMessage[]) => {
425
414
  if (messages.every((message) => message instanceof DeprecatedGqlMessage)) {
426
- return latestSetMessages.current?.(gqlToAGUI(messages));
415
+ return agent?.setMessages?.(gqlToAGUI(messages));
427
416
  }
428
- return latestSetMessages.current?.(messages);
417
+ return agent?.setMessages?.(messages);
429
418
  },
430
- [latestSetMessages, agent],
419
+ [agent?.setMessages, agent],
431
420
  );
432
421
 
433
422
  const latestReload = useUpdatedRef(reload);
@@ -438,10 +427,9 @@ export function useCopilotChatInternal({
438
427
  [latestReload],
439
428
  );
440
429
 
441
- const latestStop = useUpdatedRef(agent?.abortRun);
442
430
  const latestStopFunc = useCallback(() => {
443
- return latestStop.current?.();
444
- }, [latestStop]);
431
+ return agent?.abortRun?.();
432
+ }, [agent?.abortRun]);
445
433
 
446
434
  const latestReset = useUpdatedRef(reset);
447
435
  const latestResetFunc = useCallback(() => {
@@ -471,18 +459,19 @@ export function useCopilotChatInternal({
471
459
  }
472
460
  }
473
461
 
474
- const bridgeRenderer = legacyCustomMessageRenderer || renderCustomMessage
475
- ? () => {
476
- const customRender = renderCustomMessage?.({
477
- message,
478
- position: "before",
479
- });
480
- if (customRender) {
481
- return customRender;
462
+ const bridgeRenderer =
463
+ legacyCustomMessageRenderer || renderCustomMessage
464
+ ? () => {
465
+ const customRender = renderCustomMessage?.({
466
+ message,
467
+ position: "before",
468
+ });
469
+ if (customRender) {
470
+ return customRender;
471
+ }
472
+ return legacyCustomMessageRenderer?.({ message, position: "before" });
482
473
  }
483
- return legacyCustomMessageRenderer?.({ message, position: "before" });
484
- }
485
- : null;
474
+ : null;
486
475
 
487
476
  if (bridgeRenderer) {
488
477
  return { ...message, generativeUI: bridgeRenderer };
@@ -492,26 +481,27 @@ export function useCopilotChatInternal({
492
481
 
493
482
  const hasAssistantMessages = processedMessages.some((msg) => msg.role === "assistant");
494
483
 
495
- if (legacyCustomMessageRenderer && !hasAssistantMessages) {
496
- const placeholderId = `coagent-state-render-${resolvedAgentId}`;
497
- const placeholderMessage: Message = {
498
- id: placeholderId,
499
- role: "assistant",
500
- content: "",
501
- name: "coagent-state-render",
502
- };
503
- processedMessages = [
504
- ...processedMessages,
505
- {
506
- ...placeholderMessage,
507
- generativeUI: () =>
508
- legacyCustomMessageRenderer({
509
- message: placeholderMessage,
510
- position: "before",
511
- }),
512
- } as Message,
513
- ];
514
- }
484
+ // TODO: what is this?
485
+ // if (legacyCustomMessageRenderer && !hasAssistantMessages) {
486
+ // const placeholderId = `coagent-state-render-${resolvedAgentId}`;
487
+ // const placeholderMessage: Message = {
488
+ // id: placeholderId,
489
+ // role: "assistant",
490
+ // content: "",
491
+ // name: "coagent-state-render",
492
+ // };
493
+ // processedMessages = [
494
+ // ...processedMessages,
495
+ // {
496
+ // ...placeholderMessage,
497
+ // generativeUI: () =>
498
+ // legacyCustomMessageRenderer({
499
+ // message: placeholderMessage,
500
+ // position: "before",
501
+ // }),
502
+ // } as Message,
503
+ // ];
504
+ // }
515
505
 
516
506
  return processedMessages;
517
507
  }, [
@@ -519,10 +509,20 @@ export function useCopilotChatInternal({
519
509
  lazyToolRendered,
520
510
  allMessages,
521
511
  renderCustomMessage,
522
- legacyCustomMessageRenderer,
512
+ // legacyCustomMessageRenderer,
523
513
  resolvedAgentId,
524
514
  ]);
525
515
 
516
+ const renderedSuggestions = useMemo(() => {
517
+ if (Array.isArray(suggestions)) {
518
+ return {
519
+ suggestions: suggestions.map((s) => ({ ...s, isLoading: false })),
520
+ isLoading: false,
521
+ };
522
+ }
523
+ return currentSuggestions;
524
+ }, [suggestions, currentSuggestions]);
525
+
526
526
  // @ts-ignore
527
527
  return {
528
528
  messages: resolvedMessages,
@@ -533,15 +533,16 @@ export function useCopilotChatInternal({
533
533
  stopGeneration: latestStopFunc,
534
534
  reset: latestResetFunc,
535
535
  deleteMessage: latestDeleteFunc,
536
- isAvailable: !agentAvailable,
536
+ isAvailable: agentAvailable,
537
537
  isLoading: Boolean(agent?.isRunning),
538
538
  // mcpServers,
539
539
  // setMcpServers,
540
- suggestions: currentSuggestions.suggestions,
541
- setSuggestions: (suggestions: Suggestion[]) => copilotkit.addSuggestionsConfig({ suggestions }),
540
+ suggestions: renderedSuggestions.suggestions,
541
+ setSuggestions: (suggestions: Omit<Suggestion, "isLoading">[]) =>
542
+ copilotkit.addSuggestionsConfig({ suggestions }),
542
543
  generateSuggestions: async () => copilotkit.reloadSuggestions(resolvedAgentId),
543
544
  resetSuggestions: () => copilotkit.clearSuggestions(resolvedAgentId),
544
- isLoadingSuggestions: currentSuggestions.isLoading,
545
+ isLoadingSuggestions: renderedSuggestions.isLoading,
545
546
  interrupt,
546
547
  agent,
547
548
  threadId,
@@ -585,13 +586,12 @@ function useLegacyCoagentRenderer({
585
586
 
586
587
  return ({ message, position }: LegacyRenderParams) => {
587
588
  const effectiveThreadId = threadId ?? agent.threadId ?? "default";
588
- const existingRunId = copilotkit.getRunIdForMessage(
589
- agentId,
590
- effectiveThreadId,
591
- message.id,
592
- );
589
+ const existingRunId = copilotkit.getRunIdForMessage(agentId, effectiveThreadId, message.id);
593
590
  const runId = existingRunId || `pending:${message.id}`;
594
- const messageIndex = Math.max(agent.messages.findIndex((msg) => msg.id === message.id), 0);
591
+ const messageIndex = Math.max(
592
+ agent.messages.findIndex((msg) => msg.id === message.id),
593
+ 0,
594
+ );
595
595
 
596
596
  const bridgeProps: CoAgentStateRenderBridgeProps = {
597
597
  message: message as any,
@@ -61,9 +61,8 @@
61
61
  * }
62
62
  * ```
63
63
  */
64
+ import { useCopilotKit } from "@copilotkitnext/react";
64
65
  import { useEffect, useRef } from "react";
65
- import { useCopilotContext } from "../context/copilot-context";
66
- import { useAgentContext } from "@copilotkitnext/react";
67
66
 
68
67
  /**
69
68
  * Options for the useCopilotReadable hook.
@@ -99,19 +98,38 @@ export interface UseCopilotReadableOptions {
99
98
  convert?: (description: string, value: any) => string;
100
99
  }
101
100
 
102
- function convertToJSON(description: string, value: any): string {
103
- return `${description}: ${typeof value === "string" ? value : JSON.stringify(value)}`;
104
- }
105
-
106
101
  /**
107
102
  * Adds the given information to the Copilot context to make it readable by Copilot.
108
103
  */
109
104
  export function useCopilotReadable(
110
- { description, value }: UseCopilotReadableOptions,
105
+ { description, value, convert, available }: UseCopilotReadableOptions,
111
106
  dependencies?: any[],
112
- ): void {
113
- useAgentContext({
114
- description,
115
- value,
116
- });
107
+ ): string | undefined {
108
+ const { copilotkit } = useCopilotKit();
109
+ const ctxIdRef = useRef<string | undefined>(undefined);
110
+ useEffect(() => {
111
+ if (!copilotkit) return;
112
+
113
+ const found = Object.entries(copilotkit.context).find(([id, ctxItem]) => {
114
+ return JSON.stringify({ description, value }) == JSON.stringify(ctxItem);
115
+ });
116
+ if (found) {
117
+ ctxIdRef.current = found[0];
118
+ if (available === "disabled") copilotkit.removeContext(ctxIdRef.current);
119
+ return;
120
+ }
121
+ if (!found && available === "disabled") return;
122
+
123
+ ctxIdRef.current = copilotkit.addContext({
124
+ description,
125
+ value: (convert ?? JSON.stringify)(value),
126
+ });
127
+
128
+ return () => {
129
+ if (!ctxIdRef.current) return;
130
+ copilotkit.removeContext(ctxIdRef.current);
131
+ };
132
+ }, [description, value, convert]);
133
+
134
+ return ctxIdRef.current;
117
135
  }
@@ -3,7 +3,10 @@ import { ActionRenderProps, FrontendAction } from "../types/frontend-action";
3
3
  import { Parameter, getZodParameters, MappedParameterTypes } from "@copilotkit/shared";
4
4
  import { parseJson } from "@copilotkit/shared";
5
5
  import { ToolCallStatus } from "@copilotkitnext/core";
6
- import { type ReactFrontendTool, useFrontendTool as useFrontendToolVNext } from "@copilotkitnext/react";
6
+ import {
7
+ type ReactFrontendTool,
8
+ useFrontendTool as useFrontendToolVNext,
9
+ } from "@copilotkitnext/react";
7
10
 
8
11
  type FrontendToolOptions<T extends Parameter[] | []> = ReactFrontendTool<MappedParameterTypes<T>>;
9
12
  type FrontendToolRenderArgs<T extends Parameter[] | []> =
@@ -47,7 +50,12 @@ export function useFrontendTool<const T extends Parameter[] = []>(
47
50
 
48
51
  if (typeof render === "string") {
49
52
  const staticRender = render;
50
- return (() => React.createElement(React.Fragment, null, staticRender)) as FrontendToolOptions<T>["render"];
53
+ return (() =>
54
+ React.createElement(
55
+ React.Fragment,
56
+ null,
57
+ staticRender,
58
+ )) as FrontendToolOptions<T>["render"];
51
59
  }
52
60
 
53
61
  return ((args: FrontendToolRenderArgs<T>) => {
@@ -3,6 +3,8 @@ import React, { useCallback, useEffect, useMemo } from "react";
3
3
  import type { AbstractAgent, AgentSubscriber } from "@ag-ui/client";
4
4
  import { MetaEventName } from "@copilotkit/runtime-client-gql";
5
5
  import { dataToUUID, parseJson } from "@copilotkit/shared";
6
+ import { useAgentNodeName } from "./use-agent-nodename";
7
+ import { useCopilotChatConfiguration } from "@copilotkitnext/react";
6
8
 
7
9
  type InterruptProps = {
8
10
  event: any;
@@ -28,11 +30,15 @@ export function useLangGraphInterruptRender(
28
30
  threadId,
29
31
  interruptEventQueue,
30
32
  addInterruptEvent,
31
- removeInterruptEvent,
33
+ resolveInterruptEvent,
32
34
  } = useCopilotContext();
35
+ const existingConfig = useCopilotChatConfiguration();
36
+ const resolvedAgentId = existingConfig?.agentId ?? "default";
37
+ const nodeName = useAgentNodeName(resolvedAgentId);
33
38
 
34
39
  useEffect(() => {
35
40
  if (!agent) return;
41
+ let localInterrupt: any = null;
36
42
  const subscriber: AgentSubscriber = {
37
43
  onCustomEvent: ({ event }) => {
38
44
  if (event.name === "on_interrupt") {
@@ -41,12 +47,21 @@ export function useLangGraphInterruptRender(
41
47
  type: event.type,
42
48
  value: parseJson(event.value, event.value),
43
49
  };
44
- const eventId = dataToUUID(JSON.stringify(eventData), "interruptEvents");
45
- addInterruptEvent({
50
+ const eventId = dataToUUID(eventData, "interruptEvents");
51
+ localInterrupt = {
46
52
  eventId,
47
53
  threadId,
48
54
  event: eventData,
49
- });
55
+ };
56
+ }
57
+ },
58
+ onRunStartedEvent: () => {
59
+ localInterrupt = null;
60
+ },
61
+ onRunFinalized: () => {
62
+ if (localInterrupt) {
63
+ addInterruptEvent(localInterrupt);
64
+ localInterrupt = null;
50
65
  }
51
66
  },
52
67
  };
@@ -67,7 +82,7 @@ export function useLangGraphInterruptRender(
67
82
  },
68
83
  },
69
84
  });
70
- removeInterruptEvent(threadId, eventId);
85
+ resolveInterruptEvent(threadId, eventId, response ?? "");
71
86
  },
72
87
  // eslint-disable-next-line react-hooks/exhaustive-deps
73
88
  [agent, threadId],
@@ -78,7 +93,7 @@ export function useLangGraphInterruptRender(
78
93
  const eventQueue = interruptEventQueue[threadId] || [];
79
94
  const currentQueuedEvent = eventQueue.find((qe) => !qe.event.response);
80
95
 
81
- if (!currentQueuedEvent) return null;
96
+ if (!currentQueuedEvent || !agentSession) return null;
82
97
 
83
98
  // Find the first matching action from all registered actions
84
99
  const allActions = Object.values(interruptActions);
@@ -86,7 +101,10 @@ export function useLangGraphInterruptRender(
86
101
  if (!action.enabled) return true; // No filter = match all
87
102
  return action.enabled({
88
103
  eventValue: currentQueuedEvent.event.value,
89
- agentMetadata: agentSession,
104
+ agentMetadata: {
105
+ ...agentSession,
106
+ nodeName,
107
+ },
90
108
  });
91
109
  });
92
110
 
@@ -1,7 +1,6 @@
1
1
  import { useContext, useEffect, useMemo } from "react";
2
2
  import { CopilotContext } from "../context/copilot-context";
3
3
  import { LangGraphInterruptRender } from "../types/interrupt-action";
4
- import { useCopilotChatInternal } from "./use-copilot-chat_internal";
5
4
  import { useToast } from "../components/toast/toast-provider";
6
5
  import { dataToUUID } from "@copilotkit/shared";
7
6
 
@@ -13,7 +12,7 @@ export function useLangGraphInterrupt<TEventValue = any>(
13
12
  useContext(CopilotContext);
14
13
  const { addToast } = useToast();
15
14
 
16
- const actionId = dataToUUID(JSON.stringify(action), "lgAction");
15
+ const actionId = dataToUUID(action, "lgAction");
17
16
 
18
17
  useEffect(() => {
19
18
  if (!action) return;
@@ -27,7 +26,7 @@ export function useLangGraphInterrupt<TEventValue = any>(
27
26
  // return;
28
27
  // }
29
28
 
30
- setInterruptAction(threadId, { ...action, id: actionId });
29
+ setInterruptAction({ ...action, id: actionId });
31
30
 
32
31
  // Cleanup: remove action on unmount
33
32
  return () => {
@@ -26,7 +26,7 @@ export interface LangGraphInterruptRender<TEventValue = any> {
26
26
  * Method that returns a boolean, indicating if the interrupt action should run
27
27
  * Useful when using multiple interrupts
28
28
  */
29
- enabled?: (args: { eventValue: TEventValue; agentMetadata: AgentSession | null }) => boolean;
29
+ enabled?: (args: { eventValue: TEventValue; agentMetadata: AgentSession }) => boolean;
30
30
  }
31
31
 
32
32
  export type LangGraphInterruptAction = LangGraphInterruptRender & {
@@ -34,10 +34,7 @@ export type LangGraphInterruptAction = LangGraphInterruptRender & {
34
34
  };
35
35
 
36
36
  export type LangGraphInterruptActionSetterArgs = Partial<LangGraphInterruptRender> | null;
37
- export type LangGraphInterruptActionSetter = (
38
- threadId: string,
39
- action: LangGraphInterruptActionSetterArgs,
40
- ) => void;
37
+ export type LangGraphInterruptActionSetter = (action: LangGraphInterruptActionSetterArgs) => void;
41
38
 
42
39
  export interface QueuedInterruptEvent {
43
40
  eventId: string; // Generated unique ID for tracking
package/src/v2/index.ts CHANGED
@@ -1,2 +1,4 @@
1
+ import "./index.css";
2
+
1
3
  export * from "@copilotkitnext/core";
2
4
  export * from "@copilotkitnext/react";
package/tsup.config.ts CHANGED
@@ -10,7 +10,7 @@ export default defineConfig((options: Options) => ({
10
10
  format: ["esm", "cjs"],
11
11
  dts: true,
12
12
  minify: false,
13
- external: ["react", "@copilotkitnext/core", "@copilotkitnext/react"],
13
+ external: ["react"],
14
14
  sourcemap: true,
15
15
  ...options,
16
16
  }));
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../src/hooks/use-coagent.ts"],"sourcesContent":["/**\n * <Callout type=\"info\">\n * Usage of this hook assumes some additional setup in your application, for more information\n * on that see the CoAgents <span className=\"text-blue-500\">[getting started guide](/coagents/quickstart/langgraph)</span>.\n * </Callout>\n * <Frame className=\"my-12\">\n * <img\n * src=\"https://cdn.copilotkit.ai/docs/copilotkit/images/coagents/SharedStateCoAgents.gif\"\n * alt=\"CoAgents demonstration\"\n * className=\"w-auto\"\n * />\n * </Frame>\n *\n * This hook is used to integrate an agent into your application. With its use, you can\n * render and update the state of an agent, allowing for a dynamic and interactive experience.\n * We call these shared state experiences agentic copilots, or CoAgents for short.\n *\n * ## Usage\n *\n * ### Simple Usage\n *\n * ```tsx\n * import { useCoAgent } from \"@copilotkit/react-core\";\n *\n * type AgentState = {\n * count: number;\n * }\n *\n * const agent = useCoAgent<AgentState>({\n * name: \"my-agent\",\n * initialState: {\n * count: 0,\n * },\n * });\n *\n * ```\n *\n * `useCoAgent` returns an object with the following properties:\n *\n * ```tsx\n * const {\n * name, // The name of the agent currently being used.\n * nodeName, // The name of the current LangGraph node.\n * state, // The current state of the agent.\n * setState, // A function to update the state of the agent.\n * running, // A boolean indicating if the agent is currently running.\n * start, // A function to start the agent.\n * stop, // A function to stop the agent.\n * run, // A function to re-run the agent. Takes a HintFunction to inform the agent why it is being re-run.\n * } = agent;\n * ```\n *\n * Finally we can leverage these properties to create reactive experiences with the agent!\n *\n * ```tsx\n * const { state, setState } = useCoAgent<AgentState>({\n * name: \"my-agent\",\n * initialState: {\n * count: 0,\n * },\n * });\n *\n * return (\n * <div>\n * <p>Count: {state.count}</p>\n * <button onClick={() => setState({ count: state.count + 1 })}>Increment</button>\n * </div>\n * );\n * ```\n *\n * This reactivity is bidirectional, meaning that changes to the state from the agent will be reflected in the UI and vice versa.\n *\n * ## Parameters\n * <PropertyReference name=\"options\" type=\"UseCoagentOptions<T>\" required>\n * The options to use when creating the coagent.\n * <PropertyReference name=\"name\" type=\"string\" required>\n * The name of the agent to use.\n * </PropertyReference>\n * <PropertyReference name=\"initialState\" type=\"T | any\">\n * The initial state of the agent.\n * </PropertyReference>\n * <PropertyReference name=\"state\" type=\"T | any\">\n * State to manage externally if you are using this hook with external state management.\n * </PropertyReference>\n * <PropertyReference name=\"setState\" type=\"(newState: T | ((prevState: T | undefined) => T)) => void\">\n * A function to update the state of the agent if you are using this hook with external state management.\n * </PropertyReference>\n * </PropertyReference>\n */\n\nimport { useCallback, useEffect, useMemo, useRef, useState } from \"react\";\nimport { Message } from \"@copilotkit/shared\";\nimport { useAgent } from \"@copilotkitnext/react\";\nimport { type AgentSubscriber } from \"@ag-ui/client\";\n\ninterface UseCoagentOptionsBase {\n /**\n * The name of the agent being used.\n */\n name: string;\n /**\n * @deprecated - use \"config.configurable\"\n * Config to pass to a LangGraph Agent\n */\n configurable?: Record<string, any>;\n /**\n * Config to pass to a LangGraph Agent\n */\n config?: {\n configurable?: Record<string, any>;\n [key: string]: any;\n };\n}\n\ninterface WithInternalStateManagementAndInitial<T> extends UseCoagentOptionsBase {\n /**\n * The initial state of the agent.\n */\n initialState: T;\n}\n\ninterface WithInternalStateManagement extends UseCoagentOptionsBase {\n /**\n * Optional initialState with default type any\n */\n initialState?: any;\n}\n\ninterface WithExternalStateManagement<T> extends UseCoagentOptionsBase {\n /**\n * The current state of the agent.\n */\n state: T;\n /**\n * A function to update the state of the agent.\n */\n setState: (newState: T | ((prevState: T | undefined) => T)) => void;\n}\n\ntype UseCoagentOptions<T> =\n | WithInternalStateManagementAndInitial<T>\n | WithInternalStateManagement\n | WithExternalStateManagement<T>;\n\nexport interface UseCoagentReturnType<T> {\n /**\n * The name of the agent being used.\n */\n name: string;\n /**\n * The name of the current LangGraph node.\n */\n nodeName?: string;\n /**\n * The ID of the thread the agent is running in.\n */\n threadId?: string;\n /**\n * A boolean indicating if the agent is currently running.\n */\n running: boolean;\n /**\n * The current state of the agent.\n */\n state: T;\n /**\n * A function to update the state of the agent.\n */\n setState: (newState: T | ((prevState: T | undefined) => T)) => void;\n /**\n * A function to start the agent.\n */\n start: () => void;\n /**\n * A function to stop the agent.\n */\n stop: () => void;\n /**\n * A function to re-run the agent. The hint function can be used to provide a hint to the agent\n * about why it is being re-run again.\n */\n run: (...args: any[]) => Promise<any>;\n}\n\nexport interface HintFunctionParams {\n /**\n * The previous state of the agent.\n */\n previousState: any;\n /**\n * The current state of the agent.\n */\n currentState: any;\n}\n\nexport type HintFunction = (params: HintFunctionParams) => Message | undefined;\n\n/**\n * This hook is used to integrate an agent into your application. With its use, you can\n * render and update the state of the agent, allowing for a dynamic and interactive experience.\n * We call these shared state experiences \"agentic copilots\". To get started using agentic copilots, which\n * we refer to as CoAgents, checkout the documentation at https://docs.copilotkit.ai/coagents/quickstart/langgraph.\n */\nexport function useCoAgent<T = any>(options: UseCoagentOptions<T>): UseCoagentReturnType<T> {\n const { agent } = useAgent({ agentId: options.name });\n const nodeNameRef = useRef<string>(\"start\");\n\n const handleStateUpdate = useCallback(\n (newState: T | ((prevState: T | undefined) => T)) => {\n if (!agent) return;\n\n if (typeof newState === \"function\") {\n const updater = newState as (prevState: T | undefined) => T;\n agent.setState(updater(agent.state));\n } else {\n agent.setState({ ...agent.state, ...newState });\n }\n },\n [agent?.state, agent?.setState],\n );\n\n const externalStateStr = useMemo(\n () => (isExternalStateManagement(options) ? JSON.stringify(options.state) : undefined),\n [isExternalStateManagement(options) ? JSON.stringify(options.state) : undefined],\n );\n\n // Sync internal state with external state if state management is external\n useEffect(() => {\n if (\n agent?.state &&\n isExternalStateManagement(options) &&\n JSON.stringify(options.state) !== JSON.stringify(agent.state)\n ) {\n handleStateUpdate(options.state);\n }\n }, [agent, externalStateStr, handleStateUpdate]);\n\n const hasStateValues = useCallback((value?: Record<string, any>) => {\n return Boolean(value && Object.keys(value).length);\n }, []);\n\n const initialStateRef = useRef<any>(\n isExternalStateManagement(options)\n ? options.state\n : \"initialState\" in options\n ? options.initialState\n : undefined,\n );\n\n useEffect(() => {\n if (isExternalStateManagement(options)) {\n initialStateRef.current = options.state;\n } else if (\"initialState\" in options) {\n initialStateRef.current = options.initialState;\n }\n }, [\n isExternalStateManagement(options)\n ? JSON.stringify(options.state)\n : \"initialState\" in options\n ? JSON.stringify(options.initialState)\n : undefined,\n ]);\n\n useEffect(() => {\n if (!agent) return;\n const subscriber: AgentSubscriber = {\n onStateChanged: (args: any) => {\n if (isExternalStateManagement(options)) {\n options.setState(args.state);\n }\n },\n onRunInitialized: (args: any) => {\n const runHasState = hasStateValues(args.state);\n if (runHasState) {\n handleStateUpdate(args.state);\n return;\n }\n\n if (hasStateValues(agent.state)) {\n return;\n }\n\n if (initialStateRef.current !== undefined) {\n handleStateUpdate(initialStateRef.current);\n }\n },\n onStepStartedEvent: ({ event }) => {\n nodeNameRef.current = event.stepName;\n },\n onRunStartedEvent: () => {\n nodeNameRef.current = \"start\";\n },\n onRunFinishedEvent: () => {\n nodeNameRef.current = \"end\";\n },\n };\n\n const subscription = agent.subscribe(subscriber);\n return () => {\n subscription.unsubscribe();\n };\n }, [agent, handleStateUpdate, hasStateValues]);\n\n // Return a consistent shape whether or not the agent is available\n return useMemo<UseCoagentReturnType<T>>(() => {\n if (!agent) {\n const noop = () => {};\n const noopAsync = async () => {};\n const initialState =\n // prefer externally provided state if available\n (\"state\" in options && (options as any).state) ??\n // then initialState if provided\n (\"initialState\" in options && (options as any).initialState) ??\n ({} as T);\n return {\n name: options.name,\n nodeName: nodeNameRef.current,\n threadId: undefined,\n running: false,\n state: initialState as T,\n setState: noop,\n start: noop,\n stop: noop,\n run: noopAsync,\n };\n }\n\n return {\n name: agent?.agentId ?? options.name,\n nodeName: nodeNameRef.current,\n threadId: agent.threadId,\n running: agent.isRunning,\n state: agent.state,\n setState: handleStateUpdate,\n // TODO: start and run both have same thing. need to figure out\n start: agent.runAgent,\n stop: agent.abortRun,\n run: agent.runAgent,\n };\n }, [\n agent?.state,\n agent?.runAgent,\n agent?.abortRun,\n agent?.runAgent,\n agent?.threadId,\n agent?.isRunning,\n agent?.agentId,\n handleStateUpdate,\n options.name,\n ]);\n}\n\nconst isExternalStateManagement = <T>(\n options: UseCoagentOptions<T>,\n): options is WithExternalStateManagement<T> => {\n return \"state\" in options && \"setState\" in options;\n};\n"],"mappings":"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","names":[]}
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../src/components/CopilotListeners.tsx"],"sourcesContent":["import { useCallback, useEffect, useMemo, useRef } from \"react\";\nimport { useAgent, useCopilotChatConfiguration, useCopilotKit } from \"@copilotkitnext/react\";\nimport { CopilotKitError, parseJson } from \"@copilotkit/shared\";\nimport { useCopilotContext } from \"../context\";\nimport { AbstractAgent, AgentSubscriber, AGUIConnectNotImplementedError } from \"@ag-ui/client\";\nimport { useErrorToast } from \"./error-boundary/error-utils\";\nimport { CopilotKitCoreSubscriber } from \"@copilotkitnext/core\";\nimport { useToast } from \"./toast/toast-provider\";\nimport { CopilotKitLowLevelError } from \"@copilotkit/shared\";\n\nconst usePredictStateSubscription = (agent?: AbstractAgent) => {\n const predictStateToolsRef = useRef<\n {\n tool: string;\n state_key: string;\n tool_argument: string;\n }[]\n >([]);\n\n const getSubscriber = useCallback(\n (agent: AbstractAgent): AgentSubscriber => ({\n onCustomEvent: ({ event }) => {\n if (event.name === \"PredictState\") {\n predictStateToolsRef.current = event.value;\n }\n },\n onToolCallArgsEvent: ({ partialToolCallArgs, toolCallName }) => {\n predictStateToolsRef.current.forEach((t) => {\n if (t?.tool !== toolCallName) return;\n\n const emittedState =\n typeof partialToolCallArgs === \"string\"\n ? parseJson(partialToolCallArgs as unknown as string, partialToolCallArgs)\n : partialToolCallArgs;\n\n agent.setState({\n [t.state_key]: emittedState[t.state_key],\n });\n });\n },\n }),\n [],\n );\n\n useEffect(() => {\n if (!agent) return;\n\n const subscriber = getSubscriber(agent);\n const { unsubscribe } = agent.subscribe(subscriber);\n return () => {\n unsubscribe();\n };\n }, [agent, getSubscriber]);\n};\n\nexport function CopilotListeners() {\n const { copilotkit } = useCopilotKit();\n const { agentSession } = useCopilotContext();\n const existingConfig = useCopilotChatConfiguration();\n const resolvedAgentId = agentSession?.agentName ?? existingConfig?.agentId ?? \"default\";\n const { setBannerError } = useToast();\n\n const { agent } = useAgent({ agentId: resolvedAgentId });\n\n usePredictStateSubscription(agent);\n\n useEffect(() => {\n const subscriber: CopilotKitCoreSubscriber = {\n onError: ({ error }) => {\n // @ts-expect-error -- for now, choose a random CPK error type to display the error toast\n setBannerError(new CopilotKitLowLevelError({ error, message: error.message }));\n },\n };\n const subscription = copilotkit.subscribe(subscriber);\n\n return () => {\n subscription.unsubscribe();\n };\n }, [copilotkit?.subscribe]);\n\n return null;\n}\n"],"mappings":";;;;;;;;AAAA,SAAS,aAAa,WAAoB,cAAc;AACxD,SAAS,UAAU,6BAA6B,qBAAqB;AACrE,SAA0B,iBAAiB;AAM3C,SAAS,+BAA+B;AAExC,IAAM,8BAA8B,CAAC,UAA0B;AAC7D,QAAM,uBAAuB,OAM3B,CAAC,CAAC;AAEJ,QAAM,gBAAgB;AAAA,IACpB,CAACA,YAA2C;AAAA,MAC1C,eAAe,CAAC,EAAE,MAAM,MAAM;AAC5B,YAAI,MAAM,SAAS,gBAAgB;AACjC,+BAAqB,UAAU,MAAM;AAAA,QACvC;AAAA,MACF;AAAA,MACA,qBAAqB,CAAC,EAAE,qBAAqB,aAAa,MAAM;AAC9D,6BAAqB,QAAQ,QAAQ,CAAC,MAAM;AAC1C,eAAI,uBAAG,UAAS;AAAc;AAE9B,gBAAM,eACJ,OAAO,wBAAwB,WAC3B,UAAU,qBAA0C,mBAAmB,IACvE;AAEN,UAAAA,OAAM,SAAS;AAAA,YACb,CAAC,EAAE,SAAS,GAAG,aAAa,EAAE,SAAS;AAAA,UACzC,CAAC;AAAA,QACH,CAAC;AAAA,MACH;AAAA,IACF;AAAA,IACA,CAAC;AAAA,EACH;AAEA,YAAU,MAAM;AACd,QAAI,CAAC;AAAO;AAEZ,UAAM,aAAa,cAAc,KAAK;AACtC,UAAM,EAAE,YAAY,IAAI,MAAM,UAAU,UAAU;AAClD,WAAO,MAAM;AACX,kBAAY;AAAA,IACd;AAAA,EACF,GAAG,CAAC,OAAO,aAAa,CAAC;AAC3B;AAEO,SAAS,mBAAmB;AAvDnC;AAwDE,QAAM,EAAE,WAAW,IAAI,cAAc;AACrC,QAAM,EAAE,aAAa,IAAI,kBAAkB;AAC3C,QAAM,iBAAiB,4BAA4B;AACnD,QAAM,mBAAkB,wDAAc,cAAd,YAA2B,iDAAgB,YAA3C,YAAsD;AAC9E,QAAM,EAAE,eAAe,IAAI,SAAS;AAEpC,QAAM,EAAE,MAAM,IAAI,SAAS,EAAE,SAAS,gBAAgB,CAAC;AAEvD,8BAA4B,KAAK;AAEjC,YAAU,MAAM;AACd,UAAM,aAAuC;AAAA,MAC3C,SAAS,CAAC,EAAE,MAAM,MAAM;AAEtB,uBAAe,IAAI,wBAAwB,EAAE,OAAO,SAAS,MAAM,QAAQ,CAAC,CAAC;AAAA,MAC/E;AAAA,IACF;AACA,UAAM,eAAe,WAAW,UAAU,UAAU;AAEpD,WAAO,MAAM;AACX,mBAAa,YAAY;AAAA,IAC3B;AAAA,EACF,GAAG,CAAC,yCAAY,SAAS,CAAC;AAE1B,SAAO;AACT;","names":["agent"]}
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../src/hooks/use-langgraph-interrupt.ts"],"sourcesContent":["import { useContext, useEffect, useMemo } from \"react\";\nimport { CopilotContext } from \"../context/copilot-context\";\nimport { LangGraphInterruptRender } from \"../types/interrupt-action\";\nimport { useCopilotChatInternal } from \"./use-copilot-chat_internal\";\nimport { useToast } from \"../components/toast/toast-provider\";\nimport { dataToUUID } from \"@copilotkit/shared\";\n\nexport function useLangGraphInterrupt<TEventValue = any>(\n action: Omit<LangGraphInterruptRender<TEventValue>, \"id\">,\n dependencies?: any[],\n) {\n const { setInterruptAction, removeInterruptAction, interruptActions, threadId } =\n useContext(CopilotContext);\n const { addToast } = useToast();\n\n const actionId = dataToUUID(JSON.stringify(action), \"lgAction\");\n\n useEffect(() => {\n if (!action) return;\n\n // if (!action.enabled) {\n // TODO: if there are any other actions registered, we need to warn the user that a current action without \"enabled\" might render for everything\n // addToast({\n // type: \"warning\",\n // message: \"An action is already registered for the interrupt event\",\n // });\n // return;\n // }\n\n setInterruptAction(threadId, { ...action, id: actionId });\n\n // Cleanup: remove action on unmount\n return () => {\n removeInterruptAction(actionId);\n };\n }, [setInterruptAction, removeInterruptAction, threadId, actionId, ...(dependencies || [])]);\n}\n"],"mappings":";;;;;;;;;;;;AAAA,SAAS,YAAY,iBAA0B;AAK/C,SAAS,kBAAkB;AAEpB,SAAS,sBACd,QACA,cACA;AACA,QAAM,EAAE,oBAAoB,uBAAuB,kBAAkB,SAAS,IAC5E,WAAW,cAAc;AAC3B,QAAM,EAAE,SAAS,IAAI,SAAS;AAE9B,QAAM,WAAW,WAAW,KAAK,UAAU,MAAM,GAAG,UAAU;AAE9D,YAAU,MAAM;AACd,QAAI,CAAC;AAAQ;AAWb,uBAAmB,UAAU,iCAAK,SAAL,EAAa,IAAI,SAAS,EAAC;AAGxD,WAAO,MAAM;AACX,4BAAsB,QAAQ;AAAA,IAChC;AAAA,EACF,GAAG,CAAC,oBAAoB,uBAAuB,UAAU,UAAU,GAAI,gBAAgB,CAAC,CAAE,CAAC;AAC7F;","names":[]}