@copilotkit/react-core 1.57.3 → 1.57.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (266) hide show
  1. package/LICENSE +21 -0
  2. package/package.json +12 -13
  3. package/skills/react-core/SKILL.md +108 -0
  4. package/skills/react-core/references/agent-access.md +288 -0
  5. package/skills/react-core/references/attachments.md +291 -0
  6. package/skills/react-core/references/capabilities.md +138 -0
  7. package/skills/react-core/references/chat-components.md +221 -0
  8. package/skills/react-core/references/client-side-tools.md +358 -0
  9. package/skills/react-core/references/custom-message-renderers.md +226 -0
  10. package/skills/react-core/references/debug-mode.md +153 -0
  11. package/skills/react-core/references/human-in-the-loop.md +312 -0
  12. package/skills/react-core/references/provider-setup.md +326 -0
  13. package/skills/react-core/references/rendering-activity-messages.md +207 -0
  14. package/skills/react-core/references/rendering-tool-calls.md +319 -0
  15. package/skills/react-core/references/suggestions.md +211 -0
  16. package/skills/react-core/references/switching-agents-recipes.md +160 -0
  17. package/skills/react-core/references/switching-agents.md +231 -0
  18. package/skills/react-core/references/threads.md +226 -0
  19. package/.attw.json +0 -3
  20. package/CHANGELOG.md +0 -5043
  21. package/scripts/scope-preflight.mjs +0 -100
  22. package/src/components/CopilotListeners.tsx +0 -137
  23. package/src/components/__tests__/CopilotListeners.test.tsx +0 -38
  24. package/src/components/copilot-provider/__tests__/copilot-messages-key.test.tsx +0 -92
  25. package/src/components/copilot-provider/__tests__/copilotkit-error.test.tsx +0 -77
  26. package/src/components/copilot-provider/__tests__/error-visibility-prod.test.tsx +0 -70
  27. package/src/components/copilot-provider/__tests__/v1-explicit-threadid-bridge.test.tsx +0 -107
  28. package/src/components/copilot-provider/copilot-messages.tsx +0 -314
  29. package/src/components/copilot-provider/copilotkit-props.tsx +0 -214
  30. package/src/components/copilot-provider/copilotkit.tsx +0 -853
  31. package/src/components/copilot-provider/index.ts +0 -3
  32. package/src/components/dev-console/console-trigger.tsx +0 -283
  33. package/src/components/dev-console/developer-console-modal.tsx +0 -1016
  34. package/src/components/dev-console/icons.tsx +0 -106
  35. package/src/components/error-boundary/error-boundary.tsx +0 -99
  36. package/src/components/error-boundary/error-utils.tsx +0 -105
  37. package/src/components/index.ts +0 -1
  38. package/src/components/toast/exclamation-mark-icon.tsx +0 -27
  39. package/src/components/toast/toast-provider.tsx +0 -448
  40. package/src/components/usage-banner.tsx +0 -266
  41. package/src/context/__tests__/threads-context.test.tsx +0 -141
  42. package/src/context/coagent-state-renders-context.tsx +0 -89
  43. package/src/context/copilot-context.tsx +0 -365
  44. package/src/context/copilot-messages-context.tsx +0 -35
  45. package/src/context/index.ts +0 -22
  46. package/src/context/threads-context.tsx +0 -69
  47. package/src/hooks/__tests__/use-coagent-config.test.ts +0 -352
  48. package/src/hooks/__tests__/use-coagent-state-render-bridge.helpers.test.ts +0 -107
  49. package/src/hooks/__tests__/use-coagent-state-render.e2e.test.tsx +0 -1209
  50. package/src/hooks/__tests__/use-coagent-state-render.test.tsx +0 -356
  51. package/src/hooks/__tests__/use-copilot-chat-internal-connect.test.tsx +0 -241
  52. package/src/hooks/__tests__/use-frontend-tool-available.test.tsx +0 -72
  53. package/src/hooks/__tests__/use-frontend-tool-remount.e2e.test.tsx +0 -102
  54. package/src/hooks/index.ts +0 -33
  55. package/src/hooks/use-agent-nodename.ts +0 -33
  56. package/src/hooks/use-coagent-state-render-bridge.helpers.ts +0 -345
  57. package/src/hooks/use-coagent-state-render-bridge.tsx +0 -222
  58. package/src/hooks/use-coagent-state-render-registry.ts +0 -230
  59. package/src/hooks/use-coagent-state-render.ts +0 -163
  60. package/src/hooks/use-coagent.ts +0 -377
  61. package/src/hooks/use-configure-chat-suggestions.tsx +0 -96
  62. package/src/hooks/use-copilot-action.ts +0 -245
  63. package/src/hooks/use-copilot-additional-instructions.ts +0 -98
  64. package/src/hooks/use-copilot-authenticated-action.ts +0 -73
  65. package/src/hooks/use-copilot-chat-headless_c.ts +0 -264
  66. package/src/hooks/use-copilot-chat-suggestions.tsx +0 -134
  67. package/src/hooks/use-copilot-chat.ts +0 -132
  68. package/src/hooks/use-copilot-chat_internal.ts +0 -875
  69. package/src/hooks/use-copilot-readable.ts +0 -135
  70. package/src/hooks/use-copilot-runtime-client.ts +0 -178
  71. package/src/hooks/use-default-tool.ts +0 -13
  72. package/src/hooks/use-flat-category-store.ts +0 -109
  73. package/src/hooks/use-frontend-tool.ts +0 -113
  74. package/src/hooks/use-human-in-the-loop.ts +0 -138
  75. package/src/hooks/use-langgraph-interrupt.ts +0 -103
  76. package/src/hooks/use-lazy-tool-renderer.tsx +0 -30
  77. package/src/hooks/use-make-copilot-document-readable.ts +0 -30
  78. package/src/hooks/use-render-tool-call.ts +0 -89
  79. package/src/hooks/use-tree.ts +0 -222
  80. package/src/index.tsx +0 -7
  81. package/src/lib/copilot-task.ts +0 -215
  82. package/src/lib/index.ts +0 -1
  83. package/src/lib/status-checker.ts +0 -67
  84. package/src/setupTests.ts +0 -37
  85. package/src/test-helpers/copilot-context.ts +0 -91
  86. package/src/types/chat-suggestion-configuration.ts +0 -23
  87. package/src/types/coagent-action.ts +0 -35
  88. package/src/types/coagent-state.ts +0 -13
  89. package/src/types/crew.ts +0 -89
  90. package/src/types/document-pointer.ts +0 -7
  91. package/src/types/frontend-action.ts +0 -213
  92. package/src/types/index.ts +0 -17
  93. package/src/types/interrupt-action.ts +0 -58
  94. package/src/types/system-message.ts +0 -4
  95. package/src/utils/dev-console.ts +0 -19
  96. package/src/utils/index.ts +0 -2
  97. package/src/utils/suggestions-constants.ts +0 -8
  98. package/src/utils/utils.test.ts +0 -7
  99. package/src/utils/utils.ts +0 -6
  100. package/src/v2/__tests__/A2UIMessageRenderer.test.tsx +0 -240
  101. package/src/v2/__tests__/globalSetup.ts +0 -14
  102. package/src/v2/__tests__/setup.ts +0 -93
  103. package/src/v2/__tests__/utils/test-helpers.tsx +0 -570
  104. package/src/v2/a2ui/A2UICatalogContext.tsx +0 -79
  105. package/src/v2/a2ui/A2UIMessageRenderer.tsx +0 -294
  106. package/src/v2/a2ui/A2UIToolCallRenderer.tsx +0 -290
  107. package/src/v2/components/CopilotKitInspector.tsx +0 -52
  108. package/src/v2/components/MCPAppsActivityRenderer.tsx +0 -815
  109. package/src/v2/components/OpenGenerativeUIRenderer.tsx +0 -598
  110. package/src/v2/components/WildcardToolCallRender.tsx +0 -86
  111. package/src/v2/components/__tests__/OpenGenerativeUIRenderer.test.tsx +0 -665
  112. package/src/v2/components/chat/CopilotChat.tsx +0 -664
  113. package/src/v2/components/chat/CopilotChatAssistantMessage.tsx +0 -393
  114. package/src/v2/components/chat/CopilotChatAttachmentQueue.tsx +0 -374
  115. package/src/v2/components/chat/CopilotChatAttachmentRenderer.tsx +0 -159
  116. package/src/v2/components/chat/CopilotChatAudioRecorder.tsx +0 -350
  117. package/src/v2/components/chat/CopilotChatInput.tsx +0 -1412
  118. package/src/v2/components/chat/CopilotChatMessageView.tsx +0 -716
  119. package/src/v2/components/chat/CopilotChatReasoningMessage.tsx +0 -265
  120. package/src/v2/components/chat/CopilotChatSuggestionPill.tsx +0 -59
  121. package/src/v2/components/chat/CopilotChatSuggestionView.tsx +0 -134
  122. package/src/v2/components/chat/CopilotChatToggleButton.tsx +0 -171
  123. package/src/v2/components/chat/CopilotChatToolCallsView.tsx +0 -40
  124. package/src/v2/components/chat/CopilotChatUserMessage.tsx +0 -445
  125. package/src/v2/components/chat/CopilotChatView.tsx +0 -890
  126. package/src/v2/components/chat/CopilotModalHeader.tsx +0 -129
  127. package/src/v2/components/chat/CopilotPopup.tsx +0 -81
  128. package/src/v2/components/chat/CopilotPopupView.tsx +0 -317
  129. package/src/v2/components/chat/CopilotSidebar.tsx +0 -80
  130. package/src/v2/components/chat/CopilotSidebarView.tsx +0 -269
  131. package/src/v2/components/chat/Lightbox.tsx +0 -103
  132. package/src/v2/components/chat/__tests__/CopilotChat.absentThreadConnect.test.tsx +0 -66
  133. package/src/v2/components/chat/__tests__/CopilotChat.attachments.test.tsx +0 -168
  134. package/src/v2/components/chat/__tests__/CopilotChat.e2e.test.tsx +0 -1239
  135. package/src/v2/components/chat/__tests__/CopilotChat.onError.test.tsx +0 -73
  136. package/src/v2/components/chat/__tests__/CopilotChat.slots.e2e.test.tsx +0 -432
  137. package/src/v2/components/chat/__tests__/CopilotChat.suggestionsAlways.test.tsx +0 -183
  138. package/src/v2/components/chat/__tests__/CopilotChat.welcomeGate.test.tsx +0 -184
  139. package/src/v2/components/chat/__tests__/CopilotChatActivityRendering.e2e.test.tsx +0 -649
  140. package/src/v2/components/chat/__tests__/CopilotChatAssistantMessage.slots.e2e.test.tsx +0 -624
  141. package/src/v2/components/chat/__tests__/CopilotChatAssistantMessage.test.tsx +0 -702
  142. package/src/v2/components/chat/__tests__/CopilotChatAssistantMessage.thumbs.test.tsx +0 -72
  143. package/src/v2/components/chat/__tests__/CopilotChatCopyButton.clipboard.test.tsx +0 -241
  144. package/src/v2/components/chat/__tests__/CopilotChatCssClasses.test.tsx +0 -107
  145. package/src/v2/components/chat/__tests__/CopilotChatInput.slots.e2e.test.tsx +0 -929
  146. package/src/v2/components/chat/__tests__/CopilotChatInput.test.tsx +0 -1567
  147. package/src/v2/components/chat/__tests__/CopilotChatMessageView.slots.e2e.test.tsx +0 -1004
  148. package/src/v2/components/chat/__tests__/CopilotChatMessageView.test.tsx +0 -279
  149. package/src/v2/components/chat/__tests__/CopilotChatPerf.e2e.test.tsx +0 -336
  150. package/src/v2/components/chat/__tests__/CopilotChatPropsRerender.e2e.test.tsx +0 -249
  151. package/src/v2/components/chat/__tests__/CopilotChatSuggestionView.slots.e2e.test.tsx +0 -530
  152. package/src/v2/components/chat/__tests__/CopilotChatToolRendering.e2e.test.tsx +0 -785
  153. package/src/v2/components/chat/__tests__/CopilotChatToolRerenders.e2e.test.tsx +0 -2416
  154. package/src/v2/components/chat/__tests__/CopilotChatUserMessage.slots.e2e.test.tsx +0 -621
  155. package/src/v2/components/chat/__tests__/CopilotChatView.connectingGate.test.tsx +0 -56
  156. package/src/v2/components/chat/__tests__/CopilotChatView.inputOverlay.test.tsx +0 -264
  157. package/src/v2/components/chat/__tests__/CopilotChatView.onClick.e2e.test.tsx +0 -853
  158. package/src/v2/components/chat/__tests__/CopilotChatView.pinToSend.test.tsx +0 -94
  159. package/src/v2/components/chat/__tests__/CopilotChatView.slots.e2e.test.tsx +0 -1050
  160. package/src/v2/components/chat/__tests__/CopilotModalHeader.slots.e2e.test.tsx +0 -484
  161. package/src/v2/components/chat/__tests__/CopilotPopupView.slots.e2e.test.tsx +0 -612
  162. package/src/v2/components/chat/__tests__/CopilotSidebarView.position.test.tsx +0 -159
  163. package/src/v2/components/chat/__tests__/CopilotSidebarView.slots.e2e.test.tsx +0 -502
  164. package/src/v2/components/chat/__tests__/MCPAppsActivityRenderer.e2e.test.tsx +0 -1068
  165. package/src/v2/components/chat/__tests__/MCPAppsProxy.e2e.test.tsx +0 -589
  166. package/src/v2/components/chat/__tests__/MCPAppsUiMessage.e2e.test.tsx +0 -403
  167. package/src/v2/components/chat/__tests__/copilot-chat-throttle.test.tsx +0 -137
  168. package/src/v2/components/chat/__tests__/normalize-auto-scroll.test.ts +0 -37
  169. package/src/v2/components/chat/__tests__/setup.ts +0 -1
  170. package/src/v2/components/chat/index.ts +0 -90
  171. package/src/v2/components/chat/last-user-message-context.ts +0 -21
  172. package/src/v2/components/chat/normalize-auto-scroll.ts +0 -17
  173. package/src/v2/components/chat/scroll-element-context.ts +0 -13
  174. package/src/v2/components/index.ts +0 -8
  175. package/src/v2/components/intelligence-indicator/IntelligenceIndicator.tsx +0 -286
  176. package/src/v2/components/intelligence-indicator/__tests__/IntelligenceIndicator.e2e.test.tsx +0 -464
  177. package/src/v2/components/intelligence-indicator/index.ts +0 -2
  178. package/src/v2/components/license-warning-banner.tsx +0 -217
  179. package/src/v2/components/ui/button.tsx +0 -124
  180. package/src/v2/components/ui/dropdown-menu.tsx +0 -258
  181. package/src/v2/components/ui/tooltip.tsx +0 -60
  182. package/src/v2/context.ts +0 -62
  183. package/src/v2/headless.ts +0 -64
  184. package/src/v2/hooks/__tests__/standard-schema-types.test.tsx +0 -152
  185. package/src/v2/hooks/__tests__/standard-schema.test.tsx +0 -282
  186. package/src/v2/hooks/__tests__/use-agent-context-timing.e2e.test.tsx +0 -140
  187. package/src/v2/hooks/__tests__/use-agent-context.test.tsx +0 -401
  188. package/src/v2/hooks/__tests__/use-agent-error-state.test.tsx +0 -44
  189. package/src/v2/hooks/__tests__/use-agent-stability.test.tsx +0 -211
  190. package/src/v2/hooks/__tests__/use-agent-throttle.test.tsx +0 -1029
  191. package/src/v2/hooks/__tests__/use-agent.e2e.test.tsx +0 -159
  192. package/src/v2/hooks/__tests__/use-attachments.test.tsx +0 -169
  193. package/src/v2/hooks/__tests__/use-capabilities.test.tsx +0 -76
  194. package/src/v2/hooks/__tests__/use-component.test.tsx +0 -126
  195. package/src/v2/hooks/__tests__/use-configure-suggestions.e2e.test.tsx +0 -696
  196. package/src/v2/hooks/__tests__/use-default-render-tool.test.tsx +0 -153
  197. package/src/v2/hooks/__tests__/use-frontend-tool-available.test.tsx +0 -167
  198. package/src/v2/hooks/__tests__/use-frontend-tool.e2e.test.tsx +0 -2148
  199. package/src/v2/hooks/__tests__/use-human-in-the-loop.e2e.test.tsx +0 -1261
  200. package/src/v2/hooks/__tests__/use-interrupt.test.tsx +0 -397
  201. package/src/v2/hooks/__tests__/use-katex-styles.test.tsx +0 -56
  202. package/src/v2/hooks/__tests__/use-keyboard-height.test.tsx +0 -192
  203. package/src/v2/hooks/__tests__/use-pin-to-send.test.tsx +0 -219
  204. package/src/v2/hooks/__tests__/use-render-custom-messages.test.tsx +0 -55
  205. package/src/v2/hooks/__tests__/use-render-tool.test.tsx +0 -259
  206. package/src/v2/hooks/__tests__/use-suggestions.e2e.test.tsx +0 -524
  207. package/src/v2/hooks/__tests__/use-threads.test.tsx +0 -757
  208. package/src/v2/hooks/__tests__/zod-regression.test.tsx +0 -311
  209. package/src/v2/hooks/index.ts +0 -24
  210. package/src/v2/hooks/use-agent-context.tsx +0 -45
  211. package/src/v2/hooks/use-agent.tsx +0 -227
  212. package/src/v2/hooks/use-attachments.tsx +0 -269
  213. package/src/v2/hooks/use-capabilities.tsx +0 -25
  214. package/src/v2/hooks/use-component.tsx +0 -91
  215. package/src/v2/hooks/use-configure-suggestions.tsx +0 -236
  216. package/src/v2/hooks/use-default-render-tool.tsx +0 -271
  217. package/src/v2/hooks/use-frontend-tool.tsx +0 -46
  218. package/src/v2/hooks/use-human-in-the-loop.tsx +0 -81
  219. package/src/v2/hooks/use-interrupt.tsx +0 -305
  220. package/src/v2/hooks/use-keyboard-height.tsx +0 -67
  221. package/src/v2/hooks/use-pin-to-send.ts +0 -94
  222. package/src/v2/hooks/use-render-activity-message.tsx +0 -72
  223. package/src/v2/hooks/use-render-custom-messages.tsx +0 -93
  224. package/src/v2/hooks/use-render-tool-call.tsx +0 -208
  225. package/src/v2/hooks/use-render-tool.tsx +0 -184
  226. package/src/v2/hooks/use-suggestions.tsx +0 -91
  227. package/src/v2/hooks/use-threads.tsx +0 -325
  228. package/src/v2/hooks/useKatexStyles.ts +0 -27
  229. package/src/v2/index.css +0 -1
  230. package/src/v2/index.ts +0 -27
  231. package/src/v2/lib/__tests__/completePartialMarkdown.test.ts +0 -495
  232. package/src/v2/lib/__tests__/processPartialHtml.test.ts +0 -112
  233. package/src/v2/lib/__tests__/renderSlot.test.tsx +0 -588
  234. package/src/v2/lib/__tests__/slots.test.ts +0 -56
  235. package/src/v2/lib/processPartialHtml.ts +0 -45
  236. package/src/v2/lib/react-core.ts +0 -156
  237. package/src/v2/lib/slots.tsx +0 -184
  238. package/src/v2/lib/transcription-client.ts +0 -184
  239. package/src/v2/lib/utils.ts +0 -8
  240. package/src/v2/providers/CopilotChatConfigurationProvider.tsx +0 -196
  241. package/src/v2/providers/CopilotKitProvider.tsx +0 -800
  242. package/src/v2/providers/SandboxFunctionsContext.ts +0 -10
  243. package/src/v2/providers/__tests__/CopilotChatConfigurationProvider.test.tsx +0 -652
  244. package/src/v2/providers/__tests__/CopilotKitProvider.license.test.tsx +0 -101
  245. package/src/v2/providers/__tests__/CopilotKitProvider.onError.test.tsx +0 -69
  246. package/src/v2/providers/__tests__/CopilotKitProvider.renderCustomMessages.e2e.test.tsx +0 -881
  247. package/src/v2/providers/__tests__/CopilotKitProvider.sandboxFunctions.test.tsx +0 -198
  248. package/src/v2/providers/__tests__/CopilotKitProvider.stability.test.tsx +0 -740
  249. package/src/v2/providers/__tests__/CopilotKitProvider.test.tsx +0 -713
  250. package/src/v2/providers/__tests__/CopilotKitProvider.wildcard.test.tsx +0 -294
  251. package/src/v2/providers/index.ts +0 -21
  252. package/src/v2/styles/globals.css +0 -349
  253. package/src/v2/types/__tests__/defineToolCallRenderer.test.tsx +0 -525
  254. package/src/v2/types/defineToolCallRenderer.ts +0 -68
  255. package/src/v2/types/frontend-tool.ts +0 -8
  256. package/src/v2/types/human-in-the-loop.ts +0 -33
  257. package/src/v2/types/index.ts +0 -8
  258. package/src/v2/types/interrupt.ts +0 -15
  259. package/src/v2/types/react-activity-message-renderer.ts +0 -27
  260. package/src/v2/types/react-custom-message-renderer.ts +0 -17
  261. package/src/v2/types/react-tool-call-renderer.ts +0 -35
  262. package/src/v2/types/sandbox-function.ts +0 -11
  263. package/tsconfig.json +0 -8
  264. package/tsdown.config.ts +0 -193
  265. package/typedoc.json +0 -4
  266. package/vitest.config.mjs +0 -31
