1import{l as t,F as S,n as e}from"./vendor-9e81154e.js";import{u as A,c as L,r as c,L as T,R as P}from"./react-vendor-20f6178a.js";import{S as M,B as b}from"./index-03628c0d.js";import{B as E}from"./BreadcrumbSchema-29c7453d.js";import{m as _,A as C}from"./framer-motion-d1d06988.js";import"./mermaid-a501600d.js";import"./syntax-highlight-c51d17a4.js";import"./three-739a4b55.js";import"./livekit-288ce335.js";const i=[{id:"mesh-architecture",title:"Mesh Architecture & Coordination",lead:"The flow control layer. How agents discover each other, hand off work, recover from failures, and propagate context â without you writing the supervisor.",sections:[{heading:"Flow patterns",blocks:[{kind:"list",items:[{title:"Chain",body:"Sequential handoff from agent A to agent B to agent C, with each agent receiving the previous agent's output as input. Used for linear processes like greeting â classification â response."},{title:"Fan-out (parallel dispatch)",body:"One agent triggers multiple downstream agents concurrently, all working in parallel. Supports parallelism caps to prevent flooding shared resources like database connections or API quotas."},{title:"Parallel instances (worker pool)",body:"One config line â `instances: N` â turns a single activation into N parallel copies of the same agent inside one session, whatever triggered it (schedule, request, handoff, event). Copies split a backlog via an atomic claim tool; when they finish, their results are combined (lists joined, counts summed) and the chain continues exactly once, with per-copy detail preserved for auditing."},{title:"Fan-in (merge with boolean logic)",body:"Multiple agents converge their outputs into a single downstream agent. Supports full boolean expressions like `processor AND (researcher OR fallback_researcher)`. Handles late arrivals, skipped contributors, and failed contributors with explicit reporting."},{title:"wait_for is a gate, not a hint",body:"While a declared join is pending, every dispatch to the target is held as a contribution â even from agents not named in the expression; their data is banked and rides along, but only the expression's own terms open the gate. A timeout safety net fires with whatever arrived, reporting skips and failures explicitly."},{title:"The contract travels, never the ancestry",body:"Raw handoffs carry the sender's own output only â never the context it received â so payloads stay flat no matter how long the chain. Fan-in targets receive each contributor's declared yields, contract-shaped and rendered once. @compose/@chain shapers stay untouched: a shaped payload is the customer's contract."},{title:"Dual mode",body:"Agent A asks agent B a question, agent B replies back to agent A specifically, and agent A continues from there. Used for consultant patterns where one agent delegates a subquestion and weaves the answer back into its own reasoning."},{title:"Bounded loops",body:"Agents can call themselves or upstream agents, with a per-session rerun budget that prevents runaway retries. The Manager agent intervenes if the budget is exhausted."},{title:"Conditional branching",body:"Every routing decision can carry a Python expression evaluated against the agent's response (e.g., `confidence > 0.7`). Routes that don't match are silently skipped."}]}]},{heading:"Dynamic per-call routing (human agents)",intro:"YAML sets the default â `operator_ids` for the logical roster and an `operators:` map inside each channel block to resolve that roster to per-channel recipient IDs (Slack user IDs, WhatsApp numbers, email addresses). Pre-compose then steers per call by setting `_target_operator` in `input_data` â same key drives all configured channels simultaneously. Customers think in terms of people; each channel resolves its own platform-specific IDs.",blocks:[{kind:"list",items:[{title:"Channel-scoped operators",body:"Operators live inside the channel they're reachable on â `channels.slack.operators` holds Slack IDs, `channels.whatsapp.operators` holds phone numbers. Adding or removing a channel takes its operator info with it; no orphaned IDs in a separate top-level map."},{title:"Single key, every transport",body:"`_target_operator: 'alice'` resolves to alice's Slack DM, WhatsApp number, and email address in parallel â each channel pulls from its own operators map. No per-platform code paths in the customer's pre_compose."},{title:"Fail-soft, never drops",body:"If a `_target_operator` has no entry under a given channel's operators map, the SDK logs a warning and falls back through session continuity â
1 YAML `post_channel` â webhook outbound_url for that channel. Messages always land somewhere the operator pre-approved."},{title:"Backward compatible",body:"Legacy `_operator_ids` list override still works on the default inbox. Raw `_target_channel_id` is the escape hatch when the recipient ID comes from a dynamic source. Agents not using the new keys behave exactly as before â the override layer is purely additive."}]}]},{heading:"Per-caller response behavior",intro:"An agent's communication_type (dual / chain / execute) is the default for every caller. response_overrides lets that decision flow per upstream caller â the same agent replies back to a customer-facing router (dual) but stays silent when an internal processor calls it (chain). External entry points (mesh_call, event listeners, scheduled wake_up) have no preceding caller and always use the default â overrides are internal-call only by design.",blocks:[{kind:"list",items:[{title:"Default + override",body:"Top-level `communication_type` is the fallback. Each entry in `response_overrides` names a specific caller agent and the type the receiving agent uses when called by them."},{title:"List or dict in YAML",body:"Both shapes accepted â list of `{caller, type}` for readability, or terser dict `{caller_name: type}`. Both are treated identically at runtime."},{title:"Studio-aware UI",body:"Agent inspector restricts the caller picker to agents whose can_call actually targets this one. If nobody calls this agent and no overrides exist, the panel hides â no dead config surface."},{title:"External traffic respects default",body:"mesh_call from outside, event-listener triggers, and scheduled wake_up calls all bypass the override map â they have no called_by, so they use communication_type unchanged."}]}]},{heading:"Routing decisions",blocks:[{kind:"list",items:[{title:"Declarative conditions",body:"Each `can_call` entry takes a condition expression. Wrong condition equals no dispatch. No if-else trees in code."},{title:"Narration-driven routing",body:"Agents can describe routing intent in plain English. The Manager parses narration and applies it as a routing hint."},{title:"Learned routing",body:"Every dispatch outcome is recorded per agent pair (success, failure, timeout, cancelled). Over time, the platform biases routing toward paths with historically higher success rates. Routing statistics persist across SDK restarts and are multi-process safe."},{title:"Manager arbitration",body:"When multiple `can_call` targets qualify, the built-in Manager picks based on routing memory, agent health, in-flight load, and confidence."},{title:"Routing memory persistence",body:"Survives SDK restarts and is exposed via the SDK API for analytics."}]}]},{heading:"Safety nets",blocks:[{kind:"list",items:[{title:"Chain depth cap",body:"Capped at 50 events per session by default. Configurable upward for research and batch fan-out workloads."},{title:"Loop detection",body:"Ping-pong patterns like AâBâA are caught and stopped early â long before the depth cap would end them."},{title:"Loop guard",body:"Immediate call-backs into an agent that just ran are caught before they dispatch. Publishes an INTERVENTION_NEEDED event with full diagnostic context."},{title:"Chain completeness watchdog",body:"Every dispatch is watched against a configurable timeout. If expected agents never completed, the Manager intervenes. Fan-in targets, human-type targets, and already-completed agents are exempt."},{title:"Pause-and-resume",body:"Sessions can be paused mid-flow with explicit pause types: HITL pending, workflow paused, awaiting human response. Manager defers all interventions while paused. Resume restores OpenTelemetry trace context."},{title:"Status gating",body:"When a session enters outage, stopped, cancelled, or escalated status, all further chain dispatch is halted."},{title:"Auto-reset on new mesh_call",body:"When a customer initiates a new entry-point call on a stale session, status auto-resets to active."}]}]},{heading:"Chain context propagation",blocks:[{kind:"list",items:[{title:"Bounded chain history",body:"Every dispatched agent input automatically carries a list of prior hops with agent name, output summary, timestamp."},{title:"Configurable depth",body:"Default 5 hops back, configurable via `mesh.chain_context_depth`. Set to 0 to disable globally."},{title:"Per-entry character cap",body:"Default 500 characters per hop with truncation marker."},{title:"Hard total byte ceiling",body:"Keeps chain history within LLM prompt limits."},{title:"Per-target snapshot isolation",body:"Each downstream target receives its own snapshot copy."},{title:"Fan-in dedup",body:"Fan-in targets get a fresh top-level snapshot; redundant copies stripped from contributor payloads."},{title:"Universal rendering",body:"LLM, programmatic, human inbox, external
1connector â all see chain history through their native access pattern."},{title:"Pre-compose override",body:"When customer's pre-compose populates prepared_data, auto-history defers to customer control."}]}]},{heading:"Event sourcing as substrate",intro:"Every state transition in the mesh emits a typed event onto Redis Streams. Agent registration, every dispatch decision, every manager intervention, every HITL request, every channel delivery, every tool call, every config change. Streams are append-only, timestamped, and durable.",blocks:[{kind:"list",items:[{title:"Durable delivery per subsystem",body:"Every platform subsystem consumes the stream through its own durable group â no subsystem can lose or starve another's events."},{title:"Subscribable from customer code",body:"`sdk.event_bus.subscribe(EventType.X, handler)` attaches user handlers to any event type."},{title:"Multi-process safe",body:"Consumer groups distribute event handling across worker processes without external coordination."},{title:"Survives restarts",body:"The event log is durable; subscribers resume from their last acknowledged position."},{title:"Powers the rest of the platform",body:"Manager arbitration, learned routing, cost analytics, ADK Studio dashboards, agent feed, and observability all read the same event stream rather than maintaining parallel state."}]},{kind:"callout",text:"Event sourcing is what makes the audit story real â every state change is reconstructable from the stream, not patched together from logs."}]}]},{id:"agent-types",title:"Agent Types & Composability",lead:"Four agent types. One mesh. Mix freely.",sections:[{heading:"LLM agents",intro:"Agents that call a language model with a prompt, optionally with tools.",blocks:[{kind:"paragraph",text:"Configurable per agent:"},{kind:"list",items:[{body:"Model selection (any of 8 providers, 30+ models)."},{body:"Temperature, max_tokens, top_p, frequency_penalty, presence_penalty."},{body:"System prompt with template variable substitution."},{body:"Native thinking support for reasoning models (o1, o3, o4) with effort levels mapped from `thinking_budget`."},{body:"Prompt caching (Anthropic ephemeral cache, OpenAI auto-cache, Bedrock cache)."},{body:"Multimodal inputs (image URLs, file uploads, byte content)."},{body:"Streaming output (token-by-token via async iterator)."},{body:"Structured output via JSON schema enforcement."},{body:"Reasoning helpers (chain_of_thought, metacognitive_reflection)."},{body:"Per-agent tool allowlist by name or category."},{body:"Per-agent `tool_call_timeout` (e.g., 90 seconds for slow tools)."}]},{kind:"paragraph",text:"Optimization strategies per agent:"},{kind:"list",items:[{title:"performance",body:"Pick the model that historically performs best for this agent type."},{title:"cost",body:"Pick the cheapest model in the configured providers."},{title:"speed",body:"Pick the lowest-latency model."},{title:"balanced",body:"Weighted across all three dimensions."}]}]},{heading:"Programmatic agents",intro:"Plain Python functions wrapped as mesh nodes.",blocks:[{kind:"list",items:[{body:"Async function signature receiving `(llm_response, input_data, context)`."},{body:"Decorator composition â stack pre-compose, chain, compose, conditional-chain, chain-with-results on one function."},{body:"Context dictionary with session_id, agent_name, agent_type, called_by, context_type, chain_history."},{body:"Yields contract enforcement on output (auto-default missing fields, schema validation)."},{body:"Automatic tracing of every decorator step as its own OpenTelemetry span."},{body:"Automatic exception handling with AGENT_ERROR event publishing."},{body:"Manager-driven retry on recoverable failures."}]},{kind:"paragraph",text:"Use cases: deterministic data transformation, calling external APIs, business rule enforcement, data shaping between LLM agents, fast classification without LLM cost."}]},{heading:"Human agents (HITL)",blocks:[{kind:"paragraph",text:"Real human operators as first-class mesh participants. Full HITL system detailed in the Human-in-the-Loop capability."}]},{heading:"External agents",intro:"Bridges to other agent frameworks and automation tools.",blocks:[{kind:"paragraph",text:"First-class framework bridges:"},{kind:"list",items:[{title:"CrewAI",body:"Invoke a Crew as a mesh node."},{title:"LangGraph",body:"Invoke a graph as a mesh node."},{title:"AutoGen",body:"Invoke a group chat as a mesh node."},{title:"MCP (Model Context Protocol)",body:"Call any MCP server."}
1,{title:"A2A (Agent-to-Agent SDK)",body:"Google's A2A protocol."},{title:"Zapier",body:"Trigger via Zapier MCP or REST endpoint."},{title:"n8n",body:"Invoke an n8n workflow."},{title:"Composio",body:"Call any Composio action."},{title:"Custom",body:"Implement the ExternalConnector interface for proprietary frameworks."}]},{kind:"callout",text:"Existing agent investments become mesh participants without rewriting. Chain history, observability, and security boundaries apply uniformly."}]}]},{id:"agent-anatomy",title:"Agent Anatomy",lead:"Inside every LeafMesh agent. The lifecycle hooks that wrap each phase of execution, the yields contract that constrains output, and the context every agent receives. Decorators are how deterministic behavior gets layered around stochastic LLM calls.",sections:[{heading:"The execution lifecycle",intro:"Every agent run flows through the same ordered phases. Each phase has its own hook, its own trace span, and its own failure semantics.",blocks:[{kind:"list",items:[{title:"1. Input arrives",body:"Either from `mesh_call`, an upstream chain dispatch, a listener event, a schedule fire, or a webhook trigger."},{title:"2. @pre_compose",body:"Reshapes input, enriches context, validates, fetches external data â before the agent runs."},{title:"3. Core execution",body:"LLM call, programmatic function, human inbox, or external connector â whichever agent type this is."},{title:"4. @chain",body:"Sequential post-processing on the produced output. Multiple chains stack in declaration order."},{title:"5. @compose",body:"Per-target shaping â each downstream agent can receive a differently-shaped payload from the same upstream output."},{title:"6. Yields validation",body:"Output validated against the declared `yields:` contract. Missing keys defaulted, type mismatches reported."},{title:"7. Handoff",body:"Routes evaluate `can_call` conditions; matching targets get dispatched with chain context attached."}]}]},{heading:"@pre_compose â shape inputs before execution",blocks:[{kind:"paragraph",text:"Run custom logic before the agent executes â context enrichment, input validation, external data fetching."},{kind:"list",items:[{title:"Separated processors",body:"`context_processor`, `input_processor`, `others_processor` â each operates on its own slice of the agent's view."},{title:"Full session reach",body:"Access to `session_id`, chain history, prior agent outputs, channel metadata."},{title:"Pre-compose override",body:"When pre_compose populates `prepared_data`, auto-history defers to your control â the SDK won't second-guess what you've assembled."},{title:"Async-native",body:"Every pre_compose is a coroutine â make external HTTP calls, database lookups, vector queries without blocking the event loop."}]}]},{heading:"@chain â sequential post-processing",blocks:[{kind:"paragraph",text:"Run custom logic after the agent produces output â transformations, formatting, side effects, downstream prep."},{kind:"list",items:[{title:"Stackable",body:"Decorate the same function with multiple `@chain` decorators; they execute in declaration order."},{title:"Traced per step",body:"Every chain step becomes its own `chain:{func_name}` OpenTelemetry span â you can see exactly where time went."},{title:"Recoverable failures",body:"Exceptions raised inside chain steps publish `AGENT_ERROR` events; the Manager can retry with corrected input."}]}]},{heading:"@chain_with_results â collect every intermediate result",blocks:[{kind:"list",items:[{body:"Captures every intermediate result across the chain, not just the final output."},{body:"Pass-through dedup keeps the payload lean â redundant copies stripped automatically."},{body:"Use when a downstream agent needs full visibility into how the upstream got to its answer (audit, debugging, multi-stage reasoning)."}]}]},{heading:"@compose â per-target output shaping",blocks:[{kind:"paragraph",text:"Shape the payload sent to each downstream agent differently per target â the cleanest pattern for fan-outs where each branch needs tailored input."},{kind:"list",items:[{title:"Pure transformation",body:"No side effects, no I/O. Same input, deterministic output, per target."},{title:"Declared per pair",body:'`@compose(target="researcher")` and `@compose(target="summarizer")` stack on the same agent, each shaping a different downstream.'},{title:"Snapshot isolation",body:"Each target receives its own snapshot copy of chain history â composing for one target never leaks into another."}]}]},{heading:"@conditional_chain â branching post-processing",blocks:[{kind:"paragraph",text:"Conditionally run post-processing based on the agent's output. Wraps a chain step with a condition expression that decides whether to execute."},{kind:"list",items:[{title:"Expression-based",body:"Condition evaluated against the agent's response
1(e.g., `confidence > 0.7`, `intent == 'refund'`)."},{title:"Silent skip",body:"Conditions that don't match skip the step without error â no dispatching, no events, no noise."},{title:"Composable with @chain",body:"Mix conditional and unconditional chains on the same function for hybrid pipelines."}]}]},{heading:"Yields contract â the output schema",blocks:[{kind:"list",items:[{body:"Every agent declares its output in YAML under `yields:` â keys, types, validation rules."},{body:"Validation runs on every execution. Missing keys are filled with type-safe defaults â no cascading `KeyError`s in downstream code."},{body:"Type mismatches caught and reported as `DataStructureMismatch` events."},{body:"Strict mode triggers a Manager retry with `corrected_input` â the LLM sees the specific schema failure and tries again."},{body:"Per-session `reflection_budget` caps retries so an LLM can't loop forever on a broken contract."}]}]},{heading:"Context dictionary â what each agent receives",intro:"Every agent execution receives a context dictionary with everything it needs to reason about the session â no manual threading.",blocks:[{kind:"list",items:[{title:"session_id",body:"Stable identifier for the conversation; reused across handoffs and reruns."},{title:"agent_name, agent_type",body:"Self-identification â useful for shared utilities that branch on agent type."},{title:"called_by",body:"Which agent (or entry point) dispatched this run â the basis for routing analytics."},{title:"context_type",body:"Why this agent was triggered: `chain`, `fan_out`, `fan_in`, `dual`, `loop`, `manager_retry`."},{title:"chain_history",body:"Bounded list of prior hops with agent name, output summary, timestamp."},{title:"Programmatic signature",body:"Programmatic agents receive `(llm_response, input_data, context)` â direct access without unpacking."}]}]},{heading:"Decorator composition â stacking behaviors",blocks:[{kind:"list",items:[{body:"All decorators combine freely on one function â pre_compose, chain, chain_with_results, compose, conditional_chain."},{body:"Order matters: pre_compose runs before execution, chain after, compose at handoff."},{body:"Each step gets its own OpenTelemetry span â `precompose:{processor}`, `chain:{func}`, `compose:{target}` â traceable in isolation."},{body:"Standalone form: import decorators directly from `leafmesh` and use them without an active SDK instance, perfect for unit tests."},{body:"Automatic exception handling â anything thrown in a decorator publishes `AGENT_ERROR`, available for Manager-driven retry."}]},{kind:"callout",text:"Decorators are the seam where Python lives inside the YAML mesh. Everything else is configuration; this is where your business logic plugs in."}]}]},{id:"llm-providers",title:"LLM Provider Ecosystem",lead:"Eight first-class providers. Per-agent provider choice. Mix freely.",sections:[{heading:"Providers and supported models",blocks:[{kind:"list",items:[{title:"OpenAI",body:"gpt-4o, gpt-4o-mini, gpt-4-turbo, gpt-4, gpt-3.5-turbo, o1, o1-mini, o3-mini, o4-mini."},{title:"Anthropic",body:"claude-3.5-sonnet, claude-3.5-haiku, claude-3-opus, claude-3-sonnet, claude-3-haiku, claude-opus-4, claude-sonnet-4."},{title:"Google Gemini (direct)",body:"gemini-2.0-flash, gemini-1.5-pro, gemini-1.5-flash."},{title:"AWS Bedrock",body:"Claude (Bedrock-hosted), Llama, Mistral, Cohere; AWS billing and IAM."},{title:"Azure Foundry",body:"Azure OpenAI deployments, Foundry-hosted models."},{title:"Google Vertex AI",body:"Gemini on Vertex, custom fine-tunes."},{title:"DeepSeek",body:"deepseek-chat, deepseek-reasoner."},{title:"Local models",body:"vLLM, SGLang, Ollama, llama.cpp via OpenAI-compatible endpoint."}]}]},{heading:"Image generation",intro:"An agent that produces pictures picks an image model the same way any other agent picks a text one â from the model list in Studio. Routing and capability checks are handled for you: an image model is never selected for a text agent, and vice versa.",blocks:[{kind:"list",items:[{title:"Google",body:"gemini-3-pro-image, gemini-2.5-flash-image."},{title:"OpenAI",body:"gpt-image-1, dall-e-3, dall-e-2."},{title:"Google Vertex",body:"Imagen 3 (standard and fast)."}
1,{title:"AWS Bedrock",body:"Titan Image Generator v2, Nova Canvas, Stable Diffusion XL."}]}]},{heading:"Cost tracking",blocks:[{kind:"list",items:[{body:"Input and output token pricing built in for every major OpenAI, Anthropic, and Google frontier model â rates updated per release."},{body:"Per-LLM-call cost recorded on the trace span."},{body:"Per-agent-run cost rolled up across all calls."},{body:"Per-session cost totaled in session analytics."},{body:"Cache read tokens broken out separately (for Anthropic and OpenAI prompt caching)."},{body:"Reasoning tokens broken out separately (for o-series models)."}]}]},{heading:"Provider features uniformly available",blocks:[{kind:"list",items:[{title:"Native tool calling",body:"All eight providers with one tool definition format."},{title:"Multi-turn tool loop",body:"Up to 10 iterations by default, configurable per agent."},{title:"Automatic retry on context overflow",body:"`context_length_exceeded` triggers smart truncation."},{title:"Stream chunking",body:"Token-by-token output via async iterator on all providers."},{title:"Structured output",body:"JSON schema enforcement across providers."},{title:"Adaptive model selection",body:"Runtime model picking based on per-agent strategy."},{title:"Prompt caching",body:"Honored where the provider supports it."}]}]},{heading:"Resilience features",blocks:[{kind:"list",items:[{title:"Stale-transport recovery",body:"Transport-level quirks on newer Python versions are recovered transparently â no crash, no lost request."},{title:"Reconnect coalescing",body:"Concurrent recovery attempts are coordinated â one reconnection serves them all."},{title:"Connection retry",body:"Exponential backoff on initial connection failures (3 attempts default)."},{title:"Truncation retry",body:"When a request exceeds context window, the SDK truncates intelligently and retries instead of failing."}]}]},{heading:"Tool calling defense",intro:"Provider APIs are strict about tool-call bookkeeping â one inconsistent message and the whole request fails. LeafMesh guarantees consistency:",blocks:[{kind:"list",items:[{title:"Always-consistent tool exchanges",body:"Every tool call is guaranteed a matching result before the next model call â gaps are repaired automatically before they can fail a request."},{title:"Requests complete",body:"A malformed tool exchange never turns into a failed customer request."}]}]}]},{id:"built-in-intelligence",title:"Built-In Intelligence (Manager + Summarizer)",lead:"The autonomous supervisor layer. You don't write the supervisor.",sections:[{heading:"The Manager agent",intro:"Subscribes to all of these event types:",blocks:[{kind:"list",items:[{body:"AGENT_OUTPUT, AGENT_ERROR, MESH_ERROR â every agent execution and failure."},{body:"HUMAN_INPUT_REQUESTED, HUMAN_INPUT_TIMEOUT â every HITL call and operator timeout."},{body:"WORKFLOW_PAUSED / WORKFLOW_RESUMED â every pause/resume."},{body:"INTERVENTION_NEEDED â loop guard, coordination rules."},{body:"COORDINATION_RULE_TRIGGERED â declarative rule matches."},{body:"HUMAN_ESCALATION â explicit escalation events."},{body:"AGENT_HEARTBEAT â health probes."},{body:"AGENT_STARTED / AGENT_BUSY / AGENT_IDLE / AGENT_COMPLETED â state transitions."},{body:"SUMMARIZATION_COMPLETE â Summarizer analysis ready."},{body:"SESSION_START / SESSION_END â session lifecycle."},{body:"MESH_RESPONSE â chain completion."}]},{kind:"paragraph",text:"Five intervention actions:"},{kind:"list",items:[{title:"retry",body:"Re-execute the failed agent with optional corrected input from Summarizer."},{title:"escalate",body:"Route to a human or higher-tier handler with priority."},{title:"outage",body:"Mark the session as in outage and halt the chain."},{title:"call_off",body:"Abort the session cleanly with manager reason logged."},{title:"stop",body:"Emergency stop with full diagnostic context."}]},{kind:"callout",text:"Smart-skip on healthy events â successful events bypass LLM analysis. Customer pays only for analysis that matters."},{kind:"paragraph",text:"Coordination rules â declarative business rules enforced at runtime:"},{kind:"list",items:[{body:'"if priority is urgent, route to advisor immediately"'},{body:'"if three retries fail, escalate"'},{body:'"if agent stays in busy state for over 5 minutes, mark as outage"'}]},{kind:"paragraph",text:"Routing authority â records every dispatch outcome per `(from_agent, to_agent)` pair. Stats: success count, failure count, total count, last_updated timestamp. Multi-process safe. Exposed via SDK API."}]},{heading:"The Summarizer agent",blocks:[{kind:"paragraph",text:"What it produces (structured JSON output):"},{kind:"list",items:[{body:"`conversation_summary`, `from_agent`, `to_agent`, `any_action_needed`, `priority`, `reason`, `next_agents`, `session_context`, `work_log`, `routing_quality`, `agent_workflow_status`, `behavior_output`, `error_context`, `corrected_input`."}]},{kind:"paragraph",text:"Domain-tunable: customer_service, sales, healthcare, research, generic."},{kind:"paragraph",text:"Trigger-configurable â fire on specific event types, smart-skip for healthy events."}]}
1,{heading:"Self-healing",intro:"Six healing actions: retry, escalate, replace_with_fallback, mark_outage, isolate, pause_and_notify.",blocks:[{kind:"paragraph",text:"Health monitoring loop:"},{kind:"list",items:[{body:"Periodic health probes per agent."},{body:"Configurable health check interval (default 300 seconds)."},{body:"Agent timeout threshold (default 60 seconds)."},{body:"Failed health degrades routing weight."},{body:"Recovery memory â past failures inform recovery choices."}]}]},{heading:"Adaptive optimization",blocks:[{kind:"paragraph",text:"Per-agent strategies â performance, cost, speed, balanced."},{kind:"paragraph",text:"Evolutionary optimization:"},{kind:"list",items:[{body:"Genetic algorithm operates on mesh configuration as a genome."},{body:"Mutation operators on agent selection, routing rules, model picks."},{title:"task_completion_rate (default)",body:"Balanced weighting of success rate, error rate, latency, throughput, agent utilization."},{title:"latency_weighted",body:"Punishes slow responses harder."},{title:"cost_efficiency",body:"Favors cheaper paths that still complete."},{body:"Test scenarios provided by customer; SDK runs them through candidate configurations."},{body:"Outputs an evolved configuration applicable to the mesh."}]}]},{heading:"Reflection on invalid yields",blocks:[{kind:"list",items:[{body:"Agent output validated against `yields:` contract on every execution."},{body:"Missing keys filled with type-safe defaults (no KeyError cascades)."},{body:"Type mismatches caught and reported."},{body:"Strict mode triggers Manager retry with `corrected_input`."},{body:"Per-session `reflection_budget` caps retries (prevents runaway loops)."}]}]},{heading:"Multiple budget systems",intro:"Three distinct budget controls â each prevents a different class of runaway:",blocks:[{kind:"list",items:[{title:"Reflection budget",body:"Limits auto-retries on yields validation failures per session."},{title:"Loop rerun budget",body:"Limits loop-detected agent reruns per session."},{title:"Manager retry count",body:"Limits generic retry interventions per agent execution."}]}]},{heading:"Programmatic rerun API",blocks:[{kind:"list",items:[{body:"`sdk.rerun_agent(session_id, agent_name, new_input=None, feedback=None)` â explicit programmatic retry of a specific agent in a past session."},{body:"Routes through Manager's retry handler â same path used by analysis-driven retries and strict yields enforcement, so feedback rendering is consistent across surfaces."},{body:'Used by the frontend "rerun this agent" button and by orchestration scripts.'},{body:"Accepts new input (deliberate steer), feedback (correction guidance), or both."}]}]}]},{id:"tools-reasoning",title:"Tools & Reasoning",lead:"A rich set of built-in tools shipping today, plus the framework to ship your own. Every tool auto-traces, auto-times-out, and auto-validates arguments â and agents use them in a working loop, not a single shot.",sections:[{heading:"Agentic execution (work first, answer last)",intro:"Every LLM agent works like an engineer, not a form-filler. This is the default behavior â there is no flag to enable it.",blocks:[{kind:"list",items:[{title:"The working loop",body:"An agent turn is a loop: call a tool, read the result, react, call more â as many rounds as the task needs â and only produce the final structured answer once it has actually arrived. The agent decides when it is done; the tool-call cap, hard timeout, and budget bound it."},{title:"Room to work",body:"An agent with real tools is never pulled toward answering prematurely â the required yields are produced once the work is actually done. Downstream sees identical yields; the agent just got room to work first."},{title:"Verify, don't fabricate",body:"When a task depends on live data, a computation, a lookup, or prior context, the agent builds its answer from real tool results â never by inventing a value a tool could have provided."},{title:"Parallel tool use",body:"Independent tool calls in one step run concurrently (order-preserving, bounded); set allow_parallel_tool_calls: false to force strictly sequential execution."},{title:"Super agents compose it",body:"A super agent plans work into steps and runs each step as one of these working loops â plan at the top, workbench inside every step."}]}]},{heading:"Playbook â responsibilities on demand",intro:"Move an agent's detailed responsibilities out of the prompt and serve them per intent through a built-in `playbook` tool. The prompt c
1arries only the intent menu; the model loads the full instructions for whichever intents the request actually matches.",blocks:[{kind:"list",items:[{title:"Per-intent sections",body:"Each section declares an intent, a when-to-use line (the menu), the thorough responsibility text, and the variables the agent must establish (customer name, scope, deadline). Intents are enum-constrained on the tool â the model can never invent one."},{title:"Multiple loads per turn",body:"A request that spans intents loads several sections in one turn â a message that is both a greeting and a complaint runs both procedures."},{title:"Built to act",body:"Loaded responsibilities are executed with the agent's tools, not recited â the structured output reports work done rather than describing the procedure."},{title:"Pairing rule",body:"The prompt keeps identity and the output contract; the playbook keeps the how. A prompt that still carries the full job description wins over the playbook â so it shouldn't."},{title:"Live-editable",body:"Sections are ordinary agent config: edit in Studio or the Playground and the next run uses them â re-registration replaces the tool's sections in place."}]}]},{heading:"Declared connectors â Zapier, Composio, n8n",intro:"Third-party actions are declared on the agent the same way MCP servers are: a block naming the connection and the exact actions under `use:`. Each action becomes an individually-named tool (`github_create_issue`, `ops_create_ticket`) scoped to that agent.",blocks:[{kind:"list",items:[{title:"Named actions only",body:"The operator decides the surface â `use:` lists exactly what the agent may call; there is no discover-everything mode. Secrets ride as ${ENV} references, never in config."},{title:"Fail-open, never fatal",body:"A connection that can't be reached at start-up costs the agent those actions and nothing else; a failed call at runtime surfaces to the model as a tool error it can react to."},{title:"Scoped and pooled",body:"Tools register with per-agent permissions â two agents never see each other's connections â and actions on the same connection share one client."}]}]},{heading:"Computation and data tools",blocks:[{kind:"list",items:[{title:"math_eval",body:"Safe arithmetic expression evaluation without `eval()` injection risk."},{title:"timestamp",body:"Current time as ISO string, timezone-aware."},{title:"word_count",body:"Token-aware word and character counting."},{title:"data_lookup",body:"Typed key access to structured data sources."},{title:"sensitive_data_lookup",body:"Same as above but with PII redaction in traces."}]}]},{heading:"Knowledge and memory tools",blocks:[{kind:"list",items:[{title:"recall_memory",body:"Agents query their own cross-session memory, ranked by relevance and recency."},{title:"query_knowledge",body:"RAG lookup against the agent's configured vector database."}]}]},{heading:"Reasoning tools",blocks:[{kind:"list",items:[{title:"chain_of_thought",body:"Structured step-by-step reasoning with six reasoning styles: analytical, creative, logical, intuitive, systematic, exploratory."},{title:"metacognitive_reflection",body:"Agent grades its own reasoning quality."},{title:"Mandatory enforcement mode",body:"When `reasoning: true` is set, the SDK forces both reasoning tools to be called before the LLM can produce a final answer."}]}]},{heading:"External I/O tools",blocks:[{kind:"list",items:[{title:"web_request",body:"HTTP GET/POST with SSRF protection (blocks private IPs, configurable allowlist)."},{title:"web_search",body:"Search engine query."},{title:"file_read",body:"Sandboxed filesystem read."},{title:"file_write",body:"Sandboxed filesystem write."}]}]},{heading:"Messaging tools",blocks:[{kind:"list",items:[{title:"send_email",body:"Outbound via SMTP, supports HTML and plain alternatives."},{title:"send_slack_message",body:"To channel or DM with Block Kit support."},{title:"send_teams_message",body:"Adaptive Card support."},{title:"send_telegram_message",body:"Bot-driven outbound."}]}]},{heading:"Meta tools",blocks:[{kind:"list",items:[{title:"current_time",body:"Convenience time access."},{title:"wait_seconds",body:"Explicit delay for sequenced workflows."}]}]},{heading:"Custom tool framework",blocks:[{kind:"list",items:[{body:"`@tool` decorator on any Python function â agent-scoped registration."},{body:"`@global_tool` decorator â available to any agent."},{body:"Type hints automatically generate JSON Schema for argument validation."},{body:"Docstring becomes tool description visible to the LLM."},{body:"Per-agent allowlist by exact name: `tools: [my_tool, timestamp]`."},{body:"Per-agent allowlist by category: `tool_categories: [data, search]`."},{body:"Configurable per-agent `tool_call_timeout`."},{body:"Result serialization with non-JSON value warnings (datetime, bytes absorbed via `str()` with logged warnings)."}]}]},{heading:"MCP servers as ordinary tools",intro:"An agent declares the MCP servers it may reach, in its own config, and their tools become part of the tool list that agent's model sees. There is no separate registry to populate and no second place to name the same tool â you point at the server, and the agent can use it.",blocks:[{kind:"list",items:[{title:"Declared on the agent",body:"An `mcp:` block on the agent config takes a hosted server by URL, or a local one launched as a command. Editable from Studio like any other part of the agent â no code change to add a server."},{title:"Discovered, not hand-written",body:"The SDK asks the server what it offers and builds each tool's arguments from the server's own schema. Rename a tool upstream and the agent picks it up on next start."},{title:"Namespaced per server",body:"Tools carry their server's name as a prefix, so two servers can both offer `search` without colliding."},{title:"Narrow it when you want",body:"`use:` lists the specific tools to expose; leave it out and the agent gets everything the server publishes."},{title:"Scoped to the agent that asked",body:"A server declared on one agent is invisible to every other agent â the same permission model as local tools, not a shared global pool."},{title:"Same runtime, same records",body:"Remote calls run through the normal tool path: permission checks, timeouts, the tool-result guardrail, and the same execution record. They can run alongside local tools in one turn, in parallel or in sequence."},{title:"Pooled connections",body:"Agents pointing at the same server share one session rather than opening one each, and sessions close cleanly on shutdown."}]}]},{heading:"Tool security",blocks:[{kind:"list",items:[{title:"SSRF block",body:"Outbound HTTP rejects private and internal IPs (192.168.x.x, 10.x.x.x, 127.x, link-local, fc00::, fe80::)."},{title:"Argument validation",body:"JSON Schema enforced at call time."},{title:"Output guardrail",body:"Tool output is structurally isolated from instructions â prompt injection via tool responses can't escalate."},{title:"PII redaction in traces",body:"Sensitive tool payloads pass through redaction filters before recording."},{title:"Per-agent allowlists",body:"Tools and tool categories restricted per agent."}]}]}]},{id:"channel-integrations",title:"Native Channel Integrations",lead:"Seven channels first-class. Production hygiene built in.",sections:[{heading:"Knows when it is being spoken to",intro:"An agent in a shared room is a colleague, not a listener. It answers when addressed and stays out of the way otherwise â the difference between a teammate and a bot nobody wants in the channel.",blocks:[{kind:"list",items:[{title:"Silent unless addressed",body:"In a shared room the mesh replies only when mentioned, when an agent is named, or inside a thread it opened. A bare message between colleagues is left alone â and having spoken to the mesh once does not make everything said afterwards its business."},{title:"A mention starts something new",body:"Naming the mesh opens a new conversation even when it is waiting on an answer, because nobody @-mentions a bot to answer its question. Replying in the thread continues the existing one instead."},{title:"Never answers itself",body:"Its own messages are recognised as its own on every channel â the loop that would otherwise follow a bot posting where it also listens."},{title:"Staff-only seats",body:"An approval seat can refuse anyone outside its operator roster, checked before anything else so it holds in a direct message too. Customer-facing seats stay open to strangers, which is the default."}]}]},{heading:"Slack",blocks:[{kind:"paragraph",text:"Inbound events API, slash commands, interactive buttons, modals, message shortcuts. Outbound Block Kit cards, threads, reactions, file uploads. Per-channel session continuity. Socket Mode means a mesh behind NAT or on a laptop receives events over an outbound WebSocket â no public URL, no tunnel, no inbound firewall rule."}]},{heading:"Microsoft Teams",blocks:[{kind:"paragraph",text:"Bot Framework integration with raw HTTP fallback (works without `botframework-connector`). Adaptive Cards, mentions, channel posts, DM. Tenant-aware multi-instance support."}]},{heading:"Telegram",blocks:[{kind:"paragraph",text:"Bot framework via `python-telegram-bot`. Inline keyboards, callback queries, p
1hoto/document uploads. Long-poll or webhook delivery."}]},{heading:"Discord",blocks:[{kind:"paragraph",text:"Slash command interactions. Ed25519 signature verification on every inbound. Modal interactions. Per-guild instance support."}]},{heading:"Email",blocks:[{kind:"paragraph",text:"Outbound: SMTP via `aiosmtplib` (SendGrid, Mailgun, AWS SES, Postmark, custom). HTML and plain-text alternatives. File attachments."},{kind:"paragraph",text:"Inbound: signed webhook (Mailgun, SendGrid, SES). `signing_secret` required when `inbound_domain` configured. Reply parsing via `talon` (strips quoted thread and signature)."}]},{heading:"WhatsApp",blocks:[{kind:"paragraph",text:"WhatsApp Business API via Meta's Cloud API (Graph v21.0). Webhook payloads verified against the Meta app secret; an optional allow-list restricts which numbers are accepted. Numbers are normalised on the way in, so the same person is one conversation whether Meta sends `14155551234` or an operator writes `+1 415 555 1234`."}]},{heading:"Zoho Cliq",blocks:[{kind:"paragraph",text:"Human agents reachable in Cliq channels and DMs with the same first-class semantics as Slack. Inbound is verified against a token taken from the `X-Cliq-Token` header (preferred â query-string tokens end up in access logs), and fails closed: no configured secret means every inbound is rejected. Cliq has no threads, so each person holds one continuous conversation."}]},{heading:"Webhook (generic)",blocks:[{kind:"paragraph",text:"HMAC-SHA256 signature verification with timestamp + nonce binding. Replay protection (300-second skew window default). Configurable signing secret per registered webhook source."}]},{heading:"Per-channel features",blocks:[{kind:"list",items:[{title:"Session continuity",body:"Channel ID + user ID â stable session ID."},{title:"Cross-channel pivot",body:"Session moves between channels mid-conversation."},{title:"HITL inbox via channel",body:"Operators respond through their preferred channel."},{title:"Idempotent retries",body:"Webhook retries deduplicated by request_id."},{title:"Per-IP rate limiting",body:"60 requests / 60 seconds default."}]}]},{heading:"Channel security",blocks:[{kind:"list",items:[{body:"HMAC signature verification using each channel's standard."},{body:"Replay protection via timestamp + nonce."},{body:"Payload size cap (1 MB default)."},{body:"Per-IP rate limiting with token bucket."},{body:"Mandatory signing secret in production."},{body:"A signing secret is auto-provisioned when none is configured."}]}]},{heading:"Extensibility",blocks:[{kind:"paragraph",text:"Implement `BaseChannel` with four methods (`send`, `receive`, `normalize_event`, `verify_signature`) and register in YAML."}]}]},{id:"event-listeners",title:"Event-Driven Listeners",lead:"Five broker types first-class. Each external event becomes one mesh session.",sections:[{heading:"Apache Kafka",blocks:[{kind:"paragraph",text:"Driver: `aiokafka >= 0.10.0`. Consumer group support. Session ID: `listener_{name}_{topic}:{partition}:{offset}`. Configurable starting offset. Backpressure cap."}]},{heading:"AWS SQS",blocks:[{kind:"paragraph",text:"Driver: `aioboto3 >= 12.0.0`. Session ID: `listener_{name}_{MessageId}`. Visibility timeout configurable. Dead-letter queue routing."}]},{heading:"MQTT",blocks:[{kind:"paragraph",text:"Driver: `asyncio-mqtt >= 0.16.2`. Session ID: `listener_{name}_{topic}:{timestamp}:{payload_hash}`. QoS levels 0/1/2. Topic filter with wildcards."}]},{heading:"IMAP (email-as-event)",blocks:[{kind:"paragraph",text:"Driver: `aioimaplib >= 1.1.0`. Session ID: `listener_{name}_{folder}:{uid}`. Watches inbox folders. Configurable polling. Auto-mark-as-read after dispatch."}]},{heading:"Redis Streams",blocks:[{kind:"paragraph",text:"Uses core `redis >= 5.0`. Consumer-group delivery: messages are acknowledged only after successful dispatch, so nothing is lost mid-flight. Block-and-wait semantics."}]},{heading:"Common features",blocks:[{kind:"list",items:[{body:"One event = one session with deterministic, idempotent session ID."},{body:"Broker retries produce the same session_id â no duplicate work."},{body:"Per-listener concurrency cap (max in-flight events)."},{body:"Declarative payload filter at listener boundary."},{body:"Configurable dispatch target in YAML."},{body:"Per-listener tracer wrapping."}]}]},{heading:"Extras packages",blocks:[{kind:"list",items:[{body:"`pip install leafmesh[kafka]` â Kafka only."},{body:"`pip install leafmesh[sqs]` â SQS only."},{body:"`pip install leafmesh[mqtt]` â MQTT only."},{body:"`pip install leafmesh[imap]` â IMAP only."},{body:"`pip install leafmesh[listeners]` â all five at once."}]}]}]},{id:"scheduled-workflows",title:"Scheduled & Triggered Workflows",lead:"Time-based and event-based triggers for agents.",sections:[{heading:"Cron-driven scheduling",blocks:[{kind:"list",items:[{title:"Frequency expressions",body:"`30s`, `5m`, `2h`, `1d` (with 60-second minimum interval by default)."},{title:"Standard cron",body:"Full five-field cron expressions (`0 9 * * *` for daily 9am, `0 0 * * 1` for weekly Monday, `0 0 1 * *` for first of month)."},{title:"Keyword aliases",body:"`@hourly`, `@daily`, `@weekly`, `@monthly`, `@yearly`."},{title:"Complex schedules",body:'"third Wednesday of the month at 3pm", "every weekday between 9-5 every 15 minutes".'},{title:"Timezone-aware",body:"Cron expressions evaluated in configured timezone."},{title:"Misfire handling",body:"If the SDK was down during a scheduled fire, configurable behavior (skip / catch-up / fire-once)."},{title:"Validation at load time",body:"Invalid cron expressions rejected with clear errors."}]}]},{heading:"Scheduled agent triggers",blocks:[{kind:"list",items:[{body:"Agents declare a schedule in YAML."}
1,{body:"SDK fires the agent on its schedule with synthetic input."},{body:"Session ID composition: `scheduled_{agent}_{cron_id}_{fire_ts}` (idempotent on retries)."},{body:"Standard mesh routing applies after the scheduled agent runs."}]}]},{heading:"Event-driven triggers",blocks:[{kind:"list",items:[{body:"Broker events from Kafka, SQS, MQTT, IMAP, Redis Streams trigger sessions."},{body:"Each broker message becomes one mesh entry point."},{body:"Filter expressions reject uninteresting events."}]}]},{heading:"Conditional triggers",blocks:[{kind:"list",items:[{body:"Agents can fire based on coordination rule matches."},{body:"`WORKFLOW_PAUSED` / `WORKFLOW_RESUMED` events trigger downstream automation."},{body:"`INTERVENTION_NEEDED` triggers Manager-mediated actions."},{body:"Custom events via `sdk.event_bus.publish()`."}]}]},{heading:"Webhook triggers",blocks:[{kind:"list",items:[{body:"Any HTTP service can invoke a mesh entry point via webhook."},{body:"Authenticated with HMAC-signed requests."},{body:"Idempotent on duplicate deliveries."}]}]},{heading:"Agent self-scheduled continuation",intro:"Beyond author-defined cron, an agent can schedule its own continuation at runtime â the imperative counterpart to declarative wake_up.",blocks:[{kind:"list",items:[{title:"schedule_followup, pre-injected",body:'Every LLM agent gets a built-in schedule_followup tool with no configuration. Mid-task it can decide "I need to come back to this" and schedule a continuation of its own work â carrying the reason and context it needs to resume.'},{title:"Same-session continuity",body:"The woken agent runs again in the same session with its prior yields, state, and conversation intact, plus the explicit context payload â it picks up exactly where it left off, not from scratch."},{title:"Now or later",body:"Fire immediately as a fresh turn, after a relative delay (+30m, +2h, +1d), or at an absolute UTC time. Deferred follow-ups are durable records fired exactly once, surviving restarts and multiple workers."},{title:"Guardrails by default",body:"Chain-depth cap (default 5), per-session rate cap (default 20), 16 KB context cap, and target permissioning (self plus the agent's can_call set) â all tunable, none required."},{title:"Operator inbox",body:"Pending and past follow-ups are listable and cancellable via GET/DELETE /api/followups. The Manager can also schedule on an agent's behalf when it left work unfinished, deduplicated so it never stacks."}]}]},{heading:"Use cases",blocks:[{kind:"list",items:[{body:"Daily summary emails to operators."},{body:"Weekly invoice reconciliation runs."},{body:"Monthly compliance audits."},{body:"Real-time alerting on Kafka order topics."},{body:"Email-driven customer support workflows."},{body:"Per-customer scheduled health checks."},{body:"A researcher deferring a rate-limited source and re-checking it in 30 minutes."},{body:"A payments agent verifying a submission cleared, later, without a human re-trigger."}]}]}]},{id:"evolution-health-checks",title:"Evolution Health Checks",lead:"Daily tripwire for deployed agent chains. Replay the same scenarios on the live config, score each agent against operator-declared expectations, and surface drift the moment it appears â before customers do.",sections:[{heading:"What it scores",blocks:[{kind:"paragraph",text:'Per-agent quality, not just "did the chain return something." Each agent is graded on `100 à (0.5 à schema_match + 0.5 à value_match)`. Schema match checks the agent yielded the keys declared in its YAML `yields`; value match checks each key against the operator\'s `expected_outcomes` using eight frozen operators (`~contains`, `~regex`, `~gte` / `~gt` / `~lte` / `~lt`, `~in`, `~truthy` / `~falsy`, plus exact match).'},{kind:"callout",text:`Agents with no declared expectations score 50, not 100 â the dashboard surfaces "we don't know what good looks like for this agent" instead of a fake-healthy green.`}]},{heading:"Scenario library",blocks:[{kind:"list",items:[{title:"Reusable saved scenarios",body:"Name, entry point, input, per-agent `expected_outcomes`, per-agent stubs, tags. Same shape the SDK uses inline â author once, run from any schedule."},{title:"Stubs for external dependencies",body:"Pin LLM or external-connector responses so daily runs don't drift on third-party output. Stubbed agents are excluded from the scenario mean â they're inputs to the test, not part of it."},{title:"Soft archive, not delete",body:"Retire a scenario without yanking it from history. Archived scenarios are excluded from default lists and from schedule execution, but stay around for drift comparison against prior runs that used them."}]}]},{heading:"Scheduled runs",blocks:[{kind:"list",items:[{title:"Daily or cron cadence",body:'`daily_at: "09:00"` or full cron. Schedules pick scenarios from the library by id; archive a scenario and it stops running on the next tick.'},{title:"Per-schedule hyperparameters",body:"Each schedule carries its own `population_size`, `generations`, and `max_runtime_seconds`. The default is `1 à 1 à 300s` â a pure health check that scores the live config once with no mutation. Bump those values for genuine config search on a schedule (e.g. weekly `5 à 4 à 600s` to evolve a config overnight)."},{title:"Missed-fire detection",body:"If the service was down when a schedule should have fired, the runner publishes a `schedule.missed_fire` event on pickup and runs anyway â better late than skipped."},{title:"Operator-triggered run-now",body:"Manually fire any schedule from the UI without waiting for the cadence."}]}]},{heading:"Operator controls in the UI",blocks:[{kind:"list",items:[{title:"Run-Evolution dialog with Advanced section",body:"Population size, generations, and stop-after (max runtime) are exposed at the top of the manual-run dialog. The footer shows a live `pop à gens à scenarios = N runs` preview so operators can see total workload before submitting."},{title:"Schedule editor with the same controls",body:"Identical Advanced section in the schedule create/edit dialog. Setting `population=3, generations=2, max_runtime=120` once on a schedule applies it to every fire of that schedule."},{title:"Cancel mid-flight keeps the partial result",body:`Cancelling a long-running job preserves whatever the optimizer already scored â per
1-agent rollup, scenario results, and best-fitness so far. The job's human summary reads "Cancelled before completion â partial result persisted (best fitness X.XX)" instead of throwing the work away.`},{title:"Clean actual-output view",body:"Framework-injected metadata (`_llm_provider`, `_llm_tokens`, `_success`, `_agent_name`, `_chain_history`, etc.) is stripped from the scenario_result's \"actual\" payload before display. Operators see only the keys the agent's YAML schema declared, side-by-side with their `expected_outcomes`."}]}]},{heading:"Drift detection",blocks:[{kind:"list",items:[{title:"Same scenarios = comparable runs",body:"Each run gets a fingerprint of the scenario set. The next run compares its score against the previous run with the same fingerprint, framing the human summary as Î instead of a raw 0-100 number."},{title:"Survives scenario-set edits",body:"Adding or removing a scenario falls back to an overlap-based match so drift comparison continues across edits â with a note that the comparison is on the scenarios in common."},{title:"Severity-shaped summaries",body:'"Health check REGRESSED: 82.5/100 (â 12.3 vs last run). Open the per-agent breakdown to triage." â plain-English headline operators can read at a glance without interpreting the score.'}]}]},{heading:"Cost and isolation",blocks:[{kind:"list",items:[{title:"Separate cost view",body:"Health-check LLM calls are tracked separately from production traffic. The cost dashboard shows real-traffic and evolution spend side by side, so operators can see what daily runs are costing without it blending into the customer-facing total."},{title:"Tagged event stream",body:"Every event published during an evolution run carries an `_evolution_meta` tag so feed dashboards, session views, and routing memory can filter it out â health-check traffic never pollutes operator timelines."}]}]},{heading:"Use cases",blocks:[{kind:"list",items:[{body:"Catch prompt-tweak regressions before they reach customers."},{body:"Track per-agent quality over time for SLO reporting."},{body:"Validate config changes against a known-good baseline before rolling them."},{body:"Detect LLM provider drift â same prompts, same scenarios, declining scores."},{body:"Continuous proof-of-correctness for compliance and customer audits."}]}]}]},{id:"memory-knowledge",title:"Memory & Knowledge Retrieval",lead:"Three memory layers, each serving a different purpose.",sections:[{heading:"Conversation history (per session)",blocks:[{kind:"list",items:[{body:"Auto-loaded from session manager on every LLM call."},{title:"LLM with memory enabled",body:"Skipped entirely (memory feed has same content, smarter)."},{title:"LLM without memory",body:"Anchor (first user turn) + last 5 turns."},{title:"HITL human",body:"Last 10 turns verbatim."},{title:"Programmatic / external (opt-in)",body:"Set `receive_conversation_history: true` on the agent's YAML to inject prior turns into the payload â `context._conversation_history` for programmatic agents, `input_data._conversation_history` for external connectors, and the webhook body for human agents. Default OFF; when ON, `history_limit` (default 20, range 1â200) controls the cap. Operators wire it via a single toggle in Studio's Inputs & Outputs panel and Playground's agent inspector."},{body:"TTL bounded (default 7 days, configurable)."},{body:"Validated structure (drops malformed entries with warnings)."},{body:"Empty sessions cost nothing to look up."}]}]},{heading:"Streaming output (dual-mode LLM agents)",blocks:[{kind:"paragraph",text:"Dual-mode LLM agents (the default LLM agent_type) can stream the
1ir output token-by-token to the caller via Server-Sent Events. The caller passes `stream=True` to `mesh_call`, the SDK opens an SSE connection, and tokens flow out as they're generated. Tokens are surfaced as `token` chunks, the final assembled response arrives as a `final` chunk, and errors propagate as `error` chunks."},{kind:"list",items:[{title:"Caller-side opt-in",body:"Per call, not per agent â the SAME agent can serve streaming and non-streaming callers depending on what each caller asks for."},{title:"stream_yield picks the field",body:"Set `stream_yield: greeting` on the agent's YAML to stream only that yield key. If `stream_yield` is unset (and the agent has only one declared yield), the SDK auto-picks it."},{title:"SSE endpoints",body:"`POST /api/mesh/request` honours `stream=true` with a token-by-token chunk envelope for LLM agents."},{title:"Studio Test Modal + Playground",body:"A single toggle enables streaming in the Studio Test Modal and Playground session history. Operators see tokens land in real time when debugging an agent."},{title:"Falls back cleanly",body:"Non-dual-mode agents (programmatic, human, external) ignore the stream flag and return the full result in one chunk. The caller's SSE consumer code stays identical."}]}]},{heading:"Agent memory (cross-session)",intro:"Scoring blends relevance and recency. Default weights: 60% relevance, 40% recency. Default decay: 7-day half-life.",blocks:[{kind:"paragraph",text:"Per-agent configurable: decay_hours, relevance_weight, recency_weight, cross_session, cross_session_limit."},{kind:"paragraph",text:"Access pattern â tool-driven (LLM calls `recall_memory` when it decides to look back). No automatic injection."}]},{heading:"Knowledge / RAG",blocks:[{kind:"paragraph",text:"Vector database providers:"},{kind:"list",items:[{title:"MongoDB Atlas Vector Search",body:"`motor >= 3.3.0` (base dependency)."},{title:"PostgreSQL pgvector",body:"`asyncpg >= 0.29.0`."},{title:"Pinecone",body:"`pinecone-client >= 3.0.0`."},{title:"Document ingestion",body:"PDF (`PyPDF2`), DOCX (`python-docx`), CSV, JSON, Markdown."}]},{kind:"paragraph",text:"Per-agent knowledge config â serviceName, enabled, top_k, optional query_template."},{kind:"paragraph",text:"Access patterns:"},{kind:"list",items:[{title:"Auto-injection",body:"Relevant passages inserted into the LLM prompt in a dedicated knowledge section."},{title:"Explicit query via tool",body:"`query_knowledge`."},{title:"Hybrid",body:"Auto-inject for known context, tool query for follow-up."}]},{kind:"paragraph",text:"Ingestion pipeline:"},{kind:"list",items:[{body:"Declarative chunker config (chunk size, overlap, type detection)."},{body:"Auto-detection of file type from extension."},{body:"Custom embedding model per provider."},{body:"Metadata preservation (source, page, section, custom tags)."}]}]},{heading:"Skill-augmented agents",intro:"Think of skills as the agent's skill buddies â small playbooks (a tone guide, an escalation rule, a refund flow) that the agent declares and loads only when it hits that specific kind of problem. Library of SKILL.md-format prompts each agent can reference by name. Mirrors the Knowledge architecture â central library, per-agent attach via YAML, autoscale-safe storage. Uses Anthropic's open-source SKILL.md format (YAML frontmatter + Markdown body).",blocks:[{kind:"paragraph",text:"Storage backends:"},{kind:"list",items:[{title:"Hosted (Redis)",body:"Skill bodies stored directly in Redis (the source of truth). Autoscale-safe â all SDK replicas share the same catalog. No additional infra. SDK auto-creates a `default` hosted source on first boot."},{title:"Filesystem (project convention)",body:"Skills read from the project's `./skills/` folder on every call â same convention as `./agents/`. Local-dev only (each replica reads its own disk). `LEAFMESH_SKILLS_DIR` env var available for ops (Docker volume mounts) but not exposed via the UI."},{title:"Remote connectors (future)",body:"S3 / MongoDB / PostgreSQL adapters land in later cuts. Reads on remote sources are wrapped in the adaptive cache below; local sources don't need it."}]},{kind:"paragraph",text:"Adaptive-TTL cache (remote connectors only):"},{kind:"list",items:[{title:"Cold tier",body:"Cache TTL = `redis.default_ttl` from `config.yaml`. No per-source override; cache lifetime is governed in one place."},{title:"Warm tier",body:"Skills used regularly are kept warm automatically and stop re-pulling."}
1,{title:"Hot tier",body:"Heavy-use skills are effectively pinned, eliminating connector round-trips."},{title:"Automatic invalidation",body:"Cache cleared on upload / delete. Local sources skip cache writes entirely â the invalidate is a no-op."}]},{kind:"paragraph",text:"Per-agent attach:"},{kind:"list",items:[{title:"Shortform",body:"`skills: [tone-rules, escalation-policy]` â names resolved against the auto-created `default` source."},{title:"Longform",body:"`skills: { sourceName: my_library, enabled: true, names: [tone-rules] }` â explicit source binding for multi-library projects."},{title:"Lazy vs eager injection",body:"Lazy (default): system prompt carries `name + description` (~50 tokens per skill); the LLM calls `load_skill_reference` when it needs a body. Eager (`LEAFMESH_SKILLS_EAGER=true`): full bodies inline in the prompt; on Anthropic / Bedrock / Vertex the eager bodies get the prompt-cache discount automatically."}]},{kind:"paragraph",text:"Multi-file skills:"},{kind:"list",items:[{body:"A skill can be either a single `.md` file or a subfolder containing `SKILL.md` plus supporting files (images, PDFs, JSON references)."},{body:"Primary body always served as plain UTF-8 markdown â no base64 encoding for the text the LLM reads."},{body:"Supporting files referenced lazily via `load_skill_reference(skill_name, file_name)`; only the file the LLM asks for crosses the wire."}]},{kind:"paragraph",text:"Studio UI:"},{kind:"list",items:[{title:"Skills page",body:"Central library view per source â upload, edit, delete, preview. Source dropdown switches between registered backends."},{title:"Manage Sources dialog",body:"Register / remove storage backends. Type-aware config â hosted requires nothing, filesystem uses the project convention, remote connectors expose their own connection fields."},{title:"Per-agent picker",body:"Studio agent inspector + Playground both surface a Skills picker so individual agents can attach skills from any registered source without editing YAML by hand."}]}]},{heading:"Yields persistence",blocks:[{kind:"list",items:[{body:"Every agent's structured output stored durably, per session and per agent."},{body:"Type-tagged for separate searchability."},{body:"TTL inherits `session_ttl`."},{body:"Available for retries, memory recall, analytics."}]}]},{heading:"Typed data structures system",intro:"Declare reusable schemas in YAML, reference them from agent yields:",blocks:[{kind:"list",items:[{title:"Object types",body:"Properties, required fields, validation rules."},{title:"Primitive types",body:"string, number, integer, boolean, array."},{title:"Validation rules",body:"min, max, pattern (regex), enum, min_length, max_length."},{title:"Cross-agent reuse",body:"Declare an `Order` schema once, reference from any agent's yields."},{title:"Auto-validation",body:"Agent output validated against referenced schema on every run."},{title:"Non-blocking warnings",body:"`DataStructureMismatch` events emitted on violation; mesh continues."}]}]}]},{id:"super-agent",title:"Super-Agent (plan, execute, verify)",lead:"An opt-in mode on any LLM agent that lets the model plan multi-step work, execute each step, verify it, and synthesize a final answer â all inside a single mesh dispatch. Same yields contract, same can_call rules, much more structured behavior on hard tasks.",sections:[{heading:"Opt-in per agent",blocks:[{kind:"list",items:[{title:"Single YAML flag",body:"`super_agent: true` on any LLM agent flips the mode on. No project-wide switch â one super-agent and ten regular agents can coexist in the same mesh."},{title:"Full tuning surface in YAML",body:"The nested form takes every knob: `super_agent: {cost_ceiling, wall_clock, step_max_tokens, synth_max_tokens, verify_view_chars, goal_check_view_chars, step_concurrency}` â all optional, all with sensible defaults. Studio and the Playground expose the same knobs as form fields."},{title:"Verification is built into the run",body:"Step work is scored before synthesis, and the final result is judged against the original goal â the verdict travels as metadata alongside the output, so review is part of every run, not bolted on afterwards."},{title:"The synthesis is the output",body:"A run's final output is the synthesis shaped by the agent's declared yields â the goal-check verdict rides along as metadata, never as content. Downstream agents (and any wait_for join) receive the declared yields like any other handoff."},{title:"LLM agents only",body:"Super-agent is a planning layer over an LLM call â programmatic, human, and external agents are not eligible."}
1,{title:"Transparent to the mesh",body:"Downstream `can_call` rules read the declared `yields` unchanged. Session state, streaming, intelligence functions, communication_type all work identically."}]}]},{heading:"How a dispatch unfolds",intro:"The framework runs the loop on the agent's behalf â the customer's YAML stays the same.",blocks:[{kind:"list",items:[{title:"1. Plan",body:"Instead of answering, the LLM emits a multi-step plan via the framework-injected `todowrite` tool. Capped at 10 steps."},{title:"2. Execute",body:"The orchestrator walks each step â tool calls for tool-using steps, intermediate reasoning for thinking steps."},{title:"3. Verify",body:"A small follow-up check scores each step. Low-scoring steps are retried once with the verifier feedback folded in."},{title:"4. Synthesize",body:"A final synthesis pass assembles the answer per the agent's declared `yields`. The synthesized output is what downstream rules see."},{title:"5. Optional goal check",body:"Confirms the plan actually met its stated goal. Lands on the response envelope as `_goal_met` + `_goal_score`."}]}]},{heading:"Guardrails baked in",blocks:[{kind:"list",items:[{title:"Max 10 steps / 30 iterations",body:"Per-plan and per-dispatch caps prevent runaway loops even on pathological plans."},{title:"Automatic step retry",body:"Low-scoring steps get exactly one retry, then continue with the low score recorded."},{title:"2 retries per phase",body:"Transient errors (rate limits, network blips) get up to two retries before the step is marked errored."},{title:"Pause & cancel",body:'LLM can call `pause` mid-plan to checkpoint cleanly. Customer can call `sdk.cancel_dispatch(session_id, agent_name)` from outside â current step finishes, response returns with `_status: "cancelled"`.'}]}]},{heading:"Response envelope",intro:"Beyond the agent's declared `yields`, super-agent dispatches return metadata fields (all prefixed `_`) so callers can see what happened without changing the contract:",blocks:[{kind:"list",items:[{title:"`_super_agent: true`",body:"Always present on a super-agent response. Lets callers branch without inspecting other fields."},{title:"`_status` + `_status_reason`",body:"One of completed / cancelled / paused / errored / synthesis_only, with human-readable reasons."},{title:"`_plan`",body:"Plan summary with per-step status and verifier scores â meant for logging, debugging, and Studio's inspector view."},{title:"`_cost_ceiling_hit` / `_wall_clock_hit`",body:"Booleans flagging which budget (if any) ran out. Drives 'consider raising the ceiling' diagnostics."},{title:"`_goal_met` + `_goal_score`",body:"Final goal-check verdict â bool and the numeric score (null if the check didn't run)."}]}]}]},{id:"building-experience",title:"Modern Building Experience",lead:"Three tiers of how much code you write. Migrate freely between them.",sections:[{heading:"No-code (YAML-native)",intro:"The whole mesh declarative:",blocks:[{kind:"list",items:[{body:"Agents â name, type, model, prompt, tools, yields, channels."},{body:"Mesh â routing rules, conditions, fan-in expressions, narration."},{body:"Channels â full channel adapter configs."},{body:"Knowledge â vector DB connections, per-agent settings."},{body:"Memory â per-agent decay, weights, scope."},{body:"Manager â coordination rules, intervention strategies."},{body:"Listeners â Kafka topics, SQS queues, MQTT subscriptions, IMAP folders."},{body:"Schedules â cron expressions, frequency triggers."},{body:"Data structures â typed schemas for yields validation."},{body:"Channels â Slack / Teams / Telegram / Discord / email / SMS / webhook."}]},{kind:"paragraph",text:"Validation at load time:"},{kind:"list",items:[{body:"Pydantic schema enforcement."},{body:"Unknown agent references in `can_call` rejected."},{body:"Circular `can_call` reference detection."},{body:"Missing required fields rejected with clear errors."},{body:"Field applicability checks (e.g., `framework:` rejected on LLM agents)."},{body:"Cron expression validation."},{body:"Channel signing_secret enforcement when inbound_domain configured."}]},{kind:"callout",text:"Hot reload in development â config changes detected without SDK restart."}]},{heading:"Low-code (decorators)",intro:"Drop into Python only when you need to. Lifecycle decorators wrap the agent's execution; `@tool` / `@global_tool` register custom tools.",blocks:[{kind:"list",items:[{title:"Lifecycle hooks",body:"`@pre_compose`, `@chain`, `@chain_with_results`, `@compose`, `@conditional_chain` â full detail in the Agent Anatomy chapter."},{title:"@tool / @global_tool",body:"Register custom tools â agent-scoped or global. Type hints become JSON Schema, docstrings become tool descriptions."},{body:"Standalone form â decorators work without an active SDK instance (import directly from `leafmesh`), perfect for unit tests."}]}]},{heading:"Full-code (extensibility)",intro:"Pluggable interfaces:",blocks:[{kind:"list",items:[{title:"LLMProvi
1der",body:"ABC â custom LLM providers."},{title:"BaseChannel",body:"ABC â custom channels."},{title:"ExternalConnector",body:"ABC â custom framework bridges."},{title:"EventListener",body:"ABC â custom event brokers."},{title:"KnowledgeProvider",body:"ABC â custom vector DBs."}]},{kind:"paragraph",text:"Event subscribers â `sdk.event_bus.subscribe(EventType.X, handler)` for custom logic."},{kind:"paragraph",text:"Lifecycle hooks:"},{kind:"list",items:[{title:"pre_start",body:"Before SDK initialization."},{title:"post_start",body:"After all components ready."},{title:"pre_stop",body:"Before shutdown begins."},{title:"post_stop",body:"After cleanup completes."},{body:"Useful for: connection pre-warming, custom monitoring, custom backplane setup, graceful drain."}]}]},{heading:"CLI scaffolding",intro:"`create-leafmesh create my-app` generates:",blocks:[{kind:"list",items:[{body:"`config.yaml` â sample mesh config."},{body:"`agents/` â Python files for programmatic logic."},{body:"`tools/` â custom tool registration."},{body:"`main.py` â entry point with mesh_call example."},{body:"`requirements.txt` â dependencies."},{body:"`.env.example` â required env vars."},{body:"`README.md` â quickstart."}]}]},{heading:"API surface",intro:"The SDK is a first-class library, not just a server.",blocks:[{kind:"paragraph",text:"Programmatic Python API:"},{kind:"list",items:[{body:"`sdk.mesh_call(entry_point, data, session_id=...)` â invoke the mesh from any in-process Python code."},{body:"`sdk.rerun_agent(...)` â re-execute a specific agent in a past session with optional steer or correction."},{body:"`sdk.publish_agent_output(...)` â manually inject an agent output and trigger downstream dispatch."},{body:"`sdk.trigger_agents(...)` â fan out to specific agents without an entry-point chain."},{body:"`sdk.call_llm(...)` â direct LLM call with full provider abstraction."},{body:"`sdk.list_agents()`, `sdk.get_status()`, `sdk.get_agent_stats(agent_id)` â introspection."},{body:"`sdk.get_agent_feed(...)`, `sdk.get_global_feed(...)`, `sdk.get_session_feed(...)` â feed retrieval."},{body:"`sdk.add_feed_comment(...)`, `sdk.remove_feed_comment(...)` â operator commentary on agent runs."},{body:"`sdk.erase_session(...)` â GDPR-friendly hard delete."},{body:"`sdk.event_bus.subscribe(EventType.X, handler)` â custom event handlers on any internal event type."},{body:"`sdk.register_llm_provider(...)` â plug in a custom LLM provider."},{body:"Aggregated analytics + LLM cache stats are surfaced in Studio's Dashboard."},{body:"Advanced lifecycle features (self-healing, evolutionary optimization) are managed from Studio's tabs or YAML config â no per-call Python surface."}]},{kind:"paragraph",text:"HTTP REST API â full mesh control over HTTP (mesh, webhooks, callbacks, health). Customer-tier builds expose the limited public surface; hosted-tier builds expose admin endpoints."},{kind:"paragraph",text:"Streaming transports:"},{kind:"list",items:[{title:"WebSocket",body:"Real-time bidirectional delivery."},{title:"Server-Sent Events",body:"`/api/mesh/stream` for one-way streaming to UIs (cookie-authenticated, SOC 2 CC6.1 aligned)."},{title:"Async iterator",body:"Token-by-token streaming directly from LLM agents inside Python code."}]},{kind:"paragraph",text:"System health â `/healthz` and `/readyz` for orchestrators; OpenTelemetry metrics endpoint for Prometheus scrape."}]},{heading:"Development affordances",blocks:[{kind:"list",items:[{title:"Dry-run validation",body:"`validate_config(LeafMeshConfig)` loads the YAML and validates the entire mesh (agent contracts, routing graph, channel bindings, yields schemas, data structures) without starting Redis or making any LLM calls. Run in CI before deploy."},{title:"Playground (test mode)",body:"Single-agent test runner in Studio's Playground tab. Playground sessions are prefixed `pg_` and auto-skip the Manager and Summarizer so test turns don't waste tokens or pollute production metrics."},{title:"Hot reload",body:"YAML changes detected without an SDK restart in development."},{title:"Schema diff",body:"Yields-contract changes surface as structured warnings (`DataStructureMismatch` events), not silent breaks."},{title:"Replay",body:"Every event in the stream is timestamped and append-only, which makes deterministic session replay tractable. The replay tooling itself is on the roadmap."}]}]},{heading:"Backwards compatibility",blocks:[{kind:"list",items:[{body:"`SwarmSDK` alias for the `LeafMesh` class (preserved from the rebrand)."},{body:"Old type aliases (`type: list` â `array`)."},{body:"Legacy kwarg compatibility on configuration classes."},{body:"Migration is non-breaking â old code keeps working."}]}]}]},{id:"observability-cost",title:"Observability & Cost Analytics",lead:"OpenTelemetry-native. Every action traced. Every dollar tracked.",sections:[{heading:"Span taxonomy",blocks:[{kind:"list",items:[{title:"session:{id}",body:"Root span per `mesh_call`."},{title:"agent:{name}",body:"One per agent execution."}
1,{title:"precompose:{processor}",body:"Per pre-compose processor step."},{title:"connector:llm / connector:human / connector:external",body:"Provider boundary spans."},{title:"llm:{provider}/{model}",body:"Actual LLM API call."},{title:"tool:{name}",body:"Per tool execution."},{title:"chain:{func_name}",body:"Per chain decorator step."},{title:"compose:{target}",body:"Per per-target shaper."},{title:"fan_in:{target}",body:"Synthetic merge node showing contributors."},{title:"mesh_communication",body:"Per edge in agent-flow graph."},{title:"manager:analysis",body:"Manager's analytical LLM call."}]}]},{heading:"Seeing inside an external agent",intro:"When part of your mesh runs on someone else's platform â a CrewAI crew, a LangGraph deployment, an n8n workflow, an MCP or A2A endpoint â the usual answer is that the trace stops at the network boundary. It doesn't have to.",blocks:[{kind:"list",items:[{title:"One trace across the boundary",body:"The outbound call carries standard trace context, so a platform that speaks the same standard attaches its own internal steps as children of yours. One trace, both sides, no correlating by timestamp."},{title:"Their steps, in your trace",body:"For platforms that report what they did â reasoning steps, tool calls, retrieved sources, sub-agent updates â those steps are recorded against the call, so you can see how an answer was reached even when the work ran elsewhere."},{title:"Their spend, in your budget",body:"Where an external platform reports token usage, it lands in the same per-agent meter as your own model calls and counts against the same budgets. External work shows up in the cost dashboard rather than off the books."},{title:"Polling told apart from work",body:"For platforms that run asynchronously, each poll and fetch is its own step under the call â so a slow external agent is visibly slow work rather than mystery latency."},{title:"Honest about the limits",body:"A platform that reports neither usage nor steps stays a black box: you get the call, its duration, its result, and nothing about its interior. We surface what the far side chooses to tell us and never invent the rest."}]}]},{heading:"Span attributes captured",blocks:[{kind:"list",items:[{body:"`leafmesh.agent_name`, `leafmesh.agent_type`, `leafmesh.from_agent`, `leafmesh.run_type`."},{body:"`llm.prompt_tokens`, `llm.completion_tokens`, `llm.total_tokens`, `llm.cost.total`."},{body:"`llm.has_tool_calls`, `llm.tool_call_count`, `llm.cache.read_tokens`, `llm.cache.creation_tokens`."},{body:"`llm.thinking_tokens` (for o-series reasoning models)."},{body:"`leafmesh.input`, `leafmesh.output` â full payload, PII-redacted by default for third-party endpoints."},{body:"`tool.success`, `tool.error`, `tool.duration_ms`."},{body:"`leafmesh.session_id`, `leafmesh.execution_id`, `leafmesh.dispatch_seq`."}]}]},{heading:"Cost tracking",blocks:[{kind:"list",items:[{body:"Per-model input/output pricing for every major OpenAI, Anthropic, and Google frontier model."},{body:"Per-LLM-call cost recorded on the span."},{body:"Per-agent-run cost rolled up across all calls."},{body:"Per-session cost totaled in session analytics."},{body:"Cache tokens broken out separately."},{body:"Reasoning tokens broken out separately."},{body:"Costs queryable per any time window via SDK API."}]}]},{heading:"Stream events",intro:"The SDK publishes real-time stream events for:",blocks:[{kind:"list",items:[{body:"`agent.executed`, `agent.failed`."},{body:"`llm.cache.hit`, `llm.cost.tracked`."},{body:"`manager.intervention`, `manager.decision`, `manager.chain_complete`."},{body:"`mesh.call.started`, `mesh.call.completed`, `mesh.call.failed`."},{body:"`hitl.request.pending`, `hitl.request.resolved`, `hitl.request.timeout`."},{body:"`knowledge.query`, `knowledge.injected`, `knowledge.failed`, `knowledge.no_results`."},{body:"`tool.executed`, `tool.failed`."},{body:"`session.created`, `session.updated`, `session.completed`, `session.expired`."}]}]},{heading:"Session analytics",blocks:[{kind:"list",items:[{body:"`total_mesh_communications` â count of agent handoffs."},{body:"`session_duration_seconds` â wall-clock time."},{body:"`agents_involved` â unique agents that ran."},{body:"`last_activity` â timestamp of most recent event."},{body:"`session_status` â active, completed, outage, etc."},{body:"Token totals (prompt, completion, total)."},{body:"Cost totals and error count."}]}]},{heading:"LLM cache analytics",blocks:[{kind:"list",items:[{body:"Cache hit rate."},{body:"Cache miss count."},{body:"Cache eviction count."},{body:"Cache store count."},{body:"TTL distribution."}]}]},{heading:"Trace export",blocks:[{kind:"list",items:[{title:"Your own stack",body:"Traces stream to the observability backend you already run â the industry-standard wire format means no LeafMesh-specific collector to operate."},{title:"Console output",body:"For local development, traces print to the terminal instead."},{title:"Oversized payloads",body:"A very large payload is truncated with an inline marker so a chatty agent can't flood your trace storage. Nothing to tune â the SDK handles it."}]}]},{heading:"What a trace shows, and how to lock it down",blocks:[{kind:"list",items:[{title:"Content is visible by default",body:"A trace shows what an agent received and what it said back â the question anyone opens a trace to answer. Traces land in your own backend, so the payloads stay yours."},{title:"Redaction is one switch",body:"Turn it on and every payload body becomes `<redacted bytes:N>`. For teams exporting to a backend they don't control, or working under a contract that forbids content leaving the process."},{title:"Structure is never redacted",body:"Agent names, model IDs, token counts, costs, timings and status flags stay visible either way. You keep the operational picture even with content off."},{title:"One answer, everywhere",body:"The setting behaves identically wherever your traces go â no hidden variation by destination â and takes effect without a redeploy."}]}]},{heading:"Auto-instrumentation included",blocks:[{kind:"list",items:[{body:"FastAPI (HTTP request spans)."},{body:"Requests (outbound HTTP)."}
1,{body:"aiohttp client (async HTTP)."},{body:"Redis (Redis command spans)."},{body:"Logging (log correlation with traces)."},{body:"System metrics (CPU, memory)."}]}]}]},{id:"command-center",title:"Command Center â the business view",lead:"Every agent platform can tell you how many runs succeeded. None of that answers the question a business actually asks: are we getting the work done, how fast, and at what cost. Command Center is a KPI board the agency designs for itself â from the work it has actually been observed doing.",sections:[{heading:"Designed from real runs, not from your config",intro:"Nothing is pre-built and nothing is guessed. When the agency starts, it watches a handful of real runs first â what the agents produced, which tools they used, what the outcomes were called in your domain's own words. Only then does it design the board.",blocks:[{kind:"list",items:[{title:"Your vocabulary, not ours",body:"A claims agency gets claims settled, time to settle, and cases awaiting a decision. A quoting agency gets quotes issued and win rate. Nobody hands us a template â the metrics come from what your agents did."},{title:"Observed before designed",body:"The board is derived from real outcomes, so it measures what actually happens rather than what the config implied would happen. A first pass from config appears immediately at boot; it is replaced once there is real evidence."},{title:"Nothing lost in the wait",body:"Runs that happen while the agency is still learning are counted anyway, at the time they really occurred â so the first board opens with history in it, not zeros."},{title:"Redesign whenever the work changes",body:"Ask for a redesign at any time, optionally in your own words â 'focus on turnaround time, not volume' â and the board is rebuilt against the metrics that matter now."}]}]},{heading:"Business, not machinery",blocks:[{kind:"list",items:[{title:"The work, not the workers",body:"Command Center talks about invoices, tickets, quotes and cases â never about agents, prompts, tokens or queues. Those live in the operational dashboards where they belong."},{title:"Counted exactly, not estimated",body:"Each metric is a precise recipe run against what really happened. No sampling, no model guessing at a number, no extra model spend to keep the board current."},{title:"Live",body:"Numbers move as work completes, and every metric holds its own day, week, month and all-time view."},{title:"What changed",body:"The board says which numbers moved and by how much since the previous period â computed, not narrated, so it never pads a real shift with commentary."},{title:"Targets",body:"Metrics can carry a target and a direction, so a number reads as on track or off track at a glance rather than as a bare figure."}]}]},{heading:"A board, not a wall of cards",blocks:[{kind:"list",items:[{title:"Composed layout",body:"Headline figures, trends over time, breakdowns and rankings each get the shape that suits them â the board is laid out the way someone would actually brief a business, not as one uniform grid of tiles."},{title:"Waiting on a person",body:"Work paused for a human decision is surfaced separately, because a queue that isn't moving is a business problem before it is an operational one."},{title:"Yours to edit",body:"Change titles, thresholds, targets and chart types from the UI or the API. Export the whole board and upload it into another environment â the definition is portable, so staging and production can share one."},{title:"Says when it doesn't know",body:"A metric with no evidence behind it yet says so plainly instead of displaying a confident zero."}]}]}]},{id:"cost-optimization",title:"Cost Optimization",lead:"Cost reduction features, distinct from cost tracking. The SDK actively cuts your LLM spend.",sections:[{heading:"Per-agent monthly budgets",intro:"Cap what each agent can spend, in tokens and dollars, per month â opt-in per agent.",blocks:[{kind:"list",items:[{title:"Tokens and dollars",body:"Set monthly_token_budget and/or monthly_cost_budget on an agent. The budget resets monthly and is enforced on every LLM call â initial, tool-loop, reflection â none escape the cap."},{title:"Refuse before overspend",body:"The agent pre-estimates the next call and refuses it if it would exceed the cap, rather than overshooting. A budget-exhausted agent stops making LLM calls."},{title:"Graceful or escalate",body:"budget_on_exhaust: graceful (default) fills the agent's declared yields with a budget-exhausted marker and ends the chain cleanly; escalate routes to the Manager error path instead."},{title:"Visible utilisation",body:"Current-month spend per agent (tokens and cost, versus cap) is exposed via GET /api/budgets for dashboards and alerts."}]}]},{heading:"LLM response cache",blocks:[{kind:"list",items:[{body:"Redis-backed cache of LLM responses keyed by `(model, prompt, temperature, tools, max_tokens, system_prompt, top_p, frequency_penalty, presence_penalty)`."},{body:"When the same LLM request is made twice â even across sessions, agents, or processes â the second hit pulls from cache instead of paying the provider."},{body:"Cache entry enriched with metadata (`_cached_at`, `_model`, `_usage`, `_cost_estimate`)."},{body:"Per-entry TTL configurable (default 1 hour, configurable per call)."},{body:"Cache hit events published to streams for analytics."},{body:"Hit rate, miss count, store count, eviction count all queryable."}
1,{body:"Automatic invalidation on explicit invalidate calls."}]}]},{heading:"Prompt caching across providers",blocks:[{kind:"list",items:[{title:"Anthropic ephemeral cache",body:"`cache_control: {type: ephemeral}` markers honored per agent."},{title:"OpenAI automatic cache",body:"Prompt caching enabled when length thresholds met."},{title:"AWS Bedrock cache",body:"Claude on Bedrock supports Anthropic-style caching."},{body:"Cache read tokens and cache creation tokens broken out separately in traces."}]}]},{heading:"Adaptive model selection",blocks:[{kind:"list",items:[{body:"Per-agent `optimization_strategy: cost` picks the cheapest qualifying model in your configured providers."},{body:"Strategy reevaluated at runtime per call."},{body:"Tracks per-model success rate to avoid silently switching to a worse model."}]}]},{heading:"Smart conversation history selection",blocks:[{kind:"list",items:[{body:"Agents with memory enabled skip conversation history entirely (memory feed has same content, smarter, fewer tokens)."},{body:"Anchor + recent strategy for no-memory agents â the first user turn plus the most recent turns."},{body:"Per-agent-type rules instead of one-size-fits-all."},{body:"Reduces prompt token cost by 30-50% on long sessions."}]}]},{heading:"Tool result optimization",blocks:[{kind:"list",items:[{body:"Tool result truncation when output exceeds configurable byte limits."},{body:"Non-JSON values absorbed via `str()` with warning logging (operator decides if absorption is acceptable)."},{body:"Compact JSON serialization (no pretty-printing in prompts)."}]}]},{heading:"Smart-skip on manager analysis",blocks:[{kind:"list",items:[{body:"Healthy events bypass LLM analysis entirely."},{body:"Only suspicious or failed events consume Manager analysis tokens."},{body:"Saves Summarizer LLM cost on every successful agent run."}]}]},{heading:"Trace attribute truncation",blocks:[{kind:"list",items:[{body:"A single trace attribute is capped at 32KB â the limit trace collectors accept."},{body:"Oversize payloads truncate with an inline marker, so telemetry stays inside that limit without bloating per-trace bytes."},{body:"Less bandwidth spent shipping traces, and less storage billed for them."}]}]},{heading:"Multi-version build optimization",blocks:[{kind:"list",items:[{body:"Wheels ship pre-compiled for each Python version â smaller installs, no runtime compilation cost."}]}]},{heading:"Cost dashboards",blocks:[{kind:"list",items:[{body:"Per-agent cost over time."},{body:"Per-model cost breakdown."},{body:"Cache hit rate over time."},{body:"Comparison of cost vs. cost without cache."},{body:"Trends queryable via SDK API for billing systems."}]}]}]},{id:"hosting-runtime",title:"Hosting & Runtime",lead:"Runs in your infrastructure, your compliance regime, your operational shape.",sections:[{heading:"Deployment modes",blocks:[{kind:"list",items:[{title:"Single-process",body:"Long-lived process; mesh calls via in-process API or local HTTP. Fastest path from idea to running mesh."},{title:"Multi-process",body:"Multiple SDK instances share a Redis or Postgres backplane. Consumer groups split listener workload. Idempotent sessions deduplicate work."},{title:"In-pod worker fleet",body:"One command â LEAFMESH_WORKERS=N â runs N coordinated workers inside a single pod for crash redundancy, each on its own port, all on one backplane. No duplicates by construction: events deliver to exactly one worker and singleton jobs run once. A crashed worker is respawned and its in-flight work reclaimed by a sibling."},{title:"Containerized",body:"Docker images per Python version (3.10â3.14). Kubernetes-friendly with health endpoints, graceful shutdown, ConfigMap-friendly YAML, liveness/readiness probes."},{title:"Serverless",body:"AWS Lambda, Google Cloud Run, Azure Functions with Redis backplane. Pay per invocation; scale to zero between bursts."}]}]},{heading:"Runtime tuning is declared, not environmental",intro:"Everything that changes how the agency behaves lives in the config file:",blocks:[{kind:"list",items:[{title:"Five declared blocks",body:"timeouts, scheduler, runtime, limits and connectors â 41 settings covering how long the agency waits, how often sc
1heduled work fires, how connections stay alive, what size and rate ceilings apply, and how outbound connector calls behave. Every field optional; omit one and its default applies."},{title:"Versioned with the agency",body:"A number that changes behaviour sits in the same file as the agents it governs â reviewed in a pull request, identical on every machine that loads it, and visible to whoever inherits the system. An environment variable is invisible to everyone who wasn't told about it."},{title:"Editable while running",body:"Read and write the blocks through the config API or Agent Studio. Changes persist to the config file and survive a restart; send a field as null to clear it back to the default."},{title:"Toggles are three-state",body:"A connector toggle is absent, true, or false â and false is not the same as absent. An explicit off round-trips through save and reload intact instead of quietly reverting to the default."},{title:"Per-store, not per-deployment",body:"Limits that belong to a specific resource live with it: knowledge ingest caps are set per provider, because a policy-document index and a scraped-web index rarely want the same ceiling."}]}]},{heading:"Batteries included, and it tells you what's missing",blocks:[{kind:"list",items:[{title:"One install command",body:"Channels, listeners, knowledge backends, storage drivers and MCP all arrive with a single extra rather than 27 package names an operator has to know in advance."},{title:"Declared-but-missing is reported at startup",body:"If the config enables a feature whose package isn't installed, the platform says so as it boots and prints the exact install command. A declared capability can no longer sit there doing nothing while everything looks healthy."}]}]},{heading:"Build-tier separation",intro:"Two distinct distributions:",blocks:[{kind:"paragraph",text:"Customer tier (public PyPI, paying customers):"},{kind:"list",items:[{body:"Limited public API surface: mesh endpoints, webhooks, callbacks, health."},{body:"`/docs` hidden."},{body:"Production auth backend baked in."},{body:"Production telemetry endpoint."},{body:"Customer-tier API key prefix."}]},{kind:"paragraph",text:"Hosted tier (TestPyPI, internal deployments):"},{kind:"list",items:[{body:"Full API surface including agent admin, session inspector, playground, evolution dashboard."},{body:"`/docs` exposed."},{body:"Development auth backend."},{body:"Development telemetry endpoint."},{body:"Dev-tier API key prefix."}]},{kind:"callout",text:"Tier is selected at build time, baked into the wheel, not runtime-toggleable."}]},{heading:"Source protection (customer tier)",blocks:[{kind:"list",items:[{title:"Hardened build",body:"Customer wheels ship compiled and hardened â no readable source."},{title:"Clean tracebacks",body:"Tracebacks never reveal source paths or line positions."},{title:"Source removal",body:"No `.py` files ship in customer wheels."},{title:"Per-Python-version wheels",body:"cp310 / cp311 / cp312 / cp313 / cp314."}]}]},{heading:"Python compatibility & concurrency model",blocks:[{kind:"list",items:[{body:"First-class support for Python 3.10, 3.11, 3.12, 3.13, 3.14 â per-version wheels, no compiled extensions to break across upgrades."},{body:"Async-first throughout â every public method that does I/O is a coroutine; sync wrappers provided for CLI ergonomics."},{body:"Single asyncio event loop fans out to hundreds of concurrent agent executions per process."},{body:"Backpressure-aware â fan-out caps, parallelism limits, and event-listener consumer-group rebalancing prevent any one workload from starving the others."},{body:"Multi-process safe â Redis-backed state lets you scale horizontally by adding processes; consumer groups divide event handling without external coordination."},{body:"Cross-platform â Linux, macOS, Windows; CPython only (no PyPy support today)."}]}]},{heading:"Redis backplane",intro:"What it stores:",blocks:[{kind:"list",items:[{body:"Sessions and session state."},{body:"Agent state (current_state, last_seen, health)."},{body:"Yields persistence."},{body:"Conversation history."},{body:"Fan-in accumulators."},{body:"Streams (event sourcing)."},{body:"Pending HITL requests."},{body:"Routing statistics."},{body:"LLM response cache."},{body:"Channel session mappings."}]},{kind:"paragraph",text:"Requirements:"},{kind:"list",items:[{body:"Redis 5.0 or higher (uses streams, consumer groups, ACLs)."},{body:"Cluster mode supported."},{body:"TLS supported."},{body:"High availability via Sentinel or managed Redis services."}]}]},{heading:"Or run it on Postgres instead",intro:"Plenty of teams already run Postgres and would rather not add Redis to the estate to adopt an agent platform. Switch the backend in config and the whole agency â sessions, agent state, yields, conversation history, fan-in, the event log, pending approvals â runs on Postgres, with no Redis anywhere.",blocks:[{kind:"list",items:[{title:"One line to switch",body:"`persistence: backend: postgres` plus your connection details. No code changes, no agent rewrites: the same agency YAML runs on either store."},{title:"Everything, not a subset",body:"This isn't a cache tier or a read replica â it's the whole persistence layer. An agency running on Postgres has the same behaviour, the same durability, and the same features as one on Redis."},{title:"Works behind a pooler",body:"Compatible with transaction-pooling proxies (PgBouncer, Supabase, RDS Proxy), so it fits the managed-Postgres setups teams already have."},{title:"Survives flaky networks",body:"Idle connections are retired before they can go stale, so a laptop waking from sleep, a NAT timeout, or a proxy recycling connections doesn't produce a burst of errors."},{title:"Your DBA's rules apply",body:"Backups, encryption at rest, retention, access control and audit all come from the database you already govern â one fewer datastore to certify."}]}]},{heading:"Multi-tenancy",blocks:[{kind:"list",items:[{title:"Env_token isolation",body:"Every record carries an `env_token` field for tenant separation on shared Redis."},{title:"Per-tenant rate limiting",body:"Webhook and API limits applied per tenant."},{title:"Per-tenant routing statistics",body:"Learned routing isolated per tenant."},{title:"Per-tenant cost tracking",body:"Billing-ready cost attribution."},{title:"Per-tenant session isolation",body:"Sessions never visible across tenants."},{title:"Per-tenant operator allowlists",body:"HITL operators scoped per tenant."}]}]},{heading:"Disaster recovery and continuity",blocks:[{kind:"list",items:[{title:"Session persistence through restart",body:"Redis-backed, sessions survive SDK process restarts."},{title:"HITL request survival",body:"Pending human requests persist across restarts."},{title:"Routing memory persistence",body:"Learned routing stats survive restarts."},{title:"OTel context restoration",body:"Paused sessions resume with correct trace context."},{title:"Idempotent webhook retries",body:"Duplicate deliveries don't corrupt state."},{title:"Stream event sourcing",body:"Full audit trail of state changes for replay."},{title:"Backup/restore",body:"Operator brings Redis backup strategy; SDK is stateless on top."},{title:"Multi-region",body:"Multi-region Redis (Sentinel, CRDT, managed services) supported."}]}]},{heading:"Resilience features",blocks:[{kind:"list",items:[{title:"Stale-transport recovery",body:"Python 3.13 selector transport quirks transparent."},{title:"Reconnect coalescing",body:"Concurrent recovery callers share work."},{title:"Connection retry",body:"Exponential backoff (3 attempts default)."},{title:"Idempotent webhook retries",body:"Duplicate deliveries return success without re-processing."}
1,{title:"Auto-cleanup",body:"Stale sessions and expired routing state pruned periodically."}]}]},{heading:"Buffer and export tuning",intro:"Environment-tunable for ops teams:",blocks:[{kind:"list",items:[{body:"`LEAFMESH_OTEL_MAX_QUEUE_SIZE` (16,384)."},{body:"`LEAFMESH_OTEL_EXPORT_BATCH_SIZE` (512)."},{body:"`LEAFMESH_OTEL_EXPORT_INTERVAL_MS` (5,000)."},{body:"`LEAFMESH_OTEL_EXPORT_TIMEOUT_S` (5)."},{body:"`LEAFMESH_OTEL_METRICS_INTERVAL_MS` (30,000)."},{body:"`LEAFMESH_OTEL_METRICS_TIMEOUT_S` (30)."},{body:"`LEAFMESH_WEBHOOK_RATE_LIMIT_MAX` (60)."},{body:"`LEAFMESH_WEBHOOK_RATE_LIMIT_WINDOW_S` (60)."},{body:"`LEAFMESH_WEBHOOK_MAX_PAYLOAD_BYTES` (1 MB)."},{body:"`LEAFMESH_WEBHOOK_REPLAY_SKEW_S` (300)."}]}]}]},{id:"adk-studio",title:"ADK Studio â Hosted Dashboard",lead:"The visual product layer that sits on top of the SDK. Available as a hosted service for hosted-tier customers; the SDK runs in your infrastructure regardless.",sections:[{heading:"Playground",blocks:[{kind:"list",items:[{body:"Test agents and mesh configurations before deploying to production."},{body:"Send sample inputs and see end-to-end agent execution."},{body:"Inspect every agent's input, output, and intermediate state."},{body:"Live streaming of agent execution as it happens."},{body:"Save and replay test scenarios."},{body:"Every edit genuinely applies to the run: tools, memory, knowledge, skills (with per-skill eager delivery), super-agent tuning, playbook sections, execution knobs â overrides merge into the config for that execution. Mesh wiring and budgets stay Studio-only, so a test can never bypass spend caps."},{body:"Declared-block tools (playbook, MCP, Zapier / Composio / n8n) register at execute time â ad-hoc agents and edited blocks work in the Playground before anything is committed to YAML."}]}]},{heading:"Session inspector",blocks:[{kind:"list",items:[{body:"Browse all sessions in your environment."},{body:"Drill into any session's full trace."},{body:"Per-agent run details: inputs, outputs, decorator steps, tool calls, LLM calls."},{body:"Span tree visualization with cost and duration per node."},{body:"Re-run any agent from a past session with new input or feedback."}]}]},{heading:"Agent admin",blocks:[{kind:"list",items:[{body:"View all registered agents in your mesh."},{body:"Activate / deactivate agents without code changes."},{body:"See per-agent execution stats (success rate, average duration, cost)."},{body:"Per-agent health status from the monitoring loop."},{body:"Per-agent execution history."}]}]},{heading:"Evolution dashboard",blocks:[{kind:"list",items:[{body:"Run mesh optimization experiments with the genetic algorithm."},{body:"Configure test scenarios (input + expected outcome)."},{body:"Visualize fitness scores across generations."},{body:"Compare candidate configurations side-by-side."},{body:"Apply evolved configuration to production with one click (when ready)."}]}]},{heading:"Knowledge management",blocks:[{kind:"list",items:[{body:"Browse and search ingested knowledge across all configured vector providers."},{body:"Upload documents (PDF, DOCX, CSV, JSON, Markdown) for ingestion."},{body:"See per-agent knowledge query history."},{body:"Tune chunking, embedding, and retrieval parameters per provider."},{body:"Reindex on demand."}]}]},{heading:"HITL inbox",blocks:[{kind:"list",items:[{body:"Visual inbox for human operators."},{body:"Per-request cards showing what's being asked, by whom, with full chain context."},{body:"Chain history rendered visually (operator sees what each prior agent produced)."},{body:"Response form matching the agent's yields contract."},{body:"Operator allowlist enforcement."},{body:"Real-time updates via Server-Sent Events."}]}]},{heading:"Feed posts",blocks:[{kind:"list",items:[{body:"Per-session activity feed."},{body:"Agents post structured updates as they run."},{body:"Operators can comment on agent decisions for training feedback."},{body:"Used for cross-session memory recall and quality grading."}]}]},{heading:"Conversational analytics",blocks:[{kind:"list",items:[{body:"Token consumption over time, per agent, per model."},{body:"Cost trends over time."},{body:"Cache hit rate trends."},{body:"Error rate per agent type."},{body:"Session throughput per environment."}]}]},{heading:"Command Center",blocks:[{kind:"list",items:[{body:"The business board the agency de
1signs for itself, in the language of your work rather than the platform's â see the Command Center capability for how it is built."},{body:"Edit any metric, set targets, change how a number is drawn â from the UI or the API."},{body:"Export the board and upload it into another environment, so staging and production stay in step."},{body:"Ask for a redesign in your own words when the business changes what matters."}]}]},{heading:"Multi-environment support",blocks:[{kind:"list",items:[{body:"Separate dev, staging, production accounts per organization."},{body:"Switch between environments without leaving the dashboard."},{body:"Per-environment configuration with promotion workflows."},{body:"Per-environment access controls."}]}]},{heading:"Configuration editor",blocks:[{kind:"list",items:[{body:"Visual YAML editor with schema validation."},{body:"Diff view between local config and deployed config."},{body:"Versioned configuration history."},{body:"One-click rollback to prior versions."}]}]}]},{id:"hitl",title:"Human-in-the-Loop (HITL)",lead:"Real human operators as first-class mesh participants. Production-grade, not a demo.",sections:[{heading:"Per-request isolation",blocks:[{kind:"list",items:[{body:"Each HITL call generates a unique request ID (`req_<12-hex-uuid>`)."},{body:"Every pending request is tracked durably and independently of the others."},{body:"Same session can have any number of pending requests simultaneously."},{body:"Each request has its own response window and lifecycle."},{body:"Responses carry the request ID â they resolve only that specific request."},{body:"Timeouts survive restarts: every request's answer deadline is durable, so an expired request resolves (pending â resolved, with an audit entry and a live inbox update) even if the process that created it is gone. Notifications are exempt â they wait for acknowledgment indefinitely â and a genuinely answerable request is never closed early."}]}]},{heading:"Atomic state transitions",blocks:[{kind:"list",items:[{body:"Pending â resolved is a single atomic transition â no half-updated state, ever."},{body:"Concurrent duplicate webhook deliveries cannot double-process."},{body:"Idempotent retry handling â duplicates return success without re-routing."},{body:"A response is consumed atomically â it resolves exactly one request, exactly once."}]}]},{heading:"Inbox features",intro:"On every HITL request outbound payload:",blocks:[{kind:"list",items:[{body:"`request_id`, `agent_name`, `called_by`."},{body:"`input_data` â the raw input the agent received."},{body:"`operator_ids` â allowlist of operators."},{body:"`yields` â the contract the response must fulfill."},{body:"`conversation_history` â last 5 turns of session context."},{body:"`response_endpoint` â where to POST the response."},{body:"`timeout_seconds`, `env_token`."},{body:"`chain_history` â what each prior agent did."},{body:"`context`, `prompt` â rendered templates when configured."}]}]},{heading:"Template rendering",blocks:[{kind:"list",items:[{body:"`human_context_template` rendered via Python format strings with session data."},{body:"`human_prompt_template` rendered similarly."},{body:"Missing keys logged as warnings (operator sees template verbatim instead of crash)."}]}]},{heading:"Auto-routing of responses",blocks:[{kind:"list",items:[{title:"Scenario 1 â upstream-initiated",body:"Agent A asks human â human responds â routes via human's `can_call` rules, falls back to dual-mode reply to A if no match."},{title:"Scenario 2 â operator-initiated",body:"Operator sends message into inbox â SDK evaluates against `can_call` conditions â auto-routes if match, falls through to normal HITL pending flow if no match."}]}]},{heading:"Timeout handling",blocks:[{kind:"list",items:[{body:"Per-request timeout via `human_timeout_seconds` (default 300 seconds)."},{body:"The `HUMAN_INPUT_TIMEOUT` event fires on expiry."},{body:"All request state is cleaned up on timeout."},{body:"The request leaves the pending inbox."},{body:"Downstream agents see timeout event and can react."}]}]},{heading:"Channel-as-inbox",intro:"Operators respond via the channel they prefer:",blocks:[{kind:"list",items:[{body:"Native LeafCraft inbox in ADK Studio."},{body:"Slack DM."},{body:"Microsoft Teams reply."},{body:"Email reply (with thread stripping)."},{body:"Webhook to third-party UI (Salesforce, ServiceNow, custom)."}]}]},{heading:"Compliance",blocks:[{kind:"list",items:[{body:"PII redaction in audit logs."},{body:"Configurable operator allowlists per request type."},{body:"Audit trail of every HITL request and response."},{body:"Operator metrics (response times, decisions, throughput)."}]}]},{heading:"External live-agent integrations",blocks:[{kind:"list",items:[{body:"ServiceNow agent UI."},{body:"Salesforce Service Cloud."},{body:"Custom UIs via webhook protocol."}]}]}]},{id:"security-compliance",title:"Privacy, Security & Compliance",lead:"The boring stuff that decides whether enterprise legal lets you ship.",sections:[{heading:"Encryption",blocks:[{kind:"list",items:[{title:"TLS 1.2 or higher",body:"For all outbound traffic: your data store, model providers, trace collectors, webhooks, channel APIs."},{title:"AES-256 at rest",body:"For Redis where operator brings encryption (managed Redis with encryption-at-rest)."}]}]},{heading:"Credentials never touch your config",intro:"Secrets live in your mesh's own encrypted store â the same Redis or Postgres you already run â and configuration refers to them by name. The mesh will not start if it finds one written literally in a config file.",blocks:[{kind:"list",items:[{title:"Refuses to boot on an inline secret",body:"A literal provider credential in config stops startup and names the exact field. `${ENV_VAR}` still works â the secret is in the environment, not the file. Config files get committed, pasted into tickets and dropped into chats; this removes the category."},{title:"One connection, the whole credential set",body:"A provider's fields travel together â Slack carries its bot token, signing secret and app-level token as one connection. Reference it once by name and every field it holds comes with it. Adding or removing one secret never disturbs the others."},{title:"Connect without handling a token",body:"For providers where we operate a registered app, one click sends the operator to the provider's own consent screen; the token returns straight into the vault. Nobody copies a secret, so nobody can leak one in transit."},{title:"Or build the app under your own account",body:"Where a shared app would be dishonest, the platform provisions an app in the customer's own workspace instead â scopes, events and redirect URLs set for them. The app belongs to them, not to us."},{title:"Field names out, never values",body:"The API that lists connections returns which fields are populated, never what is in them. There is no read path for a stored secret."}]}]},{heading:"Webhook security",blocks:[{kind:"list",items:[{title:"HMAC-SHA256 signature verification",body:"On every inbound webhook."},{body:"Signature covers timestamp, nonce, and body â captured requests cannot be replayed."},{title:"Replay protection",body:"`X-LeafMesh-Timestamp` header verified within skew window (300s default). `X-LeafMesh-Nonce` header â each nonce is accepted exactly once."},{title:"Per-IP rate limiting",body:"60 requests / 60 seconds default."},{title:"Payload size cap",body:"1 MB default."},{title:"Mandatory signing secret",body:"SDK refuses to start in production without one."},{title:"Dev escape hatch",body:"`LEAFMESH_WEBHOOK_ALLOW_UNSIGNED=1` for local development."},{title:"Managed fallback",body:"A secret is auto-provisioned when none is configured â always set your own in production."}]}]},{heading:"PII protection",blocks:[{kind:"list",items:[{title:"Span content redaction",body:"One switch replaces every payload body in your traces with `<redacted bytes:N>`. Off by default â traces land in your own backend â and identical wherever you send them. `LEAFMESH_OTEL_REDACT_PII=1` turns it on, live, without a redeploy."},{title:"Secret redaction",body:"Credential values are replaced with `***REDACTED***` throughout nested payloads."},{title:"Log sanitization",body:"Log lines are protected against log injection and oversize input."},{title:"Structure survives redaction",body:"Agent names, model IDs, token counts, costs and status flags are never redacted, so the operational picture holds even with content off."}]}]},{heading:"Compliance posture",intro:"LeafMesh is engineered around the technical controls major compliance frameworks expect â but formal third-party certification is on the roadmap, not complete. We are honest about this so security reviews don't surface surprises later.",blocks:[{kind:"paragraph",text:"Technical controls that ship today:"},{kind:"list",items:[{body:"TLS 1.2+ in transit on every network hop."},{body:"Encryption at rest wherever your backing store supports it (Redis ACL + TLS, Postgres native encryption, cloud-provider KMS)."},{body:"Per-session and per-tenant logical isolation."},{body:"HMAC-SHA256 webhook signatures with timestamp + nonce replay protection."}
1,{body:"One-switch PII redaction in observability â off by default because traces land in your own backend; on for teams exporting elsewhere."},{body:"Append-only audit trail via event sourcing (every agent run, manager intervention, HITL decision, config change)."},{body:"Customer-configurable data retention per environment."},{body:"Tier separation as a security boundary â public-PyPI build cannot reach hosted management endpoints."}]},{kind:"paragraph",text:"Customer compliance the SDK supports today:"},{kind:"list",items:[{title:"GDPR / CCPA",body:"Data residency via tier separation, customer-controlled deletion, default-on PII redaction, no telemetry payload bodies leave the customer's collector unless they opt in. This is a posture, not a certification â your DPO still owns the regime."},{title:"HIPAA",body:"TLS, audit logging, access control, and PII handling are in place. A production HIPAA deployment still requires a BAA with your Redis provider and your LLM provider; LeafCraft does not currently offer a BAA."}]},{kind:"paragraph",text:"On the roadmap, not delivered:"},{kind:"list",items:[{title:"SOC 2 Type II",body:"Controls are designed against CC6.1 (logical access), CC7.2 (system operations), and CC7.5 (incident response). Independent audit is planned; no Type II report is available yet."},{title:"ISO 27001 / 27018",body:"Controls align with A.9 (access control), A.12.4 (logging), A.13.2 (network security), A.17 (availability) and the 27018 PII handling annex. Certification is not yet pursued."},{title:"PCI DSS",body:"Not pursued. Card data should not transit LeafMesh; tokenize at the channel edge before the agent layer sees it."}]},{kind:"callout",text:"If your procurement or security team needs a current SIG-Lite, CAIQ, or pen-test letter, ask before purchase â we will tell you what is available today and what is in flight."}]},{heading:"Tier separation as a security boundary",blocks:[{kind:"list",items:[{body:"Public PyPI customers only get the limited API surface."},{body:"Internal operator/management surfaces stay in hosted tier â customers interact with them through Studio, not via direct API calls."},{body:"Build-time selection â customers cannot toggle internal endpoints on at runtime."},{body:"API key separation â customer-tier embeds production auth key; hosted-tier embeds dev key."},{body:"Telemetry separation â traces route to different collectors per tier."}]}]},{heading:"Yields validation (anti-injection)",blocks:[{kind:"list",items:[{body:"Every agent output validated against declared `yields:` schema."},{body:"Missing keys filled with type-safe defaults (no cascading KeyErrors)."},{body:"Type mismatches caught and reported as warning events."},{body:"Auto-retry on schema mismatch with specific feedback to the LLM."},{body:"Per-session budget prevents runaway retry loops."}]}]},{heading:"Tool security",blocks:[{kind:"list",items:[{title:"SSRF block",body:"Outbound HTTP rejects private/internal IPs."},{title:"Argument validation",body:"JSON Schema enforced before any tool runs."},{title:"Output guardrail",body:"Tool output is structurally isolated from instructions."},{title:"Per-agent allowlists",body:"Tools and tool categories restricted per agent."}]}]},{heading:"Audit trail",blocks:[{kind:"list",items:[{title:"Event sourcing",body:"Every state change publishes a correlation-tagged stream event."},{title:"Manager decision history",body:"Every intervention recorded with reason, outcome, timestamp."},{title:"Span correlation IDs",body:"Every error response carries `(ref: <id>)` correlation tag."},{title:"Operator action audit",body:"Every HITL response logged with operator ID, decision, timestamp."}]}]},{heading:"Access control",blocks:[{kind:"list",items:[{body:"Multi-tenant isolation via env_token field."},{body:"Per-operator allowlists on HITL requests."},{body:"API key scoping (project-level, account-level)."},{body:"Role-based access for hosted ADK Studio (when used)."}]}]}]},{id:"licensing-commercial",title:"Licensing & Commercial",lead:"How licensing works and how customers get to production.",sections:[{heading:"License tiers",blocks:[{kind:"list",items:[{title:"Evaluation",body:"30 days, free, full feature access. For research, development, and proof-of-concept work. No commercial use."},{title:"Commercial",body:"$99/month â includes 5,000 invocations (then $0.06 each), production use, and every SDK feature (mesh, agents, tools, channels, listeners, knowledge, memory, observability, security), all eight LLM provider integrations, production support, and security updates."},{title:"Enterprise",body:"Custom annual contract. Includes everything in Commercial plus hosted ADK Studio (multi-environment, dashboards, playground, inbox, evolution), premium support with SLA, dedicated solution architect, custom integration assistance, volume pricing, multi-tenant licensing for resellers and managed-service partners."}]}]},{heading:"Licensing model",blocks:[{kind:"list",items:[{body:"Per-deployment license keys."},{body:"License validation at SDK boot."},{body:"License plan determines feature availability."},{body:"Webhook secrets auto-provisioned when none is configured."},{body:"Multi-environment licensing for dev / staging / production separation."},{body:"Multi-region licensing for global deployments."}]}]},{heading:"Distribution channels",blocks:[{kind:"list",items:[{title:"Public PyPI",body:"`pip install leafmesh` for customer-tier wheels."},{title:"Internal PyPI",body:"Hosted-tier wheels for LeafCraft-operated deployments."},{title:"Private indexes",body:"Enterprise customers can mirror to private artifact repositories."}
1,{title:"Container images",body:"Docker images per Python version on customer container registry."}]}]},{heading:"Source code policy",blocks:[{kind:"list",items:[{body:"SDK ships as obfuscated bytecode (no readable source)."},{body:"Public documentation, examples, and integration guides are open."},{body:"Customer-built decorators, tools, and agents remain customer property."},{body:"LeafMesh source code is proprietary; not available for redistribution."}]}]},{heading:"Getting started timeline",blocks:[{kind:"list",items:[{title:"Hour 1",body:"SDK installed, scaffold created via `create-leafmesh`, first mesh running locally."},{title:"Day 1",body:"First production-shape agent built, Redis configured, traces flowing."},{title:"Week 1",body:"Multi-agent flow with HITL, real channels, real LLM provider keys."},{title:"Week 2-4",body:"Production deployment, observability stack integration, security-review materials gathered."},{title:"Month 2",body:"First production traffic, cost dashboards operational, evolution experiments running."}]}]},{heading:"Support channels",blocks:[{kind:"list",items:[{title:"Documentation",body:"leafcraft.ai"},{title:"Source & examples",body:"github.com/LeafCraftStudios/LeafMesh"},{title:"Email",body:"[email protected] for commercial, enterprise, and technical inquiries."},{title:"Dedicated channels for enterprise customers",body:"Slack, shared on-call, or scheduled syncs, set up at contract signing."}]}]},{heading:"Migration paths",blocks:[{kind:"list",items:[{title:"From CrewAI / LangGraph / AutoGen",body:"Wrap existing crews/graphs/group chats as external agents in a LeafMesh mesh; gradually replace pieces with native LeafMesh agents over time."},{title:"From custom code",body:"Pre-compose decorators let you wrap existing Python functions as mesh agents; lifecycle hooks let you preserve existing initialization."},{title:"From OneReach / other platforms",body:"Channel adapters and event listeners let you receive traffic from the same sources while running orchestration in LeafMesh."}]}]}]}],h=o=>o.split(/(`[^`]+`)/g).map((a,n)=>a.startsWith("`")&&a.endsWith("`")?e("code",{className:"px-1.5 py-0.5 rounded bg-black/[0.06] text-[0.85em] font-mono text-brand-text",children:a.slice(1,-1)},n):e(P.Fragment,{children:a},n)),I=({item:o})=>t("li",{className:"flex gap-2.5 text-brand-text text-sm md:text-base leading-relaxed",children:[e("span",{className:"mt-2 w-1.5 h-1.5 bg-brand-500 shrink-0"}),t("span",{children:[o.title&&t("strong",{className:"font-semibold",children:[h(o.title)," â "]}),h(o.body)]})]}),D=({block:o})=>o.kind==="paragraph"?e("p",{className:"text-brand-text text-sm md:text-base leading-relaxed",children:h(o.text)}):o.kind==="callout"?e("div",{className:"border-l-2 border-brand-500 pl-4 py-2 my-1",children:e("p",{className:"text-brand-text text-sm md:text-base leading-relaxed font-medium italic",children:h(o.text)})}):e("ul",{className:"space-y-2.5",children:o.items.map((l,a)=>e(I,{item:l},a))}),R=({capability:o,index:l,total:a})=>t("article",{children:[t("div",{className:"flex items-center gap-3 mb-4",children:[t("span",{className:"text-brand-500 text-xs font-mono font-bold tracking-[0.25em]",children:[String(l+1).padStart(2,"0")," / ",String(a).padStart(2,"0")]}),e("div",{className:"h-px flex-1 bg-black/[0.08]"}),t("span",{className:"text-brand-text/60 text-xs font-medium tracking-[0.18em] uppercase",children:[l+1," of ",a]})]}),e("h2",{className:"font-display text-2xl sm:text-3xl md:text-4xl font-semibold tracking-tightest leading-[0.95] mb-4",children:o.title}),e("p",{className:"text-brand-text text-base md:text-lg leading-relaxed mb-8 max-w-3xl",children:h(o.lead)}),e("div",{className:"grid grid-cols-1 lg:grid-cols-2 gap-x-10 gap-y-8 items-start",children:o.sections.map((n,y)=>t("div",{children:[n.heading&&e("h3",{className:"font-display text-lg sm:text-xl font-bold tracking-tight mb-3",children:n.heading}),n.intro&&e("p",{className:"text-brand-text text-sm md:text-base leading-relaxed mb-4",children:h(n.intro)}),e("div",{className:"space-y-4",children:n.blocks.map((m,d)=>e(D,{block:m},d))})]},y))})]}),u="84px",N=48,U=()=>{const o=A(),l=L(),a=c.useRef(null),n=c.useMemo(()=>{const r=o.hash.replace("#","");return i.find(p=>p.id===r)?.id??i[0].id},[o.hash]),[y,m]=c.useState(n),[d,g]=c.useState(!1);c.useEffect(()=>{m(n)},[n]),c.useEffect(()=>{if(d&&typeof window<"u"&&window.innerWidth<1280)return document.body.style.overflow="hidden",()=>{document.body.style.overflow=""}},[d]);const s=i.findIndex(r=>
1r.id===y),f=i[s],k=s>0?i[s-1]:null,v=s<i.length-1?i[s+1]:null,w=r=>{if(m(r),g(!1),l(`${o.pathname}#${r}`,{replace:!1}),a.current){const p=a.current.getBoundingClientRect().top+window.scrollY-96;window.scrollTo({top:p,behavior:"smooth"})}};return t(S,{children:[e(M,{title:"LeafMesh Platform Capabilities â Every Shipping Feature",description:"Twenty-one capability domains of the LeafMesh agent operations fabric: mesh coordination, agent types, LLM providers, manager intelligence, tools, channels, listeners, observability, security and more.",url:`${b.url}/product/capabilities`,keywords:"LeafMesh capabilities, agent orchestration features, mesh coordination, multi-agent platform, LLM provider integration, HITL, observability, cost analytics, AI governance"}),e(E,{items:[{name:"Home",url:b.url},{name:"Platform",url:`${b.url}/product`},{name:"Capabilities",url:`${b.url}/product/capabilities`}]}),t("div",{className:"min-h-screen bg-brand-bg text-brand-text",children:[t("div",{className:"xl:hidden fixed left-0 right-0 z-30 h-[48px] bg-brand-bg/95 backdrop-blur-sm border-b border-black/[0.08] px-4 flex items-center justify-between",style:{top:u},children:[t("button",{type:"button",onClick:()=>g(!0),className:"flex items-center gap-2 text-sm font-medium text-brand-text px-2 py-1.5 -ml-2 rounded-md hover:bg-black/[0.04] active:bg-black/[0.08]","aria-label":"Open capabilities navigation",children:[e("svg",{className:"w-5 h-5",fill:"none",stroke:"currentColor",viewBox:"0 0 24 24",children:e("path",{strokeLinecap:"round",strokeLinejoin:"round",strokeWidth:2,d:"M4 6h16M4 12h16M4 18h16"})}),e("span",{className:"font-mono text-xs uppercase tracking-[0.15em] text-brand-text/60",children:"Capabilities"})]}),t("span",{className:"text-sm font-display font-semibold text-brand-text truncate max-w-[60%]",children:[String(s+1).padStart(2,"0")," · ",f.title]})]}),d&&e("div",{className:"xl:hidden fixed inset-0 z-30 bg-black/40 backdrop-blur-sm",style:{top:u},onClick:()=>g(!1),"aria-hidden":"true"}),t("aside",{className:` 2 ${d?"translate-x-0":"-translate-x-full"} 3 xl:translate-x-0 4 fixed left-0 z-40 5 w-[280px] 6 bg-brand-bg 7 border-r border-black/[0.08] 8 overflow-y-auto 9 transition-transform duration-300 ease-out
10 `,style:{top:u,height:`calc(100dvh - ${u})`},"aria-label":"Platform Capabilities navigation",children:[t("div",{className:"px-5 py-4 border-b border-black/[0.06] flex items-center justify-between sticky top-0 bg-brand-bg z-10",children:[e("h3",{className:"font-display text-base font-bold text-brand-400",children:"Platform Capabilities"}),e("button",{type:"button",onClick:()=>g(!1),className:"xl:hidden -mr-2 p-2 rounded-md text-brand-text/70 hover:text-brand-text hover:bg-black/[0.05] active:bg-black/[0.08]","aria-label":"Close capabilities navigation",children:e("svg",{className:"w-6 h-6",fill:"none",stroke:"currentColor",viewBox:"0 0 24 24",children:e("path",{strokeLinecap:"round",strokeLinejoin:"round",strokeWidth:2,d:"M6 18L18 6M6 6l12 12"})})})]}),e("nav",{className:"p-4",children:e("ul",{className:"space-y-0.5",children:i.map((r,p)=>{const x=r.id===y;return e("li",{children:t("button",{type:"button",onClick:()=>w(r.id),className:`block w-full text-left px-3 py-1.5 rounded-md transition-colors text-sm ${x?"bg-brand-500/10 text-brand-500 font-semibold":"text-brand-text/80 hover:text-brand-text hover:bg-black/[0.04]"}`,children:[e("span",{className:`font-mono text-xs mr-2 ${x?"text-brand-500":"text-brand-text/40"}`,children:String(p+1).padStart(2,"0")}),r.title]})},r.id)})})})]}),e("main",{className:"xl:ml-[280px]",style:{paddingTop:`calc(${u} + ${N}px)`},children:t("div",{ref:a,className:"max-w-4xl mx-auto px-5 sm:px-8 lg:px-12 py-8 lg:py-12",children:[t("div",{className:"mb-10",children:[t("div",{className:"flex items-center gap-2.5 mb-4",children:[e("span",{className:"w-2 h-2 bg-brand-500"}),e("span",{className:"font-mono text-[0.7rem] font-semibold tracking-[0.24em] uppercase text-brand-text/70",children:"Platform · Capabilities"})]}),t("h1",{className:"font-display text-3xl sm:text-4xl md:text-5xl font-semibold tracking-tightest leading-[0.95] mb-4",children:["Every shipping capability,"," ",e("span",{className:"text-brand-400",children:"documented."})]}),t("p",{className:"text-brand-text/70 text-sm md:text-base leading-relaxed max-w-2xl",children:[i.length," capability domains of the LeafMesh operations fabric â from mesh coordination and manager intelligence to observability, security, and cost analytics. Not a roadmap: every one ships today. Browse the reader below, or jump to any domain from the index."]})]}),t("div",{className:"mb-8",children:[t("div",{className:"flex items-center justify-between text-[0.65rem] text-brand-text/60 mb-1.5",children:[e("span",{className:"font-mono tracking-[0.18em] uppercase",children:"Progress"}),t("span",{className:"font-mono",children:[s+1," / ",i.length]})]}),e("div",{className:"h-1 w-full bg-black/[0.06] rounded-full overflow-hidden",children:e(_.div,{className:"h-full bg-brand-500 rounded-full",initial:!1,animate:{width:`${(s+1)/i.length*100}%`},transition:{type:"spring",stiffness:200,damping:28}})})]}),e("div",{className:"bg-white border border-black/[0.08] rounded-md p-5 sm:p-6 md:p-8 shadow-[3px_3px_0_0_#0E0E11]",children:e(C,{mode:"wait",children:e(_.div,{initial:{opacity:0,y:4},animate:{opacity:1,y:0},exit:{opacity:0,y:-4},transition:{duration:.2},children:e(R,{capability:f,index:s,total:i.length})},f.id)})}),t("div",{className:"mt-8 grid grid-cols-2 gap-3",children:[k?t("button",{onClick:()=>w(k.id),className:"group text-left px-4 py-3 rounded-md border border-black/[0.08] bg-white shadow-[3px_3px_0_0_#0E0E11] hover:translate-x-[1.5px] hover:translate-y-[1.5px] hover:shadow-[1.5px_1.5px_0_0_#0E0E11] transition-all duration-150",children:[t("div",{className:"flex items-center gap-2 text-[0.65rem] font-medium tracking-[0.18em] uppercase text-brand-text/60 mb-1",children:[e("svg",{className:"w-3 h-3",fill:"none",stroke:"currentColor",viewBox:"0 0 24 24",children:e("path",{strokeLinecap:"round",strokeLinejoin:"round",strokeWidth:2,d:"M11 17l-5-5m0 0l5-5m-5 5h12"})}),"Previous · ",String(s).padStart(2,"0")]}),e("div",{className:"font-display text-sm font-bold text-brand-text truncate",children:k.title})]}):e("div",{}),v?t("button",{onClick:()=>w(v.id),className:"group text-right px-4 py-3 rounded-md border border-black/[0.08] bg-white shadow-[3px_3px_0_0_#0E0E11] hover:translate-x-[1.5px] hover:translate-y-[1.5px] hover:shadow-[1.5px_1.5px_0_0_#0E0E11] transition-all duration-150",children:[t("div",{className:"flex items-center justify-end gap-2 text-[0.65rem] font-medium tracking-[0.18em] uppercase text-brand-text/60 mb-1",children:["Next · ",String(s+2).padStart(2,"0"),e("svg",{className:"w-3 h-3",fill:"none",stroke:"currentColor",viewBox:"0 0 24 24",children:e("path",{strokeLinecap:"round",strokeLinejoin:"round",strokeWidth:2,d:"M13 7l5 5m0 0l-5 5m5-5H6"})})]}),e("div",{className:"font-display text-sm font-bold text-brand-text truncate",children:v.title})]}):t(T,{to:"/contact",className:"group text-right px-4 py-3 rounded-md border border-brand-500/30 bg-brand-500/[0.06] shadow-[3px_3px_0_0_#0E0E11] hover:translate-x-[1.5px] hover:translate-y-[1.5px] hover:shadow-[1.5px_1.5px_0_0_#0E0E11] transition-all duration-150",children:[t("div",{className:"flex items-center justify-end gap-2 text-[0.65rem] font-medium tracking-[0.18em] uppercase text-brand-500 mb-1",children:["You're at the end",e("svg",{className:"w-3 h-3",fill:"none",stroke:"currentColor",viewBox:"0 0 24 24",children:e("path",{strokeLinecap:"round",strokeLinejoin:"round",strokeWidth:2,d:"M13 7l5 5m0 0l-5 5m5-5H6"})})]}),e("div",{className:"font-display text-sm font-bold text-brand-text truncate",children:"Talk to LeafCraft"})]})]})]})})]})]})};export{U as default};
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.