> ## Documentation Index
> Fetch the complete documentation index at: https://docs.leapfinancial.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Agent orchestration

> How Lola Send routes conversations to specialized agents based on sender identity and compliance status.

Lola Send routes every inbound message to one of five specialized agents based on the sender's identity and compliance status. This deterministic routing ensures that senders interact with an agent appropriate to their current state — from first-time onboarding through verified operations to compliance-restricted interactions.

## Agent types

Lola Send deploys five agents, each built as a self-contained `MacawAssistant` with its own system prompt, AI model configuration, tool functions, and RAG retrieval:

<Steps>
  <Step title="Onboarding agent">
    Handles unidentified senders. Guides first-time sender verification and first remittance, collecting identity information and invoking CIP services through tool functions.
  </Step>

  <Step title="Sender home agent">
    Handles verified senders with full conversational capabilities — saved recipients, payment methods, operation history, receipts, and new remittances.
  </Step>

  <Step title="Blocked agent">
    Handles senders flagged by compliance. Restricts interaction to status queries only. The sender can ask about their verification status but cannot initiate operations.
  </Step>

  <Step title="Pending CIP agent">
    Handles senders with in-progress identity verification. Provides limited interaction — status updates on the verification process — until the compliance verdict is resolved.
  </Step>

  <Step title="Service unavailable agent">
    Provides graceful degradation when backend services are unreachable. Informs the sender and does not attempt any backend operations. No tool functions are registered.
  </Step>
</Steps>

## Routing logic

The LogicRouter's selector function evaluates each inbound message through a deterministic decision tree:

<Accordion title="Routing decision tree">
  1. Check the `unavailable_service` flag in message metadata. If set → **service unavailable agent**.
  2. Retrieve the sender's identity from the message metadata (injected by the authentication middleware).
  3. If the sender is identified:
     * Check `is_blocked`. If true → **blocked agent**.
     * Check `verdict`. If not `passed` → **pending CIP agent**.
     * Otherwise → **sender home agent**.
  4. If the sender is not identified → **onboarding agent**.
</Accordion>

This logic runs on every message. The routing decision is based entirely on data injected by the middleware pipeline — the LogicRouter does not make external service calls.

## Tool functions per agent

Each agent declares a specific set of tool functions. The AI model can only invoke declared functions — it cannot call undeclared capabilities or access services outside its scope.

| Agent               | Key tool functions                                                                                                                                                                                   |
| ------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| Onboarding          | `get_countries`, `pre_quote`, `get_payers`, `validate_phone`, `validate_bank`, `get_banks`, `send_money`, `get_currencies`                                                                           |
| Sender home         | `get_countries`, `pre_quote`, `get_payers`, `validate_bank`, `get_payment_methods`, `get_recipients`, `search_contact_phone`, `get_operations`, `get_receipt`, `send_money_n_time`, `get_currencies` |
| Blocked             | `get_status`                                                                                                                                                                                         |
| Pending CIP         | `get_status`                                                                                                                                                                                         |
| Service unavailable | None — informational responses only                                                                                                                                                                  |

<Info>
  Agents invoke backend services exclusively through declared tool functions. All factual data — quotes, recipients, operations, exchange rates — comes from these service calls. The AI model generates this data from tool function responses, not from its training data.
</Info>

## Agent composition

Each agent is built by a dedicated `build_*_agent()` function that assembles a `MacawAssistant` with:

* **PromptTemplate** — system prompt with dynamic variables (current date, sender info, brand name, assistant name)
* **MacawSettings** — AI model configuration (core model, blend model, history window, max tokens)
* **Tool functions** — registered one by one on the assistant instance
* **State store** — Redis-backed session state, shared across all agents (singleton)
* **History store** — Redis-backed conversation history, shared across all agents (singleton)
* **RAG retrieval** — knowledge base for grounding responses in approved content

```python theme={null}
ast = MacawAssistant(
    name="Sender Assistant",
    description="This assistant helps the user to send money",
    settings=settings,
    prompt=prompt_template,
    state_store=state_store,
    history_store=history_store,
)
ast.set_rag_retrieval(rag)
```

## Security considerations

* **Scoped capabilities**: Each agent can only invoke its declared tool functions. The blocked agent, for example, can only call `get_status` — it has no access to payment or recipient operations.
* **Compliance-driven routing**: The routing decision is based on compliance verdicts from the bank's identity service. Lola Send does not make compliance decisions — it routes based on the verdict.
* **No data fabrication**: All factual data comes from tool function responses. The AI model's role is conversational — collecting inputs from the sender, invoking the right tool function, and presenting the result.
* **Graceful degradation**: When backend services are unreachable, the LogicRouter routes to the service unavailable agent instead of failing silently or producing incorrect responses.

## Configuration and control

The bank can customize agent behavior through several mechanisms:

| Mechanism                  | What changes                                                                                         |
| -------------------------- | ---------------------------------------------------------------------------------------------------- |
| System prompts             | Agent tone, language rules, conversational boundaries, and operational instructions                  |
| Tool function availability | Which backend operations each agent can invoke — add or remove functions per agent                   |
| MacawSettings              | Model selection (`core_model`, `blend_model`), history window length, token limits, and blend prompt |
| PromptTemplate variables   | Brand name, assistant name, and dynamic context like sender info and current date                    |
| Event handlers             | Custom pre-processing logic for specific message types at the agent or router level                  |

<Tip>
  Modifying system prompts and tool availability does not require application code changes. The bank can iterate on conversational flows by updating prompt text and enabling or disabling tool functions.
</Tip>
