create-leafmesh 2.1.0__py3-none-any.whl

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 (31) hide show
  1. create_leafmesh/__init__.py +3 -0
  2. create_leafmesh/cli.py +252 -0
  3. create_leafmesh/create.py +106 -0
  4. create_leafmesh/templates/Dockerfile +21 -0
  5. create_leafmesh/templates/README.md +309 -0
  6. create_leafmesh/templates/agency/__init__.py +0 -0
  7. create_leafmesh/templates/agency/advisor_agent.py +151 -0
  8. create_leafmesh/templates/agency/external_agents.py +278 -0
  9. create_leafmesh/templates/agency/fallback_researcher_agent.py +80 -0
  10. create_leafmesh/templates/agency/greeter_agent.py +79 -0
  11. create_leafmesh/templates/agency/processor_agent.py +90 -0
  12. create_leafmesh/templates/agency/researcher_agent.py +99 -0
  13. create_leafmesh/templates/agency/scheduler_agent.py +67 -0
  14. create_leafmesh/templates/agency/tools.py +123 -0
  15. create_leafmesh/templates/claude_skills/leafmesh/SKILL.md +2049 -0
  16. create_leafmesh/templates/claude_skills/leafmesh/agent-config-fields.md +1309 -0
  17. create_leafmesh/templates/claude_skills/leafmesh/examples.md +537 -0
  18. create_leafmesh/templates/claude_skills/leafmesh/reference.md +492 -0
  19. create_leafmesh/templates/configs/config.yaml +1028 -0
  20. create_leafmesh/templates/docker-compose.yml +28 -0
  21. create_leafmesh/templates/dockerignore +17 -0
  22. create_leafmesh/templates/env +109 -0
  23. create_leafmesh/templates/gitignore +33 -0
  24. create_leafmesh/templates/hitl_stub_receiver.py +149 -0
  25. create_leafmesh/templates/main.py +105 -0
  26. create_leafmesh/templates/requirements.txt +10 -0
  27. create_leafmesh-2.1.0.dist-info/METADATA +6 -0
  28. create_leafmesh-2.1.0.dist-info/RECORD +31 -0
  29. create_leafmesh-2.1.0.dist-info/WHEEL +5 -0
  30. create_leafmesh-2.1.0.dist-info/entry_points.txt +2 -0
  31. create_leafmesh-2.1.0.dist-info/top_level.txt +1 -0
