How It Works
Step-by-step flow of how Aelio processes a customer conversation.
This page walks through exactly what happens when a customer sends a message through the Aelio chat widget or WhatsApp.
Web chat flow
Customer opens your website — the chat widget loads and connects to Aelio Server over WebSocket at /widget/ws.
Widget sends an init frame with customerId + authToken. The server responds with a ready frame that includes chat history.
Customer types: "What is my order status?" — the widget sends a message frame.
Aelio Server runs processTurn():
- Recalls relevant customer facts from memory
- LLM decides to call
getOrderStatustool - Safety gate: read action → auto-allowed
- Server sends
invokeframe to your SDK (WebSocket/sdk)
Your SDK handler runs locally:
return await db.orders.findOne({ id: orderId, userId: ctx.customerId })SDK sends a result frame back to the server.
Server synthesizes a natural-language reply and sends a message frame to the widget: "Your order #A123 is shipped!"
Write action flow (with confirmation)
When the customer asks to cancel an order:
LLM decides to call cancelOrder (safety: write).
Safety gate triggers — write action requires user confirmation. Server pauses execution.
Widget shows a confirmation prompt: "Cancel order #A123? Reply yes to confirm."
Customer clicks Confirm (or types "yes") — server executes the tool via SDK invoke.
Handler runs: db.orders.cancel(orderId, ctx.customerId)
Reply: "Done! Order #A123 has been cancelled."
SDK connection model
The SDK dials out to the server. Your backend initiates the connection:
Your Backend Aelio Server
│ │
│──── WebSocket connect /sdk ────────▶│
│ Authorization: Bearer secret │
│ │
│──── register frame ────────────────▶│ (functions, states, policies)
│ │
│◀─── invoke frame ──────────────────│ (LLM wants getOrderStatus)
│ │
│──── result frame ──────────────────▶│ (handler return value)
│ │
│◀─── ping ──────────────────────────│ (keepalive every 30s)
│──── pong ──────────────────────────▶│Key point
The server never calls your REST API. It sends tool invocations over the WebSocket you opened.
Memory and intelligence
After every turn, the analytical agent runs in the background:
Turn completes — the analytical agent wakes up.
Extract durable facts — e.g. "customer prefers express shipping".
Embed fact as a vector and store it in SQLite + sqlite-vec.
Next conversation — relevant facts are injected into the LLM prompt automatically via top-K similarity search.
Lifecycle enforcement
Your SDK declares customer states. Your backend pushes the current state:
// Customer adds item to cart
await aelio.setCustomerState(customerId, 'cart_building');
// Now only cart-related tools are available
// checkout_cart is allowed, but list_invoices is blockedState-gated tools
Tools not permitted in the current lifecycle state are silently blocked at the safety gate — the LLM cannot invoke them regardless of what the customer asks.
Channel-agnostic
The same SDK tools work across all channels. A customer can start on Web and continue on WhatsApp — Aelio resolves identity and recalls memory across channels.
What you build vs what Aelio handles
| You build | Aelio handles |
|---|---|
| Business logic (tool handlers) | LLM orchestration and tool selection |
| Database queries | Safety gates and write confirmations |
| User authentication | Customer identity resolution |
| Chat widget placement | WebSocket connection and reconnect |
| WhatsApp webhook (if BYO) | Memory extraction and recall |
| Lifecycle state management | Channel delivery (Web, WhatsApp) |
| Proactive messaging guardrails | |
| Harness turn engine (plan → execute → synthesize) |