@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,201 +0,0 @@
1
- # CopilotKit Rendering Activity Messages (React)
2
-
3
- This skill builds on `copilotkit/provider-setup`. Activity-message
4
- renderers are registered as entries in the `renderActivityMessages` array
5
- prop on the `CopilotKit` provider and resolved at render time by
6
- `useRenderActivityMessage` (consumed internally by chat components).
7
-
8
- User renderers are placed first in the array so they override the built-in
9
- `MCPAppsActivityType` and `OpenGenerativeUIActivityType` renderers for the
10
- same `activityType`.
11
-
12
- Resolver order:
13
-
14
- 1. `(activityType, agentId)` match
15
- 2. `(activityType, unscoped)` match
16
- 3. `'*'` wildcard
17
- 4. `null`
18
-
19
- ## Setup
20
-
21
- ```tsx
22
- "use client";
23
- import { CopilotKit } from "@copilotkit/react-core/v2";
24
- import type { ReactActivityMessageRenderer } from "@copilotkit/react-core/v2";
25
- import { z } from "zod";
26
- import { useMemo } from "react";
27
- import { Card, CardContent } from "@/components/ui/card";
28
- import { Progress } from "@/components/ui/progress";
29
-
30
- const progressRenderer: ReactActivityMessageRenderer<{
31
- percent: number;
32
- label: string;
33
- }> = {
34
- activityType: "progress",
35
- content: z.object({ percent: z.number().min(0).max(1), label: z.string() }),
36
- render: ({ content }) => (
37
- <Card>
38
- <CardContent>
39
- <div>{content.label}</div>
40
- <Progress value={content.percent * 100} />
41
- </CardContent>
42
- </Card>
43
- ),
44
- };
45
-
46
- export function Providers({ children }: { children: React.ReactNode }) {
47
- const renderers = useMemo(() => [progressRenderer], []);
48
- return (
49
- <CopilotKit runtimeUrl="/api/copilotkit" renderActivityMessages={renderers}>
50
- {children}
51
- </CopilotKit>
52
- );
53
- }
54
- ```
55
-
56
- ## Core Patterns
57
-
58
- ### Agent-scoped renderer
59
-
60
- ```tsx
61
- const researchProgress: ReactActivityMessageRenderer<{ step: string }> = {
62
- activityType: "research-step",
63
- agentId: "research",
64
- content: z.object({ step: z.string() }),
65
- render: ({ content }) => <ResearchStepBadge step={content.step} />,
66
- };
67
- ```
68
-
69
- ### Override a built-in (MCP Apps)
70
-
71
- Place your renderer for the same `activityType` — user renderers are
72
- evaluated before built-ins.
73
-
74
- ```tsx
75
- import { MCPAppsActivityType } from "@copilotkit/react-core/v2";
76
-
77
- const customMcpRenderer: ReactActivityMessageRenderer<unknown> = {
78
- activityType: MCPAppsActivityType, // "mcp-apps" — must match the exported constant
79
- content: z.unknown(),
80
- render: ({ content, message }) => <CustomMCPCard payload={content} />,
81
- };
82
- ```
83
-
84
- ### Using the hook directly (custom chat surface)
85
-
86
- ```tsx
87
- import { useRenderActivityMessage } from "@copilotkit/react-core/v2";
88
- import type { ActivityMessage } from "@ag-ui/core";
89
-
90
- export function ActivityList({ messages }: { messages: ActivityMessage[] }) {
91
- const { renderActivityMessage } = useRenderActivityMessage();
92
- return (
93
- <div>
94
- {messages.map((m) => (
95
- <div key={m.id}>{renderActivityMessage(m)}</div>
96
- ))}
97
- </div>
98
- );
99
- }
100
- ```
101
-
102
- ## Common Mistakes
103
-
104
- ### HIGH — Incompatible content schema
105
-
106
- Wrong:
107
-
108
- ```tsx
109
- // Renderer expects `pct`
110
- const r: ReactActivityMessageRenderer<{ pct: number }> = {
111
- activityType: "progress",
112
- content: z.object({ pct: z.number() }),
113
- render: ({ content }) => <Bar value={content.pct} />,
114
- };
115
- // But the server emits { percent: 0.5 } — mismatched field name
116
- ```
117
-
118
- Correct:
119
-
120
- ```tsx
121
- const r: ReactActivityMessageRenderer<{ percent: number }> = {
122
- activityType: "progress",
123
- content: z.object({ percent: z.number() }),
124
- render: ({ content }) => <Bar value={content.percent} />,
125
- };
126
- ```
127
-
128
- `safeParse` is called on every incoming activity message. Mismatched
129
- schemas return `null` with only a `console.warn("Failed to parse content
130
- for activity message …")` — the UI renders nothing and the failure is
131
- silent unless you read the console.
132
-
133
- Source: `packages/react-core/src/v2/hooks/use-render-activity-message.tsx:44-50`
134
-
135
- ### MEDIUM — Side effects in `render`
136
-
137
- Wrong:
138
-
139
- ```tsx
140
- render: ({ content }) => {
141
- trackEvent(content); // fires on every re-render
142
- return <Badge>{content.label}</Badge>;
143
- };
144
- ```
145
-
146
- Wrong (Rules of Hooks violation):
147
-
148
- ```tsx
149
- render: ({ content }) => {
150
- // `render` is invoked as a plain function by the resolver — NOT as a
151
- // React component — so calling hooks directly inside it is illegal.
152
- useEffect(() => trackEvent(content), [content]);
153
- return <Badge>{content.label}</Badge>;
154
- };
155
- ```
156
-
157
- Correct:
158
-
159
- ```tsx
160
- function TrackedBadge({ content }: { content: { label: string } }) {
161
- useEffect(() => {
162
- trackEvent(content);
163
- }, [content]);
164
- return <Badge>{content.label}</Badge>;
165
- }
166
-
167
- // In the renderer:
168
- render: ({ content }) => <TrackedBadge content={content} />;
169
- ```
170
-
171
- Activity-message renderers re-render on every message-list tick. Side
172
- effects in the render body fire repeatedly. Hooks cannot be called
173
- directly inside `render` because the resolver invokes it as a plain
174
- function; hoist the effect into a wrapper component that React mounts as
175
- a real element.
176
-
177
- Source: `packages/react-core/src/v2/hooks/use-render-activity-message.tsx`
178
-
179
- ### MEDIUM — Building the `renderActivityMessages` array inline
180
-
181
- Wrong:
182
-
183
- ```tsx
184
- <CopilotKit
185
- runtimeUrl="/api/copilotkit"
186
- renderActivityMessages={[progressRenderer, customMcpRenderer]}
187
- />
188
- ```
189
-
190
- Correct:
191
-
192
- ```tsx
193
- const renderers = useMemo(() => [progressRenderer, customMcpRenderer], []);
194
- <CopilotKit runtimeUrl="/api/copilotkit" renderActivityMessages={renderers} />;
195
- ```
196
-
197
- The provider uses `useStableArrayProp` and console-errors when a new array
198
- identity appears every render. Memoize or hoist the array to module
199
- scope.
200
-
201
- Source: `packages/react-core/src/v2/providers/CopilotKitProvider.tsx` (useStableArrayProp)
@@ -1,319 +0,0 @@
1
- # CopilotKit Rendering Tool Calls (React)
2
-
3
- This skill builds on `copilotkit/provider-setup` and
4
- `copilotkit/client-side-tools`.
5
-
6
- Four hooks, distinct roles:
7
-
8
- | Hook | Role |
9
- | ---------------------- | ----------------------------------------------------------------- |
10
- | `useRenderTool` | Primary registration hook for a named tool's progress/result UI |
11
- | `useComponent` | Register a NEW render-only tool (agent calls it just to render) |
12
- | `useDefaultRenderTool` | Sanctioned wildcard fallback for tools without a dedicated render |
13
- | `useRenderToolCall` | Resolver — returns a function. For custom chat surfaces only |
14
-
15
- Status is camelCase: `"inProgress" | "executing" | "complete"`. The
16
- `RenderToolProps` discriminated union narrows `parameters` per state.
17
-
18
- ## UI-kit detection rule
19
-
20
- Before writing raw JSX, check the consumer's `package.json` for shadcn /
21
- MUI / Chakra / Ant / Mantine and reuse those primitives.
22
-
23
- ## Setup
24
-
25
- ```tsx
26
- "use client";
27
- import { useRenderTool } from "@copilotkit/react-core/v2";
28
- import { z } from "zod";
29
- import { Card, CardContent } from "@/components/ui/card";
30
- import { Skeleton } from "@/components/ui/skeleton";
31
-
32
- export function SearchRenderer() {
33
- useRenderTool({
34
- name: "searchDocs",
35
- parameters: z.object({ query: z.string() }),
36
- render: ({ status, parameters, result }) => {
37
- if (status === "inProgress") return <Skeleton className="h-16 w-full" />;
38
- if (status === "executing") {
39
- return (
40
- <Card>
41
- <CardContent>Searching "{parameters.query}"…</CardContent>
42
- </Card>
43
- );
44
- }
45
- return (
46
- <Card>
47
- <CardContent>{result}</CardContent>
48
- </Card>
49
- );
50
- },
51
- });
52
- return null;
53
- }
54
- ```
55
-
56
- ## Core Patterns
57
-
58
- ### Wildcard fallback with the built-in card
59
-
60
- ```tsx
61
- import { useDefaultRenderTool } from "@copilotkit/react-core/v2";
62
-
63
- useDefaultRenderTool(); // renders the built-in expandable tool-call card
64
- ```
65
-
66
- ### Custom wildcard fallback
67
-
68
- ```tsx
69
- import { useDefaultRenderTool } from "@copilotkit/react-core/v2";
70
-
71
- useDefaultRenderTool({
72
- render: ({ name, status, parameters, result }) => {
73
- // parameters is unknown — narrow by tool name
74
- if (name === "search") {
75
- const args = parameters as { q: string };
76
- return <SearchCard q={args.q} status={status} result={result} />;
77
- }
78
- return <GenericCard name={name} status={status} />;
79
- },
80
- });
81
- ```
82
-
83
- ### Render-only tool (the agent's only reason to call it is to render)
84
-
85
- ```tsx
86
- import { useComponent } from "@copilotkit/react-core/v2";
87
- import { z } from "zod";
88
-
89
- useComponent({
90
- name: "productCard",
91
- parameters: z.object({ productId: z.string() }),
92
- render: ({ productId }) => <ProductCard id={productId} />,
93
- });
94
- // `useComponent` registers a NEW tool called "productCard".
95
- // The agent calls it to render; there is no handler to run.
96
- ```
97
-
98
- ### Custom chat surface (resolver hook)
99
-
100
- `useRenderToolCall` is for building your own message list, NOT for
101
- registering renderers.
102
-
103
- ```tsx
104
- import { useRenderToolCall } from "@copilotkit/react-core/v2";
105
- import { useAgent } from "@copilotkit/react-core/v2";
106
-
107
- export function CustomToolList() {
108
- const { agent } = useAgent({ agentId: "default" });
109
- const renderToolCall = useRenderToolCall();
110
-
111
- const toolCalls = agent.messages.flatMap((m) =>
112
- "toolCalls" in m ? (m.toolCalls ?? []) : [],
113
- );
114
-
115
- return (
116
- <>
117
- {toolCalls.map((tc) => (
118
- <div key={tc.id}>{renderToolCall({ toolCall: tc })}</div>
119
- ))}
120
- </>
121
- );
122
- }
123
- ```
124
-
125
- ## Common Mistakes
126
-
127
- ### CRITICAL — Using `useRenderToolCall` for registration
128
-
129
- Wrong:
130
-
131
- ```tsx
132
- useRenderToolCall({
133
- name: "search",
134
- args: z.object({ q: z.string() }),
135
- render: ({ status, args }) => <Card>…</Card>,
136
- });
137
- ```
138
-
139
- Correct:
140
-
141
- ```tsx
142
- useRenderTool({
143
- name: "search",
144
- parameters: z.object({ q: z.string() }),
145
- render: ({ status, parameters }) => <Card>…</Card>,
146
- });
147
- ```
148
-
149
- `useRenderToolCall` takes no arguments — it returns a resolver function for
150
- custom chat surfaces. Passing config to it does nothing. `useRenderTool` is
151
- the registration hook.
152
-
153
- Source: `packages/react-core/src/v2/hooks/index.ts:2,7`;
154
- `packages/react-core/src/v2/hooks/use-render-tool.tsx:37-40`
155
-
156
- ### CRITICAL — Using hyphenated `"in-progress"` status
157
-
158
- Wrong:
159
-
160
- ```tsx
161
- render: ({ status, parameters, result }) => {
162
- if (status === "in-progress") return <Spinner />;
163
- if (status === "executing") return <RunningCard args={parameters} />;
164
- return <ResultCard result={result} />;
165
- };
166
- ```
167
-
168
- Correct:
169
-
170
- ```tsx
171
- render: ({ status, parameters, result }) => {
172
- if (status === "inProgress") return <Spinner />;
173
- if (status === "executing") return <RunningCard args={parameters} />;
174
- return <ResultCard result={result} />;
175
- };
176
- ```
177
-
178
- Real status values are camelCase: `"inProgress" | "executing" | "complete"`.
179
- Hyphenated branches never match — users see no progress UI and the fallback
180
- path fires.
181
-
182
- Source: `packages/react-core/src/v2/hooks/use-render-tool.tsx:8-35`
183
-
184
- ### CRITICAL — Writing JSX from scratch when the app has a UI kit
185
-
186
- Wrong:
187
-
188
- ```tsx
189
- useRenderTool({
190
- name: "search",
191
- parameters: z.object({ q: z.string() }),
192
- render: () => <div className="my-badge">…</div>,
193
- });
194
- ```
195
-
196
- Correct:
197
-
198
- ```tsx
199
- import { Badge } from "@/components/ui/badge";
200
-
201
- useRenderTool({
202
- name: "search",
203
- parameters: z.object({ q: z.string() }),
204
- render: () => <Badge variant="secondary">…</Badge>,
205
- });
206
- ```
207
-
208
- Check consumer `package.json` for shadcn / MUI / Chakra / Ant / Mantine
209
- first. Raw JSX ignores their design system.
210
-
211
- Source: maintainer interview (Phase 2c)
212
-
213
- ### HIGH — Dereferencing required fields from `Partial<T>` during `inProgress`
214
-
215
- Wrong:
216
-
217
- ```tsx
218
- render: ({ status, parameters }) => (
219
- <span>{parameters.user.id.toUpperCase()}</span>
220
- );
221
- // `parameters` is Partial<T> during inProgress — `parameters.user` may be undefined.
222
- ```
223
-
224
- Correct:
225
-
226
- ```tsx
227
- render: ({ status, parameters }) =>
228
- status === "inProgress" ? (
229
- <Skeleton />
230
- ) : (
231
- <span>{parameters.user.id.toUpperCase()}</span>
232
- );
233
- ```
234
-
235
- During streaming, `RenderToolInProgressProps` has
236
- `parameters: Partial<InferSchemaOutput<S>>`. Fields are `undefined` until
237
- the stream completes. Narrow with `status === "inProgress"` first.
238
-
239
- Source: `packages/react-core/src/v2/hooks/use-render-tool.tsx:8-14`
240
-
241
- ### HIGH — Using `useComponent` to decorate an existing tool
242
-
243
- Wrong:
244
-
245
- ```tsx
246
- useFrontendTool({ name: "search", parameters, handler });
247
- useComponent({
248
- name: "search", // creates a SECOND tool named "search" — collision
249
- parameters: z.object({ q: z.string() }),
250
- render: ({ q }) => <SearchCard q={q} />,
251
- });
252
- ```
253
-
254
- Correct:
255
-
256
- ```tsx
257
- useFrontendTool({ name: "search", parameters, handler });
258
- useRenderTool({
259
- name: "search",
260
- parameters: z.object({ q: z.string() }),
261
- render: ({ status, parameters, result }) => {
262
- if (status === "inProgress") return <Skeleton />;
263
- if (status === "executing") return <div>Searching {parameters.q}…</div>;
264
- return <div>{result}</div>;
265
- },
266
- });
267
-
268
- // useComponent is only for render-only tools the agent invokes:
269
- useComponent({
270
- name: "productCard",
271
- parameters: z.object({ productId: z.string() }),
272
- render: ({ productId }) => <ProductCard id={productId} />,
273
- });
274
- ```
275
-
276
- `useComponent` synthesizes a NEW tool whose only job is to render —
277
- description is auto-prefixed with "Use this tool to display the …
278
- component". It does NOT decorate an existing tool. The misleading name
279
- trap: agents read "useComponent" as "register a component for this tool"
280
- and end up with two tools colliding on the same name.
281
-
282
- Source: `packages/react-core/src/v2/hooks/use-component.tsx:59-88`
283
-
284
- ### HIGH — Hand-rolling `useRenderTool({ name: "*" })` instead of `useDefaultRenderTool`
285
-
286
- Wrong:
287
-
288
- ```tsx
289
- useRenderTool({
290
- name: "*",
291
- render: ({ parameters }) => <pre>{JSON.stringify(parameters)}</pre>,
292
- });
293
- ```
294
-
295
- Correct:
296
-
297
- ```tsx
298
- // Use the built-in default card:
299
- useDefaultRenderTool();
300
-
301
- // Or customize, with the correct DefaultRenderProps typing (parameters: unknown):
302
- useDefaultRenderTool({
303
- render: ({ name, status, parameters, result }) => {
304
- if (name === "search") {
305
- const args = parameters as { q: string };
306
- return <SearchCard q={args.q} status={status} />;
307
- }
308
- return <GenericCard name={name} status={status} />;
309
- },
310
- });
311
- ```
312
-
313
- The sanctioned wildcard API is `useDefaultRenderTool`. It wraps
314
- `useRenderTool({ name: "*" })` with the correct `DefaultRenderProps`
315
- typing (`parameters: unknown`) and provides a built-in default card when
316
- no `render` is passed. Hand-rolling loses the default card and invites
317
- the untyped-args footgun.
318
-
319
- Source: `packages/react-core/src/v2/hooks/use-default-render-tool.tsx:15-64`