Skip to content

Commit 6f13ed2

Browse files
committed
docs: add debug mode documentation to troubleshooting section
1 parent 7e0a632 commit 6f13ed2

3 files changed

Lines changed: 166 additions & 0 deletions

File tree

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
---
2+
title: "Debug Mode"
3+
description: "Enable debug mode to get detailed logging of the AG-UI event pipeline on both the server and client."
4+
icon: "lucide/Bug"
5+
---
6+
7+
import DebugMode from "@/snippets/shared/troubleshooting/debug-mode.mdx";
8+
9+
<DebugMode components={props.components} />

docs/content/docs/(root)/troubleshooting/meta.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
{
22
"pages": [
33
"error-debugging",
4+
"debug-mode",
45
"observability-connectors",
56
"common-issues"
67
]
Lines changed: 156 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,156 @@
1+
# Debug Mode
2+
3+
CopilotKit has a built-in debug mode that provides detailed logging of the AG-UI event pipeline. It works on both the server (runtime) and client (React) side, and each can be enabled independently.
4+
5+
Debug mode is useful when you need to understand:
6+
- What events are being emitted by your agent
7+
- Whether events are being received, validated, or dropped on the client
8+
- Where in the pipeline something is going wrong
9+
- The full lifecycle of a request from start to finish
10+
11+
## Enabling Debug Mode
12+
13+
### Server-Side (Runtime)
14+
15+
Pass `debug: true` to the `CopilotRuntime` constructor:
16+
17+
```ts title="app/api/copilotkit/route.ts"
18+
const runtime = new CopilotRuntime({
19+
agents: {
20+
// your agents
21+
},
22+
debug: true, // [!code highlight]
23+
});
24+
```
25+
26+
This produces structured Pino logs with a `copilotkit-debug` component label:
27+
28+
```
29+
[copilotkit-debug] Agent run started { agentName: "default", threadId: "abc-123" }
30+
[copilotkit-debug] SSE stream opened
31+
[copilotkit-debug] Event emitted { type: "TEXT_MESSAGE_START", messageId: "msg-1", role: "assistant" }
32+
[copilotkit-debug] Event emitted { type: "TEXT_MESSAGE_CONTENT", deltaLength: 42 }
33+
[copilotkit-debug] Event emitted { type: "TEXT_MESSAGE_END" }
34+
[copilotkit-debug] Event emitted { type: "RUN_FINISHED" }
35+
[copilotkit-debug] SSE stream completed { eventCount: 4 }
36+
```
37+
38+
### Client-Side (React)
39+
40+
Pass `debug={true}` to the `<CopilotKit>` provider:
41+
42+
```tsx
43+
<CopilotKit
44+
runtimeUrl="/api/copilotkit"
45+
debug={true} // [!code highlight]
46+
>
47+
<YourApp />
48+
</CopilotKit>
49+
```
50+
51+
This produces `console.debug` output in the browser devtools, showing the event pipeline at each stage:
52+
53+
```
54+
[SSE] Event received: { type: "TEXT_MESSAGE_START" }
55+
[HTTP] Event validated: { type: "TEXT_MESSAGE_START", valid: true }
56+
[VERIFY]: { type: "TEXT_MESSAGE_START" }
57+
[APPLY] Event applied: { type: "TEXT_MESSAGE_START", subscribers: 2 }
58+
```
59+
60+
<Callout type="info">
61+
The server and client debug toggles are independent. Enabling debug on the client does not affect the server, and vice versa.
62+
</Callout>
63+
64+
## Granular Configuration
65+
66+
Instead of `true`, you can pass an object for fine-grained control over what gets logged:
67+
68+
```ts
69+
debug: {
70+
events: true, // Log every event emitted/received
71+
lifecycle: true, // Log request/run lifecycle (start, finish, error)
72+
verbose: false, // Log full payloads instead of summaries
73+
}
74+
```
75+
76+
This works the same way on both the server and client.
77+
78+
### Defaults
79+
80+
| Input | `events` | `lifecycle` | `verbose` |
81+
|-------|----------|-------------|-----------|
82+
| `debug: true` | `true` | `true` | `true` |
83+
| `debug: {}` | `true` | `true` | `false` |
84+
| `debug: { events: false }` | `false` | `true` | `false` |
85+
86+
When `debug` is a boolean (`true`), verbose mode is on by default so you get full event payloads. When using the object form, verbose defaults to off so you get concise summaries.
87+
88+
### Examples
89+
90+
Log only lifecycle events (no per-event logs):
91+
92+
```ts
93+
debug: { events: false, lifecycle: true }
94+
```
95+
96+
Log events with full payloads but skip lifecycle:
97+
98+
```ts
99+
debug: { events: true, lifecycle: false, verbose: true }
100+
```
101+
102+
## What Gets Logged
103+
104+
### Server-Side Logs
105+
106+
| Category | Log Message | Description |
107+
|----------|-------------|-------------|
108+
| Lifecycle | `Agent run started` | An agent run was initiated, includes agent name and thread ID |
109+
| Lifecycle | `SSE stream opened` | The SSE response stream was created |
110+
| Lifecycle | `SSE stream completed` | The stream finished, includes total event count |
111+
| Lifecycle | `SSE stream errored` | The stream encountered an error |
112+
| Events | `Event emitted` | Each AG-UI event as it's written to the stream |
113+
114+
In **summary mode** (verbose off), event logs include key identifiers like `messageId`, `toolCallId`, `toolCallName`, `role`, and content lengths instead of full payloads.
115+
116+
### Client-Side Logs
117+
118+
Events pass through several pipeline stages. Debug mode logs at each one:
119+
120+
| Stage | Prefix | What's Logged |
121+
|-------|--------|---------------|
122+
| SSE Parser | `[SSE]` | Raw events received from the server |
123+
| HTTP Transform | `[HTTP]` | Stream format detection, event validation (valid/invalid) |
124+
| Chunk Transform | `[TRANSFORM]` | Chunk events expanded into START/CONTENT/END sequences |
125+
| Event Verification | `[VERIFY]` | Each event passing through the state machine validator |
126+
| Event Application | `[APPLY]` | Events applied to state, or dropped via `stopPropagation` |
127+
| Agent Lifecycle | `[LIFECYCLE]` | Run started, finished, or errored |
128+
129+
<Callout type="warn">
130+
Debug mode can produce a large volume of log output, especially in verbose mode. Use it during development and debugging, not in production.
131+
</Callout>
132+
133+
## Troubleshooting with Debug Mode
134+
135+
### Events Not Reaching the Client
136+
137+
Enable debug on both sides:
138+
1. Check server logs for `Event emitted` — are the expected events being sent?
139+
2. Check client logs for `[SSE] Event received` — are they arriving?
140+
3. Check `[HTTP] Event validated` — are any events failing validation?
141+
4. Check `[VERIFY]` — are events being rejected by the state machine?
142+
143+
### Events Being Dropped
144+
145+
Look for `[APPLY] Event dropped` in the client logs. This means a subscriber called `stopPropagation`, preventing the event from being applied to state.
146+
147+
### Tool Calls Not Executing
148+
149+
Enable debug and look for:
150+
1. `TOOL_CALL_START` events being emitted on the server
151+
2. `TOOL_CALL_ARGS` and `TOOL_CALL_END` events following correctly
152+
3. The events being validated and applied on the client
153+
154+
### State Not Updating
155+
156+
Look for `STATE_SNAPSHOT` or `STATE_DELTA` events in both server and client logs. If they appear on the server but not the client, there may be a connection issue. If they appear on the client but state isn't updating, check for `stopPropagation` in the apply stage.

0 commit comments

Comments
 (0)