Coordination Patterns
LeafMesh provides automatic coordination across a multi-agent chain -- retrying transient failures, halting runaway chains, and escalating decisions that need human review. You tune the behavior through a small set of YAML knobs; the platform handles the rest.
What the Coordinator Does
The coordinator continuously observes the chain and intervenes when needed. Typical behaviors:
- Retry an agent when a call fails transiently (rate limit, transient network error)
- Halt the current chain when an unrecoverable error occurs
- Escalate to a human reviewer when configured conditions are met
- Continue quietly when nothing needs attention -- the most common outcome
All intervention behavior is reactive and deterministic. The coordinator never originates work; it only acts on signals from the agents in flight.
Coordination Configuration
You control coordinator behavior through coordination_rules:
manager:
enabled: true
model: "gpt-4o-mini" # Model used for lightweight classification
coordination_rules:
max_agent_calls: 10 # Maximum agent calls per session
max_call_depth: 5 # Maximum chained call depth
max_retries: 3 # Maximum retries per agent on transient failure
score_threshold: 0.7 # Minimum classifier confidence to act| Field | Description |
|---|---|
max_agent_calls | Hard cap on the number of agent calls per session. Once reached, no further calls are allowed. |
max_call_depth | Maximum chain depth (A → B → C → ...). Prevents runaway recursive call patterns. |
max_retries | How many times the coordinator may retry a single agent before giving up and escalating or halting. |
score_threshold | The minimum confidence required for the coordinator to take an action other than "continue." |
Chain Cap & Bounding Cycles
LeafMesh has a hard safety net on chain length. Every session counts how many chain events (agent → agent hops) it has produced, and once that exceeds mesh.max_chain_events, the session is stopped with a ChainCapExceeded error.
mesh:
max_chain_events: 50 # default; raise for deep research / batch-fanout pipelinesThis is a backstop, not a design tool. It stops a runaway loop after the fact, often after burning real LLM spend. If your mesh has any back-edge — a can_call that routes back upstream (e.g. "retry the extractor when the record is not_found", or a critic that loops back to a writer) — the condition can stay true forever and the chain will climb straight to the cap.
Required pattern: bound every retry back-edge
Any back-edge whose condition can stay true indefinitely must be bounded in the agent's own intelligence. Count attempts per session, yield an exhaustion boolean, gate the back-edge on that boolean, and give the exhausted case a terminal route:
agents:
matching_agent:
name: "matching_agent"
yields:
record_found: "boolean"
retry_exhausted: "boolean" # loop guard — set by the Python below
can_call:
# Retry edge — only fires while retries remain
- agent: "intake_agent"
condition: "calling_agent_response.record_found == false and calling_agent_response.retry_exhausted == false"
# Terminal route once retries are spent — never loops again
- agent: "fallback_agent"
condition: "calling_agent_response.record_found == false and calling_agent_response.retry_exhausted == true"# matching_agent.py — per-session attempt counter
_MAX_RETRIES = 1
async def matching_agent(llm_response, input_data, context):
result = do_matching(...)
result["retry_exhausted"] = False
if not result.get("record_found"):
session_id = context.get("session_id", "")
stash = get_session_stash(session_id) # your per-session store
attempts = int(stash.get("match_attempts") or 0)
if attempts >= _MAX_RETRIES:
result["retry_exhausted"] = True # steers the terminal edge
else:
stash["match_attempts"] = attempts + 1
save_session_stash(session_id, stash)
return resultRules of thumb:
- Every back-edge that can stay true forever needs an exhaustion counter and a terminal route for the exhausted case.
- Back-edges through a human agent are the worst offenders — without a guard the human is re-asked on every lap. Bound them first.
- A→B→A ping-pong (critic ↔ writer) is legitimate and allowed by the runtime; the chain cap is the only automatic backstop, so the bounding is your responsibility.
- Raising
max_chain_eventsdoes not fix an unbounded loop — it just delays the cap.
Coordination Flow
Agent completes (success, failure, timeout, or low-quality output)
│
▼
Coordinator observes the event
│
▼
Classifies the event and decides whether to intervene
│
├── Continue → No action, chain proceeds normally
├── Retry → Re-run the agent (bounded by max_retries)
├── Halt → Stop the current chain
└── Escalate → Route to a human reviewer
In normal operation, the coordinator almost always returns "continue" -- intervention is the exception, not the rule.
Intervention History
Every coordinator decision is recorded and surfaced in Studio's Activity tab as a complete audit trail of every coordination decision in a session.
Self-Healing Integration
Coordination operates alongside LeafMesh's self-healing system:
- Coordinator: Per-session protection -- tracks failed agents, prevents routing to known-bad targets within the current chain.
- Self-healing: System-wide health -- notifies a person about a failing agent and, when
actions_enabledis on, restarts it or starts a backup that takes its work.
Both react to error signals independently and complement each other.
Next Steps
- Self-Healing — Automatic failure recovery
- Event System — Event delivery and durable history
- Mesh Architecture — Routing infrastructure
LeafMesh — Automatic coordination across multi-agent chains