@copilotkit/react-core 1.57.3 → 1.58.0-canary.thread-id-propagation
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/dist/{copilotkit-CtXcs1ea.cjs → copilotkit-B4ouY7qC.cjs} +14 -3
- package/dist/copilotkit-B4ouY7qC.cjs.map +1 -0
- package/dist/copilotkit-BK9CVq9A.d.cts.map +1 -1
- package/dist/{copilotkit-CC8DjOiC.mjs → copilotkit-L4mM_JqG.mjs} +14 -3
- package/dist/copilotkit-L4mM_JqG.mjs.map +1 -0
- package/dist/copilotkit-WlmeVijs.d.mts.map +1 -1
- package/dist/index.cjs +3 -77
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +2 -2
- package/dist/index.d.mts +2 -2
- package/dist/index.mjs +3 -77
- package/dist/index.mjs.map +1 -1
- package/dist/index.umd.js +15 -78
- package/dist/index.umd.js.map +1 -1
- package/dist/v2/headless.cjs +11 -0
- package/dist/v2/headless.cjs.map +1 -1
- package/dist/v2/headless.d.cts.map +1 -1
- package/dist/v2/headless.d.mts.map +1 -1
- package/dist/v2/headless.mjs +11 -0
- package/dist/v2/headless.mjs.map +1 -1
- package/dist/v2/index.cjs +1 -1
- package/dist/v2/index.mjs +1 -1
- package/dist/v2/index.umd.js +13 -2
- package/dist/v2/index.umd.js.map +1 -1
- package/package.json +12 -13
- package/skills/react-core/SKILL.md +108 -0
- package/skills/react-core/references/agent-access.md +288 -0
- package/skills/react-core/references/attachments.md +291 -0
- package/skills/react-core/references/capabilities.md +138 -0
- package/skills/react-core/references/chat-components.md +221 -0
- package/skills/react-core/references/client-side-tools.md +358 -0
- package/skills/react-core/references/custom-message-renderers.md +226 -0
- package/skills/react-core/references/debug-mode.md +153 -0
- package/skills/react-core/references/human-in-the-loop.md +312 -0
- package/skills/react-core/references/provider-setup.md +326 -0
- package/skills/react-core/references/rendering-activity-messages.md +207 -0
- package/skills/react-core/references/rendering-tool-calls.md +319 -0
- package/skills/react-core/references/suggestions.md +211 -0
- package/skills/react-core/references/switching-agents-recipes.md +160 -0
- package/skills/react-core/references/switching-agents.md +231 -0
- package/skills/react-core/references/threads.md +226 -0
- package/.attw.json +0 -3
- package/CHANGELOG.md +0 -5043
- package/dist/copilotkit-CC8DjOiC.mjs.map +0 -1
- package/dist/copilotkit-CtXcs1ea.cjs.map +0 -1
- package/scripts/scope-preflight.mjs +0 -100
- package/src/components/CopilotListeners.tsx +0 -137
- package/src/components/__tests__/CopilotListeners.test.tsx +0 -38
- package/src/components/copilot-provider/__tests__/copilot-messages-key.test.tsx +0 -92
- package/src/components/copilot-provider/__tests__/copilotkit-error.test.tsx +0 -77
- package/src/components/copilot-provider/__tests__/error-visibility-prod.test.tsx +0 -70
- package/src/components/copilot-provider/__tests__/v1-explicit-threadid-bridge.test.tsx +0 -107
- package/src/components/copilot-provider/copilot-messages.tsx +0 -314
- package/src/components/copilot-provider/copilotkit-props.tsx +0 -214
- package/src/components/copilot-provider/copilotkit.tsx +0 -853
- package/src/components/copilot-provider/index.ts +0 -3
- package/src/components/dev-console/console-trigger.tsx +0 -283
- package/src/components/dev-console/developer-console-modal.tsx +0 -1016
- package/src/components/dev-console/icons.tsx +0 -106
- package/src/components/error-boundary/error-boundary.tsx +0 -99
- package/src/components/error-boundary/error-utils.tsx +0 -105
- package/src/components/index.ts +0 -1
- package/src/components/toast/exclamation-mark-icon.tsx +0 -27
- package/src/components/toast/toast-provider.tsx +0 -448
- package/src/components/usage-banner.tsx +0 -266
- package/src/context/__tests__/threads-context.test.tsx +0 -141
- package/src/context/coagent-state-renders-context.tsx +0 -89
- package/src/context/copilot-context.tsx +0 -365
- package/src/context/copilot-messages-context.tsx +0 -35
- package/src/context/index.ts +0 -22
- package/src/context/threads-context.tsx +0 -69
- package/src/hooks/__tests__/use-coagent-config.test.ts +0 -352
- package/src/hooks/__tests__/use-coagent-state-render-bridge.helpers.test.ts +0 -107
- package/src/hooks/__tests__/use-coagent-state-render.e2e.test.tsx +0 -1209
- package/src/hooks/__tests__/use-coagent-state-render.test.tsx +0 -356
- package/src/hooks/__tests__/use-copilot-chat-internal-connect.test.tsx +0 -241
- package/src/hooks/__tests__/use-frontend-tool-available.test.tsx +0 -72
- package/src/hooks/__tests__/use-frontend-tool-remount.e2e.test.tsx +0 -102
- package/src/hooks/index.ts +0 -33
- package/src/hooks/use-agent-nodename.ts +0 -33
- package/src/hooks/use-coagent-state-render-bridge.helpers.ts +0 -345
- package/src/hooks/use-coagent-state-render-bridge.tsx +0 -222
- package/src/hooks/use-coagent-state-render-registry.ts +0 -230
- package/src/hooks/use-coagent-state-render.ts +0 -163
- package/src/hooks/use-coagent.ts +0 -377
- package/src/hooks/use-configure-chat-suggestions.tsx +0 -96
- package/src/hooks/use-copilot-action.ts +0 -245
- package/src/hooks/use-copilot-additional-instructions.ts +0 -98
- package/src/hooks/use-copilot-authenticated-action.ts +0 -73
- package/src/hooks/use-copilot-chat-headless_c.ts +0 -264
- package/src/hooks/use-copilot-chat-suggestions.tsx +0 -134
- package/src/hooks/use-copilot-chat.ts +0 -132
- package/src/hooks/use-copilot-chat_internal.ts +0 -875
- package/src/hooks/use-copilot-readable.ts +0 -135
- package/src/hooks/use-copilot-runtime-client.ts +0 -178
- package/src/hooks/use-default-tool.ts +0 -13
- package/src/hooks/use-flat-category-store.ts +0 -109
- package/src/hooks/use-frontend-tool.ts +0 -113
- package/src/hooks/use-human-in-the-loop.ts +0 -138
- package/src/hooks/use-langgraph-interrupt.ts +0 -103
- package/src/hooks/use-lazy-tool-renderer.tsx +0 -30
- package/src/hooks/use-make-copilot-document-readable.ts +0 -30
- package/src/hooks/use-render-tool-call.ts +0 -89
- package/src/hooks/use-tree.ts +0 -222
- package/src/index.tsx +0 -7
- package/src/lib/copilot-task.ts +0 -215
- package/src/lib/index.ts +0 -1
- package/src/lib/status-checker.ts +0 -67
- package/src/setupTests.ts +0 -37
- package/src/test-helpers/copilot-context.ts +0 -91
- package/src/types/chat-suggestion-configuration.ts +0 -23
- package/src/types/coagent-action.ts +0 -35
- package/src/types/coagent-state.ts +0 -13
- package/src/types/crew.ts +0 -89
- package/src/types/document-pointer.ts +0 -7
- package/src/types/frontend-action.ts +0 -213
- package/src/types/index.ts +0 -17
- package/src/types/interrupt-action.ts +0 -58
- package/src/types/system-message.ts +0 -4
- package/src/utils/dev-console.ts +0 -19
- package/src/utils/index.ts +0 -2
- package/src/utils/suggestions-constants.ts +0 -8
- package/src/utils/utils.test.ts +0 -7
- package/src/utils/utils.ts +0 -6
- package/src/v2/__tests__/A2UIMessageRenderer.test.tsx +0 -240
- package/src/v2/__tests__/globalSetup.ts +0 -14
- package/src/v2/__tests__/setup.ts +0 -93
- package/src/v2/__tests__/utils/test-helpers.tsx +0 -570
- package/src/v2/a2ui/A2UICatalogContext.tsx +0 -79
- package/src/v2/a2ui/A2UIMessageRenderer.tsx +0 -294
- package/src/v2/a2ui/A2UIToolCallRenderer.tsx +0 -290
- package/src/v2/components/CopilotKitInspector.tsx +0 -52
- package/src/v2/components/MCPAppsActivityRenderer.tsx +0 -815
- package/src/v2/components/OpenGenerativeUIRenderer.tsx +0 -598
- package/src/v2/components/WildcardToolCallRender.tsx +0 -86
- package/src/v2/components/__tests__/OpenGenerativeUIRenderer.test.tsx +0 -665
- package/src/v2/components/chat/CopilotChat.tsx +0 -664
- package/src/v2/components/chat/CopilotChatAssistantMessage.tsx +0 -393
- package/src/v2/components/chat/CopilotChatAttachmentQueue.tsx +0 -374
- package/src/v2/components/chat/CopilotChatAttachmentRenderer.tsx +0 -159
- package/src/v2/components/chat/CopilotChatAudioRecorder.tsx +0 -350
- package/src/v2/components/chat/CopilotChatInput.tsx +0 -1412
- package/src/v2/components/chat/CopilotChatMessageView.tsx +0 -716
- package/src/v2/components/chat/CopilotChatReasoningMessage.tsx +0 -265
- package/src/v2/components/chat/CopilotChatSuggestionPill.tsx +0 -59
- package/src/v2/components/chat/CopilotChatSuggestionView.tsx +0 -134
- package/src/v2/components/chat/CopilotChatToggleButton.tsx +0 -171
- package/src/v2/components/chat/CopilotChatToolCallsView.tsx +0 -40
- package/src/v2/components/chat/CopilotChatUserMessage.tsx +0 -445
- package/src/v2/components/chat/CopilotChatView.tsx +0 -890
- package/src/v2/components/chat/CopilotModalHeader.tsx +0 -129
- package/src/v2/components/chat/CopilotPopup.tsx +0 -81
- package/src/v2/components/chat/CopilotPopupView.tsx +0 -317
- package/src/v2/components/chat/CopilotSidebar.tsx +0 -80
- package/src/v2/components/chat/CopilotSidebarView.tsx +0 -269
- package/src/v2/components/chat/Lightbox.tsx +0 -103
- package/src/v2/components/chat/__tests__/CopilotChat.absentThreadConnect.test.tsx +0 -66
- package/src/v2/components/chat/__tests__/CopilotChat.attachments.test.tsx +0 -168
- package/src/v2/components/chat/__tests__/CopilotChat.e2e.test.tsx +0 -1239
- package/src/v2/components/chat/__tests__/CopilotChat.onError.test.tsx +0 -73
- package/src/v2/components/chat/__tests__/CopilotChat.slots.e2e.test.tsx +0 -432
- package/src/v2/components/chat/__tests__/CopilotChat.suggestionsAlways.test.tsx +0 -183
- package/src/v2/components/chat/__tests__/CopilotChat.welcomeGate.test.tsx +0 -184
- package/src/v2/components/chat/__tests__/CopilotChatActivityRendering.e2e.test.tsx +0 -649
- package/src/v2/components/chat/__tests__/CopilotChatAssistantMessage.slots.e2e.test.tsx +0 -624
- package/src/v2/components/chat/__tests__/CopilotChatAssistantMessage.test.tsx +0 -702
- package/src/v2/components/chat/__tests__/CopilotChatAssistantMessage.thumbs.test.tsx +0 -72
- package/src/v2/components/chat/__tests__/CopilotChatCopyButton.clipboard.test.tsx +0 -241
- package/src/v2/components/chat/__tests__/CopilotChatCssClasses.test.tsx +0 -107
- package/src/v2/components/chat/__tests__/CopilotChatInput.slots.e2e.test.tsx +0 -929
- package/src/v2/components/chat/__tests__/CopilotChatInput.test.tsx +0 -1567
- package/src/v2/components/chat/__tests__/CopilotChatMessageView.slots.e2e.test.tsx +0 -1004
- package/src/v2/components/chat/__tests__/CopilotChatMessageView.test.tsx +0 -279
- package/src/v2/components/chat/__tests__/CopilotChatPerf.e2e.test.tsx +0 -336
- package/src/v2/components/chat/__tests__/CopilotChatPropsRerender.e2e.test.tsx +0 -249
- package/src/v2/components/chat/__tests__/CopilotChatSuggestionView.slots.e2e.test.tsx +0 -530
- package/src/v2/components/chat/__tests__/CopilotChatToolRendering.e2e.test.tsx +0 -785
- package/src/v2/components/chat/__tests__/CopilotChatToolRerenders.e2e.test.tsx +0 -2416
- package/src/v2/components/chat/__tests__/CopilotChatUserMessage.slots.e2e.test.tsx +0 -621
- package/src/v2/components/chat/__tests__/CopilotChatView.connectingGate.test.tsx +0 -56
- package/src/v2/components/chat/__tests__/CopilotChatView.inputOverlay.test.tsx +0 -264
- package/src/v2/components/chat/__tests__/CopilotChatView.onClick.e2e.test.tsx +0 -853
- package/src/v2/components/chat/__tests__/CopilotChatView.pinToSend.test.tsx +0 -94
- package/src/v2/components/chat/__tests__/CopilotChatView.slots.e2e.test.tsx +0 -1050
- package/src/v2/components/chat/__tests__/CopilotModalHeader.slots.e2e.test.tsx +0 -484
- package/src/v2/components/chat/__tests__/CopilotPopupView.slots.e2e.test.tsx +0 -612
- package/src/v2/components/chat/__tests__/CopilotSidebarView.position.test.tsx +0 -159
- package/src/v2/components/chat/__tests__/CopilotSidebarView.slots.e2e.test.tsx +0 -502
- package/src/v2/components/chat/__tests__/MCPAppsActivityRenderer.e2e.test.tsx +0 -1068
- package/src/v2/components/chat/__tests__/MCPAppsProxy.e2e.test.tsx +0 -589
- package/src/v2/components/chat/__tests__/MCPAppsUiMessage.e2e.test.tsx +0 -403
- package/src/v2/components/chat/__tests__/copilot-chat-throttle.test.tsx +0 -137
- package/src/v2/components/chat/__tests__/normalize-auto-scroll.test.ts +0 -37
- package/src/v2/components/chat/__tests__/setup.ts +0 -1
- package/src/v2/components/chat/index.ts +0 -90
- package/src/v2/components/chat/last-user-message-context.ts +0 -21
- package/src/v2/components/chat/normalize-auto-scroll.ts +0 -17
- package/src/v2/components/chat/scroll-element-context.ts +0 -13
- package/src/v2/components/index.ts +0 -8
- package/src/v2/components/intelligence-indicator/IntelligenceIndicator.tsx +0 -286
- package/src/v2/components/intelligence-indicator/__tests__/IntelligenceIndicator.e2e.test.tsx +0 -464
- package/src/v2/components/intelligence-indicator/index.ts +0 -2
- package/src/v2/components/license-warning-banner.tsx +0 -217
- package/src/v2/components/ui/button.tsx +0 -124
- package/src/v2/components/ui/dropdown-menu.tsx +0 -258
- package/src/v2/components/ui/tooltip.tsx +0 -60
- package/src/v2/context.ts +0 -62
- package/src/v2/headless.ts +0 -64
- package/src/v2/hooks/__tests__/standard-schema-types.test.tsx +0 -152
- package/src/v2/hooks/__tests__/standard-schema.test.tsx +0 -282
- package/src/v2/hooks/__tests__/use-agent-context-timing.e2e.test.tsx +0 -140
- package/src/v2/hooks/__tests__/use-agent-context.test.tsx +0 -401
- package/src/v2/hooks/__tests__/use-agent-error-state.test.tsx +0 -44
- package/src/v2/hooks/__tests__/use-agent-stability.test.tsx +0 -211
- package/src/v2/hooks/__tests__/use-agent-throttle.test.tsx +0 -1029
- package/src/v2/hooks/__tests__/use-agent.e2e.test.tsx +0 -159
- package/src/v2/hooks/__tests__/use-attachments.test.tsx +0 -169
- package/src/v2/hooks/__tests__/use-capabilities.test.tsx +0 -76
- package/src/v2/hooks/__tests__/use-component.test.tsx +0 -126
- package/src/v2/hooks/__tests__/use-configure-suggestions.e2e.test.tsx +0 -696
- package/src/v2/hooks/__tests__/use-default-render-tool.test.tsx +0 -153
- package/src/v2/hooks/__tests__/use-frontend-tool-available.test.tsx +0 -167
- package/src/v2/hooks/__tests__/use-frontend-tool.e2e.test.tsx +0 -2148
- package/src/v2/hooks/__tests__/use-human-in-the-loop.e2e.test.tsx +0 -1261
- package/src/v2/hooks/__tests__/use-interrupt.test.tsx +0 -397
- package/src/v2/hooks/__tests__/use-katex-styles.test.tsx +0 -56
- package/src/v2/hooks/__tests__/use-keyboard-height.test.tsx +0 -192
- package/src/v2/hooks/__tests__/use-pin-to-send.test.tsx +0 -219
- package/src/v2/hooks/__tests__/use-render-custom-messages.test.tsx +0 -55
- package/src/v2/hooks/__tests__/use-render-tool.test.tsx +0 -259
- package/src/v2/hooks/__tests__/use-suggestions.e2e.test.tsx +0 -524
- package/src/v2/hooks/__tests__/use-threads.test.tsx +0 -757
- package/src/v2/hooks/__tests__/zod-regression.test.tsx +0 -311
- package/src/v2/hooks/index.ts +0 -24
- package/src/v2/hooks/use-agent-context.tsx +0 -45
- package/src/v2/hooks/use-agent.tsx +0 -227
- package/src/v2/hooks/use-attachments.tsx +0 -269
- package/src/v2/hooks/use-capabilities.tsx +0 -25
- package/src/v2/hooks/use-component.tsx +0 -91
- package/src/v2/hooks/use-configure-suggestions.tsx +0 -236
- package/src/v2/hooks/use-default-render-tool.tsx +0 -271
- package/src/v2/hooks/use-frontend-tool.tsx +0 -46
- package/src/v2/hooks/use-human-in-the-loop.tsx +0 -81
- package/src/v2/hooks/use-interrupt.tsx +0 -305
- package/src/v2/hooks/use-keyboard-height.tsx +0 -67
- package/src/v2/hooks/use-pin-to-send.ts +0 -94
- package/src/v2/hooks/use-render-activity-message.tsx +0 -72
- package/src/v2/hooks/use-render-custom-messages.tsx +0 -93
- package/src/v2/hooks/use-render-tool-call.tsx +0 -208
- package/src/v2/hooks/use-render-tool.tsx +0 -184
- package/src/v2/hooks/use-suggestions.tsx +0 -91
- package/src/v2/hooks/use-threads.tsx +0 -325
- package/src/v2/hooks/useKatexStyles.ts +0 -27
- package/src/v2/index.css +0 -1
- package/src/v2/index.ts +0 -27
- package/src/v2/lib/__tests__/completePartialMarkdown.test.ts +0 -495
- package/src/v2/lib/__tests__/processPartialHtml.test.ts +0 -112
- package/src/v2/lib/__tests__/renderSlot.test.tsx +0 -588
- package/src/v2/lib/__tests__/slots.test.ts +0 -56
- package/src/v2/lib/processPartialHtml.ts +0 -45
- package/src/v2/lib/react-core.ts +0 -156
- package/src/v2/lib/slots.tsx +0 -184
- package/src/v2/lib/transcription-client.ts +0 -184
- package/src/v2/lib/utils.ts +0 -8
- package/src/v2/providers/CopilotChatConfigurationProvider.tsx +0 -196
- package/src/v2/providers/CopilotKitProvider.tsx +0 -800
- package/src/v2/providers/SandboxFunctionsContext.ts +0 -10
- package/src/v2/providers/__tests__/CopilotChatConfigurationProvider.test.tsx +0 -652
- package/src/v2/providers/__tests__/CopilotKitProvider.license.test.tsx +0 -101
- package/src/v2/providers/__tests__/CopilotKitProvider.onError.test.tsx +0 -69
- package/src/v2/providers/__tests__/CopilotKitProvider.renderCustomMessages.e2e.test.tsx +0 -881
- package/src/v2/providers/__tests__/CopilotKitProvider.sandboxFunctions.test.tsx +0 -198
- package/src/v2/providers/__tests__/CopilotKitProvider.stability.test.tsx +0 -740
- package/src/v2/providers/__tests__/CopilotKitProvider.test.tsx +0 -713
- package/src/v2/providers/__tests__/CopilotKitProvider.wildcard.test.tsx +0 -294
- package/src/v2/providers/index.ts +0 -21
- package/src/v2/styles/globals.css +0 -349
- package/src/v2/types/__tests__/defineToolCallRenderer.test.tsx +0 -525
- package/src/v2/types/defineToolCallRenderer.ts +0 -68
- package/src/v2/types/frontend-tool.ts +0 -8
- package/src/v2/types/human-in-the-loop.ts +0 -33
- package/src/v2/types/index.ts +0 -8
- package/src/v2/types/interrupt.ts +0 -15
- package/src/v2/types/react-activity-message-renderer.ts +0 -27
- package/src/v2/types/react-custom-message-renderer.ts +0 -17
- package/src/v2/types/react-tool-call-renderer.ts +0 -35
- package/src/v2/types/sandbox-function.ts +0 -11
- package/tsconfig.json +0 -8
- package/tsdown.config.ts +0 -193
- package/typedoc.json +0 -4
- package/vitest.config.mjs +0 -31
|
@@ -0,0 +1,231 @@
|
|
|
1
|
+
# CopilotKit Switching Agents (React)
|
|
2
|
+
|
|
3
|
+
This skill builds on `copilotkit/agent-access`, `copilotkit/client-side-tools`,
|
|
4
|
+
and `copilotkit/rendering-tool-calls`.
|
|
5
|
+
|
|
6
|
+
Three main patterns:
|
|
7
|
+
|
|
8
|
+
1. **Parallel panels** — one `useAgent({ agentId })` per surface.
|
|
9
|
+
2. **Slot swap** — `<CopilotChat key={agentId} agentId={agentId} />`.
|
|
10
|
+
3. **Discovery** — subscribe to `onAgentsChanged` (no `useAgents()` hook).
|
|
11
|
+
|
|
12
|
+
## Setup
|
|
13
|
+
|
|
14
|
+
```tsx
|
|
15
|
+
"use client";
|
|
16
|
+
import { CopilotChat } from "@copilotkit/react-core/v2";
|
|
17
|
+
import { useState } from "react";
|
|
18
|
+
|
|
19
|
+
export function AgentSwitcherChat() {
|
|
20
|
+
const [activeAgent, setActiveAgent] = useState("research");
|
|
21
|
+
|
|
22
|
+
return (
|
|
23
|
+
<div>
|
|
24
|
+
<div>
|
|
25
|
+
<button onClick={() => setActiveAgent("research")}>Research</button>
|
|
26
|
+
<button onClick={() => setActiveAgent("coding")}>Coding</button>
|
|
27
|
+
</div>
|
|
28
|
+
|
|
29
|
+
{/* key={activeAgent} forces remount so thread state doesn't leak */}
|
|
30
|
+
<CopilotChat key={activeAgent} agentId={activeAgent} />
|
|
31
|
+
</div>
|
|
32
|
+
);
|
|
33
|
+
}
|
|
34
|
+
```
|
|
35
|
+
|
|
36
|
+
## Core Patterns
|
|
37
|
+
|
|
38
|
+
### Side-by-side chat panels
|
|
39
|
+
|
|
40
|
+
```tsx
|
|
41
|
+
<div className="grid grid-cols-2 gap-4">
|
|
42
|
+
<CopilotChat agentId="research" threadId="research-main" />
|
|
43
|
+
<CopilotChat agentId="coding" threadId="coding-main" />
|
|
44
|
+
</div>
|
|
45
|
+
```
|
|
46
|
+
|
|
47
|
+
### Agent-scoped tool
|
|
48
|
+
|
|
49
|
+
```tsx
|
|
50
|
+
import { useFrontendTool } from "@copilotkit/react-core/v2";
|
|
51
|
+
import { z } from "zod";
|
|
52
|
+
|
|
53
|
+
useFrontendTool({
|
|
54
|
+
name: "saveFindings",
|
|
55
|
+
agentId: "research", // ← only the research agent sees this tool
|
|
56
|
+
parameters: z.object({ summary: z.string() }),
|
|
57
|
+
handler: async ({ summary }) => {
|
|
58
|
+
await fetch("/api/findings", { method: "POST", body: summary });
|
|
59
|
+
},
|
|
60
|
+
});
|
|
61
|
+
```
|
|
62
|
+
|
|
63
|
+
### Agent-scoped renderer
|
|
64
|
+
|
|
65
|
+
```tsx
|
|
66
|
+
import { useRenderTool } from "@copilotkit/react-core/v2";
|
|
67
|
+
import { z } from "zod";
|
|
68
|
+
|
|
69
|
+
useRenderTool({
|
|
70
|
+
name: "search",
|
|
71
|
+
agentId: "research", // ← only applies to research's "search" tool
|
|
72
|
+
parameters: z.object({ q: z.string() }),
|
|
73
|
+
render: ({ status, parameters, result }) => {
|
|
74
|
+
if (status === "inProgress") return <div>Preparing...</div>;
|
|
75
|
+
if (status === "executing") return <div>Searching {parameters.q}</div>;
|
|
76
|
+
return <div>{result}</div>;
|
|
77
|
+
},
|
|
78
|
+
});
|
|
79
|
+
```
|
|
80
|
+
|
|
81
|
+
### Discover available agents (no `useAgents` hook)
|
|
82
|
+
|
|
83
|
+
```tsx
|
|
84
|
+
"use client";
|
|
85
|
+
import { useCopilotKit } from "@copilotkit/react-core/v2";
|
|
86
|
+
import { useEffect, useState } from "react";
|
|
87
|
+
|
|
88
|
+
export function useAvailableAgents() {
|
|
89
|
+
const { copilotkit } = useCopilotKit();
|
|
90
|
+
const [ids, setIds] = useState<string[]>(() =>
|
|
91
|
+
Object.keys(copilotkit.agents ?? {}),
|
|
92
|
+
);
|
|
93
|
+
|
|
94
|
+
useEffect(() => {
|
|
95
|
+
const subscription = copilotkit.subscribe({
|
|
96
|
+
onAgentsChanged: ({ agents }) => {
|
|
97
|
+
setIds(Object.keys(agents ?? {}));
|
|
98
|
+
},
|
|
99
|
+
});
|
|
100
|
+
return () => subscription.unsubscribe();
|
|
101
|
+
}, [copilotkit]);
|
|
102
|
+
|
|
103
|
+
return ids;
|
|
104
|
+
}
|
|
105
|
+
```
|
|
106
|
+
|
|
107
|
+
## Common Mistakes
|
|
108
|
+
|
|
109
|
+
### HIGH — Switching `agentId` on a persisted `<CopilotChat>` without `key`
|
|
110
|
+
|
|
111
|
+
Wrong:
|
|
112
|
+
|
|
113
|
+
```tsx
|
|
114
|
+
<CopilotChat agentId={activeAgent} />
|
|
115
|
+
```
|
|
116
|
+
|
|
117
|
+
Correct:
|
|
118
|
+
|
|
119
|
+
```tsx
|
|
120
|
+
<CopilotChat key={activeAgent} agentId={activeAgent} />
|
|
121
|
+
```
|
|
122
|
+
|
|
123
|
+
Without remount via `key`, prior thread state and in-flight runs leak into
|
|
124
|
+
the new agent's view. The remount pattern gives each agent a clean slate.
|
|
125
|
+
|
|
126
|
+
Source: `examples/v2/react-router/app/routes/_index.tsx:38-39`
|
|
127
|
+
|
|
128
|
+
### MEDIUM — Omitting `agentId` when multiple agents share a tool name
|
|
129
|
+
|
|
130
|
+
Wrong:
|
|
131
|
+
|
|
132
|
+
```tsx
|
|
133
|
+
// Both research and coding agents have a "search" tool — unscoped wins globally
|
|
134
|
+
useRenderToolCall({
|
|
135
|
+
name: "search",
|
|
136
|
+
args: z.object({ q: z.string() }),
|
|
137
|
+
render,
|
|
138
|
+
});
|
|
139
|
+
```
|
|
140
|
+
|
|
141
|
+
Correct:
|
|
142
|
+
|
|
143
|
+
```tsx
|
|
144
|
+
useRenderTool({
|
|
145
|
+
name: "search",
|
|
146
|
+
agentId: "research",
|
|
147
|
+
parameters: z.object({ q: z.string() }),
|
|
148
|
+
render: researchSearchRender,
|
|
149
|
+
});
|
|
150
|
+
useRenderTool({
|
|
151
|
+
name: "search",
|
|
152
|
+
agentId: "coding",
|
|
153
|
+
parameters: z.object({ q: z.string() }),
|
|
154
|
+
render: codingSearchRender,
|
|
155
|
+
});
|
|
156
|
+
```
|
|
157
|
+
|
|
158
|
+
Unscoped renderers apply to every agent. When two agents have a tool with
|
|
159
|
+
the same name and only one has a renderer, the unscoped renderer wins
|
|
160
|
+
globally and the other agent never gets its intended renderer.
|
|
161
|
+
|
|
162
|
+
Source: `packages/react-core/src/v2/hooks/use-render-tool-call.tsx:145-154`
|
|
163
|
+
|
|
164
|
+
### MEDIUM — Tools registered without `agentId` leak across panels
|
|
165
|
+
|
|
166
|
+
Wrong:
|
|
167
|
+
|
|
168
|
+
```tsx
|
|
169
|
+
useFrontendTool({
|
|
170
|
+
name: "saveFindings",
|
|
171
|
+
parameters: z.object({ summary: z.string() }),
|
|
172
|
+
handler,
|
|
173
|
+
});
|
|
174
|
+
// Both research and coding agents now see saveFindings.
|
|
175
|
+
```
|
|
176
|
+
|
|
177
|
+
Correct:
|
|
178
|
+
|
|
179
|
+
```tsx
|
|
180
|
+
useFrontendTool({
|
|
181
|
+
name: "saveFindings",
|
|
182
|
+
agentId: "research",
|
|
183
|
+
parameters: z.object({ summary: z.string() }),
|
|
184
|
+
handler,
|
|
185
|
+
});
|
|
186
|
+
```
|
|
187
|
+
|
|
188
|
+
Omitting `agentId` attaches the tool to every agent. In a multi-agent UI
|
|
189
|
+
this leaks the handler across panels. Scope tools explicitly when they
|
|
190
|
+
should only apply to one agent.
|
|
191
|
+
|
|
192
|
+
Source: `packages/react-core/src/v2/hooks/use-frontend-tool.tsx`
|
|
193
|
+
|
|
194
|
+
### MEDIUM — Using `useAgents()` (does not exist)
|
|
195
|
+
|
|
196
|
+
Wrong:
|
|
197
|
+
|
|
198
|
+
```tsx
|
|
199
|
+
import { useAgents } from "@copilotkit/react-core/v2"; // not exported
|
|
200
|
+
const agents = useAgents();
|
|
201
|
+
```
|
|
202
|
+
|
|
203
|
+
Correct:
|
|
204
|
+
|
|
205
|
+
```tsx
|
|
206
|
+
import { useCopilotKit } from "@copilotkit/react-core/v2";
|
|
207
|
+
import { useEffect, useState } from "react";
|
|
208
|
+
|
|
209
|
+
function useAvailableAgents() {
|
|
210
|
+
const { copilotkit } = useCopilotKit();
|
|
211
|
+
const [ids, setIds] = useState<string[]>(() =>
|
|
212
|
+
Object.keys(copilotkit.agents ?? {}),
|
|
213
|
+
);
|
|
214
|
+
useEffect(() => {
|
|
215
|
+
const sub = copilotkit.subscribe({
|
|
216
|
+
onAgentsChanged: ({ agents }) => setIds(Object.keys(agents ?? {})),
|
|
217
|
+
});
|
|
218
|
+
return () => sub.unsubscribe();
|
|
219
|
+
}, [copilotkit]);
|
|
220
|
+
return ids;
|
|
221
|
+
}
|
|
222
|
+
```
|
|
223
|
+
|
|
224
|
+
There is no `useAgents` hook in v2. Discover agents by subscribing to
|
|
225
|
+
`onAgentsChanged` on the core client.
|
|
226
|
+
|
|
227
|
+
Source: `packages/react-core/src/v2/hooks/index.ts` (no `useAgents` export)
|
|
228
|
+
|
|
229
|
+
## References
|
|
230
|
+
|
|
231
|
+
- [Agent switcher recipes](switching-agents-recipes.md) — dropdown, tabs, keyboard shortcuts
|
|
@@ -0,0 +1,226 @@
|
|
|
1
|
+
# CopilotKit Threads (React)
|
|
2
|
+
|
|
3
|
+
This skill builds on `copilotkit/agent-access`. Durable threads only exist
|
|
4
|
+
in Intelligence mode — a runtime pointed at `api.cloud.copilotkit.ai` or a
|
|
5
|
+
self-managed Intelligence instance. In plain SSE mode the hook errors.
|
|
6
|
+
|
|
7
|
+
## Setup
|
|
8
|
+
|
|
9
|
+
```tsx
|
|
10
|
+
"use client";
|
|
11
|
+
import { useThreads } from "@copilotkit/react-core/v2";
|
|
12
|
+
|
|
13
|
+
export function ThreadSidebar({ agentId }: { agentId: string }) {
|
|
14
|
+
const {
|
|
15
|
+
threads,
|
|
16
|
+
isLoading,
|
|
17
|
+
error,
|
|
18
|
+
hasMoreThreads,
|
|
19
|
+
fetchMoreThreads,
|
|
20
|
+
renameThread,
|
|
21
|
+
archiveThread,
|
|
22
|
+
deleteThread,
|
|
23
|
+
} = useThreads({ agentId });
|
|
24
|
+
|
|
25
|
+
if (error) return <div className="text-red-500">{error.message}</div>;
|
|
26
|
+
if (isLoading) return <div>Loading threads…</div>;
|
|
27
|
+
|
|
28
|
+
return (
|
|
29
|
+
<ul className="space-y-1">
|
|
30
|
+
{threads.map((t) => (
|
|
31
|
+
<li key={t.id} className="flex gap-2">
|
|
32
|
+
<span>{t.name ?? "Untitled"}</span>
|
|
33
|
+
<button onClick={() => renameThread(t.id, "Renamed")}>Rename</button>
|
|
34
|
+
<button onClick={() => archiveThread(t.id)}>Archive</button>
|
|
35
|
+
</li>
|
|
36
|
+
))}
|
|
37
|
+
{hasMoreThreads && <button onClick={fetchMoreThreads}>Load more</button>}
|
|
38
|
+
</ul>
|
|
39
|
+
);
|
|
40
|
+
}
|
|
41
|
+
```
|
|
42
|
+
|
|
43
|
+
## Core Patterns
|
|
44
|
+
|
|
45
|
+
### Paginated list
|
|
46
|
+
|
|
47
|
+
```tsx
|
|
48
|
+
const { threads, hasMoreThreads, fetchMoreThreads, isFetchingMoreThreads } =
|
|
49
|
+
useThreads({ agentId: "default", limit: 25 });
|
|
50
|
+
```
|
|
51
|
+
|
|
52
|
+
### Include archived threads
|
|
53
|
+
|
|
54
|
+
```tsx
|
|
55
|
+
const { threads: archived } = useThreads({
|
|
56
|
+
agentId: "default",
|
|
57
|
+
includeArchived: true,
|
|
58
|
+
});
|
|
59
|
+
```
|
|
60
|
+
|
|
61
|
+
### Optimistic archive with error rollback
|
|
62
|
+
|
|
63
|
+
```tsx
|
|
64
|
+
const { threads, archiveThread } = useThreads({ agentId: "default" });
|
|
65
|
+
|
|
66
|
+
async function onArchive(id: string) {
|
|
67
|
+
try {
|
|
68
|
+
await archiveThread(id);
|
|
69
|
+
toast.success("Archived");
|
|
70
|
+
} catch (err) {
|
|
71
|
+
toast.error(`Failed to archive: ${String(err)}`);
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
```
|
|
75
|
+
|
|
76
|
+
### Thread-switcher + `<CopilotChat>`
|
|
77
|
+
|
|
78
|
+
```tsx
|
|
79
|
+
import { CopilotChat, useThreads } from "@copilotkit/react-core/v2";
|
|
80
|
+
import { useState } from "react";
|
|
81
|
+
|
|
82
|
+
export function ThreadSwitcher() {
|
|
83
|
+
const { threads } = useThreads({ agentId: "default" });
|
|
84
|
+
const [activeId, setActiveId] = useState<string | null>(null);
|
|
85
|
+
|
|
86
|
+
return (
|
|
87
|
+
<div className="grid grid-cols-[200px_1fr]">
|
|
88
|
+
<ul>
|
|
89
|
+
{threads.map((t) => (
|
|
90
|
+
<li key={t.id}>
|
|
91
|
+
<button onClick={() => setActiveId(t.id)}>
|
|
92
|
+
{t.name ?? "Untitled"}
|
|
93
|
+
</button>
|
|
94
|
+
</li>
|
|
95
|
+
))}
|
|
96
|
+
</ul>
|
|
97
|
+
{activeId && (
|
|
98
|
+
<CopilotChat key={activeId} agentId="default" threadId={activeId} />
|
|
99
|
+
)}
|
|
100
|
+
</div>
|
|
101
|
+
);
|
|
102
|
+
}
|
|
103
|
+
```
|
|
104
|
+
|
|
105
|
+
## Common Mistakes
|
|
106
|
+
|
|
107
|
+
### HIGH — Using `useThreads` with an SSE-only runtime
|
|
108
|
+
|
|
109
|
+
Wrong:
|
|
110
|
+
|
|
111
|
+
```tsx
|
|
112
|
+
// Runtime has no Intelligence configured
|
|
113
|
+
new CopilotRuntime({ agents });
|
|
114
|
+
|
|
115
|
+
// Client side:
|
|
116
|
+
const { threads, error } = useThreads({ agentId: "default" });
|
|
117
|
+
// error: "Runtime URL is not configured" or empty list forever
|
|
118
|
+
```
|
|
119
|
+
|
|
120
|
+
Correct:
|
|
121
|
+
|
|
122
|
+
```ts
|
|
123
|
+
// Server — upgrade to Intelligence mode:
|
|
124
|
+
import {
|
|
125
|
+
CopilotIntelligenceRuntime,
|
|
126
|
+
CopilotKitIntelligence,
|
|
127
|
+
} from "@copilotkit/runtime/v2";
|
|
128
|
+
|
|
129
|
+
const intelligence = new CopilotKitIntelligence({
|
|
130
|
+
apiUrl: process.env.COPILOTKIT_INTELLIGENCE_API_URL!,
|
|
131
|
+
wsUrl: process.env.COPILOTKIT_INTELLIGENCE_WS_URL!,
|
|
132
|
+
apiKey: process.env.COPILOTKIT_INTELLIGENCE_API_KEY!,
|
|
133
|
+
organizationId: process.env.COPILOTKIT_ORG_ID!,
|
|
134
|
+
});
|
|
135
|
+
|
|
136
|
+
const runtime = new CopilotIntelligenceRuntime({
|
|
137
|
+
agents,
|
|
138
|
+
intelligence,
|
|
139
|
+
identifyUser: async (req) => ({ userId: await getUserId(req) }),
|
|
140
|
+
});
|
|
141
|
+
```
|
|
142
|
+
|
|
143
|
+
`CopilotKitIntelligence` and `CopilotIntelligenceRuntime` are only exposed
|
|
144
|
+
on the `@copilotkit/runtime/v2` subpath — the package root exports SSE
|
|
145
|
+
primitives only.
|
|
146
|
+
|
|
147
|
+
Thread routes only exist in Intelligence mode. In plain SSE the list fetch
|
|
148
|
+
fails and mutations reject.
|
|
149
|
+
|
|
150
|
+
Source: `packages/react-core/src/v2/hooks/use-threads.tsx:207-213,229`
|
|
151
|
+
|
|
152
|
+
### HIGH — Expecting `deleteThread` to be recoverable
|
|
153
|
+
|
|
154
|
+
Wrong:
|
|
155
|
+
|
|
156
|
+
```tsx
|
|
157
|
+
await deleteThread(id); // user expected a trash bin
|
|
158
|
+
```
|
|
159
|
+
|
|
160
|
+
Correct:
|
|
161
|
+
|
|
162
|
+
```tsx
|
|
163
|
+
// For soft-delete UX, use archive:
|
|
164
|
+
await archiveThread(id);
|
|
165
|
+
|
|
166
|
+
// Then expose archived threads in a separate view:
|
|
167
|
+
const { threads: archived } = useThreads({
|
|
168
|
+
agentId: "default",
|
|
169
|
+
includeArchived: true,
|
|
170
|
+
});
|
|
171
|
+
```
|
|
172
|
+
|
|
173
|
+
`deleteThread` is irreversible at the Intelligence platform level. Use
|
|
174
|
+
`archiveThread` for user-facing delete UX and only call `deleteThread` for
|
|
175
|
+
genuine "permanently erase" flows.
|
|
176
|
+
|
|
177
|
+
Source: `packages/react-core/src/v2/hooks/use-threads.tsx:101-105`
|
|
178
|
+
|
|
179
|
+
### MEDIUM — Assuming archived threads appear by default
|
|
180
|
+
|
|
181
|
+
Wrong:
|
|
182
|
+
|
|
183
|
+
```tsx
|
|
184
|
+
const { threads } = useThreads({ agentId: "default" });
|
|
185
|
+
// User archived a thread. User opens the "Archived" tab. It's empty.
|
|
186
|
+
```
|
|
187
|
+
|
|
188
|
+
Correct:
|
|
189
|
+
|
|
190
|
+
```tsx
|
|
191
|
+
const { threads: activeThreads } = useThreads({ agentId: "default" });
|
|
192
|
+
const { threads: archivedThreads } = useThreads({
|
|
193
|
+
agentId: "default",
|
|
194
|
+
includeArchived: true,
|
|
195
|
+
});
|
|
196
|
+
```
|
|
197
|
+
|
|
198
|
+
`includeArchived` defaults to `false`. Archived threads are filtered out of
|
|
199
|
+
the default list; opt in explicitly for an archived-view tab.
|
|
200
|
+
|
|
201
|
+
Source: `packages/react-core/src/v2/hooks/use-threads.tsx:60-62`
|
|
202
|
+
|
|
203
|
+
### MEDIUM — Not handling `error`
|
|
204
|
+
|
|
205
|
+
Wrong:
|
|
206
|
+
|
|
207
|
+
```tsx
|
|
208
|
+
const { threads } = useThreads({ agentId: "default" });
|
|
209
|
+
return <ul>{threads.map(...)}</ul>;
|
|
210
|
+
// Silent failures — handshake errors, network errors all vanish.
|
|
211
|
+
```
|
|
212
|
+
|
|
213
|
+
Correct:
|
|
214
|
+
|
|
215
|
+
```tsx
|
|
216
|
+
const { threads, isLoading, error } = useThreads({ agentId: "default" });
|
|
217
|
+
if (error) return <ErrorBanner message={error.message} />;
|
|
218
|
+
if (isLoading) return <Spinner />;
|
|
219
|
+
return <ul>{threads.map(...)}</ul>;
|
|
220
|
+
```
|
|
221
|
+
|
|
222
|
+
`error` holds the most recent fetch/mutation error until the next
|
|
223
|
+
successful fetch clears it. Surface it or you'll miss Intelligence-mode
|
|
224
|
+
mis-configuration.
|
|
225
|
+
|
|
226
|
+
Source: `packages/react-core/src/v2/hooks/use-threads.tsx:70-74`
|
package/.attw.json
DELETED