@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.
Files changed (35) hide show
  1. package/dist/{copilotkit-B4Jb1QEy.cjs → copilotkit-BkVEkUS0.cjs} +5 -2
  2. package/dist/copilotkit-BkVEkUS0.cjs.map +1 -0
  3. package/dist/{copilotkit-snbJkMqQ.mjs → copilotkit-D5BTo0YG.mjs} +5 -2
  4. package/dist/copilotkit-D5BTo0YG.mjs.map +1 -0
  5. package/dist/index.cjs +1 -1
  6. package/dist/index.mjs +1 -1
  7. package/dist/index.umd.js +4 -1
  8. package/dist/index.umd.js.map +1 -1
  9. package/dist/v2/headless.cjs +4 -1
  10. package/dist/v2/headless.cjs.map +1 -1
  11. package/dist/v2/headless.mjs +4 -1
  12. package/dist/v2/headless.mjs.map +1 -1
  13. package/dist/v2/index.cjs +1 -1
  14. package/dist/v2/index.mjs +1 -1
  15. package/dist/v2/index.umd.js +4 -1
  16. package/dist/v2/index.umd.js.map +1 -1
  17. package/package.json +8 -9
  18. package/dist/copilotkit-B4Jb1QEy.cjs.map +0 -1
  19. package/dist/copilotkit-snbJkMqQ.mjs.map +0 -1
  20. package/skills/react-core/SKILL.md +0 -110
  21. package/skills/react-core/references/agent-access.md +0 -398
  22. package/skills/react-core/references/attachments.md +0 -311
  23. package/skills/react-core/references/capabilities.md +0 -138
  24. package/skills/react-core/references/chat-components.md +0 -246
  25. package/skills/react-core/references/client-side-tools.md +0 -358
  26. package/skills/react-core/references/custom-message-renderers.md +0 -223
  27. package/skills/react-core/references/debug-mode.md +0 -140
  28. package/skills/react-core/references/human-in-the-loop.md +0 -312
  29. package/skills/react-core/references/provider-setup.md +0 -358
  30. package/skills/react-core/references/rendering-activity-messages.md +0 -201
  31. package/skills/react-core/references/rendering-tool-calls.md +0 -319
  32. package/skills/react-core/references/suggestions.md +0 -211
  33. package/skills/react-core/references/switching-agents-recipes.md +0 -161
  34. package/skills/react-core/references/switching-agents.md +0 -240
  35. package/skills/react-core/references/threads.md +0 -289
