AI Orchestrator
The brain that understands intent and routes to the right product.
Overview
The AI Orchestrator is the central intelligence layer of Yebo. It:
- Understands what users want (intent recognition)
- Routes requests to the right product
- Formats responses for chat display
- Manages conversation context
- Executes side effects (payments, notifications)
Architecture
┌─────────────────────────────────────────────────────────────┐
│ AI ORCHESTRATOR │
│ │
│ ┌────────────────────────────────────────────────────────┐ │
│ │ Intent Classifier │ │
│ │ (Gemini 2.5) │ │
│ │ "Sell these clothes" → { intent: sell_item } │ │
│ └────────────────────────────────────────────────────────┘ │
│ │ │
│ ▼ │
│ ┌────────────────────────────────────────────────────────┐ │
│ │ Product Router │ │
│ │ sell_item → YeboShops.createListing() │ │
│ │ find_job → YeboJobs.search() │ │
│ │ send_invoice → YeboLink.createInvoice() │ │
│ └────────────────────────────────────────────────────────┘ │
│ │ │
│ ▼ │
│ ┌────────────────────────────────────────────────────────┐ │
│ │ Response Formatter │ │
│ │ API response → Chat cards, buttons, text │ │
│ └────────────────────────────────────────────────────────┘ │
│ │ │
│ ▼ │
│ ┌────────────────────────────────────────────────────────┐ │
│ │ Context Manager │ │
│ │ Maintains conversation state, user preferences │ │
│ └────────────────────────────────────────────────────────┘ │
└─────────────────────────────────────────────────────────────┘Intent Categories
javascript
const INTENTS = {
// Commerce (YeboShops)
'sell_item': { product: 'yeboshops', action: 'create_listing' },
'buy_item': { product: 'yeboshops', action: 'search' },
'check_orders': { product: 'yeboshops', action: 'list_orders' },
'track_order': { product: 'yeboshops', action: 'track' },
// Jobs (YeboJobs)
'find_job': { product: 'yebojobs', action: 'search' },
'apply_job': { product: 'yebojobs', action: 'apply' },
'post_job': { product: 'yebojobs', action: 'create' },
'check_applications': { product: 'yebojobs', action: 'list_applications' },
// Learning (YeboLearn)
'learn_skill': { product: 'yebolearn', action: 'search_courses' },
'enroll_course': { product: 'yebolearn', action: 'enroll' },
'check_progress': { product: 'yebolearn', action: 'progress' },
// Business (YeboLink)
'send_invoice': { product: 'yebolink', action: 'create_invoice' },
'check_invoices': { product: 'yebolink', action: 'list_invoices' },
'send_message': { product: 'yebolink', action: 'send_sms' },
// Sourcing (YeboNa)
'find_supplier': { product: 'yebona', action: 'search' },
'place_order': { product: 'yebona', action: 'order' },
'track_shipment': { product: 'yebona', action: 'track' },
// Payments (YeboSafe)
'pay': { product: 'yebosafe', action: 'initiate_payment' },
'withdraw': { product: 'yebosafe', action: 'withdraw' },
'check_balance': { product: 'yebosafe', action: 'balance' },
// General
'greeting': { product: 'system', action: 'greet' },
'help': { product: 'system', action: 'help' },
'unknown': { product: 'system', action: 'clarify' },
}Processing Flow
1. Receive Message
json
{
"userId": "user_123",
"conversationId": "conv_456",
"message": "Find me design jobs in Lagos",
"attachments": []
}2. Intent Classification
javascript
const classification = await gemini.classify(message, context);
// Returns:
{
"intent": "find_job",
"confidence": 0.95,
"entities": {
"role": "design",
"location": "Lagos"
}
}3. Route to Product
javascript
const adapter = getAdapter('yebojobs');
const result = await adapter.search({
userId: 'user_123',
query: 'design',
location: 'Lagos'
});4. Format Response
javascript
const response = formatForChat(result);
// Returns:
{
"message": "Found 5 design jobs in Lagos:",
"cards": [
{ "emoji": "🎨", "title": "UI Designer", "meta": "Paystack • ₦350k/mo", "status": "92% match" },
{ "emoji": "🎨", "title": "Product Designer", "meta": "Kuda • ₦400k/mo", "status": "85% match" }
],
"actions": ["Apply to all", "Filter results"]
}Context Management
The orchestrator maintains context across messages:
javascript
const context = {
conversationId: "conv_456",
userId: "user_123",
// Last few messages
recentMessages: [...],
// Current state
activeProduct: "yebojobs",
pendingAction: null,
// Extracted entities (persisted)
entities: {
jobRole: "design",
location: "Lagos"
},
// User preferences (from YeboID)
userPreferences: { ... }
}Multi-Turn Conversations
User: "Find me design jobs"
Yebo: "Found 5 jobs. [cards]"
User: "Apply to the first one"
↓
Context knows "first one" = Paystack job
↓
Yebo: "Applied to UI Designer at Paystack!"Product Adapters
Each product has an adapter that:
- Authenticates as the user
- Translates chat requests to API calls
- Formats responses for chat display
javascript
class YeboJobsAdapter {
async search(params) {
const jobs = await yeboJobsAPI.search(params);
return {
message: `Found ${jobs.length} matches:`,
cards: jobs.map(formatJobCard)
};
}
async apply(params) {
const result = await yeboJobsAPI.apply(params);
return {
message: `✅ Applied to ${result.jobTitle}!`
};
}
}javascript
class YeboShopsAdapter {
async createListing(params) {
const listing = await vavuAPI.createListing(params);
return {
message: `Listed! Distributing to buyers now.`,
cards: [formatListingCard(listing)]
};
}
}Error Handling
javascript
try {
const result = await adapter.execute(action, params);
return formatSuccess(result);
} catch (error) {
if (error.code === 'INSUFFICIENT_KYC') {
return {
message: "You need to verify your identity first.",
actions: ["Start verification"]
};
}
if (error.code === 'INSUFFICIENT_BALANCE') {
return {
message: "Not enough balance. Top up?",
actions: ["Add money"]
};
}
return {
message: "Something went wrong. Try again?"
};
}Open Questions
- [ ] How to handle ambiguous intents?
- [ ] Fallback to human support?
- [ ] Rate limiting per user?
- [ ] Caching product responses?
- [ ] Multi-language support?