@@ -1,159 +0,0 @@
1
- import React from "react";
2
- import { screen, fireEvent, waitFor } from "@testing-library/react";
3
- import { describe, it, expect } from "vitest";
4
- import { type BaseEvent, type RunAgentInput } from "@ag-ui/client";
5
- import { Observable } from "rxjs";
6
- import {
7
- MockStepwiseAgent,
8
- renderWithCopilotKit,
9
- runStartedEvent,
10
- runFinishedEvent,
11
- textChunkEvent,
12
- testId,
13
- } from "../../__tests__/utils/test-helpers";
14
- import { useAgent } from "../use-agent";
15
- import { useCopilotKit } from "../../providers/CopilotKitProvider";
16
- import { CopilotChat } from "../../components/chat/CopilotChat";
17
-
18
- /**
19
- * Mock agent that captures RunAgentInput to verify state is passed correctly
20
- */
21
- class StateCapturingMockAgent extends MockStepwiseAgent {
22
- // Shared via a container so the clone and original both see the same value
23
- private _capture: { lastRunInput?: RunAgentInput } = {};
24
-
25
- get lastRunInput(): RunAgentInput | undefined {
26
- return this._capture.lastRunInput;
27
- }
28
-
29
- clone(): this {
30
- const cloned = super.clone();
31
- (cloned as unknown as StateCapturingMockAgent)._capture = this._capture;
32
- return cloned;
33
- }
34
-
35
- run(input: RunAgentInput): Observable<BaseEvent> {
36
- this._capture.lastRunInput = input;
37
- return super.run(input);
38
- }
39
- }
40
-
41
- describe("useAgent e2e", () => {
42
- describe("setState passes state to agent run", () => {
43
- it("agent receives state set via setState when runAgent is called", async () => {
44
- const agent = new StateCapturingMockAgent();
45
-
46
- /**
47
- * Test component that:
48
- * 1. Gets agent via useAgent()
49
- * 2. Gets copilotkit via useCopilotKit()
50
- * 3. Sets state on agent and calls runAgent
51
- */
52
- function StateTestComponent() {
53
- const { agent: hookAgent } = useAgent();
54
- const { copilotkit } = useCopilotKit();
55
-
56
- const handleSetStateAndRun = async () => {
57
- hookAgent.setState({ testKey: "testValue", counter: 42 });
58
- await copilotkit.runAgent({ agent: hookAgent });
59
- };
60
-
61
- return (
62
- <button data-testid="trigger-btn" onClick={handleSetStateAndRun}>
63
- Set State and Run
64
- </button>
65
- );
66
- }
67
-
68
- renderWithCopilotKit({
69
- agent,
70
- children: <StateTestComponent />,
71
- });
72
-
73
- // Click the button to set state and trigger runAgent
74
- const triggerBtn = await screen.findByTestId("trigger-btn");
75
- fireEvent.click(triggerBtn);
76
-
77
- // Wait for the agent's run method to be called
78
- await waitFor(() => {
79
- expect(agent.lastRunInput).toBeDefined();
80
- });
81
-
82
- // Complete the agent run
83
- agent.emit(runStartedEvent());
84
- agent.emit(runFinishedEvent());
85
- agent.complete();
86
-
87
- // Verify the state was passed to the agent
88
- expect(agent.lastRunInput?.state).toEqual({
89
- testKey: "testValue",
90
- counter: 42,
91
- });
92
- });
93
- });
94
-
95
- describe("addMessage + runAgent displays in CopilotChat", () => {
96
- it("messages added via useAgent show up in CopilotChat", async () => {
97
- const agent = new MockStepwiseAgent();
98
-
99
- /**
100
- * Test component that:
101
- * 1. Gets agent via useAgent()
102
- * 2. Gets copilotkit via useCopilotKit()
103
- * 3. Adds a user message and calls runAgent
104
- */
105
- function MessageTestComponent() {
106
- const { agent: hookAgent } = useAgent();
107
- const { copilotkit } = useCopilotKit();
108
-
109
- const handleAddMessageAndRun = async () => {
110
- hookAgent.addMessage({
111
- id: testId("user-msg"),
112
- role: "user",
113
- content: "Hello from useAgent!",
114
- });
115
- await copilotkit.runAgent({ agent: hookAgent });
116
- };
117
-
118
- return (
119
- <div>
120
- <button data-testid="send-btn" onClick={handleAddMessageAndRun}>
121
- Send Message
122
- </button>
123
- <div style={{ height: 400 }}>
124
- <CopilotChat />
125
- </div>
126
- </div>
127
- );
128
- }
129
-
130
- renderWithCopilotKit({
131
- agent,
132
- children: <MessageTestComponent />,
133
- });
134
-
135
- // Click the button to add message and trigger runAgent
136
- const sendBtn = await screen.findByTestId("send-btn");
137
- fireEvent.click(sendBtn);
138
-
139
- // User message should appear in the chat
140
- await waitFor(() => {
141
- expect(screen.getByText("Hello from useAgent!")).toBeDefined();
142
- });
143
-
144
- // Simulate agent response
145
- const responseId = testId("assistant-msg");
146
- agent.emit(runStartedEvent());
147
- agent.emit(textChunkEvent(responseId, "Hello! I received your message."));
148
- agent.emit(runFinishedEvent());
149
- agent.complete();
150
-
151
- // Assistant response should appear in the chat
152
- await waitFor(() => {
153
- expect(
154
- screen.getByText("Hello! I received your message."),
155
- ).toBeDefined();
156
- });
157
- });
158
- });
159
- });
@@ -1,169 +0,0 @@
1
- import React, { useRef, useEffect } from "react";
2
- import { renderHook, act } from "@testing-library/react";
3
- import { describe, it, expect, vi } from "vitest";
4
- import { useAttachments } from "../use-attachments";
5
-
6
- describe("useAttachments", () => {
7
- // -----------------------------------------------------------------------
8
- // Referential stability — callbacks must not change between renders
9
- // -----------------------------------------------------------------------
10
-
11
- describe("referential stability", () => {
12
- it("all callbacks are stable across re-renders with same config", () => {
13
- const config = { enabled: true, accept: "image/*" };
14
- const { result, rerender } = renderHook(() => useAttachments({ config }));
15
-
16
- const first = result.current;
17
- rerender();
18
- const second = result.current;
19
-
20
- expect(second.processFiles).toBe(first.processFiles);
21
- expect(second.handleFileUpload).toBe(first.handleFileUpload);
22
- expect(second.handleDragOver).toBe(first.handleDragOver);
23
- expect(second.handleDragLeave).toBe(first.handleDragLeave);
24
- expect(second.handleDrop).toBe(first.handleDrop);
25
- expect(second.removeAttachment).toBe(first.removeAttachment);
26
- expect(second.consumeAttachments).toBe(first.consumeAttachments);
27
- });
28
-
29
- it("callbacks remain stable when config object reference changes", () => {
30
- let config = { enabled: true, accept: "image/*" };
31
- const { result, rerender } = renderHook(() => useAttachments({ config }));
32
-
33
- const first = result.current;
34
-
35
- // Create a new config with same values — different reference
36
- config = { enabled: true, accept: "image/*" };
37
- rerender();
38
- const second = result.current;
39
-
40
- expect(second.processFiles).toBe(first.processFiles);
41
- expect(second.handleFileUpload).toBe(first.handleFileUpload);
42
- expect(second.handleDragOver).toBe(first.handleDragOver);
43
- expect(second.handleDragLeave).toBe(first.handleDragLeave);
44
- expect(second.handleDrop).toBe(first.handleDrop);
45
- expect(second.removeAttachment).toBe(first.removeAttachment);
46
- expect(second.consumeAttachments).toBe(first.consumeAttachments);
47
- });
48
-
49
- it("refs are stable across re-renders", () => {
50
- const { result, rerender } = renderHook(() =>
51
- useAttachments({ config: undefined }),
52
- );
53
-
54
- const first = result.current;
55
- rerender();
56
- const second = result.current;
57
-
58
- expect(second.fileInputRef).toBe(first.fileInputRef);
59
- expect(second.containerRef).toBe(first.containerRef);
60
- });
61
- });
62
-
63
- // -----------------------------------------------------------------------
64
- // Re-render counting — hook should not cause unnecessary renders
65
- // -----------------------------------------------------------------------
66
-
67
- describe("re-render counting", () => {
68
- it("does not re-render when consumeAttachments is called on empty queue", () => {
69
- let renderCount = 0;
70
-
71
- const { result } = renderHook(() => {
72
- renderCount++;
73
- return useAttachments({ config: undefined });
74
- });
75
-
76
- const initialRenderCount = renderCount;
77
-
78
- act(() => {
79
- result.current.consumeAttachments();
80
- });
81
-
82
- // consumeAttachments on empty queue should not trigger a state update
83
- expect(renderCount).toBe(initialRenderCount);
84
- });
85
-
86
- it("does not re-render on repeated consumeAttachments with empty queue", () => {
87
- let renderCount = 0;
88
-
89
- const { result } = renderHook(() => {
90
- renderCount++;
91
- return useAttachments({ config: undefined });
92
- });
93
-
94
- const initialRenderCount = renderCount;
95
-
96
- act(() => {
97
- result.current.consumeAttachments();
98
- result.current.consumeAttachments();
99
- result.current.consumeAttachments();
100
- });
101
-
102
- expect(renderCount).toBe(initialRenderCount);
103
- });
104
- });
105
-
106
- // -----------------------------------------------------------------------
107
- // State defaults
108
- // -----------------------------------------------------------------------
109
-
110
- describe("initial state", () => {
111
- it("returns empty attachments and disabled by default", () => {
112
- const { result } = renderHook(() =>
113
- useAttachments({ config: undefined }),
114
- );
115
-
116
- expect(result.current.attachments).toEqual([]);
117
- expect(result.current.enabled).toBe(false);
118
- expect(result.current.dragOver).toBe(false);
119
- });
120
-
121
- it("returns enabled when config.enabled is true", () => {
122
- const { result } = renderHook(() =>
123
- useAttachments({ config: { enabled: true } }),
124
- );
125
-
126
- expect(result.current.enabled).toBe(true);
127
- });
128
- });
129
-
130
- // -----------------------------------------------------------------------
131
- // consumeAttachments behavior
132
- // -----------------------------------------------------------------------
133
-
134
- describe("consumeAttachments", () => {
135
- it("returns empty array when no attachments", () => {
136
- const { result } = renderHook(() =>
137
- useAttachments({ config: undefined }),
138
- );
139
-
140
- let consumed: any[];
141
- act(() => {
142
- consumed = result.current.consumeAttachments();
143
- });
144
-
145
- expect(consumed!).toEqual([]);
146
- });
147
- });
148
-
149
- // -----------------------------------------------------------------------
150
- // removeAttachment
151
- // -----------------------------------------------------------------------
152
-
153
- describe("removeAttachment", () => {
154
- it("is a no-op when id does not exist", () => {
155
- const { result } = renderHook(() =>
156
- useAttachments({ config: undefined }),
157
- );
158
-
159
- const before = result.current.attachments;
160
-
161
- act(() => {
162
- result.current.removeAttachment("nonexistent");
163
- });
164
-
165
- // Should still be empty, no crash
166
- expect(result.current.attachments).toEqual([]);
167
- });
168
- });
169
- });
@@ -1,76 +0,0 @@
1
- import React from "react";
2
- import { renderHook } from "@testing-library/react";
3
- import { describe, it, expect, beforeEach, vi } from "vitest";
4
- import type { AgentCapabilities } from "@ag-ui/core";
5
- import { useCapabilities } from "../use-capabilities";
6
- import { useAgent } from "../use-agent";
7
-
8
- vi.mock("../use-agent", () => ({
9
- useAgent: vi.fn(),
10
- }));
11
-
12
- const mockUseAgent = useAgent as ReturnType<typeof vi.fn>;
13
-
14
- describe("useCapabilities", () => {
15
- beforeEach(() => {
16
- vi.clearAllMocks();
17
- });
18
-
19
- it("returns capabilities when agent exposes them", () => {
20
- const caps: AgentCapabilities = {
21
- tools: { supported: true, clientProvided: true },
22
- };
23
-
24
- mockUseAgent.mockReturnValue({
25
- agent: { capabilities: caps },
26
- });
27
-
28
- const { result } = renderHook(() => useCapabilities("my-agent"));
29
-
30
- expect(result.current).toEqual(caps);
31
- expect(mockUseAgent).toHaveBeenCalledWith({ agentId: "my-agent" });
32
- });
33
-
34
- it("returns undefined when agent has no capabilities property", () => {
35
- mockUseAgent.mockReturnValue({
36
- agent: { description: "basic agent" },
37
- });
38
-
39
- const { result } = renderHook(() => useCapabilities("basic"));
40
-
41
- expect(result.current).toBeUndefined();
42
- });
43
-
44
- it("returns undefined when agent is undefined (not connected yet)", () => {
45
- mockUseAgent.mockReturnValue({ agent: undefined });
46
-
47
- const { result } = renderHook(() => useCapabilities());
48
-
49
- expect(result.current).toBeUndefined();
50
- });
51
-
52
- it("returns undefined when capabilities property is explicitly undefined", () => {
53
- mockUseAgent.mockReturnValue({
54
- agent: { capabilities: undefined },
55
- });
56
-
57
- const { result } = renderHook(() => useCapabilities());
58
-
59
- expect(result.current).toBeUndefined();
60
- });
61
-
62
- it("uses default agent when no agentId is provided", () => {
63
- const caps: AgentCapabilities = {
64
- transport: { streaming: true },
65
- };
66
-
67
- mockUseAgent.mockReturnValue({
68
- agent: { capabilities: caps },
69
- });
70
-
71
- const { result } = renderHook(() => useCapabilities());
72
-
73
- expect(result.current).toEqual(caps);
74
- expect(mockUseAgent).toHaveBeenCalledWith({ agentId: undefined });
75
- });
76
- });
@@ -1,126 +0,0 @@
1
- import React from "react";
2
- import { render } from "@testing-library/react";
3
- import { describe, it, expect, beforeEach, vi } from "vitest";
4
- import { z } from "zod";
5
- import { useComponent } from "../use-component";
6
- import { useFrontendTool } from "../use-frontend-tool";
7
-
8
- vi.mock("../use-frontend-tool", () => ({
9
- useFrontendTool: vi.fn(),
10
- }));
11
-
12
- const mockUseFrontendTool = useFrontendTool as ReturnType<typeof vi.fn>;
13
-
14
- describe("useComponent", () => {
15
- beforeEach(() => {
16
- vi.clearAllMocks();
17
- });
18
-
19
- it("registers a component tool with generated default description", () => {
20
- const DemoComponent: React.FC<{ city: string }> = ({ city }) => (
21
- <div>{city}</div>
22
- );
23
-
24
- const Harness: React.FC = () => {
25
- useComponent({
26
- name: "showWeatherCard",
27
- render: DemoComponent,
28
- });
29
- return null;
30
- };
31
-
32
- render(<Harness />);
33
-
34
- expect(mockUseFrontendTool).toHaveBeenCalledTimes(1);
35
- const [toolConfig] = mockUseFrontendTool.mock.calls[0] as [
36
- {
37
- name: string;
38
- description: string;
39
- },
40
- ];
41
-
42
- expect(toolConfig.name).toBe("showWeatherCard");
43
- expect(toolConfig.description).toContain(
44
- 'Use this tool to display the "showWeatherCard" component in the chat.',
45
- );
46
- });
47
-
48
- it("appends custom description and forwards parameters, agentId, deps, and followUp", () => {
49
- const weatherSchema = z.object({
50
- city: z.string(),
51
- unit: z.enum(["c", "f"]),
52
- });
53
-
54
- const DemoComponent: React.FC<z.infer<typeof weatherSchema>> = ({
55
- city,
56
- }) => <div>{city}</div>;
57
-
58
- const deps = ["v1"] as const;
59
-
60
- const Harness: React.FC = () => {
61
- useComponent(
62
- {
63
- name: "showWeatherCard",
64
- description: "Render a weather card for the selected city.",
65
- parameters: weatherSchema,
66
- render: DemoComponent,
67
- agentId: "weather-agent",
68
- followUp: false,
69
- },
70
- deps,
71
- );
72
- return null;
73
- };
74
-
75
- render(<Harness />);
76
-
77
- expect(mockUseFrontendTool).toHaveBeenCalledTimes(1);
78
- const [toolConfig, forwardedDeps] = mockUseFrontendTool.mock.calls[0] as [
79
- {
80
- description: string;
81
- parameters: typeof weatherSchema;
82
- agentId?: string;
83
- followUp?: boolean;
84
- },
85
- ReadonlyArray<unknown>,
86
- ];
87
-
88
- expect(toolConfig.description).toContain(
89
- 'Use this tool to display the "showWeatherCard" component in the chat.',
90
- );
91
- expect(toolConfig.description).toContain(
92
- "Render a weather card for the selected city.",
93
- );
94
- expect(toolConfig.parameters).toBe(weatherSchema);
95
- expect(toolConfig.agentId).toBe("weather-agent");
96
- expect(toolConfig.followUp).toBe(false);
97
- expect(forwardedDeps).toBe(deps);
98
- });
99
-
100
- it("creates a render function that passes args into the component", () => {
101
- const DemoComponent: React.FC<{ city: string }> = ({ city }) => (
102
- <div data-testid="city">{city}</div>
103
- );
104
-
105
- const Harness: React.FC = () => {
106
- useComponent({
107
- name: "showWeatherCard",
108
- render: DemoComponent,
109
- });
110
- return null;
111
- };
112
-
113
- render(<Harness />);
114
-
115
- const [toolConfig] = mockUseFrontendTool.mock.calls[0] as [
116
- {
117
- render: (props: { args: { city: string } }) => React.ReactElement;
118
- },
119
- ];
120
-
121
- const { getByTestId } = render(
122
- toolConfig.render({ args: { city: "Paris" } }),
123
- );
124
- expect(getByTestId("city").textContent).toBe("Paris");
125
- });
126
- });