@botpress/adk-cli 1.19.0-beta.4 → 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.
Files changed (65) hide show
  1. package/dist/{README-wjb7z7f0.md → README-824wa4jj.md} +1 -1
  2. package/dist/SKILL-75ym6tcj.md +257 -0
  3. package/dist/SKILL-chnwzmt1.md +548 -0
  4. package/dist/SKILL-d4bs53y3.md +244 -0
  5. package/dist/SKILL-h4b2f1n9.md +114 -0
  6. package/dist/SKILL-hbw5nt95.md +111 -0
  7. package/dist/actions-h7hxxvxr.md +823 -0
  8. package/dist/adk-build-emhwd0tg.md +39 -0
  9. package/dist/adk-debug-yrrdtpmb.md +23 -0
  10. package/dist/adk-dev-console-7z9rtjpy.md +17 -0
  11. package/dist/adk-document-ras6zzzh.md +68 -0
  12. package/dist/adk-eval-vx76dwq0.md +17 -0
  13. package/dist/adk-explain-fcsaw852.md +22 -0
  14. package/dist/adk-init-9kmxmbbe.md +30 -0
  15. package/dist/adk-ship-dybzn884.md +29 -0
  16. package/dist/adk-test-xq67savs.md +27 -0
  17. package/dist/adk-validate-1p4skv4m.md +31 -0
  18. package/dist/advanced-patterns-z86m9h1a.md +669 -0
  19. package/dist/agent-config-1aqvkrgf.md +450 -0
  20. package/dist/agent-steps-zj4c1n9t.md +115 -0
  21. package/dist/assets-q7jt8r2q.md +237 -0
  22. package/dist/autonomous-execution-fymc12e5.md +747 -0
  23. package/dist/cli-c31e06yr.md +1334 -0
  24. package/dist/cli.js +970 -566
  25. package/dist/commands.json +24 -3
  26. package/dist/common-failures-ht29w2db.md +231 -0
  27. package/dist/component-registry-bbpw0see.md +43 -0
  28. package/dist/context-api-760cvh0h.md +461 -0
  29. package/dist/conversation-analysis-8ka4nrm4.md +420 -0
  30. package/dist/conversation-lifecycle-4seqqjc1.md +311 -0
  31. package/dist/conversations-gwfvxaee.md +1111 -0
  32. package/dist/custom-components-y5wdgpey.md +167 -0
  33. package/dist/debug-workflow-vz84q80v.md +239 -0
  34. package/dist/desk-k54ktvsd.md +852 -0
  35. package/dist/doc-standards-ck6ax2jd.md +124 -0
  36. package/dist/eval-format-7n9brja4.md +354 -0
  37. package/dist/evals-y1zcr1mc.md +11 -0
  38. package/dist/explain-config-1yaq3zzd.md +424 -0
  39. package/dist/files-dzt0wxn3.md +918 -0
  40. package/dist/integration-actions-xang7tma.md +659 -0
  41. package/dist/integrations-k5ss07f4.md +266 -0
  42. package/dist/interfaces-6t0bpxs4.md +97 -0
  43. package/dist/knowledge-bases-20rg8p5c.md +456 -0
  44. package/dist/llm-debugging-76ng8rzm.md +209 -0
  45. package/dist/mcp-server-n1asyzhv.md +112 -0
  46. package/dist/messages-gkkg0b54.md +769 -0
  47. package/dist/model-configuration-f273kgd0.md +201 -0
  48. package/dist/multi-agent-dashboard-1mdfjdts.md +70 -0
  49. package/dist/pages-xn18xn73.md +273 -0
  50. package/dist/patterns-mistakes-5vb99dhf.md +469 -0
  51. package/dist/plugins-ttnx8f49.md +280 -0
  52. package/dist/tables-x45t36dd.md +1136 -0
  53. package/dist/tags-46td3qrg.md +516 -0
  54. package/dist/test-patterns-hj47w4nc.md +355 -0
  55. package/dist/testing-workflow-2vkp932f.md +225 -0
  56. package/dist/tools-wk7bq24z.md +581 -0
  57. package/dist/trace-summarization-hdyx1c2e.md +313 -0
  58. package/dist/traces-and-logs-f2kjfh19.md +203 -0
  59. package/dist/triggers-4j2cc86x.md +719 -0
  60. package/dist/ui-server-entry.js +952 -137
  61. package/dist/workflow-steps-mrdrf1c5.md +851 -0
  62. package/dist/workflows-gadx3s69.md +1408 -0
  63. package/dist/zai-agent-reference-e6644aad.md +454 -0
  64. package/dist/zai-complete-guide-mnna5d6f.md +1408 -0
  65. package/package.json +4 -4
