@copilotkit/react-core 1.71.0 → 1.71.1
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/dist/{copilotkit-B4Jb1QEy.cjs → copilotkit-BkVEkUS0.cjs} +5 -2
- package/dist/copilotkit-BkVEkUS0.cjs.map +1 -0
- package/dist/{copilotkit-snbJkMqQ.mjs → copilotkit-D5BTo0YG.mjs} +5 -2
- package/dist/copilotkit-D5BTo0YG.mjs.map +1 -0
- package/dist/index.cjs +1 -1
- package/dist/index.mjs +1 -1
- package/dist/index.umd.js +4 -1
- package/dist/index.umd.js.map +1 -1
- package/dist/v2/headless.cjs +4 -1
- package/dist/v2/headless.cjs.map +1 -1
- package/dist/v2/headless.mjs +4 -1
- 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 +4 -1
- package/dist/v2/index.umd.js.map +1 -1
- package/package.json +8 -9
- package/dist/copilotkit-B4Jb1QEy.cjs.map +0 -1
- package/dist/copilotkit-snbJkMqQ.mjs.map +0 -1
- package/skills/react-core/SKILL.md +0 -110
- package/skills/react-core/references/agent-access.md +0 -398
- package/skills/react-core/references/attachments.md +0 -311
- package/skills/react-core/references/capabilities.md +0 -138
- package/skills/react-core/references/chat-components.md +0 -246
- package/skills/react-core/references/client-side-tools.md +0 -358
- package/skills/react-core/references/custom-message-renderers.md +0 -223
- package/skills/react-core/references/debug-mode.md +0 -140
- package/skills/react-core/references/human-in-the-loop.md +0 -312
- package/skills/react-core/references/provider-setup.md +0 -358
- package/skills/react-core/references/rendering-activity-messages.md +0 -201
- package/skills/react-core/references/rendering-tool-calls.md +0 -319
- package/skills/react-core/references/suggestions.md +0 -211
- package/skills/react-core/references/switching-agents-recipes.md +0 -161
- package/skills/react-core/references/switching-agents.md +0 -240
- package/skills/react-core/references/threads.md +0 -289
|
@@ -1,289 +0,0 @@
|
|
|
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
|
-
{/*
|
|
98
|
-
`key` here remounts ONLY <CopilotChat>. Keep it that way: a `key` on
|
|
99
|
-
an ancestor would remount the app tree below it too. See
|
|
100
|
-
"Keying a subtree on the active thread id" below.
|
|
101
|
-
*/}
|
|
102
|
-
{activeId && (
|
|
103
|
-
<CopilotChat key={activeId} agentId="default" threadId={activeId} />
|
|
104
|
-
)}
|
|
105
|
-
</div>
|
|
106
|
-
);
|
|
107
|
-
}
|
|
108
|
-
```
|
|
109
|
-
|
|
110
|
-
`activeId` starts as `null` and becomes a real thread id only after the
|
|
111
|
-
`useThreads` fetch resolves — so this is an **asynchronous, post-mount**
|
|
112
|
-
change, not something settled during the first render.
|
|
113
|
-
|
|
114
|
-
## Common Mistakes
|
|
115
|
-
|
|
116
|
-
### HIGH — Keying a subtree on the active thread id above app state
|
|
117
|
-
|
|
118
|
-
Wrong:
|
|
119
|
-
|
|
120
|
-
```tsx
|
|
121
|
-
// app/layout.tsx
|
|
122
|
-
const { threadId } = useThreadSelection();
|
|
123
|
-
|
|
124
|
-
return (
|
|
125
|
-
<CopilotKitProvider runtimeUrl="/api/copilotkit">
|
|
126
|
-
{/* Remounts EVERYTHING below on every thread change. */}
|
|
127
|
-
<MyAppProvider key={threadId}>{children}</MyAppProvider>
|
|
128
|
-
</CopilotKitProvider>
|
|
129
|
-
);
|
|
130
|
-
```
|
|
131
|
-
|
|
132
|
-
Correct:
|
|
133
|
-
|
|
134
|
-
```tsx
|
|
135
|
-
// app/layout.tsx — app state stays mounted across thread changes.
|
|
136
|
-
return (
|
|
137
|
-
<CopilotKitProvider runtimeUrl="/api/copilotkit">
|
|
138
|
-
<MyAppProvider>{children}</MyAppProvider>
|
|
139
|
-
</CopilotKitProvider>
|
|
140
|
-
);
|
|
141
|
-
```
|
|
142
|
-
|
|
143
|
-
```tsx
|
|
144
|
-
// Reset only what is genuinely per-thread, as deep as possible.
|
|
145
|
-
<ThreadScopedTranscript key={threadId} />
|
|
146
|
-
```
|
|
147
|
-
|
|
148
|
-
`key={threadId}` is a legitimate way to reset per-thread state, but it
|
|
149
|
-
discards **all** state below it — refs, correlation maps, in-flight request
|
|
150
|
-
bookkeeping, scroll positions. Placed on a layout-level provider it wipes
|
|
151
|
-
the whole page, with no error and no warning; the symptom surfaces
|
|
152
|
-
somewhere unrelated, as "our response routing is flaky".
|
|
153
|
-
|
|
154
|
-
Two properties make this hard to catch:
|
|
155
|
-
|
|
156
|
-
- The reset is asynchronous. Durable threads only exist in Intelligence
|
|
157
|
-
mode, so with a plain SSE runtime `useThreads` returns nothing, the
|
|
158
|
-
selected thread never changes, and the remount never fires. It appears
|
|
159
|
-
the moment Intelligence is wired.
|
|
160
|
-
- It is timing-dependent. Whether state survives depends on whether the
|
|
161
|
-
user acted before the thread list resolved.
|
|
162
|
-
|
|
163
|
-
Put the `key` on the smallest subtree that genuinely owns per-thread
|
|
164
|
-
state, and never above state the application expects to keep. If a
|
|
165
|
-
component both dispatches requests and correlates the responses, it must
|
|
166
|
-
sit **outside** the keyed subtree.
|
|
167
|
-
|
|
168
|
-
Source: `packages/react-core/src/v2/hooks/use-threads.tsx:282-289` (thread
|
|
169
|
-
endpoints exist only in Intelligence mode), `364-368` (the list fetch is
|
|
170
|
-
deferred until `/info` resolves)
|
|
171
|
-
|
|
172
|
-
### HIGH — Using `useThreads` with an SSE-only runtime
|
|
173
|
-
|
|
174
|
-
Wrong:
|
|
175
|
-
|
|
176
|
-
```tsx
|
|
177
|
-
// Runtime has no Intelligence configured
|
|
178
|
-
new CopilotRuntime({ agents });
|
|
179
|
-
|
|
180
|
-
// Client side:
|
|
181
|
-
const { threads, error } = useThreads({ agentId: "default" });
|
|
182
|
-
// error: "Runtime URL is not configured" or empty list forever
|
|
183
|
-
```
|
|
184
|
-
|
|
185
|
-
Correct:
|
|
186
|
-
|
|
187
|
-
```ts
|
|
188
|
-
// Server — upgrade to Intelligence mode:
|
|
189
|
-
import {
|
|
190
|
-
CopilotIntelligenceRuntime,
|
|
191
|
-
CopilotKitIntelligence,
|
|
192
|
-
} from "@copilotkit/runtime/v2";
|
|
193
|
-
|
|
194
|
-
const intelligence = new CopilotKitIntelligence({
|
|
195
|
-
// apiUrl / wsUrl default to cloud-hosted CopilotKit Intelligence — leave unset.
|
|
196
|
-
apiKey: process.env.CPK_INTELLIGENCE_API_KEY!,
|
|
197
|
-
});
|
|
198
|
-
|
|
199
|
-
const runtime = new CopilotIntelligenceRuntime({
|
|
200
|
-
agents,
|
|
201
|
-
intelligence,
|
|
202
|
-
identifyUser: async (req) => ({ userId: await getUserId(req) }),
|
|
203
|
-
});
|
|
204
|
-
```
|
|
205
|
-
|
|
206
|
-
`CopilotKitIntelligence` and `CopilotIntelligenceRuntime` are only exposed
|
|
207
|
-
on the `@copilotkit/runtime/v2` subpath — the package root exports SSE
|
|
208
|
-
primitives only.
|
|
209
|
-
|
|
210
|
-
Thread routes only exist in Intelligence mode. In plain SSE the list fetch
|
|
211
|
-
fails and mutations reject.
|
|
212
|
-
|
|
213
|
-
Source: `packages/react-core/src/v2/hooks/use-threads.tsx:207-213,229`
|
|
214
|
-
|
|
215
|
-
### HIGH — Expecting `deleteThread` to be recoverable
|
|
216
|
-
|
|
217
|
-
Wrong:
|
|
218
|
-
|
|
219
|
-
```tsx
|
|
220
|
-
await deleteThread(id); // user expected a trash bin
|
|
221
|
-
```
|
|
222
|
-
|
|
223
|
-
Correct:
|
|
224
|
-
|
|
225
|
-
```tsx
|
|
226
|
-
// For soft-delete UX, use archive:
|
|
227
|
-
await archiveThread(id);
|
|
228
|
-
|
|
229
|
-
// Then expose archived threads in a separate view:
|
|
230
|
-
const { threads: archived } = useThreads({
|
|
231
|
-
agentId: "default",
|
|
232
|
-
includeArchived: true,
|
|
233
|
-
});
|
|
234
|
-
```
|
|
235
|
-
|
|
236
|
-
`deleteThread` is irreversible in CopilotKit Intelligence. Use
|
|
237
|
-
`archiveThread` for user-facing delete UX and only call `deleteThread` for
|
|
238
|
-
genuine "permanently erase" flows.
|
|
239
|
-
|
|
240
|
-
Source: `packages/react-core/src/v2/hooks/use-threads.tsx:101-105`
|
|
241
|
-
|
|
242
|
-
### MEDIUM — Assuming archived threads appear by default
|
|
243
|
-
|
|
244
|
-
Wrong:
|
|
245
|
-
|
|
246
|
-
```tsx
|
|
247
|
-
const { threads } = useThreads({ agentId: "default" });
|
|
248
|
-
// User archived a thread. User opens the "Archived" tab. It's empty.
|
|
249
|
-
```
|
|
250
|
-
|
|
251
|
-
Correct:
|
|
252
|
-
|
|
253
|
-
```tsx
|
|
254
|
-
const { threads: activeThreads } = useThreads({ agentId: "default" });
|
|
255
|
-
const { threads: archivedThreads } = useThreads({
|
|
256
|
-
agentId: "default",
|
|
257
|
-
includeArchived: true,
|
|
258
|
-
});
|
|
259
|
-
```
|
|
260
|
-
|
|
261
|
-
`includeArchived` defaults to `false`. Archived threads are filtered out of
|
|
262
|
-
the default list; opt in explicitly for an archived-view tab.
|
|
263
|
-
|
|
264
|
-
Source: `packages/react-core/src/v2/hooks/use-threads.tsx:60-62`
|
|
265
|
-
|
|
266
|
-
### MEDIUM — Not handling `error`
|
|
267
|
-
|
|
268
|
-
Wrong:
|
|
269
|
-
|
|
270
|
-
```tsx
|
|
271
|
-
const { threads } = useThreads({ agentId: "default" });
|
|
272
|
-
return <ul>{threads.map(...)}</ul>;
|
|
273
|
-
// Silent failures — handshake errors, network errors all vanish.
|
|
274
|
-
```
|
|
275
|
-
|
|
276
|
-
Correct:
|
|
277
|
-
|
|
278
|
-
```tsx
|
|
279
|
-
const { threads, isLoading, error } = useThreads({ agentId: "default" });
|
|
280
|
-
if (error) return <ErrorBanner message={error.message} />;
|
|
281
|
-
if (isLoading) return <Spinner />;
|
|
282
|
-
return <ul>{threads.map(...)}</ul>;
|
|
283
|
-
```
|
|
284
|
-
|
|
285
|
-
`error` holds the most recent fetch/mutation error until the next
|
|
286
|
-
successful fetch clears it. Surface it or you'll miss Intelligence-mode
|
|
287
|
-
mis-configuration.
|
|
288
|
-
|
|
289
|
-
Source: `packages/react-core/src/v2/hooks/use-threads.tsx:70-74`
|