Celai is the agentic framework that underpins Lola Send. It provides the core infrastructure for receiving messages from messaging channels, processing them through an ordered middleware pipeline, routing conversations to the appropriate agent, and delivering formatted responses — all within a single, auditable execution path.
What Celai provides
| Component | Purpose |
|---|
| MessageGateway | Central HTTP server that receives messages, runs middleware, and dispatches to agents |
| Channel connectors | Pluggable adapters (WhatsApp, Telegram) that normalize inbound and format outbound messages |
| LogicRouter | Evaluates sender state and compliance status to select the appropriate agent |
| MacawAssistant | Agent implementation combining a system prompt, AI model, tool functions, and RAG retrieval |
| Middleware chain | Ordered pipeline of processors for authentication, enrichment, and transformation |
| State and history stores | Redis-backed providers for session state and conversation history |
MessageGateway is the central HTTP server that orchestrates all message processing. It is configured with:
- An assistant (the LogicRouter that selects agents)
- Host and port for the HTTP server
- Webhook URL for channel callbacks
- A message enhancer for formatting outbound responses
- An on_startup hook for initialization tasks
gateway = MessageGateway(
assistant=main,
host=os.environ.get("HOST"),
port=int(os.environ.get("PORT")),
on_startup=on_startup,
webhook_url=os.environ.get("WEBHOOK_URL"),
message_enhancer=CustomMsgEnhancerGeminiPipe(),
)
MessageGateway handles CORS configuration, registers channel connectors, and manages the middleware chain. Connectors and middleware are registered in sequence — the registration order determines execution order.
MessageGateway registers encrypted callback endpoints via HttpCallbackProvider, enabling secure communication between Lola Send and frontend web widgets for operations like payment confirmation and identity verification.
LogicRouter
LogicRouter is the entry-point assistant that evaluates each inbound message and delegates it to the appropriate specialized agent. It accepts:
- A list of registered assistants (agents)
- An assistant selector function that inspects the sender’s identity and compliance status
- Shared state and history stores
The selector function receives the conversation lead, session ID, message, state, and the list of available assistants. It returns a single agent to handle the message. This deterministic routing ensures every conversation follows a predictable, auditable path.
LogicRouter also supports event handlers — for example, intercepting document or image messages at the router level before they reach any agent.
MacawAssistant
MacawAssistant is the agent implementation used by all of Lola Send’s specialized agents. Each agent is a self-contained MacawAssistant with its own configuration:
MacawSettings
MacawSettings controls the AI model behavior for each agent:
| Setting | Purpose |
|---|
core_model | Primary AI model for conversation reasoning — gpt-4o, configurable per agent |
blend_model | Secondary model for response refinement — gpt-4.1 for tone and brand consistency |
core_history_window_length | Number of conversation turns the model sees for context |
blend_history_window_length | History window for the blend model |
core_max_tokens | Maximum token output for the primary model |
blend_prompt | Prompt that guides response refinement and tone |
The architecture uses three models, each with a bounded role:
| Model | Provider | Role |
|---|
| GPT-4o | OpenAI | Conversation reasoning and tool invocation |
| GPT-4.1 | OpenAI | Response refinement for tone, clarity, and brand consistency |
| Gemini 2.5 Flash Lite | Google Cloud (Vertex AI) | Language detection and structured message formatting |
The core and blend models handle agent logic. Gemini runs on Google Cloud Vertex AI, which supports VPC Service Controls — keeping all inference traffic within the bank’s GCP perimeter. This three-model architecture isolates each concern (reasoning, refinement, channel formatting) and allows the bank to configure or replace models independently.
PromptTemplate
Each agent’s behavior is defined by a PromptTemplate with dynamic variables:
| Variable | Source |
|---|
date | Current date and time, injected at runtime |
get_client_info | Sender’s name, phone, registration status, and payment methods from the identity service |
get_brand_name | Configurable brand name for the deployment |
assistant_name | The name Lola Send uses when addressing senders |
The bank can customize agent behavior by modifying system prompts and the values injected into these variables — without changing application code.
Each agent declares a specific set of tool functions that it can invoke. These are the only operations available to the AI model during a conversation. The model cannot invent or call undeclared capabilities.
RAG retrieval
Agents can be configured with retrieval-augmented generation via ast.set_rag_retrieval(rag), grounding their responses in bank-approved knowledge bases. See RAG capabilities for details.
Event system
Agents can register event handlers to intercept specific message types before standard processing:
@ast.event('message')
async def handle_message(session, ctx: RequestContext):
# Intercept and handle specific message types
pass
This is used at both the LogicRouter level (to reject unsupported message types like documents and images) and at the individual agent level (to track message counts or perform pre-processing).
Security considerations
- Encrypted callbacks:
HttpCallbackProvider uses AES encryption and HMAC signing for all communication between Lola Send and frontend widgets. The encryption key and secret key are loaded from environment variables managed by Doppler.
- Deterministic routing: Every message follows the same auditable path — connector → middleware → LogicRouter → agent. No message bypasses the pipeline.
- Scoped agent capabilities: Each agent can only invoke its declared tool functions. The AI model has no access to undeclared operations.
- Stateless application: Celai’s application layer holds no persistent data. State and history live in Redis; identity lives in backend services.
Configuration and control
The bank retains control over the following Celai components:
| Component | What the bank configures |
|---|
| Agent prompts | System prompts defining agent tone, behavior, and conversational boundaries |
| Tool availability | Which backend service calls each agent can invoke |
| Middleware chain | The sequence and composition of the pre-processing pipeline |
| MacawSettings | Model selection, history window length, and blend behavior per agent |
| PromptTemplate variables | Brand name, assistant name, and dynamic context injected into prompts |
| Event handlers | Custom logic for intercepting specific message types |