@@ -0,0 +1,1309 @@
1
+ # LeafMesh Agent Configuration — Complete Field Reference
2
+
3
+ This document lists every configuration field, its type, default value, and accepted values. Use this to build frontend forms, dropdowns, and validation.
4
+
5
+ ---
6
+
7
+ ## Table of Contents
8
+
9
+ 1. [Agent Types](#agent-types)
10
+ 2. [AgentConfig — Core Fields (All Types)](#agentconfig--core-fields-all-types)
11
+ 3. [LLM Agent Fields](#llm-agent-fields-agent_type-llm)
12
+ 4. [Human Agent Fields](#human-agent-fields-agent_type-human)
13
+ 5. [External Agent Fields](#external-agent-fields-agent_type-external)
14
+ 6. [Programmatic Agent Fields](#programmatic-agent-fields-agent_type-programmatic)
15
+ 7. [WebhookConfig](#webhookconfig)
16
+ 8. [ChannelConfig](#channelconfig)
17
+ 9. [Memory Config](#memory-config)
18
+ 10. [EscalationConfig](#escalationconfig)
19
+ 11. [EscalationTarget](#escalationtarget)
20
+ 12. [Top-Level Config (LeafMeshConfig)](#top-level-config-leafmeshconfig)
21
+ 13. [ManagerConfig](#managerconfig)
22
+ 14. [MeshConfig & Cloud Providers](#meshconfig--cloud-providers)
23
+ 15. [RedisConfig](#redisconfig)
24
+ 16. [EvolutionConfig](#evolutionconfig)
25
+ 17. [DataStructure](#datastructure)
26
+ 18. [Entry Points](#entry-points)
27
+ 19. [Validation Rules](#validation-rules)
28
+ 20. [Field Applicability by Agent Type](#field-applicability-by-agent-type)
29
+
30
+ ---
31
+
32
+ ## Agent Types
33
+
34
+ | Value | Description |
35
+ |-------|-------------|
36
+ | `llm` | LLM-powered agent (default). Executes via OpenAI, Claude, Bedrock, Vertex, or Foundry. |
37
+ | `human` | Human operator agent. Routes to a person via API, webhook, or channel. |
38
+ | `programmatic` | Python function with business logic. No LLM calls. |
39
+ | `external` | Delegates to an external framework (CrewAI, LangGraph, AutoGen, etc.). |
40
+
41
+ ---
42
+
43
+ ## AgentConfig — Core Fields (All Types)
44
+
45
+ These fields apply to every agent regardless of `agent_type`.
46
+
47
+ | Field | Type | Default | Accepted Values | Required | Description |
48
+ |-------|------|---------|-----------------|----------|-------------|
49
+ | `name` | string | — | any string | **yes** | Unique agent name within the mesh |
50
+ | `description` | string | `null` | any string | no | Agent description and purpose |
51
+ | `agent_type` | string | `"llm"` | `llm`, `human`, `programmatic`, `external` | no | Agent execution type (see note below) |
52
+ | `communication_type` | string | `"dual"` | `dual`, `chain`, `execute` | no | How agent communicates with the mesh |
53
+ | `parallel` | bool | `false` | `true`, `false` | no | Enable parallel processing |
54
+ | `max_concurrent` | int | `null` | 1 – unlimited | no | Max concurrent calls when `parallel: true` (null = unlimited) |
55
+ | `wake_up` | string | `null` | cron expression (e.g. `"0 9 * * *"`) | no | Schedule for periodic wake-up |
56
+ | `yields` | dict | `{}` | key: field name, value: type string or nested object | no | Output schema — what agent produces |
57
+ | `inputs` | dict | `{}` | key: field name, value: type string or nested object | no | Input schema — what agent expects |
58
+ | `can_call` | list | `[]` | list of `{"agent": "name"}` or `{"agent": "name", "condition": "expr"}` | no | Agents this agent can invoke |
59
+ | `narration` | string | `null` | any string (multiline supported) | no | Plain-English routing hints for the Manager — evaluated by the Summarizer when conditions don't cover everything (see [Narration Routing](#narration-routing)) |
60
+ | `wait_for` | string or list | `[]` | agent names or expression string | no | Fan-in/join condition |
61
+ | `wait_for_timeout` | int | `60` | 1 – unlimited (seconds) | no | Hard timeout for fan-in |
62
+ | `auto_store_response` | bool | `true` | `true`, `false` | no | Auto-store responses in Redis |
63
+ | `auto_store_yields` | bool | `true` | `true`, `false` | no | Auto-store yields in Redis |
64
+ | `memory` | bool or dict | `false` | `true`, `false`, or memory config dict | no | Agent memory — see [Memory Config](#memory-config) |
65
+ | `memory_limit` | int | `10` | 1 – 100 | no | Legacy: max recent feed posts (use `memory.limit` instead) |
66
+ | `knowledge` | bool or dict | `false` | `false`, or `{serviceName, enabled, groupName}` | no | Knowledge/RAG — see [Knowledge Config](#knowledge-config) |
67
+ | `enforce_yields` | bool | `false` | `true`, `false` | no | Strictly validate this agent's output against the declared `yields:` schema. `false` (default) fills missing keys with type defaults and logs warnings; `true` triggers a Manager-driven retry up to `enforce_yields_retry` times, then escalates. See [Yields Enforcement](#yields-enforcement). |
68
+ | `enforce_yields_retry` | int | `0` | 0 – unlimited | no | Maximum self-correction attempts when `enforce_yields: true`. `0` fails on first contract violation. Each retry passes the previous output + validation errors as feedback so LLM/external/human/programmatic agents can self-correct. Honored by every agent type. |
69
+
70
+ ### Yields Enforcement
71
+
72
+ `enforce_yields` and `enforce_yields_retry` work together to make `yields:` an enforceable contract on the producer side, without coupling agents to each other's shapes.
73
+
74
+ **Default behavior (`enforce_yields: false`)** — lenient mode, backwards-compatible:
75
+
76
+ - Missing yield keys → filled with type defaults (`""`, `0`, `[]`, `{}`, `false`).
77
+ - Type mismatches → kept verbatim, WARNING logged.
78
+ - `can_call` conditions evaluate on a known shape (no more silent skips on undefined keys).
79
+
80
+ **Strict mode (`enforce_yields: true`)** — for production-critical agents:
81
+
82
+ - On contract violation, the SDK fires a Manager-driven retry through `Manager.execute_state(...)`.
83
+ - Up to `enforce_yields_retry` attempts. Each retry sees the previous (wrong) output + validation errors as `_rerun_context`:
84
+ - **LLM agents** — prompt builder appends a correction note.
85
+ - **Human agents** — outbound payload exposes `_rerun_context`; inbox/channel UI surfaces what's needed.
86
+ - **External connectors** — `data._rerun_context` is added to the workflow payload.
87
+ - **Programmatic agents** — `input_data._rerun_context` is available alongside the (possibly Summarizer-corrected) inputs.
88
+ - After the retry budget is exhausted, fires `AGENT_ERROR` with `error_type="YieldContractFailure"` + `retry_exhausted=true`. Routes through `manager.escalation:` if configured.
89
+
90
+ **Example:**
91
+
92
+ ```yaml
93
+ agents:
94
+ client:
95
+ agent_type: human
96
+ human_interface: webhook
97
+ yields:
98
+ request_data: object
99
+ decision: string
100
+ enforce_yields: true # strict
101
+ enforce_yields_retry: 3 # 3 self-correction attempts before escalating
102
+ ```
103
+
104
+ **Programmatic agents are retryable too** — the Summarizer can inspect the failure and produce a `corrected_input` (e.g. fix `"ORGANIZATION"` → `"Organization"`). The retry runs the same deterministic function with the corrected input and produces a different result. See [Manager — Rerun Flow](../core-concepts/manager#rerun) for the full path.
105
+
106
+ ### Changing `agent_type`
107
+
108
+ You can change an agent's type via `PATCH /api/yaml/agents/{name}`. When `agent_type` changes, the ADK automatically **removes fields that don't belong to the new type**:
109
+
110
+ | Switching away from... | Fields removed |
111
+ |------------------------|----------------|
112
+ | `llm` | `model`, `prompt`, `temperature`, `max_tokens`, `max_completion_tokens`, `reasoning`, `thinking`, `thinking_budget`, `tools`, `tool_categories`, `context_parts`, `tool_choice`, `response_format` |
113
+ | `human` | `webhook_config`, `human_interface`, `human_timeout_seconds`, `channels`, `is_human_powered` |
114
+ | `external` | `framework`, `connector_config` |
115
+ | `programmatic` | `integration` |
116
+
117
+ This prevents stale configuration from the old type interfering with the new type's execution.
118
+
119
+ ### `yields` and `inputs` Type Strings
120
+
121
+ Values can be a simple type string (flat field) or a nested object definition.
122
+
123
+ **Flat fields** — value is a type string:
124
+
125
+ | Type String | Description |
126
+ |-------------|-------------|
127
+ | `"string"` | Text value |
128
+ | `"number"` | Numeric value |
129
+ | `"boolean"` | True/false |
130
+ | `"list"` | Array/list |
131
+ | `"object"` | Dictionary/object (unstructured) |
132
+
133
+ **Nested fields** — value is an object with `type` and `fields`:
134
+
135
+ ```yaml
136
+ inputs:
137
+ # Flat fields
138
+ name: string
139
+ email: string
140
+
141
+ # Nested object with defined sub-fields
142
+ arguments:
143
+ type: object
144
+ fields:
145
+ summary: string
146
+ start_datetime: string
147
+ end_datetime: string
148
+ timezone: string
149
+
150
+ yields:
151
+ # Flat
152
+ status: string
153
+
154
+ # Nested
155
+ data:
156
+ type: object
157
+ fields:
158
+ result: string
159
+ metadata: object
160
+ ```
161
+
162
+ When a field uses the nested format, the frontend renders individual sub-field editors instead of a single text input. This is useful for external framework integrations (Composio, Zapier, etc.) where the request body has a known structure.
163
+
164
+ ### `wait_for` Expression Syntax
165
+
166
+ ```yaml
167
+ # Simple list — all required (AND)
168
+ wait_for:
169
+ - agent_a
170
+ - agent_b
171
+
172
+ # Expression strings
173
+ wait_for: "agent_a AND agent_b" # Wait for both
174
+ wait_for: "agent_a OR agent_b" # Wait for first
175
+ wait_for: "agent_a AND agent_b?" # agent_b is optional (? suffix)
176
+ wait_for: "agent_a AND (agent_b OR agent_c)" # Nested logic
177
+ wait_for: "agent_a AND (agent_b OR agent_c) AND agent_d?" # Complex expression
178
+ ```
179
+
180
+ ### `can_call` Format
181
+
182
+ ```yaml
183
+ # Simple
184
+ can_call:
185
+ - agent: "next_agent"
186
+
187
+ # With condition
188
+ can_call:
189
+ - agent: "next_agent"
190
+ - agent: "conditional_agent"
191
+ condition: "calling_agent_response.status == 'ready'"
192
+ ```
193
+
194
+ ### Narration Routing
195
+
196
+ `narration` is an agent-level field for routing hints you **can't express as conditions**. Conditions handle definitive routes ("if category is billing, call billing_agent"). Narration handles non-definitive routes ("if the customer sounds frustrated and mentions cancelling, maybe call retention_agent").
197
+
198
+ ```yaml
199
+ agents:
200
+ triage:
201
+ yields:
202
+ category: "string"
203
+ urgency: "number"
204
+ can_call:
205
+ - agent: "billing_agent"
206
+ condition: "category == 'billing'"
207
+ - agent: "technical_agent"
208
+ condition: "category == 'technical'"
209
+ narration: >
210
+ If the customer mentions cancelling their subscription, route to retention_agent.
211
+ If the customer mentions a competitor by name, route to win_back_agent.
212
+ If the customer asks about enterprise plans, route to sales_agent.
213
+ ```
214
+
215
+ **How it works:**
216
+
217
+ 1. Conditions are evaluated first by the control plane (AST, instant, deterministic)
218
+ 2. Condition targets are dispatched immediately
219
+ 3. The Summarizer — which already analyzes every agent output via LLM — sees the narration in its prompt context
220
+ 4. The Summarizer's `next_agents` recommendation now reflects both condition-routed agents and narration-suggested agents
221
+ 5. The Manager compares `next_agents` against what conditions already dispatched, and calls the difference
222
+
223
+ **Key rules:**
224
+
225
+ - Conditions are the authority — narration never overrides a condition result
226
+ - Narration targets are **additive** — they add to condition targets, never remove
227
+ - Narration can reference **any agent** in the mesh, not just those in `can_call`
228
+ - No narration = zero overhead (the Summarizer's prompt is unchanged)
229
+ - If the Manager is disabled, narrations are ignored
230
+
231
+ See **[Manager — Narration Routing](../core-concepts/manager#narration-routing)** and **[Message Routing](../messages/routing#narration-routing)** for the full flow.
232
+
233
+ ### Knowledge Config
234
+
235
+ `knowledge` enables RAG-powered context injection from a vector database. The agent gets both pre-call injection (automatic) and a `query_knowledge` tool (on-demand) — same dual pattern as memory.
236
+
237
+ ```yaml
238
+ agents:
239
+ support_agent:
240
+ knowledge:
241
+ serviceName: "mongo_main"
242
+ enabled: true
243
+ groupName: "product_docs"
244
+ ```
245
+
246
+ | Field | Type | Required | Default | Description |
247
+ |-------|------|----------|---------|-------------|
248
+ | `serviceName` | string | yes | — | Provider name (configured via Knowledge API, stored in Redis) |
249
+ | `enabled` | bool | no | `true` | Enable/disable knowledge for this agent |
250
+ | `groupName` | string | no | `null` | Query a specific group. Omit to query all groups. |
251
+
252
+ **Key points:**
253
+
254
+ - Provider connection details (connection strings, API keys, embedding model) are configured via the Knowledge API, not in YAML
255
+ - When enabled, both retrieval paths are active automatically — no mode flag
256
+ - `query_knowledge` tool is stripped from agents without knowledge enabled
257
+ - The Manager can also have knowledge for SOP awareness (configured under `manager.knowledge`)
258
+
259
+ See **[Manager — Narration Routing](../core-concepts/manager#narration-routing)** for how knowledge integrates with the Summarizer.
260
+
261
+ ---
262
+
263
+ ## LLM Agent Fields (`agent_type: "llm"`)
264
+
265
+ These fields are used when `agent_type` is `"llm"`. Ignored for other types.
266
+
267
+ | Field | Type | Default | Accepted Values | Description |
268
+ |-------|------|---------|-----------------|-------------|
269
+ | `model` | string | `"gpt-4o-mini"` | see [Model List](#model-list) below | LLM model name |
270
+ | `prompt` | string | `null` | any string (multiline supported) | System prompt |
271
+ | `temperature` | float | `0.1` | `0.0` – `2.0` | LLM temperature (creativity/randomness) |
272
+ | `max_tokens` | int | `800` | 1 – model max | Max output tokens (legacy models) |
273
+ | `max_completion_tokens` | int | `null` | 1 – model max | Max completion tokens (o1, gpt-5.x models) |
274
+ | `reasoning` | bool | `false` | `true`, `false` | Enable ADK-level chain-of-thought reasoning (tool injection — works with any model) |
275
+ | `thinking` | bool | `false` | `true`, `false` | Enable native model-level extended thinking (requires model support — see below) |
276
+ | `thinking_budget` | int | `null` | 1024 – 32768 (tokens) | Max thinking tokens. Provider defaults apply when omitted. |
277
+ | `enable_prompt_caching` | bool | `false` | `true`, `false` | Enable provider-native prompt caching for cost reduction (see below) |
278
+ | `response_format` | dict | `null` | JSON Schema object | Structured output — forces LLM to respond with valid JSON matching this schema |
279
+ | `optimization_strategy` | string | `null` | `performance`, `cost`, `speed` | Per-agent model selection strategy |
280
+ | `context_parts` | dict | `null` | see below | Optional context parts |
281
+ | `tools` | list | `[]` | tool name strings | Available tools |
282
+ | `tool_choice` | string | `"auto"` | `auto`, `none`, or specific tool name | Tool selection strategy |
283
+ | `max_tool_calls_per_message` | int | `5` | 0 – 20 | Max tool calls per LLM message |
284
+ | `tool_call_timeout` | float | `30.0` | 0.1 – 300 (seconds) | Tool execution timeout |
285
+ | `allow_parallel_tool_calls` | bool | `true` | `true`, `false` | Allow parallel tool execution |
286
+ | `tool_categories` | list | `[]` | category name strings | Tool categories agent can access |
287
+
288
+ ### `context_parts` Keys
289
+
290
+ Each key is injected as a separate system message with a bracketed label, in the order below. Custom keys are also supported — they receive an auto-generated label from their name (`MY_KEY` → `[MY KEY]`).
291
+
292
+ | Key | Label injected | Description |
293
+ |-----|---------------|-------------|
294
+ | `care` | `[EMPATHY & TONE]` | Warmth/empathy instructions — shapes how the agent expresses itself |
295
+ | `sentiment_analysis` | `[SENTIMENT ANALYSIS]` | Tone detection instructions — tells the agent to read user mood |
296
+ | `guardrails` | `[SAFETY GUARDRAILS]` | Safety and compliance rules — what the agent must never do |
297
+ | `flows` | `[FLOW INSTRUCTIONS]` | **Per-caller routing behaviour** — what the agent should do differently depending on who called it and where in the mesh it is |
298
+
299
+ Values are free text strings. All keys are optional — use any combination.
300
+
301
+ ```yaml
302
+ context_parts:
303
+ care: |
304
+ Always respond with empathy. Acknowledge frustration before solving.
305
+ guardrails: |
306
+ Never share internal system details. No PII disclosure.
307
+ flows: |
308
+ When called from the entry point (no from_agent):
309
+ - This is a new user. Greet warmly and gather requirements.
310
+ When called from client (human agent):
311
+ - The human has already responded. Don't re-greet. Summarise and proceed.
312
+ When called from scheduler_agent:
313
+ - This is a scheduled run. Skip greeting, produce a structured summary.
314
+ ```
315
+
316
+ ### Model List
317
+
318
+ **OpenAI:**
319
+ - `gpt-4o-mini`, `gpt-4o`
320
+ - `gpt-4.1`, `gpt-4.1-mini`, `gpt-4.1-nano`
321
+ - `gpt-5.1`, `gpt-5.2`
322
+ - `o1`, `o1-mini`, `o3`, `o3-mini`, `o4-mini`
323
+
324
+ **Anthropic:**
325
+ - `claude-opus-4-6`, `claude-sonnet-4-6`
326
+ - `claude-haiku-4-5-20251001`
327
+
328
+ **Google:**
329
+ - `gemini-2.0-flash`, `gemini-2.5-pro`
330
+
331
+ **DeepSeek:**
332
+ - `deepseek-chat`, `deepseek-reasoner`
333
+
334
+ **AWS Bedrock:**
335
+ - Any Bedrock model ID (e.g. `anthropic.claude-3-sonnet-20240229-v1:0`, `amazon.titan-text-premier-v1:0`)
336
+ - Requires `mesh.bedrock` config
337
+
338
+ **Google Vertex AI:**
339
+ - Any Vertex model ID (e.g. `gemini-1.5-pro`)
340
+ - Requires `mesh.vertex` config
341
+
342
+ **Azure Foundry:**
343
+ - Any Azure deployment name
344
+ - Requires `mesh.foundry` config
345
+
346
+ **Local Models (vLLM, SGLang, Ollama, llama.cpp, etc.):**
347
+ - Any model name supported by your local server
348
+ - Requires `mesh.local` config (or `LOCAL_MODEL_ENDPOINT` env var)
349
+ - See [LocalModelConfig](#localmodelconfig) for server setup
350
+
351
+ ### `reasoning` vs `thinking`
352
+
353
+ These are two **separate** features:
354
+
355
+ | Feature | `reasoning: true` | `thinking: true` |
356
+ |---------|-------------------|-------------------|
357
+ | **What it does** | ADK injects chain-of-thought tool calls into the prompt | Enables provider-native extended thinking/reasoning |
358
+ | **Works with** | Any model (tool injection) | Only models that support native thinking |
359
+ | **Token cost** | Tool call overhead | Dedicated thinking tokens (billed as output) |
360
+ | **Quality** | Good for structured reasoning | Best quality — model's internal reasoning |
361
+
362
+ You can use both together — `reasoning` adds ADK tools while `thinking` enables native model thinking.
363
+
364
+ ### Native Thinking — Provider Support
365
+
366
+ | Provider | Model Requirement | Behavior |
367
+ |----------|------------------|----------|
368
+ | **Anthropic** | Claude Sonnet 4.6, Opus 4.6 | Adaptive/extended thinking with `budget_tokens` |
369
+ | **OpenAI** | o1, o3, o3-mini, o4-mini | `reasoning.effort` parameter (low/medium/high) |
370
+ | **Google** | Gemini 2.5+, Gemini 3.x | `thinkingConfig` with `thinkingBudget` |
371
+ | **DeepSeek** | DeepSeek-R1 | Native chain-of-thought (auto-enabled for R1 models) |
372
+ | **Bedrock** | Claude models on Bedrock | Extended thinking with `budgetTokens` |
373
+ | **Vertex** | Claude + Gemini on Vertex | Both thinking APIs supported |
374
+ | **Foundry** | Azure o-series models | `reasoning.effort` parameter |
375
+ | **Local** | Depends on model/server | Passthrough if server supports it |
376
+
377
+ ### Prompt Caching — Provider Support
378
+
379
+ | Provider | How it works | Savings |
380
+ |----------|-------------|---------|
381
+ | **Anthropic** | `cache_control: ephemeral` on system prompt + tools | ~90% on cached reads |
382
+ | **Bedrock** | `promptCaching` parameter | ~90% on cached reads |
383
+ | **Vertex (Claude)** | `cache_control: ephemeral` on system prompt | ~90% on cached reads |
384
+ | **OpenAI** | Automatic — no config needed (stats in response) | ~50% on cached |
385
+ | **Google** | Context caching API (requires separate setup) | Varies |
386
+
387
+ ### `response_format` — Structured Output
388
+
389
+ Forces the LLM to respond with valid JSON matching a JSON Schema. Supported across all providers — each provider translates the schema to its native structured output API.
390
+
391
+ ```yaml
392
+ agents:
393
+ data_extractor:
394
+ agent_type: llm
395
+ model: gpt-4o
396
+ prompt: "Extract structured data from the user's message."
397
+ response_format:
398
+ type: json_schema
399
+ json_schema:
400
+ name: extracted_data
401
+ strict: true
402
+ schema:
403
+ type: object
404
+ properties:
405
+ name:
406
+ type: string
407
+ email:
408
+ type: string
409
+ priority:
410
+ type: string
411
+ enum: [low, medium, high]
412
+ required: [name, email, priority]
413
+ additionalProperties: false
414
+ ```
415
+
416
+ | Provider | Native API used |
417
+ |----------|----------------|
418
+ | **OpenAI** | `response_format` parameter (structured outputs) |
419
+ | **Anthropic** | Tool-based JSON extraction with schema |
420
+ | **Google** | `response_schema` in generation config |
421
+ | **DeepSeek** | `response_format` parameter |
422
+ | **Bedrock** | Schema injected into system prompt |
423
+ | **Foundry** | `response_format` parameter |
424
+ | **Local** | `response_format` passthrough |
425
+
426
+ ### Example
427
+
428
+ ```yaml
429
+ agents:
430
+ analyst:
431
+ agent_type: llm
432
+ model: claude-sonnet-4-6
433
+ thinking: true # native model thinking
434
+ thinking_budget: 8192 # max 8K thinking tokens
435
+ reasoning: true # also inject ADK chain-of-thought tools
436
+ enable_prompt_caching: true # cache system prompt + tools
437
+ prompt: |
438
+ You are a data analyst. Analyze the provided data thoroughly.
439
+ ```
440
+
441
+ ---
442
+
443
+ ## Human Agent Fields (`agent_type: "human"`)
444
+
445
+ These fields are used when `agent_type` is `"human"`. `is_human_powered` is auto-set to `true`.
446
+
447
+ | Field | Type | Default | Accepted Values | Description |
448
+ |-------|------|---------|-----------------|-------------|
449
+ | `is_human_powered` | bool | `false` | `true`, `false` | Auto-synced to `true` when agent_type="human" |
450
+ | `human_interface` | string | `"api"` | `default`, `api`, `webhook`, `custom` | How human receives/submits input (see below) |
451
+ | `human_timeout_seconds` | int | `300` | 1 – 3600 (seconds) | Human response timeout |
452
+ | `human_context_template` | string | `null` | any string | Template for presenting context to human |
453
+ | `human_prompt_template` | string | `null` | any string | Template for human prompts |
454
+ | `fallback_on_timeout` | bool | `true` | `true`, `false` | Use fallback response when human doesn't respond |
455
+ | `fallback_response` | dict | `null` | arbitrary JSON | Default response on human timeout |
456
+ | `require_human_confirmation` | bool | `false` | `true`, `false` | Require approval before proceeding |
457
+ | `human_escalation_triggers` | list | `[]` | free text strings | Conditions triggering human escalation |
458
+ | `operator_ids` | list | `[]` | list of strings (email or ID) | Operators who can see this agent's HITL requests. Empty = broadcast (all operators see it). |
459
+ | `webhook_config` | object | `null` | see [WebhookConfig](#webhookconfig) | Webhook settings (required for `webhook` interface) |
460
+ | `channels` | dict | `{}` | see [ChannelConfig](#channelconfig) | Native channel adapters (Slack, Telegram, etc.) |
461
+
462
+ ### `human_interface` — Interface Types
463
+
464
+ | Value | Description | How it works |
465
+ |-------|-------------|-------------|
466
+ | `default` | **ADK-Frontend HITL Inbox** (recommended) | Writes request to Redis, emits stream event. ADK-Frontend renders an inbox with conversation thread. Human replies via the UI. Supports parallel requests per session. |
467
+ | `webhook` | **External webhook** | POSTs request to `webhook_config.outbound_url`. Human responds via inbound webhook endpoint. Also supports native channel adapters (Slack, Telegram, etc.). |
468
+ | `api` | **Python callback** | Calls a Python handler registered via `sdk.register_human_handler()`. No outbound HTTP. Used for custom integrations and testing. |
469
+ | `custom` | **Custom handler** | Same as `api` — uses the registered `human_interface_handler` callback. |
470
+
471
+ > **Note:** `default` is only available on the LeafMesh hosted platform. For self-hosted deployments, use `webhook` with your own `outbound_url`, or `api` with a Python callback.
472
+
473
+ ### Example — Default (ADK-Frontend Inbox)
474
+
475
+ ```yaml
476
+ agents:
477
+ support_human:
478
+ agent_type: human
479
+ human_interface: default # ADK-Frontend inbox
480
+ human_timeout_seconds: 300
481
+ yields:
482
+ resolution: string
483
+ action_taken: string
484
+ ```
485
+
486
+ ### Example — Webhook with Channel Adapter
487
+
488
+ ```yaml
489
+ agents:
490
+ support_human:
491
+ agent_type: human
492
+ human_interface: webhook
493
+ human_timeout_seconds: 600
494
+ webhook_config:
495
+ outbound_url: "https://my-app.com/api/human-requests"
496
+ channels:
497
+ slack:
498
+ bot_token: "${SLACK_BOT_TOKEN:}"
499
+ signing_secret: "${SLACK_SIGNING_SECRET:}"
500
+ post_channel: "C123456"
501
+ ```
502
+
503
+ ### Two Scenarios for Human Agent Sessions
504
+
505
+ Human agents support two interaction patterns via the same webhook endpoint:
506
+
507
+ **Scenario 1 — Resume (session_id present):** When a POST to `/webhook/{entry_point}` includes a `session_id` that matches a pending HITL request, the ADK resumes that session. The operator's response is routed via `can_call` to the next agent.
508
+
509
+ **Scenario 2 — New (no session_id or not found):** When a POST has no `session_id` or the session has no pending expectation, the ADK creates a new workflow. If the human agent has no upstream caller, the operator's message is immediately routed via `can_call` — no HITL pending step is created.
510
+
511
+ ---
512
+
513
+ ## External Agent Fields (`agent_type: "external"`)
514
+
515
+ These fields are used when `agent_type` is `"external"`.
516
+
517
+ | Field | Type | Default | Accepted Values | Required | Description |
518
+ |-------|------|---------|-----------------|----------|-------------|
519
+ | `framework` | string | `null` | `crewai`, `langgraph`, `autogen`, `a2a`, `mcp`, `zapier`, `composio`, `n8n`, `custom` | **yes** | External framework name |
520
+ | `connector_config` | dict | `{}` | framework-specific key-values | no | Connection configuration — passed as `**kwargs` to the connector |
521
+
522
+ > **One agent = one action/workflow.** Each agent targets one specific endpoint, graph, tool, or action. Create multiple agents with different `connector_config` values to call different workflows.
523
+ >
524
+ > All `connector_config` fields can also be overridden per-call via `request.connector_config` at runtime.
525
+
526
+ ### Common connector_config fields (all frameworks)
527
+
528
+ These fields are available on **every** connector type:
529
+
530
+ | Field | Type | Default | Description |
531
+ |-------|------|---------|-------------|
532
+ | `mode` | string | `"sync"` | Execution mode: `"sync"` (wait for HTTP response) or `"callback"` (fire request, wait for external system to POST back) |
533
+ | `callback_timeout` | float | `120.0` | Seconds to wait for a callback response before timing out (only used when `mode: "callback"`) |
534
+
535
+ #### Sync vs Callback Mode
536
+
537
+ **Sync mode** (default): The connector POSTs to the external system and holds the HTTP connection open until the response arrives. This works when the external system returns the actual result in the same HTTP response.
538
+
539
+ **Callback mode**: The connector POSTs to the external system with a `_leafmesh_callback_url` and `_leafmesh_session_id` injected into the payload. The connector then blocks internally until the external system POSTs the result back to `/callback/{agent_name}`. Use this when:
540
+ - The external workflow takes longer than the HTTP timeout
541
+ - The external system uses "fire and forget" (e.g., n8n's "Respond Immediately" mode)
542
+ - You need the external system to process asynchronously and deliver results later
543
+
544
+ **How external systems use callbacks:**
545
+
546
+ The LeafMesh connector injects these fields into the outbound payload:
547
+ - `_leafmesh_callback_url` — the URL to POST the result back to
548
+ - `_leafmesh_session_id` — the session ID to include in the callback
549
+
550
+ The external system should POST to `_leafmesh_callback_url` with a JSON body containing:
551
+ ```json
552
+ {
553
+ "session_id": "<the _leafmesh_session_id value>",
554
+ "result": { ... }
555
+ }
556
+ ```
557
+
558
+ ### connector_config fields per framework
559
+
560
+ #### crewai
561
+
562
+ | Field | Type | Default | Required | Env Fallback | Description |
563
+ |-------|------|---------|----------|-------------|-------------|
564
+ | `endpoint` | string | `""` | **yes** | `CREWAI_ENDPOINT` | HTTP endpoint for deployed CrewAI crew |
565
+ | `api_key` | string | `""` | no | `CREWAI_API_KEY` | Bearer Token for authentication |
566
+ | `user_api_key` | string | `""` | no | `CREWAI_USER_API_KEY` | User Bearer Token (preferred over `api_key` when both are set) |
567
+ | `poll_interval` | float | `2.0` | no | — | Seconds between status polls |
568
+ | `max_poll_seconds` | float | `300.0` | no | — | Max total polling time (seconds) |
569
+ | `http_timeout` | float | `30.0` | no | — | HTTP request timeout (seconds) |
570
+
571
+ #### langgraph
572
+
573
+ | Field | Type | Default | Required | Env Fallback | Description |
574
+ |-------|------|---------|----------|-------------|-------------|
575
+ | `endpoint` | string | `""` | **yes** | `LANGGRAPH_ENDPOINT`, `LANGCHAIN_ENDPOINT` | LangGraph Platform deployment URL |
576
+ | `api_key` | string | `""` | no | `LANGCHAIN_API_KEY`, `LANGGRAPH_API_KEY` | API key |
577
+ | `graph_id` | string | `"agent"` | no | — | **Which graph to run** — this is the workflow selector |
578
+ | `poll_interval` | float | `1.0` | no | — | Seconds between status polls |
579
+ | `max_poll_seconds` | float | `300.0` | no | — | Max total polling time (seconds) |
580
+ | `http_timeout` | float | `30.0` | no | — | HTTP request timeout (seconds) |
581
+
582
+ #### autogen
583
+
584
+ Connects to an external AutoGen Studio or custom AutoGen API service via HTTP.
585
+
586
+ | Field | Type | Default | Required | Env Fallback | Description |
587
+ |-------|------|---------|----------|-------------|-------------|
588
+ | `endpoint` | string | `""` | **yes** | `AUTOGEN_ENDPOINT` | AutoGen service base URL (e.g. `http://localhost:8081`) |
589
+ | `api_key` | string | `""` | no | `AUTOGEN_API_KEY` | Bearer token for authentication |
590
+ | `workflow_id` | string | `""` | no | — | Workflow/agent ID to execute on the AutoGen service |
591
+ | `timeout` | float | `120.0` | no | — | HTTP request timeout (seconds) |
592
+ | `poll_interval` | float | `2.0` | no | — | Seconds between status poll requests |
593
+ | `max_poll_seconds` | float | `300.0` | no | — | Max total polling time (seconds) |
594
+
595
+ #### a2a
596
+
597
+ | Field | Type | Default | Required | Env Fallback | Description |
598
+ |-------|------|---------|----------|-------------|-------------|
599
+ | `url` | string | `""` | **yes** | `A2A_AGENT_URL` | A2A-compatible agent server base URL |
600
+ | `auth_token` | string | `""` | no | `A2A_AUTH_TOKEN` | Bearer token for authentication |
601
+ | `auth_scheme` | string | `"Bearer"` | no | — | Authorization header scheme |
602
+ | `poll_interval` | float | `2.0` | no | — | Seconds between task status polls |
603
+ | `max_poll_seconds` | float | `300.0` | no | — | Max total polling time (seconds) |
604
+ | `http_timeout` | float | `30.0` | no | — | HTTP request timeout (seconds) |
605
+
606
+ #### mcp
607
+
608
+ MCP supports two transport modes. `tool_name` is always required.
609
+
610
+ **Common fields (both transports):**
611
+
612
+ | Field | Type | Default | Required | Env Fallback | Description |
613
+ |-------|------|---------|----------|-------------|-------------|
614
+ | `tool_name` | string | `""` | **yes** | — | **Which MCP tool to call** — the workflow selector |
615
+ | `transport` | string | `"stdio"` | no | — | Transport mode: `"stdio"` or `"http"` |
616
+ | `timeout` | float | `60.0` | no | — | Request timeout (seconds) |
617
+
618
+ **stdio transport fields:**
619
+
620
+ | Field | Type | Default | Required | Description |
621
+ |-------|------|---------|----------|-------------|
622
+ | `command` | string | `""` | **yes** (stdio) | Executable to launch (e.g. `"npx"`) |
623
+ | `args` | list | `[]` | no | Command arguments (e.g. `["-y", "@mcp/server-npm"]`) |
624
+ | `env` | dict | `null` | no | Environment variables for the subprocess |
625
+
626
+ **http transport fields:**
627
+
628
+ | Field | Type | Default | Required | Description |
629
+ |-------|------|---------|----------|-------------|
630
+ | `url` | string | `""` | **yes** (http) | MCP server HTTP/SSE endpoint |
631
+ | `auth_token` | string | `""` | no | Bearer token |
632
+
633
+ #### zapier
634
+
635
+ Tool name is built as `{connection}_{action}` (e.g. `google_sheets_create_row`).
636
+
637
+ | Field | Type | Default | Required | Env Fallback | Description |
638
+ |-------|------|---------|----------|-------------|-------------|
639
+ | `connection` | string | `""` | yes* | — | Zapier app name (e.g. `"google_sheets"`, `"slack"`, `"gmail"`) |
640
+ | `action` | string | `""` | yes* | — | Action name (e.g. `"create_row"`, `"send_message"`) |
641
+ | `mcp_key` | string | `""` | yes† | `ZAPIER_MCP_KEY` | Zapier MCP key — used first if `prefer_mcp=true` |
642
+ | `api_key` | string | `""` | yes† | `ZAPIER_API_KEY` | Zapier REST API key — used as fallback |
643
+ | `prefer_mcp` | bool | `true` | no | — | Try MCP path first; fall back to REST on failure |
644
+ | `instructions` | string | `""` | no | — | Optional natural language instructions (REST path only) |
645
+ | `timeout` | float | `60.0` | no | — | HTTP request timeout (seconds) |
646
+
647
+ *At least one of `connection` or `action` required for the tool name. †At least one of `mcp_key` or `api_key` required.
648
+
649
+ #### composio
650
+
651
+ | Field | Type | Default | Required | Env Fallback | Description |
652
+ |-------|------|---------|----------|-------------|-------------|
653
+ | `action` | string | `""` | **yes** | — | **Composio action enum** (e.g. `"GITHUB_STAR_A_REPOSITORY"`) — the workflow selector |
654
+ | `entity_id` | string | `"default"` | no | `COMPOSIO_ENTITY_ID` | User/entity context for managed auth |
655
+ | `api_key` | string | `""` | no | `COMPOSIO_API_KEY` | Composio API key |
656
+ | `timeout` | float | `60.0` | no | — | Execution timeout (seconds) |
657
+
658
+ #### n8n
659
+
660
+ | Field | Type | Default | Required | Env Fallback | Description |
661
+ |-------|------|---------|----------|-------------|-------------|
662
+ | `webhook_url` | string | `""` | **yes** | `N8N_WEBHOOK_URL` | Full webhook trigger URL — **one URL per n8n workflow** |
663
+ | `auth_token` | string | `""` | no | `N8N_AUTH_TOKEN` | Bearer token |
664
+ | `timeout` | float | `60.0` | no | — | HTTP request timeout (seconds, sync mode only) |
665
+
666
+ **n8n webhook URL types:**
667
+ - **Production:** `https://your-instance.app.n8n.cloud/webhook/<id>` — works when workflow is **activated** (toggle ON)
668
+ - **Test:** `https://your-instance.app.n8n.cloud/webhook-test/<id>` — only works while n8n editor has "Listen for Test Event" active (one-shot, for development only)
669
+
670
+ **n8n + callback mode:**
671
+
672
+ When `mode: "callback"`, the n8n workflow should:
673
+ 1. Start with a Webhook trigger node (receives the payload including `_leafmesh_callback_url`)
674
+ 2. Configure the Webhook node to "Respond Immediately" (optional — sync mode works too)
675
+ 3. Process the workflow
676
+ 4. End with an HTTP Request node that POSTs back to `{{ $json._leafmesh_callback_url }}` with body:
677
+ ```json
678
+ { "session_id": "{{ $json._leafmesh_session_id }}", "result": { ... } }
679
+ ```
680
+
681
+ ---
682
+
683
+ ## Programmatic Agent Fields (`agent_type: "programmatic"`)
684
+
685
+ These fields are used when `agent_type` is `"programmatic"`.
686
+
687
+ | Field | Type | Default | Accepted Values | Description |
688
+ |-------|------|---------|-----------------|-------------|
689
+ | `integration` | string | `null` | `zapier`, `composio`, `n8n`, `mcp` | Integration connector (optional) |
690
+ | `connector_config` | dict | `{}` | integration-specific key-values | Same fields as the matching external framework connector — see tables above |
691
+
692
+ **Validation rule:** `integration` is only valid when `agent_type` is `"programmatic"`.
693
+
694
+ When `integration` is set, `connector_config` is passed as `**kwargs` to the connector's `__init__`. Use the same fields as the matching framework in the tables above (zapier → zapier fields, mcp → mcp fields, etc.).
695
+
696
+ The common fields (`mode`, `callback_timeout`) are also available here — programmatic agents with connectors support the same sync/callback modes as external agents.
697
+
698
+ ---
699
+
700
+ ## WebhookConfig
701
+
702
+ Used inside `webhook_config` for human agents.
703
+
704
+ | Field | Type | Default | Description |
705
+ |-------|------|---------|-------------|
706
+ | `outbound_url` | string | `null` | URL to POST responses to external system |
707
+ | `outbound_headers` | dict | `{}` | Headers for outbound webhook (key-value string pairs) |
708
+ | `outbound_timeout` | int | `30` | Timeout for outbound calls (seconds) |
709
+ | `inbound_endpoint` | string | `null` | Endpoint path for inbound responses (e.g. `"/webhook/human_contact"`). If not set, derived from entry points. |
710
+ | `inbound_auth_token` | string | `null` | Auth token for validating inbound requests |
711
+ | `response_mapping` | dict | `{}` | Field mapping for webhook response transformation |
712
+ | `max_retries` | int | `3` | Max retry attempts for failed outbound webhooks |
713
+ | `retry_delay` | int | `5` | Delay between retries (seconds) |
714
+
715
+ ---
716
+
717
+ ## ChannelConfig
718
+
719
+ Used inside `channels` dict for human agents. Keys are provider names.
720
+
721
+ ### Supported Provider Keys
722
+
723
+ | Key | Provider |
724
+ |-----|----------|
725
+ | `slack` | Slack Bot API |
726
+ | `telegram` | Telegram Bot API |
727
+ | `discord` | Discord Bot API |
728
+ | `whatsapp` | WhatsApp Business API (Meta Cloud API) |
729
+ | `teams` | Microsoft Teams Bot Framework |
730
+
731
+ ### Fields Per Channel
732
+
733
+ | Field | Type | Default | Description |
734
+ |-------|------|---------|-------------|
735
+ | `bot_token` | string | `null` | Bot/API token for the provider (see per-provider notes below) |
736
+ | `signing_secret` | string | `null` | Request verification secret (see per-provider notes below) |
737
+ | `listen_channels` | list | `[]` | Channel/chat IDs to accept inbound messages from (empty = all) |
738
+ | `post_channel` | string | `null` | Default channel/chat ID for outbound messages (see per-provider notes below) |
739
+ | `verify_token` | string | `null` | Webhook verification token — **WhatsApp only** (`hub.verify_token`) |
740
+
741
+ **Note:** `ChannelConfig` allows extra fields (`extra="allow"`) for any provider-specific config.
742
+
743
+ ### Per-Provider Field Semantics
744
+
745
+ | Provider | `bot_token` | `signing_secret` | `post_channel` | `verify_token` |
746
+ |----------|------------|------------------|----------------|----------------|
747
+ | `slack` | Bot OAuth token (`xoxb-…`) | Slack signing secret (HMAC-SHA256) | Channel ID (e.g. `C123456`) | — |
748
+ | `telegram` | Bot token from @BotFather | Secret token set when registering webhook | Chat ID | — |
749
+ | `discord` | Bot token (without `Bot ` prefix) | App public key (Ed25519 — requires `pynacl`) | Channel ID | — |
750
+ | `whatsapp` | Meta Graph API access token | Meta app secret (HMAC-SHA256) | Phone number ID | `hub.verify_token` for webhook registration |
751
+ | `teams` | Bot Framework App ID | Bot Framework App password | Conversation ID | — |
752
+
753
+ ### Inbound Route Registered Per Provider
754
+
755
+ | Provider | Route |
756
+ |----------|-------|
757
+ | `slack` | `POST /channels/slack/{agent_name}/events` |
758
+ | `telegram` | `POST /channels/telegram/{agent_name}/webhook` |
759
+ | `discord` | `POST /channels/discord/{agent_name}/interactions` |
760
+ | `whatsapp` | `GET /channels/whatsapp/{agent_name}/webhook` (verification) + `POST` (messages) |
761
+ | `teams` | `POST /channels/teams/{agent_name}/messages` |
762
+
763
+ ### Example
764
+
765
+ ```yaml
766
+ channels:
767
+ slack:
768
+ bot_token: "${SLACK_BOT_TOKEN:}"
769
+ signing_secret: "${SLACK_SIGNING_SECRET:}"
770
+ listen_channels: ["C123456", "C789012"]
771
+ post_channel: "C123456"
772
+
773
+ telegram:
774
+ bot_token: "${TELEGRAM_BOT_TOKEN:}"
775
+ signing_secret: "${TELEGRAM_SECRET_TOKEN:}" # optional
776
+ listen_channels: [] # empty = all chats
777
+ post_channel: ""
778
+
779
+ discord:
780
+ bot_token: "${DISCORD_BOT_TOKEN:}"
781
+ signing_secret: "${DISCORD_PUBLIC_KEY:}" # Ed25519 public key
782
+ listen_channels: ["987654321098765432"]
783
+ post_channel: "987654321098765432"
784
+
785
+ whatsapp:
786
+ bot_token: "${WHATSAPP_ACCESS_TOKEN:}"
787
+ signing_secret: "${META_APP_SECRET:}"
788
+ post_channel: "${WHATSAPP_PHONE_NUMBER_ID:}" # phone number ID, not a phone number
789
+ verify_token: "my_verify_token" # set same value in Meta dashboard
790
+
791
+ teams:
792
+ bot_token: "${TEAMS_APP_ID:}"
793
+ signing_secret: "${TEAMS_APP_PASSWORD:}"
794
+ post_channel: "" # set at runtime from inbound activity
795
+ ```
796
+
797
+ ---
798
+
799
+ ## Memory Config
800
+
801
+ Field: `memory` — accepts `bool` or `dict`.
802
+
803
+ ### Simple Mode
804
+
805
+ ```yaml
806
+ memory: false # Disabled (default)
807
+ memory: true # Enabled with defaults
808
+ ```
809
+
810
+ ### Advanced Mode (Dict)
811
+
812
+ | Field | Type | Default | Accepted Values | Description |
813
+ |-------|------|---------|-----------------|-------------|
814
+ | `strategy` | string | `"recency"` | `recency`, `relevance`, `hybrid` | Memory retrieval strategy |
815
+ | `limit` | int | `10` | 1 – 100 | Max feed posts per invocation |
816
+ | `cross_session` | bool | `false` | `true`, `false` | Persist memory across sessions |
817
+ | `cross_session_limit` | int | `50` | 1 – 500 | Max cross-session posts to retain |
818
+ | `relevance_weight` | float | `0.6` | 0.0 – 1.0 | Weight for relevance scoring |
819
+ | `recency_weight` | float | `0.4` | 0.0 – 1.0 | Weight for recency scoring |
820
+ | `decay_hours` | int | `24` | 1 – unlimited | Hours before entries decay |
821
+
822
+ ### Example
823
+
824
+ ```yaml
825
+ memory:
826
+ strategy: "hybrid"
827
+ limit: 10
828
+ cross_session: true
829
+ cross_session_limit: 50
830
+ relevance_weight: 0.6
831
+ recency_weight: 0.4
832
+ decay_hours: 24
833
+ ```
834
+
835
+ ---
836
+
837
+ ## EscalationConfig
838
+
839
+ Used inside `manager.escalation`.
840
+
841
+ | Field | Type | Default | Description |
842
+ |-------|------|---------|-------------|
843
+ | `targets` | list of [EscalationTarget](#escalationtarget) | `[]` | Escalation targets — all fire in parallel |
844
+ | `auto_escalate` | dict | see below | Auto-escalation rules |
845
+
846
+ ### `auto_escalate` Fields
847
+
848
+ | Field | Type | Default | Description |
849
+ |-------|------|---------|-------------|
850
+ | `max_retries` | int | `3` | Max retry attempts before escalating |
851
+ | `max_errors_per_session` | int | `5` | Error count threshold per session |
852
+ | `timeout_threshold` | int | `2` | Consecutive timeouts before escalating |
853
+
854
+ ---
855
+
856
+ ## EscalationTarget
857
+
858
+ Each target in the `escalation.targets` list.
859
+
860
+ | Field | Type | Default | Accepted Values | Applies To |
861
+ |-------|------|---------|-----------------|------------|
862
+ | `type` | string | **required** | `human_agent`, `webhook`, `channel` | all |
863
+ | `agent` | string | `null` | agent name | `human_agent` |
864
+ | `entry_point` | string | `null` | entry point name | `human_agent` |
865
+ | `url` | string | `null` | URL | `webhook` |
866
+ | `method` | string | `"POST"` | `POST`, `PUT`, `PATCH` | `webhook` |
867
+ | `headers` | dict | `{}` | key-value string pairs | `webhook` |
868
+ | `payload_template` | dict | `null` | JSON with `{{var}}` placeholders | `webhook` |
869
+ | `provider` | string | `null` | `slack`, `telegram`, `discord`, `whatsapp`, `teams` | `channel` |
870
+ | `channel_id` | string | `null` | channel ID | `channel` |
871
+ | `message_template` | string | `null` | text with `{{var}}` placeholders | `channel` |
872
+
873
+ ### Example
874
+
875
+ ```yaml
876
+ escalation:
877
+ targets:
878
+ - type: "human_agent"
879
+ agent: "customer_support_team"
880
+
881
+ - type: "webhook"
882
+ url: "https://incident.example.com/api/escalate"
883
+ method: "POST"
884
+ headers:
885
+ Authorization: "Bearer ${ESCALATION_TOKEN:}"
886
+ payload_template:
887
+ incident_id: "{{session_id}}"
888
+ severity: "{{severity_level}}"
889
+ message: "{{error_message}}"
890
+
891
+ - type: "channel"
892
+ provider: "slack"
893
+ channel_id: "#critical-incidents"
894
+ message_template: "Escalation: {{message}} (session: {{session_id}})"
895
+
896
+ auto_escalate:
897
+ max_retries: 3
898
+ max_errors_per_session: 5
899
+ timeout_threshold: 2
900
+ ```
901
+
902
+ ---
903
+
904
+ ## Top-Level Config (LeafMeshConfig)
905
+
906
+ | Field | Type | Default | Accepted Values | Description |
907
+ |-------|------|---------|-----------------|-------------|
908
+ | `name` | string | `"default_mesh"` | any string | Mesh name |
909
+ | `version` | string | `"1.0.0"` | any string | Configuration version |
910
+ | `architecture` | string | `"managed_mesh"` | `managed_mesh` | Architecture type (only one supported) |
911
+ | `debug` | bool | `false` | `true`, `false` | Enable debug mode |
912
+ | `log_level` | string | `"INFO"` | `DEBUG`, `INFO`, `WARNING`, `ERROR` | Logging level |
913
+ | `environment` | string | `"development"` | `development`, `production` | Environment |
914
+ | `redis` | object | see [RedisConfig](#redisconfig) | — | Redis connection |
915
+ | `manager` | object | see [ManagerConfig](#managerconfig) | — | Manager coordination + analysis |
916
+ | `mesh` | object | see [MeshConfig](#meshconfig--cloud-providers) | — | Mesh network + cloud providers |
917
+ | `agents` | dict | `{}` | agent name → AgentConfig | Agent configurations |
918
+ | `entry_points` | list | `[{"name": "default_entry", "target": "summarizer", "condition": "always"}]` | see [Entry Points](#entry-points) | Named portals into mesh |
919
+ | `data_structures` | dict | `{}` | name → DataStructure | Custom data type definitions |
920
+ | `auto_discover` | dict | `null` | `{"directory": "path", "pattern": "*.py", "recursive": true}` | Auto-discover agent files |
921
+ | `evolution` | object | see [EvolutionConfig](#evolutionconfig) | — | Evolutionary optimization |
922
+
923
+ **Note:** `LeafMeshConfig` has `extra="forbid"` — unknown top-level keys will raise a validation error.
924
+
925
+ ---
926
+
927
+ ## ManagerConfig
928
+
929
+ | Field | Type | Default | Accepted Values | Description |
930
+ |-------|------|---------|-----------------|-------------|
931
+ | `enabled` | bool | `true` | `true`, `false` | Enable manager + summarizer |
932
+ | `model` | string | `"gpt-4o-mini"` | same as [Model List](#model-list) | LLM model for Summarizer analysis |
933
+ | `domain` | string | `"generic"` | `generic`, `ecommerce`, `data_analysis` | Summarizer domain specialization |
934
+ | `prompt` | string | `null` | any string (multiline supported) | **Evaluation criteria** — tell the Manager what success looks like, what to escalate on, and what patterns to watch. Injected into every Summarizer analysis call as an `EVALUATION CRITERIA` section, alongside the domain prompt. |
935
+ | `can_intervene` | bool | `true` | `true`, `false` | Allow manager interventions (false = read-only) |
936
+ | `coordination_rules` | dict | `{}` | arbitrary key-values | User-defined business rules |
937
+ | `chain_completion_timeout` | float | `60.0` | seconds | Wait time before checking chain completeness |
938
+ | `health_check_interval` | int | `60` | seconds | Seconds between health checks |
939
+ | `agent_timeout_threshold` | int | `180` | seconds | Seconds before agent is timed out |
940
+ | `escalation` | object | `null` | see [EscalationConfig](#escalationconfig) | Escalation targets and rules |
941
+ | `routing` | dict | see below | — | Manager routing configuration |
942
+
943
+ ### `manager.prompt` — Evaluation Criteria
944
+
945
+ Gives the Manager direct context about your mesh's specific purpose, success criteria, and escalation triggers. The Summarizer reads this on every agent turn alongside its domain template.
946
+
947
+ ```yaml
948
+ manager:
949
+ model: "gpt-4o-mini"
950
+ domain: "generic"
951
+ prompt: |
952
+ This mesh handles customer support tickets.
953
+ A successful flow means:
954
+ - greeter identifies the issue category correctly
955
+ - processor routes to the right specialist agent
956
+ - the customer receives a clear resolution within 5 minutes
957
+
958
+ Escalate if:
959
+ - the same issue loops more than twice
960
+ - sentiment is negative AND no resolution has been proposed
961
+ - the human agent times out without responding
962
+
963
+ Watch for:
964
+ - advisor_agent confidence scores below 0.6
965
+ - processor_agent routing to fallback more than 50% of the time
966
+ ```
967
+
968
+ ### `routing` Fields
969
+
970
+ | Field | Type | Default | Accepted Values | Description |
971
+ |-------|------|---------|-----------------|-------------|
972
+ | `mode` | string | `"static"` | `static`, `learning` | Routing mode (static=YAML only, learning=adaptive) |
973
+ | `memory_size` | int | `100` | 1 – 1000 | Max routing decisions to remember |
974
+ | `confidence_threshold` | float | `0.7` | 0.0 – 1.0 | Min confidence to accept learned route |
975
+ | `fallback` | string | `"all"` | `all` | Fallback when confidence too low |
976
+ | `decay_days` | int | `30` | 1 – 365 | Days before old routing memory decays |
977
+
978
+ ### `human_input_rules` (Defaults)
979
+
980
+ | Field | Type | Default |
981
+ |-------|------|---------|
982
+ | `max_concurrent_requests` | int | `3` |
983
+ | `max_agent_requests` | int | `5` |
984
+ | `enable_request_queuing` | bool | `true` |
985
+
986
+ ### `timeout_rules` (Defaults)
987
+
988
+ | Field | Type | Default |
989
+ |-------|------|---------|
990
+ | `max_timeouts_before_escalation` | int | `2` |
991
+ | `timeout_escalation_enabled` | bool | `true` |
992
+ | `escalation_notify_managers` | bool | `true` |
993
+
994
+ ### `workflow_pause_rules` (Defaults)
995
+
996
+ | Field | Type | Default |
997
+ |-------|------|---------|
998
+ | `max_pause_duration_minutes` | int | `30` |
999
+ | `max_concurrent_paused_workflows` | int | `2` |
1000
+ | `pause_monitoring_enabled` | bool | `true` |
1001
+
1002
+ ### `human_response_rules` (Defaults)
1003
+
1004
+ | Scenario | `requires_manager_review` | `auto_escalate` |
1005
+ |----------|--------------------------|-----------------|
1006
+ | `approval` | `false` | `false` |
1007
+ | `escalation` | `true` | `true` |
1008
+ | `timeout` | `true` | `false` |
1009
+
1010
+ ---
1011
+
1012
+ ## MeshConfig & Cloud Providers
1013
+
1014
+ ### MeshConfig
1015
+
1016
+ | Field | Type | Default | Description |
1017
+ |-------|------|---------|-------------|
1018
+ | `call_timeout` | int | `30` | Call timeout in seconds |
1019
+ | `bedrock` | object | `null` | AWS Bedrock config |
1020
+ | `vertex` | object | `null` | Google Vertex AI config |
1021
+ | `foundry` | object | `null` | Microsoft Foundry/Azure AI config |
1022
+ | `local` | object | `null` | Local model server config (vLLM, SGLang, Ollama, etc.) |
1023
+
1024
+ ### BedrockConfig (AWS)
1025
+
1026
+ | Field | Type | Default | Description |
1027
+ |-------|------|---------|-------------|
1028
+ | `region` | string | `"us-east-1"` | AWS region |
1029
+ | `profile` | string | `null` | AWS profile from `~/.aws/credentials` |
1030
+ | `endpoint_url` | string | `null` | Custom Bedrock endpoint URL |
1031
+
1032
+ Auth: `AWS_ACCESS_KEY_ID` + `AWS_SECRET_ACCESS_KEY` env vars, IAM role, or `~/.aws/credentials`
1033
+
1034
+ ### VertexConfig (Google Cloud)
1035
+
1036
+ | Field | Type | Default | Required | Description |
1037
+ |-------|------|---------|----------|-------------|
1038
+ | `project` | string | — | **yes** | GCP project ID |
1039
+ | `location` | string | `"us-central1"` | no | GCP region |
1040
+
1041
+ Auth: `GOOGLE_APPLICATION_CREDENTIALS` env var or `gcloud auth`
1042
+
1043
+ ### FoundryConfig (Azure)
1044
+
1045
+ | Field | Type | Default | Required | Description |
1046
+ |-------|------|---------|----------|-------------|
1047
+ | `endpoint` | string | — | **yes** | Foundry endpoint URL (e.g. `https://<resource>.openai.azure.com`) |
1048
+ | `api_version` | string | `null` | no | Azure API version (e.g. `2024-10-21`). Omit for v1 endpoint. |
1049
+
1050
+ Auth: `AZURE_FOUNDRY_API_KEY` or `AZURE_FOUNDRY_TOKEN` env vars
1051
+
1052
+ ### LocalModelConfig
1053
+
1054
+ | Field | Type | Default | Required | Description |
1055
+ |-------|------|---------|----------|-------------|
1056
+ | `endpoint` | string | `"http://localhost:11434/api/generate"` | no | Model server URL |
1057
+ | `server_type` | string | `null` (auto-detect) | no | Server type: `openai`, `ollama`, `textgen`, `huggingface` |
1058
+ | `timeout` | float | `120.0` | no | Request timeout in seconds |
1059
+ | `headers` | dict | `{}` | no | Custom HTTP headers (e.g. for auth) |
1060
+
1061
+ Env fallbacks: `LOCAL_MODEL_ENDPOINT`, `LOCAL_MODEL_SERVER_TYPE`, `LOCAL_MODEL_TIMEOUT`
1062
+
1063
+ **Supported servers and their `endpoint` + `server_type`:**
1064
+
1065
+ | Server | `server_type` | Example `endpoint` |
1066
+ |--------|--------------|-------------------|
1067
+ | vLLM | `openai` | `http://localhost:8000/v1/chat/completions` |
1068
+ | SGLang | `openai` | `http://localhost:30000/v1/chat/completions` |
1069
+ | llama.cpp server | `openai` | `http://localhost:8080/v1/chat/completions` |
1070
+ | LM Studio | `openai` | `http://localhost:1234/v1/chat/completions` |
1071
+ | LocalAI | `openai` | `http://localhost:8080/v1/chat/completions` |
1072
+ | TGI (--api openai) | `openai` | `http://localhost:8080/v1/chat/completions` |
1073
+ | TensorRT-LLM | `openai` | `http://localhost:8000/v1/chat/completions` |
1074
+ | Triton + vLLM | `openai` | `http://localhost:8000/v1/chat/completions` |
1075
+ | Ollama | `ollama` | `http://localhost:11434/api/generate` |
1076
+ | Text Gen Web UI | `textgen` | `http://localhost:5000/api/v1/generate` |
1077
+ | HF Inference | `huggingface` | `https://api-inference.huggingface.co/models/...` |
1078
+
1079
+ > **Tip:** Most production servers (vLLM, SGLang, TGI, llama.cpp) expose OpenAI-compatible endpoints. Use `server_type: openai` for all of them. If `server_type` is omitted, it's auto-detected from the URL.
1080
+
1081
+ ```yaml
1082
+ mesh:
1083
+ local:
1084
+ endpoint: http://localhost:8000/v1/chat/completions
1085
+ server_type: openai
1086
+ timeout: 120
1087
+ headers:
1088
+ Authorization: "Bearer ${VLLM_API_KEY:}"
1089
+ ```
1090
+
1091
+ ---
1092
+
1093
+ ## RedisConfig
1094
+
1095
+ | Field | Type | Default | Description |
1096
+ |-------|------|---------|-------------|
1097
+ | `host` | string | `"localhost"` | Redis server host |
1098
+ | `port` | int | `6379` | Redis server port |
1099
+ | `db` | int | `0` | Redis database number |
1100
+ | `password` | string | `null` | Redis password |
1101
+ | `decode_responses` | bool | `true` | Decode Redis responses |
1102
+ | `auto_storage` | bool | `true` | Enable automatic data storage |
1103
+ | `default_ttl` | int | `3600` | Default TTL (seconds) |
1104
+ | `session_ttl` | int | `7200` | Session TTL (seconds) |
1105
+ | `cluster_mode` | bool | `false` | Use Redis cluster |
1106
+ | `cluster_nodes` | list | `[]` | Cluster node addresses (strings) |
1107
+ | `ssl` | bool | `false` | Enable TLS for Redis connection |
1108
+ | `ssl_cert_reqs` | string | `"required"` | TLS verification mode: `required` \| `optional` \| `none` |
1109
+ | `ssl_ca_certs` | string | `null` | Path to CA bundle for verifying Redis server cert |
1110
+ | `ssl_certfile` | string | `null` | Client TLS cert path (mutual TLS) |
1111
+ | `ssl_keyfile` | string | `null` | Client TLS private key path (mutual TLS) |
1112
+ | `ssl_check_hostname` | bool | `true` | Verify server hostname against certificate |
1113
+
1114
+ ---
1115
+
1116
+ ## APIConfig
1117
+
1118
+ Top-level `api:` block Configures the ADK's HTTP server.
1119
+
1120
+ | Field | Type | Default | Description |
1121
+ |-------|------|---------|-------------|
1122
+ | `cors_origins` | list[string] | `[]` | Additional CORS origins, appended to the ADK's built-in defaults (`https://platform.leafcraft.ai` + localhost dev ports). Each entry must be a full origin (`scheme://host[:port]`). |
1123
+
1124
+ ---
1125
+
1126
+ ## EvolutionConfig
1127
+
1128
+ | Field | Type | Default | Accepted Values | Description |
1129
+ |-------|------|---------|-----------------|-------------|
1130
+ | `enabled` | bool | `false` | `true`, `false` | Enable evolutionary optimization |
1131
+ | `strategy` | string | `"genetic"` | free text | Evolution strategy |
1132
+ | `population_size` | int | `20` | 1+ | Population size per generation |
1133
+ | `generations` | int | `50` | 1+ | Maximum generations |
1134
+ | `mutation_rate` | float | `0.1` | 0.0 – 1.0 | Mutation probability |
1135
+ | `crossover_rate` | float | `0.7` | 0.0 – 1.0 | Crossover probability |
1136
+ | `elite_size` | int | `2` | 1+ | Elite genomes to preserve per generation |
1137
+ | `mutation_types` | list | `["prompt_variation", "temperature_adjustment", "tool_selection"]` | `prompt_variation`, `temperature_adjustment`, `tool_selection` | Mutation types |
1138
+ | `fitness_function` | string | `"task_completion_rate"` | free text | Fitness evaluation function |
1139
+ | `selection_method` | string | `"tournament"` | free text | Selection method |
1140
+ | `test_scenarios` | list | `[]` | list of scenario dicts — see below | Weighted test scenarios for fitness evaluation |
1141
+
1142
+ ### `test_scenarios` — Scenario Dict Fields
1143
+
1144
+ Each scenario in `test_scenarios` is a dict with these fields:
1145
+
1146
+ | Field | Type | Default | Description |
1147
+ |-------|------|---------|-------------|
1148
+ | `name` | string | `"scenario_N"` | Human-readable label — shown in logs and Studio |
1149
+ | `entry_point` | string | `"test"` | Which mesh entry point to call |
1150
+ | `input` | any | `"Test scenario input"` | Input data passed to the mesh call |
1151
+ | `expected_outcome` | dict | `{}` | Key/value pairs the response must contain. All keys checked — partial matches return a partial score. |
1152
+ | `weight` | float | `1.0` | How much this scenario counts toward the overall fitness score. Higher = matters more. |
1153
+ | `timeout` | float | `30.0` | Per-scenario timeout in seconds |
1154
+
1155
+ **Fitness formula:**
1156
+ ```
1157
+ fitness = Σ (weight × scenario_score) / Σ (weights)
1158
+ ```
1159
+ where `scenario_score = outcome_match_ratio × (1 − latency_penalty)`.
1160
+
1161
+ A scenario with `weight: 2.0` counts twice as much as one with `weight: 1.0`. Timed-out scenarios score 0 and still count toward the denominator.
1162
+
1163
+ ### Example
1164
+
1165
+ ```yaml
1166
+ evolution:
1167
+ enabled: true
1168
+ population_size: 20
1169
+ generations: 50
1170
+ elite_size: 2
1171
+ test_scenarios:
1172
+ - name: "happy_path"
1173
+ entry_point: "greet_user"
1174
+ input: { "message": "I need help with my order" }
1175
+ expected_outcome:
1176
+ status: "success"
1177
+ weight: 1.0
1178
+
1179
+ - name: "escalation_path"
1180
+ entry_point: "greet_user"
1181
+ input: { "message": "This is urgent and completely broken" }
1182
+ expected_outcome:
1183
+ escalated: true
1184
+ weight: 2.0 # weighted heavier — escalation correctness matters more
1185
+
1186
+ - name: "hitl_flow"
1187
+ entry_point: "human_contact"
1188
+ input: { "user_message": "I want a refund" }
1189
+ expected_outcome:
1190
+ human_involved: true
1191
+ weight: 1.5
1192
+ ```
1193
+
1194
+ ---
1195
+
1196
+ ## DataStructure
1197
+
1198
+ | Field | Type | Default | Description |
1199
+ |-------|------|---------|-------------|
1200
+ | `type` | string | **required** | `object`, `string`, `number`, `boolean`, `list` |
1201
+ | `properties` | dict | `null` | Object properties (for type=object) |
1202
+ | `required` | list | `[]` | Required field names |
1203
+ | `validation_rules` | dict | `{}` | Validation rules (key-value strings) |
1204
+
1205
+ ---
1206
+
1207
+ ## Entry Points
1208
+
1209
+ Each entry point is a named portal into the mesh.
1210
+
1211
+ | Field | Type | Default | Description |
1212
+ |-------|------|---------|-------------|
1213
+ | `name` | string | **required** | Entry point name |
1214
+ | `target` | string | **required** | Target agent name |
1215
+ | `description` | string | optional | Description |
1216
+ | `condition` | string | `"always"` | Trigger condition |
1217
+
1218
+ ### Example
1219
+
1220
+ ```yaml
1221
+ entry_points:
1222
+ - name: "greet_user"
1223
+ target: "greeter_agent"
1224
+ description: "Main entry — greets user and starts the agent chain"
1225
+ - name: "direct_research"
1226
+ target: "researcher_agent"
1227
+ description: "Skip greeting, go straight to research"
1228
+ ```
1229
+
1230
+ ---
1231
+
1232
+ ## Validation Rules
1233
+
1234
+ These are enforced by Pydantic validators in the ADK:
1235
+
1236
+ | Rule | Constraint |
1237
+ |------|-----------|
1238
+ | `agent_type` | Must be `llm`, `human`, `programmatic`, or `external` |
1239
+ | `communication_type` | Must be `dual`, `chain`, or `execute` |
1240
+ | `optimization_strategy` | Must be `performance`, `cost`, or `speed` (or null) |
1241
+ | `max_tool_calls_per_message` | Must be 0–20 |
1242
+ | `tool_call_timeout` | Must be > 0 and <= 300 seconds |
1243
+ | `tool_choice` | Must be a non-empty string (`auto`, `none`, or tool name) |
1244
+ | `framework` | Must be `crewai`, `langgraph`, `autogen`, `a2a`, `mcp`, `zapier`, `composio`, `n8n`, `custom` (or null) |
1245
+ | `framework` required | When `agent_type` is `external`, `framework` must be set |
1246
+ | `integration` | Must be `zapier`, `composio`, `n8n`, `mcp` (or null) |
1247
+ | `integration` restricted | Only valid when `agent_type` is `programmatic` |
1248
+ | `is_human_powered` sync | Auto-set to `true` when `agent_type="human"`, forced to `false` when `agent_type="llm"` |
1249
+ | `AgentConfig` extras | Allows arbitrary extra fields (`extra="allow"`) |
1250
+ | `LeafMeshConfig` extras | Rejects unknown top-level keys (`extra="forbid"`) |
1251
+
1252
+ ---
1253
+
1254
+ ## Field Applicability by Agent Type
1255
+
1256
+ Shows which fields are **used** (U), **ignored** (—), or **required** (R) for each agent type.
1257
+
1258
+ | Field | `llm` | `human` | `programmatic` | `external` |
1259
+ |-------|-------|---------|----------------|------------|
1260
+ | `name` | R | R | R | R |
1261
+ | `description` | U | U | U | U |
1262
+ | `model` | U | — | — | — |
1263
+ | `prompt` | U | — | — | — |
1264
+ | `temperature` | U | — | — | — |
1265
+ | `max_tokens` | U | — | — | — |
1266
+ | `max_completion_tokens` | U | — | — | — |
1267
+ | `reasoning` | U | — | — | — |
1268
+ | `thinking` | U | — | — | — |
1269
+ | `thinking_budget` | U | — | — | — |
1270
+ | `enable_prompt_caching` | U | — | — | — |
1271
+ | `response_format` | U | — | — | — |
1272
+ | `optimization_strategy` | U | — | — | — |
1273
+ | `context_parts` | U | — | — | — |
1274
+ | `tools` | U | — | — | — |
1275
+ | `tool_choice` | U | — | — | — |
1276
+ | `max_tool_calls_per_message` | U | — | — | — |
1277
+ | `tool_call_timeout` | U | — | — | — |
1278
+ | `allow_parallel_tool_calls` | U | — | — | — |
1279
+ | `tool_categories` | U | — | — | — |
1280
+ | `is_human_powered` | — | auto | — | — |
1281
+ | `human_interface` | — | U | — | — |
1282
+ | `human_timeout_seconds` | — | U | — | — |
1283
+ | `human_context_template` | — | U | — | — |
1284
+ | `human_prompt_template` | — | U | — | — |
1285
+ | `fallback_on_timeout` | — | U | — | — |
1286
+ | `fallback_response` | — | U | — | — |
1287
+ | `require_human_confirmation` | — | U | — | — |
1288
+ | `human_escalation_triggers` | — | U | — | — |
1289
+ | `webhook_config` | — | U | — | — |
1290
+ | `channels` | — | U | — | — |
1291
+ | `framework` | — | — | — | R |
1292
+ | `connector_config` | — | — | — | U |
1293
+ | `integration` | — | — | U | — |
1294
+ | `communication_type` | U | U | U | U |
1295
+ | `parallel` | U | U | U | U |
1296
+ | `max_concurrent` | U | U | U | U |
1297
+ | `wake_up` | U | U | U | U |
1298
+ | `yields` | U | U | U | U |
1299
+ | `inputs` | U | U | U | U |
1300
+ | `can_call` | U | U | U | U |
1301
+ | `narration` | U | U | U | U |
1302
+ | `knowledge` | U | U | U | U |
1303
+ | `wait_for` | U | U | U | U |
1304
+ | `wait_for_timeout` | U | U | U | U |
1305
+ | `auto_store_response` | U | U | U | U |
1306
+ | `auto_store_yields` | U | U | U | U |
1307
+ | `memory` | U | U | U | U |
1308
+
1309
+ **Legend:** R = required, U = used, — = ignored, auto = auto-set