@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,747 @@
1
+ # Autonomous Execution
2
+
3
+ The `execute()` function is the core of AI-powered behavior in ADK bots. It runs a code-generating LLM in a sandboxed loop: the model writes TypeScript, the runtime executes it, and the loop continues until an exit is reached or iterations are exhausted.
4
+
5
+ This reference covers **Objects, Exits, execution hooks, and configuration options**. For basic tool definition and handler patterns, see [tools.md](./tools.md).
6
+
7
+ ## execute() Full API
8
+
9
+ `execute()` is provided as a parameter in conversation handlers and is also available in workflows. It accepts these properties:
10
+
11
+ ```typescript
12
+ type Props = {
13
+ /** System prompt guiding the LLM. Can be static or dynamic per iteration. */
14
+ instructions: string | ((ctx: Context) => string | Promise<string>)
15
+
16
+ /** AI-callable tools. See tools.md for creation patterns. */
17
+ tools?: Tool[] | ((ctx: Context) => Tool[] | Promise<Tool[]>)
18
+
19
+ /** Namespaced objects with properties and scoped tools. */
20
+ objects?: Object[] | ((ctx: Context) => Object[] | Promise<Object[]>)
21
+
22
+ /** Structured termination points. Controls how execution ends. */
23
+ exits?: Exit[] | ((ctx: Context) => Exit[] | Promise<Exit[]>)
24
+
25
+ /** Execution lifecycle hooks. */
26
+ hooks?: Hooks
27
+
28
+ /** LLM temperature (0-2). Default: 0.7 */
29
+ temperature?: number | ((ctx: Context) => number | Promise<number>)
30
+
31
+ /** Model or fallback chain. Uses agent config default if omitted. */
32
+ model?: Model | Model[] | ((ctx: Context) => Model | Model[] | Promise<Model | Model[]>)
33
+
34
+ /** Reasoning effort for models that support it. */
35
+ reasoningEffort?: 'low' | 'medium' | 'high' | 'dynamic' | 'none'
36
+
37
+ /** Knowledge bases for RAG. Adds a search_knowledge tool automatically. */
38
+ knowledge?: BaseKnowledge[]
39
+
40
+ /** Maximum iteration loops. Default: 10. Clamped to 1-100. */
41
+ iterations?: number
42
+
43
+ /** AbortSignal to cancel execution externally. */
44
+ signal?: AbortSignal
45
+ }
46
+ ```
47
+
48
+ Every property except `instructions` is optional. Most properties accept a **ValueOrGetter** — either a static value or a function receiving the current execution context that returns the value (optionally async). This lets you change tools, objects, or instructions between iterations based on what happened previously.
49
+
50
+ ## Exits
51
+
52
+ Exits define the structured ways an execution can terminate. The LLM ends execution by writing `return { action: 'exit_name', ...data }` in its generated code.
53
+
54
+ ### Creating Exits
55
+
56
+ ```typescript
57
+ import { Autonomous, z } from '@botpress/runtime'
58
+
59
+ // Simple exit (no data)
60
+ const Done = new Autonomous.Exit({
61
+ name: 'done',
62
+ description: 'Task is complete',
63
+ })
64
+
65
+ // Exit with typed data
66
+ const TriageComplete = new Autonomous.Exit({
67
+ name: 'triage_complete',
68
+ description: 'Classification is done and the user has been notified.',
69
+ schema: z.object({
70
+ category: z.string().describe('The category the request was classified as'),
71
+ }),
72
+ })
73
+
74
+ // Exit with aliases
75
+ const Escalate = new Autonomous.Exit({
76
+ name: 'escalate',
77
+ aliases: ['transfer', 'handoff'],
78
+ description: 'Escalate to a human agent',
79
+ schema: z.object({
80
+ reason: z.enum(['frustrated', 'technical', 'sensitive', 'other']),
81
+ priority: z.enum(['low', 'medium', 'high']).default('medium'),
82
+ }),
83
+ })
84
+
85
+ // Exit with metadata for orchestration
86
+ const Handoff = new Autonomous.Exit({
87
+ name: 'handoff_sales',
88
+ description: 'Transfer to sales team',
89
+ metadata: { department: 'sales', type: 'handoff' },
90
+ schema: z.object({ reason: z.string() }),
91
+ })
92
+ ```
93
+
94
+ ### Exit Constructor
95
+
96
+ ```typescript
97
+ new Autonomous.Exit<T>({
98
+ name: string // Required. Valid TypeScript identifier.
99
+ description: string // Required. Tells the LLM when to use this exit.
100
+ schema?: ZuiType<T> // Optional. Zod schema for validated return data.
101
+ aliases?: string[] // Optional. Alternative names the LLM can use.
102
+ metadata?: Record<string, unknown> // Optional. Custom data for orchestration.
103
+ })
104
+ ```
105
+
106
+ ### Using Exits in execute()
107
+
108
+ ```typescript
109
+ export const SlackDM = new Conversation({
110
+ channel: 'slack.dm',
111
+
112
+ async handler({ execute }) {
113
+ const result = await execute({
114
+ instructions: `Classify the user's request, tell them the result, then exit.`,
115
+ tools: [classifyRequest.asTool()],
116
+ exits: [TriageComplete],
117
+ })
118
+
119
+ // Type-safe result checking
120
+ if (result.is(TriageComplete)) {
121
+ console.log(`Triaged as: ${result.output.category}`)
122
+ }
123
+ },
124
+ })
125
+ ```
126
+
127
+ ### Multiple Exits for Branching
128
+
129
+ ```typescript
130
+ const Approved = new Autonomous.Exit({
131
+ name: 'approved',
132
+ description: 'Loan application approved',
133
+ schema: z.object({ amount: z.number(), reference: z.string() }),
134
+ })
135
+
136
+ const Rejected = new Autonomous.Exit({
137
+ name: 'rejected',
138
+ description: 'Loan application rejected',
139
+ schema: z.object({ reason: z.string() }),
140
+ })
141
+
142
+ const result = await execute({
143
+ instructions: 'Review and decide on the loan application.',
144
+ tools: [creditCheckTool, reviewTool],
145
+ exits: [Approved, Rejected],
146
+ })
147
+
148
+ if (result.is(Approved)) {
149
+ console.log(`Approved: $${result.output.amount} (ref: ${result.output.reference})`)
150
+ } else if (result.is(Rejected)) {
151
+ console.log(`Rejected: ${result.output.reason}`)
152
+ }
153
+ ```
154
+
155
+ ### Built-in Exits
156
+
157
+ Three exits are built into the runtime. Do not redefine them.
158
+
159
+ | Exit | When Available | Action Name | Purpose |
160
+ |------|----------------|-------------|---------|
161
+ | **ListenExit** | Chat mode (conversation handlers) | `listen` | Pauses execution, returns control to the user. Auto-added when `execute()` runs in a conversation. |
162
+ | **ThinkExit** | Always | `think` | LLM pauses to reflect. Triggers another iteration (does not end execution). |
163
+ | **DefaultExit** | Worker mode, when no custom exits provided | `done` | Returns `{ success: true, result? }` or `{ success: false, error }`. |
164
+
165
+ ```typescript
166
+ import { Autonomous } from '@botpress/runtime'
167
+
168
+ // Check for built-in exits
169
+ if (result.is(Autonomous.ListenExit)) {
170
+ // Agent is waiting for user input
171
+ }
172
+
173
+ if (result.is(Autonomous.DefaultExit)) {
174
+ if (result.output.success) {
175
+ console.log('Result:', result.output.result)
176
+ } else {
177
+ console.error('Error:', result.output.error)
178
+ }
179
+ }
180
+ ```
181
+
182
+ **Chat mode behavior**: In conversation handlers, `ListenExit` is added automatically. When no custom exits are provided the LLM will use `ListenExit` to hand control back after responding. When you provide custom exits, both your exits and `ListenExit` are available.
183
+
184
+ **Worker mode behavior**: When `execute()` runs without a chat context (e.g. in a workflow or standalone), `ListenExit` is not available. If no custom exits are provided, `DefaultExit` is added automatically.
185
+
186
+ ### Exit Utilities
187
+
188
+ ```typescript
189
+ // Clone and rename an exit
190
+ const customExit = baseExit.clone().rename('custom')
191
+
192
+ // Deduplicate exit names
193
+ const uniqueExits = Autonomous.Exit.withUniqueNames([exit1, exit2])
194
+
195
+ // Match an exit result
196
+ if (someExit.match(exitResult)) {
197
+ // exitResult is typed as ExitResult<T>
198
+ }
199
+ ```
200
+
201
+ ## Objects
202
+
203
+ Objects group related properties and tools into a namespace. The LLM sees them as TypeScript namespaces with typed constants and methods.
204
+
205
+ ### Creating Objects
206
+
207
+ ```typescript
208
+ import { Autonomous, z } from '@botpress/runtime'
209
+
210
+ const userProfile = new Autonomous.Object({
211
+ name: 'user',
212
+ description: 'Current user profile data',
213
+ properties: [
214
+ {
215
+ name: 'name',
216
+ value: 'John Doe',
217
+ type: z.string().min(1),
218
+ description: 'User full name',
219
+ writable: true,
220
+ },
221
+ {
222
+ name: 'email',
223
+ value: null,
224
+ type: z.string().email().nullable(),
225
+ description: 'User email address',
226
+ writable: true,
227
+ },
228
+ {
229
+ name: 'id',
230
+ value: 'user_123',
231
+ writable: false, // Read-only — LLM cannot modify
232
+ },
233
+ ],
234
+ })
235
+ ```
236
+
237
+ The LLM sees this as:
238
+
239
+ ```typescript
240
+ export namespace user {
241
+ const name: Writable<string> = "John Doe"
242
+ const email: Writable<string | null> = null
243
+ const id: Readonly<string> = "user_123"
244
+ }
245
+ ```
246
+
247
+ ### Object Constructor
248
+
249
+ ```typescript
250
+ new Autonomous.Object({
251
+ name: string // Required. Valid TypeScript identifier.
252
+ description?: string // What this object represents.
253
+ properties?: ObjectProperty[] // Stateful variables (max 100).
254
+ tools?: Tool[] // Scoped tools (called as obj.toolName()).
255
+ metadata?: Record<string, unknown>
256
+ })
257
+ ```
258
+
259
+ ### ObjectProperty
260
+
261
+ ```typescript
262
+ type ObjectProperty = {
263
+ name: string // Valid TypeScript identifier.
264
+ value: any // Current value.
265
+ type?: ZuiType // Zod schema for validation on write.
266
+ description?: string // Helps the LLM understand the property.
267
+ writable?: boolean // Default: false. If true, LLM can assign new values.
268
+ }
269
+ ```
270
+
271
+ ### Objects with Scoped Tools
272
+
273
+ Tools on an object are called as `objectName.toolName()` by the LLM:
274
+
275
+ ```typescript
276
+ const fileSystem = new Autonomous.Object({
277
+ name: 'fs',
278
+ description: 'File system operations',
279
+ tools: [
280
+ new Autonomous.Tool({
281
+ name: 'readFile',
282
+ input: z.object({ path: z.string() }),
283
+ output: z.string(),
284
+ handler: async ({ path }) => readFileSync(path, 'utf8'),
285
+ }),
286
+ new Autonomous.Tool({
287
+ name: 'writeFile',
288
+ input: z.object({ path: z.string(), content: z.string() }),
289
+ handler: async ({ path, content }) => writeFileSync(path, content),
290
+ }),
291
+ ],
292
+ })
293
+
294
+ // LLM can call: fs.readFile({ path: '/tmp/data.txt' })
295
+ // LLM can call: fs.writeFile({ path: '/tmp/out.txt', content: '...' })
296
+ ```
297
+
298
+ ### Dynamic Objects
299
+
300
+ Pass a function instead of an array to rebuild objects each iteration, reflecting current state:
301
+
302
+ ```typescript
303
+ const memory: Record<string, any> = {}
304
+
305
+ await execute({
306
+ instructions: 'Collect user information.',
307
+ objects: () => [
308
+ new Autonomous.Object({
309
+ name: 'form',
310
+ properties: [
311
+ {
312
+ name: 'name',
313
+ value: memory.name ?? null,
314
+ type: z.string().nullable(),
315
+ writable: true,
316
+ },
317
+ {
318
+ name: 'age',
319
+ value: memory.age ?? null,
320
+ type: z.number().min(0).max(150).nullable(),
321
+ writable: true,
322
+ },
323
+ ],
324
+ }),
325
+ ],
326
+ hooks: {
327
+ onTrace: ({ trace }) => {
328
+ if (trace.type === 'property') {
329
+ memory[trace.property] = trace.value
330
+ }
331
+ },
332
+ },
333
+ })
334
+ ```
335
+
336
+ ### Using Objects in execute()
337
+
338
+ ```typescript
339
+ await execute({
340
+ instructions: 'You have access to the user profile. Update fields as needed.',
341
+ objects: [userProfile],
342
+ tools: [saveProfileTool],
343
+ })
344
+ ```
345
+
346
+ ## Execution Hooks
347
+
348
+ Hooks let you observe and modify the execution loop. They are passed in the `hooks` property of `execute()`.
349
+
350
+ ### Hook Reference
351
+
352
+ ```typescript
353
+ type Hooks = {
354
+ /** NON-BLOCKING. Called for each trace (log, tool call, LLM call, etc). */
355
+ onTrace?: (props: { trace: Trace; iteration: number }) => void
356
+
357
+ /** BLOCKING. Called before each iteration. Can modify iteration parameters. */
358
+ onIterationStart?: (
359
+ iteration: Iteration,
360
+ controller: AbortController,
361
+ context: Context
362
+ ) => Promise<void | Partial<Iteration>> | void | Partial<Iteration>
363
+
364
+ /** BLOCKING. Called after each iteration. Good for logging and cleanup. */
365
+ onIterationEnd?: (
366
+ iteration: Iteration,
367
+ controller: IterationController
368
+ ) => void | Promise<void>
369
+
370
+ /** BLOCKING. Called when an exit is reached. Throw to reject the exit. */
371
+ onExit?: <T = unknown>(result: ExitResult<T>) => Promise<void> | void
372
+
373
+ /** BLOCKING, MUTATION. Called after LLM generates code, before execution. */
374
+ onBeforeExecution?: (
375
+ iteration: Iteration,
376
+ controller: AbortController
377
+ ) => Promise<{ code?: string } | void>
378
+
379
+ /** BLOCKING, MUTATION. Called before any tool executes. Can modify input. */
380
+ onBeforeTool?: (event: {
381
+ iteration: Iteration
382
+ tool: Tool
383
+ input: unknown
384
+ controller: AbortController
385
+ }) => Promise<{ input?: unknown } | void>
386
+
387
+ /** BLOCKING, MUTATION. Called after a tool executes. Can modify output. */
388
+ onAfterTool?: (event: {
389
+ iteration: Iteration
390
+ tool: Tool
391
+ input: unknown
392
+ output: unknown
393
+ controller: AbortController
394
+ }) => Promise<{ output?: unknown } | void>
395
+ }
396
+ ```
397
+
398
+ ### Hook Categories
399
+
400
+ | Category | Hooks | Behavior |
401
+ |----------|-------|----------|
402
+ | **Non-blocking** | `onTrace` | Fire-and-forget. Cannot delay execution. |
403
+ | **Blocking, mutation** | `onIterationStart`, `onBeforeTool`, `onAfterTool`, `onBeforeExecution` | Block until resolved. Can return modified values. |
404
+ | **Blocking, non-mutation** | `onIterationEnd`, `onExit` | Block until resolved. Cannot change tool I/O or code. |
405
+
406
+ ### Common Hook Patterns
407
+
408
+ **Logging tool calls:**
409
+
410
+ ```typescript
411
+ await execute({
412
+ instructions: 'Help the user',
413
+ tools: [searchTool, ticketTool],
414
+ hooks: {
415
+ onBeforeTool: async ({ tool, input }) => {
416
+ console.log(`[tool:start] ${tool.name}`, JSON.stringify(input))
417
+ },
418
+ onAfterTool: async ({ tool, input, output }) => {
419
+ console.log(`[tool:end] ${tool.name}`, JSON.stringify(output))
420
+ },
421
+ },
422
+ })
423
+ ```
424
+
425
+ **Modifying tool input (e.g. appending search scope):**
426
+
427
+ ```typescript
428
+ hooks: {
429
+ onBeforeTool: async ({ tool, input }) => {
430
+ if (tool.name === 'search') {
431
+ return { input: { ...input, query: `${input.query} site:docs.example.com` } }
432
+ }
433
+ },
434
+ }
435
+ ```
436
+
437
+ **Rejecting an exit (forces the LLM to keep iterating):**
438
+
439
+ ```typescript
440
+ hooks: {
441
+ onExit: async (result) => {
442
+ if (result.exit.name === 'done' && !result.result?.confirmed) {
443
+ throw new Error('Must confirm before exiting')
444
+ }
445
+ },
446
+ }
447
+ ```
448
+
449
+ **Aborting execution from a hook:**
450
+
451
+ ```typescript
452
+ hooks: {
453
+ onBeforeTool: async ({ controller }) => {
454
+ if (shouldStop()) {
455
+ controller.abort()
456
+ }
457
+ },
458
+ }
459
+ ```
460
+
461
+ **Modifying generated code before execution:**
462
+
463
+ ```typescript
464
+ hooks: {
465
+ onBeforeExecution: async (iteration) => {
466
+ // Inject a safety wrapper or strip dangerous patterns
467
+ const modified = iteration.code?.replace(/dangerousCall\(\)/g, '/* blocked */')
468
+ return { code: modified }
469
+ },
470
+ }
471
+ ```
472
+
473
+ **Tracking property mutations via onTrace:**
474
+
475
+ ```typescript
476
+ hooks: {
477
+ onTrace: ({ trace }) => {
478
+ if (trace.type === 'property') {
479
+ console.log(`${trace.object}.${trace.property} = ${trace.value}`)
480
+ }
481
+ },
482
+ }
483
+ ```
484
+
485
+ ## Execution Result
486
+
487
+ `execute()` returns an `ExecutionResult` with three possible statuses:
488
+
489
+ ```typescript
490
+ const result = await execute({ instructions: '...' })
491
+
492
+ // Status checks
493
+ result.isSuccess() // Completed with an exit
494
+ result.isError() // Failed (aborted, iterations exhausted)
495
+ result.isInterrupted() // Paused with a snapshot (SnapshotSignal)
496
+
497
+ // Exit type-narrowing
498
+ result.is(MyExit) // true if exited via MyExit, narrows result.output type
499
+
500
+ // Access execution data
501
+ result.iteration // Last iteration (or null)
502
+ result.iterations // All iterations
503
+ result.output // Exit data (if success), null otherwise
504
+ result.context // Full execution context
505
+ ```
506
+
507
+ ### Success Result
508
+
509
+ ```typescript
510
+ if (result.isSuccess()) {
511
+ console.log('Exit:', result.result.exit.name)
512
+ console.log('Output:', result.output)
513
+ console.log('Code:', result.iteration.code)
514
+ }
515
+
516
+ // Typed exit checking (preferred)
517
+ if (result.is(TriageComplete)) {
518
+ // result.output is typed as { category: string }
519
+ console.log(result.output.category)
520
+ }
521
+ ```
522
+
523
+ ### Error Result
524
+
525
+ ```typescript
526
+ if (result.isError()) {
527
+ console.error('Failed:', result.error)
528
+ // Inspect the last iteration for details
529
+ const last = result.iteration
530
+ if (last?.status.type === 'execution_error') {
531
+ console.error(last.status.execution_error.message)
532
+ }
533
+ }
534
+ ```
535
+
536
+ ### Interrupted Result (Snapshots)
537
+
538
+ When a tool throws `SnapshotSignal`, execution pauses and can be resumed later:
539
+
540
+ ```typescript
541
+ if (result.isInterrupted()) {
542
+ const snapshot = result.snapshot.toJSON()
543
+ // Persist snapshot, resume later with: execute({ snapshot, ... })
544
+ }
545
+ ```
546
+
547
+ ## Configuration Options
548
+
549
+ ### Model Selection
550
+
551
+ ```typescript
552
+ await execute({
553
+ instructions: '...',
554
+ model: 'openai:gpt-4o', // Single model
555
+ })
556
+
557
+ await execute({
558
+ instructions: '...',
559
+ model: ['openai:gpt-4o', 'anthropic:claude-3-5-sonnet'], // Fallback chain
560
+ })
561
+
562
+ // Dynamic model per iteration
563
+ await execute({
564
+ instructions: '...',
565
+ model: (ctx) => ctx.iteration > 2 ? 'openai:gpt-4o' : 'openai:gpt-4o-mini',
566
+ })
567
+ ```
568
+
569
+ If `model` is omitted, the `defaultModels.autonomous` value from `agent.config.ts` is used.
570
+
571
+ ### Temperature
572
+
573
+ ```typescript
574
+ await execute({
575
+ instructions: '...',
576
+ temperature: 0.1, // Low = deterministic. Default: 0.7. Range: 0-2.
577
+ })
578
+ ```
579
+
580
+ ### Reasoning Effort
581
+
582
+ ```typescript
583
+ await execute({
584
+ instructions: '...',
585
+ reasoningEffort: 'high', // 'none' | 'low' | 'medium' | 'high' | 'dynamic'
586
+ })
587
+ ```
588
+
589
+ - `'none'` disables reasoning for models with optional reasoning.
590
+ - `'dynamic'` lets the provider decide.
591
+ - Omitting this field disables reasoning for optional-reasoning models.
592
+
593
+ ### Iteration Limit
594
+
595
+ ```typescript
596
+ await execute({
597
+ instructions: '...',
598
+ iterations: 20, // Default: 10. Clamped to 1-100.
599
+ })
600
+ ```
601
+
602
+ Each "iteration" is one LLM generation + code execution cycle. The LLM can call multiple tools in a single iteration. `ThinkExit` consumes one iteration. If iterations are exhausted without an exit, the result is an error.
603
+
604
+ ### AbortSignal
605
+
606
+ ```typescript
607
+ const controller = new AbortController()
608
+ setTimeout(() => controller.abort(), 30_000)
609
+
610
+ await execute({
611
+ instructions: '...',
612
+ signal: controller.signal,
613
+ })
614
+ ```
615
+
616
+ When aborted, the current LLM generation and sandbox execution are killed immediately. The result status will be `error` with an aborted iteration.
617
+
618
+ ## Dynamic Properties (ValueOrGetter)
619
+
620
+ Most `execute()` properties accept either a static value or a function that receives the execution context:
621
+
622
+ ```typescript
623
+ // Static
624
+ tools: [searchTool, ticketTool]
625
+
626
+ // Dynamic — re-evaluated each iteration
627
+ tools: (ctx) => {
628
+ if (ctx.iteration > 0) {
629
+ return [searchTool, ticketTool, escalateTool]
630
+ }
631
+ return [searchTool]
632
+ }
633
+
634
+ // Async dynamic
635
+ instructions: async (ctx) => {
636
+ const rules = await fetchRules()
637
+ return `Follow these rules: ${rules}`
638
+ }
639
+ ```
640
+
641
+ This pattern applies to `instructions`, `tools`, `objects`, `exits`, `temperature`, and `model`.
642
+
643
+ ## Chat Mode vs Worker Mode
644
+
645
+ `execute()` behaves differently depending on where it runs:
646
+
647
+ | Aspect | Chat Mode (Conversations) | Worker Mode (Workflows, Actions) |
648
+ |--------|--------------------------|----------------------------------|
649
+ | Transcript | LLM sees conversation history | No transcript |
650
+ | ListenExit | Auto-added | Not available |
651
+ | DefaultExit | Not auto-added when exits provided | Auto-added when no exits provided |
652
+ | Components | Can yield UI components | No component rendering |
653
+ | Typical pattern | Open-ended conversation | Task completion with structured exit |
654
+
655
+ In conversation handlers, `execute()` is provided as a parameter and runs in chat mode by default:
656
+
657
+ ```typescript
658
+ export const Chat = new Conversation({
659
+ channel: 'chat.channel',
660
+ async handler({ execute }) {
661
+ await execute({
662
+ instructions: 'You are a helpful assistant.',
663
+ tools: [searchTool],
664
+ })
665
+ // After execute(), the LLM used ListenExit to return control
666
+ },
667
+ })
668
+ ```
669
+
670
+ For lifecycle event handling (nudge/expire) in conversations, see [conversation-lifecycle.md](./conversation-lifecycle.md).
671
+
672
+ ## Common Patterns
673
+
674
+ ### Classify-and-exit (single-shot)
675
+
676
+ ```typescript
677
+ const Category = new Autonomous.Exit({
678
+ name: 'categorized',
679
+ description: 'Message has been categorized',
680
+ schema: z.object({
681
+ category: z.enum(['billing', 'technical', 'general']),
682
+ confidence: z.number().min(0).max(1),
683
+ }),
684
+ })
685
+
686
+ const result = await execute({
687
+ instructions: 'Classify the user message into a category.',
688
+ exits: [Category],
689
+ iterations: 3,
690
+ })
691
+
692
+ if (result.is(Category)) {
693
+ await routeToTeam(result.output.category)
694
+ }
695
+ ```
696
+
697
+ ### Chaining execute() calls
698
+
699
+ ```typescript
700
+ async handler({ execute }) {
701
+ // First pass: classify
702
+ const result = await execute({
703
+ instructions: 'Classify the request and respond.',
704
+ tools: [classifyTool],
705
+ exits: [TriageComplete],
706
+ })
707
+
708
+ // Second pass: follow-up
709
+ if (result.is(TriageComplete) && result.output.category === 'technical') {
710
+ await execute({
711
+ instructions: 'Ask for technical details and create a ticket.',
712
+ tools: [createTicketTool],
713
+ })
714
+ }
715
+ }
716
+ ```
717
+
718
+ ### Open-ended conversation (no custom exits)
719
+
720
+ ```typescript
721
+ await execute({
722
+ instructions: 'You are an IT help desk assistant.',
723
+ tools: [createTicket, lookupTicket, updateTicket, deleteTicket],
724
+ knowledge: [DocsKB],
725
+ })
726
+ // LLM uses ListenExit to return control after each response
727
+ ```
728
+
729
+ ## Pitfalls
730
+
731
+ - **Do not redefine built-in exits.** Creating an exit named `listen`, `think`, or `done` will conflict with the built-in ListenExit, ThinkExit, and DefaultExit.
732
+ - **Exits require good descriptions.** The LLM decides which exit to use based on the `description`. Vague descriptions lead to wrong exit selection.
733
+ - **Writable properties need a schema.** If `writable: true` without `type`, the sandbox cannot validate writes and they will be unchecked.
734
+ - **Object property limit is 100.** More than 100 properties on a single object will throw.
735
+ - **ThinkExit consumes an iteration.** If your iteration limit is low and the LLM thinks frequently, it may exhaust iterations before finishing. Increase `iterations` for complex tasks.
736
+ - **Blocking hooks delay execution.** All hooks except `onTrace` are async and block the loop. Keep hook logic fast.
737
+ - **onExit throw = retry.** Throwing in `onExit` rejects the exit and the LLM gets the error as context for the next iteration. Use this deliberately.
738
+
739
+ ## See Also
740
+
741
+ - [Tools](./tools.md) — Tool creation, handler syntax, ThinkSignal, advanced properties
742
+ - [Conversations](./conversations.md) — Conversation handlers, message routing, channel IDs
743
+ - [Workflows](./workflows.md) — Long-running processes, step-based execution
744
+ - [Context API](./context-api.md) — Accessing runtime services and state
745
+ - [Model Configuration](./model-configuration.md) — Model selection and defaults
746
+ - [Workflow Steps](./workflow-steps.md) — Step API reference for using execute() within workflow handlers
747
+ - [Conversation Lifecycle](./conversation-lifecycle.md) — Lifecycle events (nudge/expire) that also receive execute as a handler prop