@botpress/adk-cli 1.19.0-beta.3 → 1.19.0-beta.5
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/assets/ui-dist/assets/{index-CSTz-oTK.js → index-B3b7PPgV.js} +4 -4
- package/{dist/index-DNqXHLNi-27nvpkee.js → assets/ui-dist/assets/index-BESZeTO5.js} +2 -2
- package/{dist/index-DAztRXeA-vr85xnxs.css → assets/ui-dist/assets/index-DIFGtVmI.css} +1 -1
- package/{dist/index-DfjXY3Oo-szsanhnt.js → assets/ui-dist/assets/index-a3ZL0_Jr.js} +2 -2
- package/assets/ui-dist/index.html +2 -2
- package/dist/{README-wjb7z7f0.md → README-824wa4jj.md} +1 -1
- package/dist/SKILL-75ym6tcj.md +257 -0
- package/dist/SKILL-chnwzmt1.md +548 -0
- package/dist/SKILL-d4bs53y3.md +244 -0
- package/dist/SKILL-h4b2f1n9.md +114 -0
- package/dist/SKILL-hbw5nt95.md +111 -0
- package/dist/actions-h7hxxvxr.md +823 -0
- package/dist/adk-build-emhwd0tg.md +39 -0
- package/dist/adk-debug-yrrdtpmb.md +23 -0
- package/dist/adk-dev-console-7z9rtjpy.md +17 -0
- package/dist/adk-document-ras6zzzh.md +68 -0
- package/dist/adk-eval-vx76dwq0.md +17 -0
- package/dist/adk-explain-fcsaw852.md +22 -0
- package/dist/adk-init-9kmxmbbe.md +30 -0
- package/dist/adk-ship-dybzn884.md +29 -0
- package/dist/adk-test-xq67savs.md +27 -0
- package/dist/adk-validate-1p4skv4m.md +31 -0
- package/dist/advanced-patterns-z86m9h1a.md +669 -0
- package/dist/agent-config-1aqvkrgf.md +450 -0
- package/dist/agent-steps-zj4c1n9t.md +115 -0
- package/dist/agent0-assets/skills/adk/SKILL.md +5 -5
- package/dist/agent0-assets/skills/adk/references/cli.md +265 -24
- package/dist/agent0-assets/skills/adk-debugger/SKILL.md +5 -5
- package/dist/agent0-assets/skills/adk-debugger/references/common-failures.md +1 -1
- package/dist/agent0-assets/skills/adk-debugger/references/debug-workflow.md +3 -3
- package/dist/agent0-assets/skills/adk-debugger/references/traces-and-logs.md +15 -7
- package/dist/assets-q7jt8r2q.md +237 -0
- package/dist/autonomous-execution-fymc12e5.md +747 -0
- package/dist/cli-c31e06yr.md +1334 -0
- package/dist/cli.js +963 -548
- package/dist/commands.json +24 -3
- package/dist/common-failures-ht29w2db.md +231 -0
- package/dist/component-registry-bbpw0see.md +43 -0
- package/dist/context-api-760cvh0h.md +461 -0
- package/dist/conversation-analysis-8ka4nrm4.md +420 -0
- package/dist/conversation-lifecycle-4seqqjc1.md +311 -0
- package/dist/conversations-gwfvxaee.md +1111 -0
- package/dist/custom-components-y5wdgpey.md +167 -0
- package/dist/debug-workflow-vz84q80v.md +239 -0
- package/dist/desk-k54ktvsd.md +852 -0
- package/dist/doc-standards-ck6ax2jd.md +124 -0
- package/dist/eval-format-7n9brja4.md +354 -0
- package/dist/evals-y1zcr1mc.md +11 -0
- package/dist/explain-config-1yaq3zzd.md +424 -0
- package/dist/files-dzt0wxn3.md +918 -0
- package/dist/{index-gqxgqnyz.html → index-3t354nbw.html} +2 -2
- package/dist/{index-CSTz-oTK-mdfh47r8.js → index-B3b7PPgV-zetkb01w.js} +4 -4
- package/{assets/ui-dist/assets/index-DNqXHLNi.js → dist/index-BESZeTO5-2rpmcefa.js} +2 -2
- package/{assets/ui-dist/assets/index-DAztRXeA.css → dist/index-DIFGtVmI-d4dhjg97.css} +1 -1
- package/{assets/ui-dist/assets/index-DfjXY3Oo.js → dist/index-a3ZL0_Jr-q145h35p.js} +2 -2
- package/dist/integration-actions-xang7tma.md +659 -0
- package/dist/integrations-k5ss07f4.md +266 -0
- package/dist/interfaces-6t0bpxs4.md +97 -0
- package/dist/knowledge-bases-20rg8p5c.md +456 -0
- package/dist/llm-debugging-76ng8rzm.md +209 -0
- package/dist/mcp-server-n1asyzhv.md +112 -0
- package/dist/messages-gkkg0b54.md +769 -0
- package/dist/model-configuration-f273kgd0.md +201 -0
- package/dist/multi-agent-dashboard-1mdfjdts.md +70 -0
- package/dist/pages-xn18xn73.md +273 -0
- package/dist/patterns-mistakes-5vb99dhf.md +469 -0
- package/dist/plugins-ttnx8f49.md +280 -0
- package/dist/tables-x45t36dd.md +1136 -0
- package/dist/tags-46td3qrg.md +516 -0
- package/dist/test-patterns-hj47w4nc.md +355 -0
- package/dist/testing-workflow-2vkp932f.md +225 -0
- package/dist/tools-wk7bq24z.md +581 -0
- package/dist/trace-summarization-hdyx1c2e.md +313 -0
- package/dist/traces-and-logs-f2kjfh19.md +203 -0
- package/dist/triggers-4j2cc86x.md +719 -0
- package/dist/ui-server-entry.js +977 -162
- package/dist/workflow-steps-mrdrf1c5.md +851 -0
- package/dist/workflows-gadx3s69.md +1408 -0
- package/dist/zai-agent-reference-e6644aad.md +454 -0
- package/dist/zai-complete-guide-mnna5d6f.md +1408 -0
- package/package.json +4 -4
|
@@ -0,0 +1,313 @@
|
|
|
1
|
+
# Trace Summarization
|
|
2
|
+
|
|
3
|
+
How to fetch a trace, walk its span tree, and produce a free-form natural-language summary of what happened. The goal is a synthesized narrative, not a raw dump of span data.
|
|
4
|
+
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
## Fetching Trace Data
|
|
8
|
+
|
|
9
|
+
Use the `adk traces` CLI with filters to get the raw data.
|
|
10
|
+
|
|
11
|
+
```bash
|
|
12
|
+
# Full trace with LLM reasoning included
|
|
13
|
+
adk traces trace=<trace-id> --include-llm --format json
|
|
14
|
+
|
|
15
|
+
# All traces for a conversation
|
|
16
|
+
adk traces conversation=<id> --include-llm --format json
|
|
17
|
+
|
|
18
|
+
# Recent traces (start here if you don't have an ID)
|
|
19
|
+
adk traces --include-llm --format json
|
|
20
|
+
```
|
|
21
|
+
|
|
22
|
+
**Always pass `--include-llm`** when summarizing. Without it, `think` spans are omitted and you lose the model's reasoning, which is essential for explaining *why* the agent did what it did.
|
|
23
|
+
|
|
24
|
+
**Always pass `--format json`** for structured, parseable output.
|
|
25
|
+
|
|
26
|
+
---
|
|
27
|
+
|
|
28
|
+
## Reading the Span Tree
|
|
29
|
+
|
|
30
|
+
Traces contain a flat list of spans, but spans form a parent-child hierarchy via `parentSpanId`. To summarize effectively, reconstruct the tree.
|
|
31
|
+
|
|
32
|
+
### Span hierarchy (typical)
|
|
33
|
+
|
|
34
|
+
```
|
|
35
|
+
handler.conversation (or handler.workflow, handler.action)
|
|
36
|
+
└─ autonomous.execution
|
|
37
|
+
└─ autonomous.iteration (one per LLM turn)
|
|
38
|
+
├─ cognitive.request (the LLM call)
|
|
39
|
+
├─ think (model reasoning)
|
|
40
|
+
├─ tool_call (tool invocation)
|
|
41
|
+
│ └─ autonomous.tool (tool execution detail)
|
|
42
|
+
├─ tool_call (another tool)
|
|
43
|
+
├─ code_execution_exception (if something broke)
|
|
44
|
+
└─ end (turn complete)
|
|
45
|
+
```
|
|
46
|
+
|
|
47
|
+
### How to walk it
|
|
48
|
+
|
|
49
|
+
1. **Find the root span** -- the span with no `parentSpanId`, or the handler span (`handler.conversation`, `handler.workflow`, `handler.action`). This tells you what triggered the trace.
|
|
50
|
+
2. **Walk children in chronological order** by `startTime`. Each child span is a step in the agent's behavior.
|
|
51
|
+
3. **Group by iteration** -- `autonomous.iteration` spans each represent one LLM turn. Within each iteration, look for the `think` -> `tool_call` -> `end` sequence.
|
|
52
|
+
4. **Follow errors upward** -- if a `code_execution_exception` or failed `tool_call` appears, check its parent iteration and the subsequent iteration to see how the agent recovered (or didn't).
|
|
53
|
+
|
|
54
|
+
### Key fields per span type
|
|
55
|
+
|
|
56
|
+
| Span Type | Fields to Read | What They Tell You |
|
|
57
|
+
|-----------|---------------|-------------------|
|
|
58
|
+
| `handler.conversation` | `context.conversationId`, `context.userId` | What triggered the trace (incoming message) |
|
|
59
|
+
| `handler.workflow` | `name`, `context` | Which workflow was invoked |
|
|
60
|
+
| `handler.action` | `name`, `context` | Which action was called |
|
|
61
|
+
| `autonomous.iteration` | `data.iterationIndex` | Which LLM turn this is (0-indexed) |
|
|
62
|
+
| `cognitive.request` | `data.model`, `data.tokens` | Which model was used, token counts |
|
|
63
|
+
| `think` | `data.content` | The LLM's reasoning -- why it chose an action |
|
|
64
|
+
| `tool_call` | `data.tool_name`, `data.input`, `data.output`, `status`, `data.error` | What tool was called, with what, and what happened |
|
|
65
|
+
| `code_execution_exception` | `data.message`, `data.stackTrace` | Runtime error in the LLMz sandbox |
|
|
66
|
+
| `end` | `data.response` | What the agent said back to the user |
|
|
67
|
+
|
|
68
|
+
---
|
|
69
|
+
|
|
70
|
+
## Producing a Summary
|
|
71
|
+
|
|
72
|
+
Do **not** use a fixed template. Write a natural-language narrative that reads like a concise incident report or activity log. Cover these aspects in whatever order makes the most sense for the specific trace:
|
|
73
|
+
|
|
74
|
+
### What to cover
|
|
75
|
+
|
|
76
|
+
1. **The trigger** -- What started this trace? An incoming user message? A workflow invocation? A scheduled trigger? Extract this from the root span type and context.
|
|
77
|
+
|
|
78
|
+
2. **The LLM's plan** -- What did the model decide to do and why? Synthesize from `think` spans. Don't quote them verbatim unless a specific phrase is important -- paraphrase the reasoning.
|
|
79
|
+
|
|
80
|
+
3. **Tool calls and their outcomes** -- Which tools were called, with what key inputs, and what happened? For successful calls, note what was returned if relevant. For failures, state the error clearly.
|
|
81
|
+
|
|
82
|
+
4. **Errors and recovery** -- Were there exceptions? Did the agent retry or give up? What was the error message? If the agent recovered, explain how.
|
|
83
|
+
|
|
84
|
+
5. **The outcome** -- What was the final result? What did the agent respond with? Did the conversation turn succeed or fail?
|
|
85
|
+
|
|
86
|
+
6. **Performance** -- Only mention if relevant (e.g., unusually slow, many iterations, high token usage). Don't include timing details for normal traces.
|
|
87
|
+
|
|
88
|
+
### Adapting depth to context
|
|
89
|
+
|
|
90
|
+
The summary depth should match what the developer is asking:
|
|
91
|
+
|
|
92
|
+
| Developer Question | Summary Depth |
|
|
93
|
+
|-------------------|---------------|
|
|
94
|
+
| "What happened?" / "Summarize this trace" | **Brief** -- 3-5 sentences covering trigger, actions taken, outcome |
|
|
95
|
+
| "Why did it do X?" / "Why did the bot call tool Y?" | **Focused** -- Zoom into the relevant `think` span and the tool call, explain the reasoning chain |
|
|
96
|
+
| "What went wrong?" / "Why did this fail?" | **Diagnostic** -- Focus on the error path: what led to the failure, what the error was, whether recovery was attempted |
|
|
97
|
+
| "Walk me through the whole trace" | **Detailed** -- Full chronological narrative covering every iteration and tool call |
|
|
98
|
+
|
|
99
|
+
---
|
|
100
|
+
|
|
101
|
+
## Examples
|
|
102
|
+
|
|
103
|
+
### Sample trace data (abbreviated)
|
|
104
|
+
|
|
105
|
+
```json
|
|
106
|
+
{
|
|
107
|
+
"traceId": "tr_01J5EXAMPLE",
|
|
108
|
+
"spans": [
|
|
109
|
+
{
|
|
110
|
+
"spanId": "sp_001",
|
|
111
|
+
"name": "handler.conversation",
|
|
112
|
+
"startTime": "2026-04-21T14:00:00.000Z",
|
|
113
|
+
"endTime": "2026-04-21T14:00:03.200Z",
|
|
114
|
+
"status": "ok",
|
|
115
|
+
"context": {
|
|
116
|
+
"conversationId": "conv_abc123",
|
|
117
|
+
"userId": "user_xyz"
|
|
118
|
+
}
|
|
119
|
+
},
|
|
120
|
+
{
|
|
121
|
+
"spanId": "sp_002",
|
|
122
|
+
"parentSpanId": "sp_001",
|
|
123
|
+
"name": "autonomous.execution",
|
|
124
|
+
"startTime": "2026-04-21T14:00:00.050Z",
|
|
125
|
+
"endTime": "2026-04-21T14:00:03.100Z",
|
|
126
|
+
"status": "ok"
|
|
127
|
+
},
|
|
128
|
+
{
|
|
129
|
+
"spanId": "sp_003",
|
|
130
|
+
"parentSpanId": "sp_002",
|
|
131
|
+
"name": "autonomous.iteration",
|
|
132
|
+
"startTime": "2026-04-21T14:00:00.100Z",
|
|
133
|
+
"endTime": "2026-04-21T14:00:02.800Z",
|
|
134
|
+
"status": "ok",
|
|
135
|
+
"data": { "iterationIndex": 0 }
|
|
136
|
+
},
|
|
137
|
+
{
|
|
138
|
+
"spanId": "sp_004",
|
|
139
|
+
"parentSpanId": "sp_003",
|
|
140
|
+
"name": "think",
|
|
141
|
+
"startTime": "2026-04-21T14:00:00.200Z",
|
|
142
|
+
"data": {
|
|
143
|
+
"content": "The user is asking for the status of order #4521. I should look this up using the lookupOrder tool with the order ID."
|
|
144
|
+
}
|
|
145
|
+
},
|
|
146
|
+
{
|
|
147
|
+
"spanId": "sp_005",
|
|
148
|
+
"parentSpanId": "sp_003",
|
|
149
|
+
"name": "tool_call",
|
|
150
|
+
"startTime": "2026-04-21T14:00:00.500Z",
|
|
151
|
+
"endTime": "2026-04-21T14:00:01.200Z",
|
|
152
|
+
"status": "ok",
|
|
153
|
+
"data": {
|
|
154
|
+
"tool_name": "lookupOrder",
|
|
155
|
+
"input": { "orderId": "4521" },
|
|
156
|
+
"output": { "status": "shipped", "trackingNumber": "1Z999AA10123456784", "estimatedDelivery": "2026-04-23" }
|
|
157
|
+
}
|
|
158
|
+
},
|
|
159
|
+
{
|
|
160
|
+
"spanId": "sp_006",
|
|
161
|
+
"parentSpanId": "sp_003",
|
|
162
|
+
"name": "end",
|
|
163
|
+
"startTime": "2026-04-21T14:00:02.800Z",
|
|
164
|
+
"data": {
|
|
165
|
+
"response": "Your order #4521 has been shipped! Tracking number: 1Z999AA10123456784. Estimated delivery: April 23rd."
|
|
166
|
+
}
|
|
167
|
+
}
|
|
168
|
+
]
|
|
169
|
+
}
|
|
170
|
+
```
|
|
171
|
+
|
|
172
|
+
### Brief summary ("What happened?")
|
|
173
|
+
|
|
174
|
+
> The user asked about order #4521. The agent looked it up with `lookupOrder`, found it was shipped with tracking number 1Z999AA10123456784 and an estimated delivery of April 23rd, and relayed that information to the user. Completed in one iteration, ~3 seconds.
|
|
175
|
+
|
|
176
|
+
### Sample trace with an error (abbreviated)
|
|
177
|
+
|
|
178
|
+
```json
|
|
179
|
+
{
|
|
180
|
+
"traceId": "tr_01J5FAILURE",
|
|
181
|
+
"spans": [
|
|
182
|
+
{
|
|
183
|
+
"spanId": "sp_010",
|
|
184
|
+
"name": "handler.conversation",
|
|
185
|
+
"startTime": "2026-04-21T15:00:00.000Z",
|
|
186
|
+
"endTime": "2026-04-21T15:00:08.500Z",
|
|
187
|
+
"status": "error",
|
|
188
|
+
"context": {
|
|
189
|
+
"conversationId": "conv_def456",
|
|
190
|
+
"userId": "user_xyz"
|
|
191
|
+
}
|
|
192
|
+
},
|
|
193
|
+
{
|
|
194
|
+
"spanId": "sp_011",
|
|
195
|
+
"parentSpanId": "sp_010",
|
|
196
|
+
"name": "autonomous.execution",
|
|
197
|
+
"startTime": "2026-04-21T15:00:00.050Z",
|
|
198
|
+
"endTime": "2026-04-21T15:00:08.400Z",
|
|
199
|
+
"status": "error"
|
|
200
|
+
},
|
|
201
|
+
{
|
|
202
|
+
"spanId": "sp_012",
|
|
203
|
+
"parentSpanId": "sp_011",
|
|
204
|
+
"name": "autonomous.iteration",
|
|
205
|
+
"startTime": "2026-04-21T15:00:00.100Z",
|
|
206
|
+
"endTime": "2026-04-21T15:00:04.000Z",
|
|
207
|
+
"status": "error",
|
|
208
|
+
"data": { "iterationIndex": 0 }
|
|
209
|
+
},
|
|
210
|
+
{
|
|
211
|
+
"spanId": "sp_013",
|
|
212
|
+
"parentSpanId": "sp_012",
|
|
213
|
+
"name": "think",
|
|
214
|
+
"startTime": "2026-04-21T15:00:00.200Z",
|
|
215
|
+
"data": {
|
|
216
|
+
"content": "The user wants to cancel order #7890. I'll use the cancelOrder tool."
|
|
217
|
+
}
|
|
218
|
+
},
|
|
219
|
+
{
|
|
220
|
+
"spanId": "sp_014",
|
|
221
|
+
"parentSpanId": "sp_012",
|
|
222
|
+
"name": "tool_call",
|
|
223
|
+
"startTime": "2026-04-21T15:00:00.500Z",
|
|
224
|
+
"endTime": "2026-04-21T15:00:02.000Z",
|
|
225
|
+
"status": "error",
|
|
226
|
+
"data": {
|
|
227
|
+
"tool_name": "cancelOrder",
|
|
228
|
+
"input": { "orderId": "7890" },
|
|
229
|
+
"error": "OrderService: Cannot cancel order in 'shipped' status"
|
|
230
|
+
}
|
|
231
|
+
},
|
|
232
|
+
{
|
|
233
|
+
"spanId": "sp_015",
|
|
234
|
+
"parentSpanId": "sp_011",
|
|
235
|
+
"name": "autonomous.iteration",
|
|
236
|
+
"startTime": "2026-04-21T15:00:04.100Z",
|
|
237
|
+
"endTime": "2026-04-21T15:00:08.000Z",
|
|
238
|
+
"status": "ok",
|
|
239
|
+
"data": { "iterationIndex": 1 }
|
|
240
|
+
},
|
|
241
|
+
{
|
|
242
|
+
"spanId": "sp_016",
|
|
243
|
+
"parentSpanId": "sp_015",
|
|
244
|
+
"name": "think",
|
|
245
|
+
"startTime": "2026-04-21T15:00:04.200Z",
|
|
246
|
+
"data": {
|
|
247
|
+
"content": "The cancelOrder tool failed because the order is already shipped. I should inform the user that shipped orders cannot be cancelled and suggest they initiate a return instead."
|
|
248
|
+
}
|
|
249
|
+
},
|
|
250
|
+
{
|
|
251
|
+
"spanId": "sp_017",
|
|
252
|
+
"parentSpanId": "sp_015",
|
|
253
|
+
"name": "end",
|
|
254
|
+
"startTime": "2026-04-21T15:00:07.900Z",
|
|
255
|
+
"data": {
|
|
256
|
+
"response": "I wasn't able to cancel order #7890 because it has already shipped. You can initiate a return once it arrives — would you like me to help with that?"
|
|
257
|
+
}
|
|
258
|
+
}
|
|
259
|
+
]
|
|
260
|
+
}
|
|
261
|
+
```
|
|
262
|
+
|
|
263
|
+
### Diagnostic summary ("What went wrong?")
|
|
264
|
+
|
|
265
|
+
> The user asked to cancel order #7890. The agent called `cancelOrder` but it failed with "Cannot cancel order in 'shipped' status" -- the order was already shipped. In the second iteration, the agent recognized the failure, informed the user that shipped orders can't be cancelled, and suggested initiating a return instead. The agent handled the error gracefully; this is expected behavior for an already-shipped order, not a bug.
|
|
266
|
+
|
|
267
|
+
### Focused summary ("Why did it suggest a return?")
|
|
268
|
+
|
|
269
|
+
> After `cancelOrder` failed with a "shipped" status error, the agent's reasoning (iteration 1 `think` span) explicitly noted that shipped orders can't be cancelled and decided to suggest a return as an alternative. This came from the model's own reasoning, not from the tool output or instructions -- it inferred the next-best action based on the error context.
|
|
270
|
+
|
|
271
|
+
---
|
|
272
|
+
|
|
273
|
+
## Patterns
|
|
274
|
+
|
|
275
|
+
✅ **Synthesize, don't transcribe**
|
|
276
|
+
|
|
277
|
+
```
|
|
278
|
+
Good: "The agent looked up the order, found it was shipped, and told the user."
|
|
279
|
+
Bad: "Span sp_004 is a think span with content 'The user is asking...' then span sp_005 is a tool_call to lookupOrder with input orderId=4521..."
|
|
280
|
+
```
|
|
281
|
+
|
|
282
|
+
✅ **Name tools and key values**
|
|
283
|
+
|
|
284
|
+
```
|
|
285
|
+
Good: "Called `lookupOrder` with orderId '4521', got status 'shipped'."
|
|
286
|
+
Bad: "A tool was called and it returned some data."
|
|
287
|
+
```
|
|
288
|
+
|
|
289
|
+
✅ **Explain causation, not just sequence**
|
|
290
|
+
|
|
291
|
+
```
|
|
292
|
+
Good: "The cancelOrder call failed because the order was already shipped, so the agent suggested a return instead."
|
|
293
|
+
Bad: "cancelOrder failed. Then the agent said to try a return."
|
|
294
|
+
```
|
|
295
|
+
|
|
296
|
+
✅ **Flag what matters for the developer's question**
|
|
297
|
+
|
|
298
|
+
```
|
|
299
|
+
Good (for "why did it fail?"): "The root cause is that cancelOrder doesn't handle shipped orders -- it throws instead of returning an error object."
|
|
300
|
+
Bad: Giving a full trace walkthrough when the developer only asked about the failure.
|
|
301
|
+
```
|
|
302
|
+
|
|
303
|
+
❌ **Don't dump raw JSON or span IDs in the summary**
|
|
304
|
+
|
|
305
|
+
Span IDs and raw field values are debugging artifacts. The summary is for understanding, not for grep. Reference tool names, error messages, and key data values instead.
|
|
306
|
+
|
|
307
|
+
❌ **Don't speculate beyond the trace data**
|
|
308
|
+
|
|
309
|
+
If the trace doesn't show why something happened, say so. Don't invent explanations.
|
|
310
|
+
|
|
311
|
+
❌ **Don't include timing unless it's notable**
|
|
312
|
+
|
|
313
|
+
A 3-second conversation turn is normal. A 45-second turn with 12 iterations is worth calling out.
|
|
@@ -0,0 +1,203 @@
|
|
|
1
|
+
# Traces & Logs
|
|
2
|
+
|
|
3
|
+
Traces and logs are the primary debugging interface for ADK agents. Every conversation turn, tool call, LLM reasoning step, and error is recorded as a trace with spans. The CLI provides structured access to all of it.
|
|
4
|
+
|
|
5
|
+
## CLI Debugging Tools
|
|
6
|
+
|
|
7
|
+
Most commands support `--format json` for structured output — **always use it** when consuming output programmatically. The exception is `adk dev`, which has no `--format` flag: use `adk dev --non-interactive` to get a structured NDJSON event stream instead.
|
|
8
|
+
|
|
9
|
+
| Command | Purpose | Options / tokens |
|
|
10
|
+
|---------|---------|-----------------|
|
|
11
|
+
| `adk check --format json` | Offline project validation — catches config/schema issues before runtime | — |
|
|
12
|
+
| `adk logs --format json` | Browse or stream log entries | `--follow`, `--summary`, level filters (`error`, `warning`) |
|
|
13
|
+
| `adk traces --format json` | Query traces with span details — filter by workflow, action, trigger, conversation, error, time | `workflow=`, `action=`, `trigger=`, `conversation=`, `trace=`, `error`, `since=`, `until=`, `limit=`, `--follow`, `--include-llm` |
|
|
14
|
+
| `adk workflows runs --format json` | List or inspect durable workflow runs by id, name, or status | `name=`, `status=`, `limit=`, `nextToken=`, `<wrkflow_id>` |
|
|
15
|
+
| `adk chat --single "msg" --format json` | Send a test message and get structured response | `--conversation-id` |
|
|
16
|
+
| `adk dev --non-interactive` | Start dev server with structured NDJSON event stream (no TUI) | — |
|
|
17
|
+
|
|
18
|
+
## Querying Logs
|
|
19
|
+
|
|
20
|
+
Logs give a high-level view of what happened. Start here before diving into traces.
|
|
21
|
+
|
|
22
|
+
```bash
|
|
23
|
+
adk logs --format json # last 50 entries
|
|
24
|
+
adk logs error --format json # errors only
|
|
25
|
+
adk logs warning --format json # warnings and above
|
|
26
|
+
adk logs warning since=1h --format json # warnings from the last hour
|
|
27
|
+
adk logs error limit=10 --format json # last 10 errors
|
|
28
|
+
adk logs --follow --format json # stream live as NDJSON
|
|
29
|
+
adk logs --summary --format json # single snapshot summary
|
|
30
|
+
```
|
|
31
|
+
|
|
32
|
+
### When to use logs vs traces
|
|
33
|
+
|
|
34
|
+
- **Logs** — quick error scanning, startup issues, integration failures, deployment problems
|
|
35
|
+
- **Traces** — detailed per-conversation analysis, tool call inspection, LLM reasoning review
|
|
36
|
+
|
|
37
|
+
## Querying Traces
|
|
38
|
+
|
|
39
|
+
Traces provide the full picture of a conversation turn: every span in order. The command takes positional filter tokens (not flags) for slicing the trace store.
|
|
40
|
+
|
|
41
|
+
```bash
|
|
42
|
+
adk traces --format json # recent traces (default limit 20)
|
|
43
|
+
adk traces error --format json # error traces only
|
|
44
|
+
adk traces workflow=<name> --format json # traces for a workflow
|
|
45
|
+
adk traces conversation=<id> --format json # traces for a conversation
|
|
46
|
+
adk traces trace=<id> --include-llm --format json # drill into one trace with LLM content
|
|
47
|
+
adk traces since=1h limit=50 --format json # last hour, up to 50
|
|
48
|
+
adk traces error --follow --format json # stream errors live (NDJSON)
|
|
49
|
+
```
|
|
50
|
+
|
|
51
|
+
Combine tokens freely (`adk traces error workflow=onboarding since=1h`). `--format` only accepts `json`; omit it for the default text output.
|
|
52
|
+
|
|
53
|
+
### Trace Structure
|
|
54
|
+
|
|
55
|
+
A trace represents one unit of agent activity. Each trace contains:
|
|
56
|
+
|
|
57
|
+
- **Trace ID** — unique identifier
|
|
58
|
+
- **Timestamp** — when the trace was recorded
|
|
59
|
+
- **Conversation ID** — which conversation it belongs to
|
|
60
|
+
- **Type** — the kind of activity
|
|
61
|
+
- **Spans** — ordered list of sub-events within the trace
|
|
62
|
+
|
|
63
|
+
### Span Types
|
|
64
|
+
|
|
65
|
+
Spans are the atomic units inside a trace. Each span has a `type` field:
|
|
66
|
+
|
|
67
|
+
| Span Type | Key Fields | What It Means |
|
|
68
|
+
|-----------|-----------|---------------|
|
|
69
|
+
| `tool_call` | `tool_name`, `input`, `output`, `success`, `error` | A tool was invoked. Check `success` to see if it worked. |
|
|
70
|
+
| `code_execution_exception` | `message`, `stackTrace` | Code error in the LLMz sandbox. Read `stackTrace` to find the source. |
|
|
71
|
+
| `think` | `content` | LLM reasoning step — shows why the model made a decision. |
|
|
72
|
+
| `end` | — | Conversation turn completed. |
|
|
73
|
+
|
|
74
|
+
### Reading a Trace
|
|
75
|
+
|
|
76
|
+
When analyzing a trace:
|
|
77
|
+
|
|
78
|
+
1. Look at spans in chronological order
|
|
79
|
+
2. Find where behavior diverges from expected
|
|
80
|
+
3. For `tool_call` spans: check `success`, read `error` if false, verify `input` matches expectations
|
|
81
|
+
4. For `think` spans: understand model reasoning before a tool call
|
|
82
|
+
5. For `code_execution_exception`: read the stack trace, correlate with source code
|
|
83
|
+
|
|
84
|
+
## Reproducing Issues with `adk chat`
|
|
85
|
+
|
|
86
|
+
Use `adk chat` to send test messages and generate fresh traces:
|
|
87
|
+
|
|
88
|
+
```bash
|
|
89
|
+
# Single message with structured output
|
|
90
|
+
adk chat --single "Hello" --format json
|
|
91
|
+
|
|
92
|
+
# Continue an existing conversation
|
|
93
|
+
adk chat --single "Follow-up message" --conversation-id <id> --format json
|
|
94
|
+
```
|
|
95
|
+
|
|
96
|
+
The JSON output includes the bot's response and conversation ID, which you can use to query traces for that specific conversation and send subsequent messages.
|
|
97
|
+
|
|
98
|
+
## Programmatic Trace Access: `onTrace` Hook
|
|
99
|
+
|
|
100
|
+
For monitoring traces in code, use the `onTrace` hook in conversation handlers. This is useful for custom logging, performance monitoring, and automated error detection. The Botpress ADK also has an OTLP endpoint that can be enabled with the `--otlp` flag on `adk dev`, if the current environment is setup for OTLP traces.
|
|
101
|
+
|
|
102
|
+
### Basic Trace Logging
|
|
103
|
+
|
|
104
|
+
```typescript
|
|
105
|
+
// src/conversations/extensions/logging.ts
|
|
106
|
+
import { Autonomous } from "@botpress/runtime";
|
|
107
|
+
|
|
108
|
+
export const onTraceLogging: Autonomous.Hooks["onTrace"] = ({ trace, iteration }) => {
|
|
109
|
+
if (trace.type === "code_execution_exception") {
|
|
110
|
+
console.error(`Code Execution Error: ${trace.message}`, trace.stackTrace);
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
if (trace.type === "tool_call" && !trace.success) {
|
|
114
|
+
console.error(
|
|
115
|
+
`Error during tool call to "${trace.tool_name}" with input "${JSON.stringify(trace.input)}":`,
|
|
116
|
+
trace.error
|
|
117
|
+
);
|
|
118
|
+
}
|
|
119
|
+
};
|
|
120
|
+
```
|
|
121
|
+
|
|
122
|
+
### Comprehensive Trace Logging
|
|
123
|
+
|
|
124
|
+
```typescript
|
|
125
|
+
export const onTraceLogging: Autonomous.Hooks["onTrace"] = ({ trace, iteration }) => {
|
|
126
|
+
switch (trace.type) {
|
|
127
|
+
case "code_execution_exception":
|
|
128
|
+
console.error(`[CODE ERROR] ${trace.message}`, trace.stackTrace);
|
|
129
|
+
break;
|
|
130
|
+
case "tool_call":
|
|
131
|
+
if (trace.success) {
|
|
132
|
+
console.log(`[TOOL SUCCESS] ${trace.tool_name}`, trace.output);
|
|
133
|
+
} else {
|
|
134
|
+
console.error(`[TOOL ERROR] ${trace.tool_name}`, trace.error);
|
|
135
|
+
}
|
|
136
|
+
break;
|
|
137
|
+
case "think":
|
|
138
|
+
console.debug(`[THINK] ${trace.content}`);
|
|
139
|
+
break;
|
|
140
|
+
default:
|
|
141
|
+
console.log(`[TRACE] ${trace.type}`, trace);
|
|
142
|
+
}
|
|
143
|
+
};
|
|
144
|
+
```
|
|
145
|
+
|
|
146
|
+
### Using in a Conversation
|
|
147
|
+
|
|
148
|
+
```typescript
|
|
149
|
+
import { Conversation } from "@botpress/runtime";
|
|
150
|
+
import { onTraceLogging } from "./extensions/logging";
|
|
151
|
+
|
|
152
|
+
export default new Conversation({
|
|
153
|
+
channel: "*",
|
|
154
|
+
handler: async ({ execute }) => {
|
|
155
|
+
await execute({
|
|
156
|
+
instructions: `You are a helpful assistant...`,
|
|
157
|
+
hooks: {
|
|
158
|
+
onTrace: (props) => onTraceLogging!(props),
|
|
159
|
+
},
|
|
160
|
+
});
|
|
161
|
+
},
|
|
162
|
+
});
|
|
163
|
+
```
|
|
164
|
+
|
|
165
|
+
### Performance Monitoring
|
|
166
|
+
|
|
167
|
+
```typescript
|
|
168
|
+
export const makePerformanceMonitor = () => {
|
|
169
|
+
const startTime = Date.now();
|
|
170
|
+
const toolStartTimes = new Map<string, number>();
|
|
171
|
+
const toolMetrics = new Map<string, number[]>();
|
|
172
|
+
|
|
173
|
+
const onBeforeTool: Autonomous.Hooks["onBeforeTool"] = async ({ tool }) => {
|
|
174
|
+
toolStartTimes.set(tool.name, Date.now());
|
|
175
|
+
};
|
|
176
|
+
|
|
177
|
+
const onAfterTool: Autonomous.Hooks["onAfterTool"] = async ({ tool }) => {
|
|
178
|
+
const start = toolStartTimes.get(tool.name);
|
|
179
|
+
const duration = start ? Date.now() - start : 0;
|
|
180
|
+
const metrics = toolMetrics.get(tool.name) || [];
|
|
181
|
+
metrics.push(duration);
|
|
182
|
+
toolMetrics.set(tool.name, metrics);
|
|
183
|
+
console.log(`[PERF] ${tool.name}: ${duration}ms`);
|
|
184
|
+
};
|
|
185
|
+
|
|
186
|
+
const onTrace: Autonomous.Hooks["onTrace"] = ({ trace }) => {
|
|
187
|
+
if (trace.type === "end") {
|
|
188
|
+
console.log(`[PERF] Total conversation: ${Date.now() - startTime}ms`);
|
|
189
|
+
console.log(`[PERF] Tool metrics:`, Object.fromEntries(toolMetrics));
|
|
190
|
+
}
|
|
191
|
+
};
|
|
192
|
+
|
|
193
|
+
return { onBeforeTool, onAfterTool, onTrace };
|
|
194
|
+
};
|
|
195
|
+
```
|
|
196
|
+
|
|
197
|
+
### Hook Reference
|
|
198
|
+
|
|
199
|
+
| Hook | Parameters | When It Fires |
|
|
200
|
+
|------|-----------|--------------|
|
|
201
|
+
| `onBeforeTool` | `{ iteration, tool, input, controller }` | Before each tool call |
|
|
202
|
+
| `onAfterTool` | `{ tool, output }` | After each tool call |
|
|
203
|
+
| `onTrace` | `{ trace, iteration }` | On every trace event |
|