@@ -1,110 +0,0 @@
1
- ---
2
- name: react-core
3
- description: >
4
- @copilotkit/react-core — mount the CopilotKit provider (from @copilotkit/react-core/v2)
5
- in a Next.js App Router / React Router v7 / TanStack Start / SPA app, drop in CopilotChat/CopilotPopup/CopilotSidebar (v2 chat
6
- components ship from react-core/v2 — NOT react-ui, which is CSS-only in v2), access and
7
- subscribe to agents with useAgent / useAgentContext / useCapabilities, switch between
8
- multiple agents, manage durable Intelligence threads with useThreads, register
9
- browser-side tools via useFrontendTool, render tool calls with useRenderTool /
10
- useComponent / useDefaultRenderTool, gate execution with useHumanInTheLoop, wire file
11
- attachments with useAttachments, configure suggestion pills, and register activity- and
12
- custom-message renderers. publicLicenseKey is canonical (publicApiKey is deprecated
13
- alias). Load the reference under references/ that matches your task.
14
- type: framework
15
- library: copilotkit
16
- library_version: "1.71.0"
17
- requires:
18
- - copilotkit/runtime
19
- sources:
20
- - "CopilotKit/CopilotKit:packages/react-core/src/v2/providers/CopilotKitProvider.tsx"
21
- - "CopilotKit/CopilotKit:packages/react-core/src/v2/index.ts"
22
- - "CopilotKit/CopilotKit:packages/react-core/src/v2/components/chat/index.ts"
23
- - "CopilotKit/CopilotKit:packages/react-core/src/v2/components/chat/CopilotChat.tsx"
24
- - "CopilotKit/CopilotKit:packages/react-core/src/v2/components/chat/CopilotChatView.tsx"
25
- - "CopilotKit/CopilotKit:packages/react-core/src/v2/components/CopilotKitInspector.tsx"
26
- - "CopilotKit/CopilotKit:packages/react-core/src/v2/hooks/use-agent.tsx"
27
- - "CopilotKit/CopilotKit:packages/react-core/src/v2/hooks/use-agent-context.tsx"
28
- - "CopilotKit/CopilotKit:packages/react-core/src/v2/hooks/use-capabilities.tsx"
29
- - "CopilotKit/CopilotKit:packages/react-core/src/v2/hooks/use-threads.tsx"
30
- - "CopilotKit/CopilotKit:packages/react-core/src/v2/hooks/use-frontend-tool.tsx"
31
- - "CopilotKit/CopilotKit:packages/react-core/src/v2/hooks/use-render-tool.tsx"
32
- - "CopilotKit/CopilotKit:packages/react-core/src/v2/hooks/use-render-tool-call.tsx"
33
- - "CopilotKit/CopilotKit:packages/react-core/src/v2/hooks/use-default-render-tool.tsx"
34
- - "CopilotKit/CopilotKit:packages/react-core/src/v2/hooks/use-component.tsx"
35
- - "CopilotKit/CopilotKit:packages/react-core/src/v2/hooks/use-human-in-the-loop.tsx"
36
- - "CopilotKit/CopilotKit:packages/react-core/src/v2/hooks/use-attachments.tsx"
37
- - "CopilotKit/CopilotKit:packages/react-core/src/v2/hooks/use-configure-suggestions.tsx"
38
- - "CopilotKit/CopilotKit:packages/react-core/src/v2/hooks/use-suggestions.tsx"
39
- - "CopilotKit/CopilotKit:packages/react-core/src/v2/hooks/use-render-activity-message.tsx"
40
- - "CopilotKit/CopilotKit:packages/react-core/src/v2/hooks/use-render-custom-messages.tsx"
41
- - "CopilotKit/CopilotKit:packages/react-core/src/v2/lib/slots.tsx"
42
- - "CopilotKit/CopilotKit:packages/core/src/core/core.ts"
43
- - "CopilotKit/CopilotKit:packages/core/src/core/agent-registry.ts"
44
- - "CopilotKit/CopilotKit:packages/core/src/core/run-handler.ts"
45
- - "CopilotKit/CopilotKit:packages/core/src/types.ts"
46
- ---
47
-
48
- # CopilotKit React Core
49
-
50
- `@copilotkit/react-core` is the React frontend half of CopilotKit: it mounts a provider,
51
- speaks AG-UI over SSE to a runtime (or directly to CopilotKit Intelligence in SPA mode), and
52
- exposes hooks for every interaction surface.
53
-
54
- This SKILL.md is the **index**. Read the reference under `references/` that matches
55
- your task — do not try to absorb the whole package from this file.
56
-
57
- ## Mental model — three shells you compose
58
-
59
- 1. **Provider shell** — the `CopilotKit` provider (from `@copilotkit/react-core/v2`) at or near the root (inside `"use client"` for
60
- Next.js App Router). Carries `runtimeUrl` (or `publicLicenseKey` for SPA), `headers`,
61
- `credentials`, `properties`, `onError`, `debug`, `enableInspector`.
62
- 2. **Chat shell** — `CopilotChat` / `CopilotPopup` / `CopilotSidebar` or a composed
63
- `CopilotChatView` + slot primitives (`CopilotChatInput`, `CopilotChatMessageView`, etc.).
64
- All chat components ship from `@copilotkit/react-core/v2`. **`CopilotPanel` does not
65
- exist** — it's a common hallucination.
66
- 3. **Hook shell** — inside any component under the provider, call `useAgent`,
67
- `useFrontendTool`, `useRenderTool`, etc. Every hook takes optional `{ agentId }` for
68
- agent-scoped registration.
69
-
70
- ## When to load which reference
71
-
72
- | Task | Reference |
73
- | --------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------- |
74
- | Mount the `CopilotKit` provider, pick `runtimeUrl` vs `publicLicenseKey`, RSC boundary rules | `references/provider-setup.md` |
75
- | Drop in `CopilotChat` / `CopilotPopup` / `CopilotSidebar`, compose `CopilotChatView` with slot primitives | `references/chat-components.md` |
76
- | File / image attachments via `useAttachments` — drag-drop, click, paste, custom upload | `references/attachments.md` |
77
- | Client-side debug tooling — `enableInspector`, `debug` prop, lazy-loaded web inspector | `references/debug-mode.md` |
78
- | Read / subscribe to an agent (`useAgent`) and push global context (`useAgentContext`) | `references/agent-access.md` |
79
- | Feature-gate UI on declared agent capabilities (`useCapabilities`) | `references/capabilities.md` |
80
- | Build a multi-agent UI (per-panel `useAgent`, agent-scoped tools, key-remount pattern) | `references/switching-agents.md` (+ `switching-agents-recipes.md` for concrete layouts) |
81
- | List / rename / archive / delete durable Intelligence threads (`useThreads`) | `references/threads.md` (**requires runtime Intelligence mode**) |
82
- | Register browser-side tools (`useFrontendTool`) | `references/client-side-tools.md` |
83
- | Render per-tool UI (`useRenderTool`, `useComponent`, `useDefaultRenderTool`, `useRenderToolCall`) | `references/rendering-tool-calls.md` |
84
- | Gate tool execution behind user approval (`useHumanInTheLoop`) | `references/human-in-the-loop.md` |
85
- | Configure dynamic or static suggestion pills (`useConfigureSuggestions`, `useSuggestions`) | `references/suggestions.md` |
86
- | Render non-chat activity messages (`useRenderActivityMessage`) | `references/rendering-activity-messages.md` |
87
- | Inject custom UI before/after specific messages (`useRenderCustomMessages`) | `references/custom-message-renderers.md` |
88
-
89
- ## Invariants and gotchas (load-once, before any reference)
90
-
91
- - `publicLicenseKey` is canonical. `publicApiKey` is a **deprecated alias** — expect it in legacy code.
92
- - `agents__unsafe_dev_only` and `selfManagedAgents` are dev-only aliases of each other. **Not production-safe.** See `packages/a2ui-renderer` or the `spa-without-runtime` lifecycle skill for the supported SPA path.
93
- - `CopilotPanel` does not exist. v2 chat components ship from `react-core/v2` — **not** `react-ui` (v2 `react-ui` is CSS-only).
94
- - No `useAgents()` hook exists. Discover agents via `copilotkit.subscribe({ onAgentsChanged })`.
95
- - `useRenderToolCall` is a **resolver** (for custom chat surfaces), **not** a registration hook. Register with `useRenderTool` / `useComponent` / `useDefaultRenderTool`.
96
- - UI-kit detection rule — any `render` or tool-call UI MUST reuse the consumer's shadcn / MUI / Chakra / Ant / Mantine primitives before writing raw JSX. This applies across `client-side-tools`, `rendering-tool-calls`, and `human-in-the-loop`.
97
- - Tool-call `status` values are camelCase: `'inProgress' | 'executing' | 'complete'`. In-progress args are `Partial<T>`.
98
- - `useHumanInTheLoop` synthesized handler **MUST** call `respond(result)` (including reject paths), otherwise the agent run hangs. `respond` is `undefined` outside `Executing` status. Unmounting mid-Executing abandons the run.
99
- - `useThreads` errors with `'Runtime URL is not configured'` outside Intelligence mode.
100
- - `useAgent` returns `{ agent, isReady }`. While `isReady` is `false`, `agent` is a provisional stand-in that is **swapped** for the real instance when `/info` resolves — `agent` changes reference and every effect depending on it re-runs. Never initialize app state (correlation maps, in-flight request records) inside an effect keyed on `agent`.
101
- - A React `key` discards **all** state below it. `key={activeAgent}` / `key={threadId}` belongs on the smallest subtree that genuinely owns that state — on a layout-level provider it silently wipes unrelated app state, and with Intelligence wired the thread id changes asynchronously after mount, so it fires mid-interaction.
102
- - `v1 → v2` migration renames: `useCopilotAction` → `useFrontendTool` + `useHumanInTheLoop`; `imageUploadsEnabled` → `attachments`. See the `v1-to-v2-migration` lifecycle skill.
103
-
104
- ## Reading order for a first-time reader
105
-
106
- 1. `provider-setup` — mount the provider.
107
- 2. `chat-components` — wire a chat surface.
108
- 3. `agent-access` — talk to agents.
109
- 4. `client-side-tools` + `rendering-tool-calls` — add tool-call UI.
110
- 5. Anything else as your feature requires.
@@ -1,398 +0,0 @@
1
- # CopilotKit Agent Access (React)
2
-
3
- This skill builds on `copilotkit/provider-setup`. `useAgent` reads from the
4
- same registry the provider populates from `/info`.
5
-
6
- Two complementary surfaces:
7
-
8
- - `useAgent` — imperative access to an agent instance, subscribe to
9
- messages/state/run-status changes.
10
- - `useAgentContext` — declarative push of app state to every agent run.
11
-
12
- ## Setup
13
-
14
- ```tsx
15
- "use client";
16
- import {
17
- useAgent,
18
- useAgentContext,
19
- UseAgentUpdate,
20
- } from "@copilotkit/react-core/v2";
21
- import { useMemo } from "react";
22
-
23
- export function ChatDriver({
24
- route,
25
- userId,
26
- }: {
27
- route: string;
28
- userId: string;
29
- }) {
30
- const { agent } = useAgent({
31
- agentId: "default",
32
- updates: [
33
- UseAgentUpdate.OnMessagesChanged,
34
- UseAgentUpdate.OnRunStatusChanged,
35
- ],
36
- throttleMs: 100,
37
- });
38
-
39
- const context = useMemo(() => ({ route, userId }), [route, userId]);
40
- useAgentContext({ description: "app context", value: context });
41
-
42
- return (
43
- <div>
44
- {agent.isRunning ? "…thinking" : "idle"} — {agent.messages.length}{" "}
45
- messages
46
- </div>
47
- );
48
- }
49
- ```
50
-
51
- ## Core Patterns
52
-
53
- ### Send a message and stream the response
54
-
55
- ```tsx
56
- const { agent } = useAgent({ agentId: "default" });
57
- const { copilotkit } = useCopilotKit();
58
-
59
- async function ask(text: string) {
60
- agent.addMessage({ id: crypto.randomUUID(), role: "user", content: text });
61
- await copilotkit.runAgent({ agent });
62
- }
63
- ```
64
-
65
- ### Subscribe only to run-status to reduce re-renders
66
-
67
- ```tsx
68
- const { agent } = useAgent({
69
- agentId: "default",
70
- updates: [UseAgentUpdate.OnRunStatusChanged],
71
- });
72
- const isRunning = agent.isRunning;
73
- ```
74
-
75
- `useAgent` returns `{ agent, isReady }`; `isRunning` lives on the agent
76
- itself. Subscribing to `OnRunStatusChanged` forces a re-render when the
77
- value flips, so reading `agent.isRunning` stays live.
78
-
79
- ### Share app state with every agent run (global)
80
-
81
- ```tsx
82
- const value = useMemo(
83
- () => ({ cartItems: cart.items, currentRoute: router.pathname }),
84
- [cart.items, router.pathname],
85
- );
86
- useAgentContext({ description: "user cart + route", value });
87
- ```
88
-
89
- ### Abort the run
90
-
91
- ```tsx
92
- const { agent } = useAgent({ agentId: "default" });
93
- <button onClick={() => agent.abortRun()}>Stop</button>;
94
- ```
95
-
96
- ### Wait for the real agent before attaching to it
97
-
98
- ```tsx
99
- const { agent, isReady } = useAgent({ agentId: "default" });
100
-
101
- useEffect(() => {
102
- if (!isReady) return; // provisional stand-in — don't attach yet
103
- const sub = agent.subscribe({ onRunStartedEvent: handleRunStarted });
104
- return () => sub.unsubscribe();
105
- }, [agent, isReady]);
106
- ```
107
-
108
- Until the runtime `/info` sync resolves, `agent` is a provisional
109
- stand-in. It is a fully-constructed `AbstractAgent`, so every call on it
110
- is safe — but it is then **replaced**, and `agent` changes reference.
111
- Anything keyed to the old instance goes with it.
112
-
113
- ### Scope a private agent to a thread
114
-
115
- `useAgent` admits exactly two shapes and nothing in between:
116
-
117
- - **Bind to an agent** — `useAgent()` or `useAgent({ agentId })`. The shared
118
- instance from the registry; the thread comes from the chat configuration.
119
- - **Bind a private agent to a thread** —
120
- `useAgent({ agentId, runtimeAgentId, threadId })`. All three are required.
121
-
122
- ```tsx
123
- // A panel with a thread of its own, routed to the runtime's "default" agent.
124
- const { agent, isReady } = useAgent({
125
- agentId: "extraction-panel", // local id this hook registers under
126
- runtimeAgentId: "default", // the runtime agent to route to
127
- threadId: extractionThreadId,
128
- });
129
- ```
130
-
131
- The second shape registers a private `ProxiedCopilotRuntimeAgent` under the
132
- local `agentId` and unregisters it on unmount, so the thread is pinned to an
133
- instance nothing else shares. The registration is a single balanced effect, so
134
- it survives a StrictMode double-invoke: the cleanup unregisters before the
135
- remount re-registers.
136
-
137
- Pick a local `agentId` no real agent uses, and a different one per surface.
138
-
139
- Source: `packages/react-core/src/v2/hooks/use-agent.tsx:126-137` (the two
140
- shapes), `:239-254` (register and unregister)
141
-
142
- ## Common Mistakes
143
-
144
- ### CRITICAL — Custom `AbstractAgent.clone()` that returns `this`
145
-
146
- Wrong:
147
-
148
- ```tsx
149
- class MyAgent extends AbstractAgent {
150
- clone() {
151
- return this; // aliases one instance everywhere a copy is expected
152
- }
153
- }
154
- ```
155
-
156
- Correct:
157
-
158
- ```tsx
159
- class MyAgent extends AbstractAgent {
160
- clone() {
161
- // Pass the same constructor arguments this instance was built with.
162
- // `AbstractAgent` takes `config` as a parameter and does not retain it, so
163
- // keep whatever your subclass needs on a field of its own.
164
- const next = new MyAgent(this.myConfig);
165
- next.threadId = this.threadId;
166
- next.setState(this.state);
167
- next.setMessages(this.messages);
168
- return next;
169
- }
170
- }
171
- ```
172
-
173
- Nothing validates the return value, so returning `this` fails silently rather
174
- than throwing. On the stateful suggestions path the engine clones the provider
175
- agent and then writes a suggestion thread id, seeded messages, and seeded state
176
- onto the copy — given `this`, it writes all three onto the live agent the user
177
- is talking to. (With `suggestions: true` on a multi-route runtime it builds a
178
- fresh `HttpAgent` instead and never clones, so the fault is configuration
179
- dependent.) Delegate cloning aliases the same way.
180
-
181
- `useAgent` itself does not clone. It either binds the shared registry instance
182
- or registers a private proxied agent; see the two shapes above.
183
-
184
- Source: `packages/core/src/core/suggestion-engine.ts:218-249` (the branch, the
185
- clone, then the seeding); `packages/core/src/agent.ts:448-472`
186
- (`ProxiedCopilotRuntimeAgent.clone`, the reference implementation — it rebuilds
187
- field by field, then copies threadId, state, and messages)
188
-
189
- ### HIGH — Deriving app state from `agent` without guarding on `isReady`
190
-
191
- Wrong:
192
-
193
- ```tsx
194
- const { agent } = useAgent({ agentId: "default" });
195
-
196
- // Correlation map for matching responses back to the row that asked.
197
- const pending = useRef(new Map<string, string>());
198
-
199
- useEffect(() => {
200
- pending.current = new Map(); // re-runs when `agent` is swapped
201
- const sub = agent.subscribe({ onRunFinishedEvent: resolvePending });
202
- return () => sub.unsubscribe();
203
- }, [agent]);
204
- ```
205
-
206
- Correct:
207
-
208
- ```tsx
209
- const { agent, isReady } = useAgent({ agentId: "default" });
210
-
211
- // Owned by the component, not by the agent — survives the swap.
212
- const pending = useRef(new Map<string, string>());
213
-
214
- useEffect(() => {
215
- if (!isReady) return;
216
- const sub = agent.subscribe({ onRunFinishedEvent: resolvePending });
217
- return () => sub.unsubscribe();
218
- }, [agent, isReady]);
219
- ```
220
-
221
- `agent` changes reference exactly once per mount, when `/info` resolves and
222
- the provisional stand-in is swapped for the real instance. Any effect with
223
- `agent` in its dependency array re-runs at that moment — so app state
224
- initialized inside such an effect is silently reset partway through the
225
- first interaction.
226
-
227
- This bites hardest with Intelligence configured, because license
228
- verification and thread-endpoint discovery lengthen the provisional window
229
- past the first user action. In plain SSE mode the window usually closes
230
- before anyone can interact, which is why the bug does not reproduce in
231
- OSS-only development.
232
-
233
- Never put per-component bookkeeping (correlation maps, in-flight request
234
- records, refs) behind an `agent` dependency. Initialize it in the ref
235
- itself and let the effect only manage the subscription.
236
-
237
- Source: `packages/react-core/src/v2/hooks/use-agent.tsx:226-290,465-481`
238
-
239
- ### HIGH — Mutating `agent.messages` directly
240
-
241
- Wrong:
242
-
243
- ```tsx
244
- agent.messages.push({ id, role: "user", content: "hi" });
245
- ```
246
-
247
- Correct:
248
-
249
- ```tsx
250
- agent.addMessage({ id: crypto.randomUUID(), role: "user", content: "hi" });
251
- // or:
252
- agent.setMessages([...agent.messages, newMessage]);
253
- ```
254
-
255
- AG-UI fires `onMessagesChanged` subscribers via `addMessage` /
256
- `setMessages`. Direct array mutation bypasses subscribers and the UI never
257
- re-renders.
258
-
259
- Source: `packages/react-core/src/v2/hooks/use-agent.tsx` (throughout)
260
-
261
- ### HIGH — Registering non-serializable values via `useAgentContext`
262
-
263
- Wrong:
264
-
265
- ```tsx
266
- useAgentContext({
267
- description: "user",
268
- value: {
269
- name: "Alice",
270
- lastLogin: new Date(),
271
- onLogout: () => logout(), // dropped silently
272
- },
273
- });
274
- ```
275
-
276
- Correct:
277
-
278
- ```tsx
279
- useAgentContext({
280
- description: "user",
281
- value: { name: "Alice", lastLogin: new Date().toISOString() },
282
- });
283
- ```
284
-
285
- `useAgentContext` runs the value through `JSON.stringify`. Functions are
286
- dropped, `Date` coerces to an ISO string (which the agent has to parse), and
287
- circular references throw.
288
-
289
- Source: `packages/react-core/src/v2/hooks/use-agent-context.tsx:30-35`
290
-
291
- ### MEDIUM — Expecting lifecycle callbacks to be throttled
292
-
293
- Wrong:
294
-
295
- ```tsx
296
- useAgent({
297
- agentId: "default",
298
- throttleMs: 300,
299
- // expecting onRunInitialized / onRunFinalized / onRunFailed to also be throttled
300
- });
301
- ```
302
-
303
- Correct:
304
-
305
- ```tsx
306
- // Only OnMessagesChanged / OnStateChanged / OnRunStatusChanged are throttled.
307
- // Lifecycle callbacks always fire immediately — handle them synchronously.
308
- useAgent({ agentId: "default", throttleMs: 300 });
309
- ```
310
-
311
- `throttleMs` only applies to the three subscribed updates enumerated in
312
- `UseAgentUpdate`. Lifecycle callbacks bypass the throttler.
313
-
314
- Source: `packages/react-core/src/v2/hooks/use-agent.tsx:36-48`
315
-
316
- ### MEDIUM — Unstable context value identity
317
-
318
- Wrong:
319
-
320
- ```tsx
321
- useAgentContext({ description: "cart", value: { items: cart.items } });
322
- ```
323
-
324
- Correct:
325
-
326
- ```tsx
327
- const value = useMemo(() => ({ items: cart.items }), [cart.items]);
328
- useAgentContext({ description: "cart", value });
329
- ```
330
-
331
- A fresh object literal on every render invalidates the `useMemo` inside
332
- `useAgentContext` that serializes the value, causing constant
333
- remove/re-add churn in the core context store.
334
-
335
- Source: `packages/react-core/src/v2/hooks/use-agent-context.tsx:30-35`
336
-
337
- ### MEDIUM — Expecting `useAgentContext` or `copilotkit.addContext` to scope context per agent
338
-
339
- Wrong:
340
-
341
- ```tsx
342
- useAgentContext({ agentId: "research", description: "paper list", value });
343
- // or the imperative form:
344
- copilotkit.addContext({
345
- description: "paper list",
346
- value: JSON.stringify(value),
347
- agentId: "research",
348
- });
349
- ```
350
-
351
- Correct:
352
-
353
- ```tsx
354
- // Context is global — every agent run sees every registered entry.
355
- useAgentContext({ description: "paper list", value });
356
-
357
- // When only one agent should key off a value, branch inside its prompt
358
- // or tool logic instead of trying to scope the context entry.
359
- ```
360
-
361
- Context is intentionally global and there is no per-agent scoping hook.
362
- `useAgentContext` has no `agentId` parameter, and `copilotkit.addContext`
363
- destructures only `{ description, value }` — any `agentId` passed is
364
- silently dropped. Treat context as "state of the world" that every agent
365
- sees.
366
-
367
- Source: `packages/react-core/src/v2/hooks/use-agent-context.tsx` (no `agentId` parameter); `packages/core/src/core/context-store.ts:26-31`
368
-
369
- ### MEDIUM — Scoping a thread with `agentId` and `threadId` alone
370
-
371
- Wrong:
372
-
373
- ```tsx
374
- // A compile error. Bypass the types and a runtime guard throws instead.
375
- useAgent({ agentId: "default", threadId: "t1" });
376
- ```
377
-
378
- Correct:
379
-
380
- ```tsx
381
- useAgent({
382
- agentId: "panel-1", // a local id of this hook's own
383
- runtimeAgentId: "default", // the runtime agent to route to
384
- threadId: "t1",
385
- });
386
- ```
387
-
388
- `threadId` is written onto a single agent instance, and an agent resolved by
389
- `agentId` alone is a shared singleton, so pinning a thread to it would clobber
390
- every other `useAgent` caller. The three keys are therefore a matched set: the
391
- type rejects every partial combination, and three runtime guards throw for
392
- callers who bypass the types, each naming the correct call.
393
-
394
- Give each surface its own local `agentId`. Two mounted hooks registering the
395
- same one throw `already registered` rather than quietly sharing state.
396
-
397
- Source: `packages/react-core/src/v2/hooks/use-agent.tsx:160-198` (the guards);
398
- `packages/core/src/core/agent-registry.ts:486-491` (the duplicate-id throw)