@@ -0,0 +1,469 @@
1
+ # Patterns & Common Mistakes
2
+
3
+ Common patterns to follow and mistakes to avoid when building with the ADK.
4
+
5
+ ## Common Mistakes
6
+
7
+ ### Import Errors
8
+
9
+ #### Wrong Import Sources
10
+
11
+ ```typescript
12
+ // ❌ WRONG - Never import from these
13
+ import { z } from "zod";
14
+ import { Action } from "@botpress/sdk";
15
+ import { Workflow } from "@botpress/cli";
16
+
17
+ // ✅ CORRECT - Always import from @botpress/runtime
18
+ import { z, Action, Workflow, Conversation } from "@botpress/runtime";
19
+ ```
20
+
21
+ **Why this matters:**
22
+ - `z` from `@botpress/runtime` is Botpress's internal fork of Zod (based on Zod 3.x)
23
+ - Importing from `zod` directly can cause compatibility issues
24
+ - ADK primitives (Action, Tool, Workflow, etc.) must come from `@botpress/runtime`
25
+
26
+ **Zod Version Compatibility Note:**
27
+ Botpress uses Zod 3.x internally. If adding `zod` to your project dependencies (e.g., for frontend code), use version `3.23.8` or compatible 3.x. Zod 4.x has breaking changes and is NOT compatible with the ADK.
28
+
29
+ #### Dynamic Imports
30
+
31
+ ```typescript
32
+ // ❌ AVOID - Dynamic imports can cause issues
33
+ const { myAction } = await import("./actions/myAction");
34
+
35
+ // ✅ PREFER - Static imports
36
+ import { myAction } from "./actions/myAction";
37
+ ```
38
+
39
+ ### Handler Syntax
40
+
41
+ #### Action Handlers
42
+
43
+ Action handlers receive a props object with `input` and `client`. Both arrow functions and method syntax work fine — the handler type is `(props: ActionHandlerProps) => Promise<...>`.
44
+
45
+ ```typescript
46
+ // ✅ CORRECT - Method syntax
47
+ export const myAction = new Action({
48
+ async handler({ input }) {
49
+ return { data: input.userId };
50
+ },
51
+ });
52
+
53
+ // ✅ ALSO CORRECT - Arrow function syntax
54
+ export const myAction = new Action({
55
+ handler: async ({ input }) => {
56
+ return { data: input.userId };
57
+ },
58
+ });
59
+ ```
60
+
61
+ #### Tool Handlers
62
+
63
+ ```typescript
64
+ // ✅ Tools use arrow functions
65
+ export const myTool = new Autonomous.Tool({
66
+ handler: async ({ query, limit }) => {
67
+ return searchResults;
68
+ },
69
+ });
70
+ ```
71
+
72
+ ### State Management Mistakes
73
+
74
+ #### Conversation State Access
75
+
76
+ Conversations receive `state` as a destructured handler parameter. Do **not** use `this.state`.
77
+
78
+ ```typescript
79
+ // ❌ WRONG - this.state does not exist
80
+ export const Chat = new Conversation({
81
+ state: z.object({ count: z.number().default(0) }),
82
+ async handler({ message }) {
83
+ this.state.count += 1; // ❌ Wrong!
84
+ },
85
+ });
86
+
87
+ // ✅ CORRECT - Use the state parameter
88
+ export const Chat = new Conversation({
89
+ state: z.object({ count: z.number().default(0) }),
90
+ handler: async ({ message, state }) => {
91
+ state.count += 1; // ✅ Destructured from handler props
92
+ },
93
+ });
94
+ ```
95
+
96
+ #### State Reference vs Value
97
+
98
+ ```typescript
99
+ // ❌ WRONG - Passing state reference to async function
100
+ handler: async ({ step, state }) => {
101
+ const results = await processItems(state.items);
102
+ // state.items may have changed while processItems was running
103
+ state.items.push("new-item"); // processItems might see this!
104
+ }
105
+
106
+ // ✅ CORRECT - Pass a copy of the value
107
+ handler: async ({ step, state }) => {
108
+ const itemsCopy = [...state.items];
109
+ const results = await processItems(itemsCopy);
110
+ state.items.push("new-item"); // safe, doesn't affect processItems
111
+ }
112
+
113
+ // ✅ CORRECT - Extract values before async operation
114
+ handler: async ({ step, state }) => {
115
+ const currentCount = state.count; // Primitive - safe
116
+ const currentItems = [...state.items]; // Array - needs spread
117
+ const currentConfig = { ...state.config }; // Object - needs spread
118
+
119
+ await step("process", async () => {
120
+ return await processData(currentCount, currentItems, currentConfig);
121
+ });
122
+ }
123
+ ```
124
+
125
+ **Rules of thumb:**
126
+ - **Primitives** (string, number, boolean): Can pass directly
127
+ - **Arrays**: Use spread `[...state.items]` or `Array.from()`
128
+ - **Objects**: Use spread `{ ...state.config }` or `structuredClone()`
129
+ - **Deep objects**: Use `JSON.parse(JSON.stringify())` or `structuredClone()`
130
+
131
+ ### Workflow Step Mistakes
132
+
133
+ #### Dynamic Step Names
134
+
135
+ ```typescript
136
+ // ❌ WRONG - Dynamic step names break resume
137
+ for (let i = 0; i < items.length; i++) {
138
+ await step(`process-${i}`, async () => {
139
+ await processItem(items[i]);
140
+ });
141
+ }
142
+
143
+ // ✅ CORRECT - Single step with loop
144
+ await step("process-all", async () => {
145
+ for (const item of items) {
146
+ await processItem(item);
147
+ }
148
+ });
149
+
150
+ // ✅ CORRECT - Or use step.map
151
+ await step.map("process-items", items, async (item) => {
152
+ return processItem(item);
153
+ });
154
+ ```
155
+
156
+ #### Missing Await on Steps
157
+
158
+ ```typescript
159
+ // ❌ WRONG - Missing await
160
+ const result = step("fetch", async () => {
161
+ return fetchData();
162
+ });
163
+
164
+ // ✅ CORRECT - Always await steps
165
+ const result = await step("fetch", async () => {
166
+ return fetchData();
167
+ });
168
+ ```
169
+
170
+ ### Table Column Mistakes
171
+
172
+ #### Searchable Column Syntax
173
+
174
+ ```typescript
175
+ // ❌ WRONG - .searchable() is not a Zod method
176
+ columns: {
177
+ content: z.string().searchable()
178
+ }
179
+
180
+ // ✅ CORRECT - Object notation for searchable
181
+ columns: {
182
+ content: {
183
+ schema: z.string(),
184
+ searchable: true,
185
+ },
186
+ }
187
+ ```
188
+
189
+ ### Conversation ID Mistakes
190
+
191
+ ```typescript
192
+ // ❌ WRONG - Missing conversationId prevents communication
193
+ await MyWorkflow.start({
194
+ userId: user.id,
195
+ data: "some data",
196
+ });
197
+
198
+ // ✅ CORRECT - Include conversationId for messaging
199
+ await MyWorkflow.start({
200
+ conversationId: conversation.id,
201
+ userId: user.id,
202
+ data: "some data",
203
+ });
204
+ ```
205
+
206
+ ---
207
+
208
+ ## Common Patterns
209
+
210
+ ### Workflow Request Pattern
211
+
212
+ Request data from user during workflow execution:
213
+
214
+ ```typescript
215
+ export const MyWorkflow = new Workflow({
216
+ name: "interactive",
217
+ requests: {
218
+ topic: z.object({ topic: z.string() }),
219
+ },
220
+ handler: async ({ step, input }) => {
221
+ const { topic } = await step.request(
222
+ "topic",
223
+ "What is the topic of the question?"
224
+ );
225
+ console.log(`Topic identified: ${topic}`);
226
+ },
227
+ });
228
+ ```
229
+
230
+ ### RAG with Citations
231
+
232
+ Use citations to track sources for AI-generated responses:
233
+
234
+ ```typescript
235
+ import { Autonomous, context } from "@botpress/runtime";
236
+
237
+ const SearchTool = new Autonomous.Tool({
238
+ name: "search",
239
+ input: z.string(),
240
+ output: z.string(),
241
+ handler: async (query) => {
242
+ const client = context.get("client");
243
+ const citations = context.get("citations");
244
+
245
+ const { passages } = await client.searchFiles({
246
+ query,
247
+ tags: { type: "knowledge", kb: ["myKB"] },
248
+ });
249
+
250
+ const message = ["Here are the search results:"];
251
+ const { tag: example } = citations.registerSource({});
252
+
253
+ for (const p of passages) {
254
+ const { tag } = citations.registerSource({ file: p.file.key });
255
+ message.push(`<${tag} file="${p.file.key}">`);
256
+ message.push(`**${p.file.tags.title}**`);
257
+ message.push(p.content);
258
+ message.push(`</${tag}>`);
259
+ }
260
+
261
+ throw new Autonomous.ThinkSignal(
262
+ `When answering, MUST add inline citations (eg: "The price is $10${example} ...")`,
263
+ message.join("\n")
264
+ );
265
+ },
266
+ });
267
+ ```
268
+
269
+ ### Context Access Patterns
270
+
271
+ The context API provides access to runtime services within handlers.
272
+
273
+ #### Basic Context Usage
274
+
275
+ ```typescript
276
+ import { context } from "@botpress/runtime";
277
+
278
+ export const myAction = new Action({
279
+ handler: async ({ input }) => {
280
+ const client = context.get("client");
281
+ const cognitive = context.get("cognitive");
282
+ const logger = context.get("logger");
283
+
284
+ const { passages } = await client.searchFiles({ query: input.query });
285
+ logger.info("Search completed", { resultCount: passages.length });
286
+ return { results: passages };
287
+ },
288
+ });
289
+ ```
290
+
291
+ #### Optional Context Keys
292
+
293
+ ```typescript
294
+ export const myAction = new Action({
295
+ handler: async ({ input }) => {
296
+ const user = context.get("user", { optional: true });
297
+ const conversation = context.get("conversation", { optional: true });
298
+
299
+ if (user && conversation) {
300
+ console.log(`User ${user.id} in conversation ${conversation.id}`);
301
+ } else {
302
+ console.log("Processing without user context");
303
+ }
304
+ },
305
+ });
306
+ ```
307
+
308
+ #### Common Context Keys
309
+
310
+ **Always Available:**
311
+ - `client` — Botpress API client
312
+ - `cognitive` — AI model client
313
+ - `logger` — Structured logger
314
+ - `botId` — Current bot ID
315
+ - `configuration` — Bot configuration
316
+ - `runtime` — Runtime environment info
317
+
318
+ **Conditionally Available:**
319
+ - `user` — Current user (in conversation handlers)
320
+ - `conversation` — Current conversation (in conversation handlers, not to be used within a conversation object: use the `conversation` parameter instead)
321
+ - `message` — Incoming message (when triggered by message)
322
+ - `event` — Incoming event (when triggered by event)
323
+ - `workflow` — Current workflow (in workflow handlers)
324
+ - `integrations` — Installed integrations
325
+
326
+ #### Context in Different Handler Types
327
+
328
+ | Handler | Key context keys |
329
+ |---------|-----------------|
330
+ | **Actions** | `client`, `cognitive`, `logger`, `botId`, `configuration` |
331
+ | **Tools** | `client`, `cognitive`, `citations`, `logger`, `user`?, `conversation`? |
332
+ | **Workflows** | `client`, `workflow`, `workflowControlContext`, `logger` |
333
+ | **Conversations** | `client`, `user`, `conversation`, `message`, `event`?, `logger` |
334
+ | **Triggers** | `client`, `event`, `logger` |
335
+
336
+ ---
337
+
338
+ ## File Naming Conventions
339
+
340
+ ```
341
+ // Actions: camelCase
342
+ src/actions/fetchUser.ts
343
+ src/actions/validateOrder.ts
344
+
345
+ // Tools: camelCase
346
+ src/tools/searchDocs.ts
347
+ src/tools/createTicket.ts
348
+
349
+ // Workflows: camelCase
350
+ src/workflows/onboardUser.ts
351
+ src/workflows/processPayment.ts
352
+
353
+ // Tables: PascalCase
354
+ src/tables/Users.ts
355
+ src/tables/Orders.ts
356
+ src/tables/AuditLog.ts
357
+
358
+ // Conversations: camelCase (prefer lowercase)
359
+ src/conversations/chat.ts
360
+ src/conversations/slack.ts
361
+
362
+ // Triggers: camelCase (prefer lowercase)
363
+ src/triggers/userCreated.ts
364
+ src/triggers/linear.ts
365
+
366
+ // Knowledge: descriptive
367
+ src/knowledge/documentation.md
368
+ src/knowledge/policies/privacy.md
369
+ ```
370
+
371
+ ### Export Naming
372
+
373
+ ```typescript
374
+ // Actions
375
+ export const fetchUser = new Action({ name: "fetchUser" });
376
+
377
+ // Workflows
378
+ export const OnboardingWorkflow = new Workflow({ name: "onboarding" });
379
+
380
+ // Tables
381
+ export const UsersTable = new Table({ name: "users" });
382
+
383
+ // Conversations
384
+ export const Chat = new Conversation({ channel: "chat.channel" });
385
+
386
+ // Triggers - use default export
387
+ export default new Trigger({ name: "userEvents" });
388
+ ```
389
+
390
+ ---
391
+
392
+ ## Best Practices Summary
393
+
394
+ ### DO's
395
+
396
+ 1. Import from `@botpress/runtime`
397
+ 2. Use `state` parameter in conversation handlers (not `this.state`)
398
+ 3. Pass state values by copy, not reference
399
+ 4. Use stable step names in workflows
400
+ 5. Always await step functions
401
+ 6. Pass `conversationId` to workflows that communicate
402
+ 7. Use object notation for searchable columns
403
+ 8. Provide defaults in state schemas
404
+ 9. Handle errors gracefully
405
+ 10. Prefer parameter destructuring in handlers when available
406
+
407
+ ### DON'Ts
408
+
409
+ 1. Don't import from `zod` or `@botpress/sdk` directly
410
+ 2. Don't use `this.state` in conversations (use the `state` parameter)
411
+ 3. Don't pass state references to async functions (copy arrays/objects)
412
+ 4. Don't use dynamic step names
413
+ 5. Don't forget to await steps
414
+ 6. Don't start workflows without `conversationId` if they need to message
415
+ 7. Don't use `.searchable()` chain notation
416
+ 8. Don't hardcode secrets in configuration
417
+ 9. Don't use dynamic imports unless necessary
418
+
419
+ ---
420
+
421
+ ## Debugging Tips
422
+
423
+ ### Check Imports
424
+
425
+ ```bash
426
+ # Find incorrect imports
427
+ grep -r "from \"zod\"" src/
428
+ grep -r "from \"@botpress/sdk\"" src/
429
+ ```
430
+
431
+ ### Debug State Access
432
+
433
+ ```typescript
434
+ // In conversations - use state parameter
435
+ handler: async ({ state }) => {
436
+ console.log("Conversation state:", JSON.stringify(state, null, 2));
437
+ }
438
+
439
+ // In workflows - use state parameter
440
+ handler: async ({ state }) => {
441
+ console.log("Workflow state:", JSON.stringify(state, null, 2));
442
+ }
443
+ ```
444
+
445
+ ### Trace Workflow Steps
446
+
447
+ ```typescript
448
+ handler: async ({ step }) => {
449
+ console.log("Starting workflow");
450
+
451
+ const result = await step("step1", async () => {
452
+ console.log("Executing step1");
453
+ return "data";
454
+ });
455
+
456
+ console.log("Step1 result:", result);
457
+ }
458
+ ```
459
+
460
+ ---
461
+
462
+ ## See Also
463
+
464
+ - [./actions.md](./actions.md) — Action handler reference
465
+ - [./conversations.md](./conversations.md) — Conversation handlers
466
+ - [./workflows.md](./workflows.md) — Workflow patterns
467
+ - [./tables.md](./tables.md) — Table column syntax
468
+ - [./context-api.md](./context-api.md) — Context API details
469
+ - [./advanced-patterns.md](./advanced-patterns.md) — Guardrails, admin auth, observability