Skip to content

Repository files navigation

Concierge AI — Smart Hotel Assistant Platform

AI-powered hotel concierge for East African SMEs. Handles room bookings, M-Pesa payments, and guest queries across WhatsApp, Telegram, and web chat.

Architecture

Hotel Guest ──► WhatsApp/Telegram/Web ──► CF Worker (Ingress)
                                              │
                                    ┌─────────┼─────────┐
                                    ▼         ▼         ▼
                              Orchestrator  Sub-Agent  Booking
                              (Durable Obj) (Durable)  Workflow
                                    │
                                    ▼
                               M-Pesa STK Push (via A2A)
  • Runtime: Cloudflare Workers + Durable Objects
  • Database: D1 (SQLite) + KV + R2
  • AI: Workers AI (Llama 3.1 8B)
  • Payments: M-Pesa via Agent-to-Agent (A2A) protocol
  • Channels: WhatsApp Business API, Telegram, Web Chat

Domain: Hotel

Project Structure

concierge-ai/                      # Monorepo root
├── .codex/                        # Codex agent configuration
│   ├── config.toml                # Multi-agent + hooks config
│   ├── setup.sh                   # Sandbox bootstrap
│   ├── hooks.json                 # Quality gate hooks
│   ├── hooks/stop_verify.py       # Verification gate script
│   ├── agents/                    # Custom subagent definitions
│   └── rules/project.rules       # Command safety rules
├── docs/                          # Architecture docs, sequence diagrams
├── infra/                         # Terraform — D1, KV, R2, Queues, Access, Rate Limits
│   ├── main.tf                    # Provider + R2 state backend
│   ├── scripts/inject-tf-outputs.sh  # Auto-patches wrangler.jsonc with resource IDs
│   └── Makefile                   # make plan/apply/inject/deploy
├── packages/
│   ├── worker/                    # Backend: Cloudflare Worker + Durable Objects
│   │   ├── src/
│   │   │   ├── index.ts           # Worker entry point (Hono)
│   │   │   ├── config/            # Hotel domain configuration
│   │   │   ├── orchestrator/      # DomainOrchestratorDO (conversation state)
│   │   │   ├── routes/            # Hono route modules (a2a, admin, chat, daraja, mcp, onboarding, webhooks)
│   │   │   ├── features/          # Business logic (mpesa, booking, NLU, RAG, concierge prompt)
│   │   │   └── __tests__/         # 112 tests across 16 files
│   │   ├── migrations/            # D1 schema migrations
│   │   ├── wrangler.jsonc         # Cloudflare Workers config
│   │   └── vitest.config.ts       # Test runner config
│   ├── ui/                        # Hotel owner dashboard: React + Vite + Tailwind CSS 4
│   │   └── src/
│   │       ├── api/client.ts      # Typed API client with Bearer auth
│   │       ├── components/        # Layout, chat widget, UI primitives (Radix/shadcn)
│   │       ├── pages/             # 18 pages (Dashboard, Agent Chat, Workflows, Approvals, etc.)
│   │       └── stores/            # Zustand (auth, tenant)
│   ├── event-bridge/              # SSE event bridge: pushes real-time events to dashboard
│   │   └── src/index.ts           # Cloudflare Worker with SSE streaming
│   ├── hq/                        # Reserved for future HQ dashboard; currently empty
│   └── admin/                     # Admin panel (Next.js, internal tooling)
│       └── src/
├── AGENTS.md                      # Codex primary instructions
├── CAPSTONE_SPEC.md               # Task specification for Codex execution
├── turbo.json                     # Turborepo task pipeline
└── package.json                   # Workspace root

Getting Started

# Install all dependencies
npm ci

# Run worker locally
npm run worker:dev

# Run UI dev server
npm run ui:dev

# Run all tests
npm test

# Typecheck everything
npm run typecheck

# Infrastructure (provision D1, KV, R2, Queues, Access, Rate Limits)
cd infra && make init && make plan && make apply

# Inject Terraform outputs into wrangler.jsonc
make inject

# Deploy worker to Cloudflare
cd ../packages/worker && npx wrangler deploy

CI/CD

GitHub Actions runs ci.yml on pushes and PRs to main. It typechecks all packages, runs tests, builds the UI, and checks Prettier only on changed ts, tsx, json, and md files so unrelated historical formatting drift does not block focused changes. Deployment jobs run only from main pushes.

infrastructure.yml is currently manual-only (workflow_dispatch); automatic push/PR triggers are disabled for now. A manual run can still validate Terraform without R2 backend credentials by running terraform init -backend=false; full backend terraform plan requires configured R2/Cloudflare secrets. Production apply is intentionally not triggered by the current manual workflow because the apply job is still gated to main push events.

Use .env.example as the environment variable inventory for GitHub Actions secrets, Worker secrets, UI env vars, and Terraform variables. Keep real values in GitHub/Netlify/Cloudflare secret stores, not in committed files.

Deployed Environment

Environment Worker URL
Development (sandbox) https://concierge-ai.pmutua.workers.dev

Admin Portal (UI)

The admin portal is a React SPA (packages/ui) for hotel owners to manage their AI concierge assistant and supervise autonomous agent workflows.

Pages

Page Route Description
Login /login Email-only login; matches to tenant, redirects to dashboard or onboarding
Onboarding /onboarding 5-step wizard to create a new tenant
Dashboard /dashboard KPI cards with tooltips (customers, conversations, payments, response time) + SSE live indicator + actionable insights bar + setup checklist for new tenants
Agent Chat /agent Direct streaming chat with Concierge AI; inline tool-call visualization; workflow progress; approval cards
Workflows /workflows Scalable workflow list (150+ items): Load More pagination, search, 4 filter tabs, stats bar, compact rows with step progress bars, priority sorting
Approvals /approvals Scalable approval queue: Load More, search, risk badges, AI recommendations, priority sort (high risk first), inline approve/reject
Conversations /conversations Split-pane: filterable list + message thread with test reply composer
Customers /customers Searchable list with desktop table + mobile card layout
Live Activity /live Real-time SSE event feed (bookings, payments, messages, alerts) with connection status
Payments /payments Transaction list with status + date range filters, CSV export, mobile cards
Knowledge Base /knowledge-base Tabbed: document upload (drag-and-drop, file picker + categories, R2 storage) + FAQ CRUD + third-party Connectors (Google Docs, Notion, Dropbox, HTTP)
Channels /channels Channel configs (WhatsApp, Telegram, SMS, Web) with activate/suspend
Leads /leads Lead pipeline management
Analytics /analytics Period-selectable KPIs + area charts (Recharts)
Billing /billing Plan comparison cards with upgrade confirmation dialog; Enterprise → mailto:sales@concierge-ai.co
Settings /settings Tabbed: Business Info, Assistant config (tone, language, escalation sensitivity, max auto-payment), Branding, Notifications (with save)
Landing / Public marketing page with guest chat widget — visitors can book rooms without login via floating chat bubble
Hotel Demo /demo Public hotel booking showcase: room cards, amenities, embedded chat, CTA — demonstrates the guest booking experience end-to-end

Key UI Features

  • Agentic Chat — Owner chats directly with AI, sees tool calls (availability check, payment processing) rendered as inline cards
  • Workflow Visualization — 150+ active booking pipelines with Load More pagination, search, filters, compact collapsible rows with step progress bars
  • Human-in-the-Loop Approvals — AI escalates high-value decisions (payments > threshold, refunds, complaints) to scalable owner queue with risk badges, AI recommendations, and contextual tooltips
  • Live Activity Feed — Real-time SSE events from event-bridge showing bookings, payments, messages with connection status indicator (Live/Connecting/Offline)
  • Actionable Dashboard Insights — Contextual nudges when metrics need attention (low payment success rate, high escalations, low AI resolution) with direct links to fix
  • Contextual Tooltips — Every KPI card and metric explains what it means and when to act (via Radix tooltip on hover)
  • Guest Chat Widget — Floating chat bubble on landing page — guests book rooms without login, identify by phone number for M-Pesa
  • React Error Boundary — App-level error boundary in Shell catches crashes gracefully with reload option
  • Toast notifications — success/error/info feedback (auto-dismiss 4s)
  • Skeleton loading — CardSkeleton, ListSkeleton, ChatSkeleton placeholders
  • Mobile responsive — Payments and Customers tables switch to card layout on small screens
  • Accessibilityaria-label on all search inputs, focus-visible outlines, prefers-reduced-motion support
  • PerformanceuseMemo on expensive filter/stats calculations, debounced search inputs
  • Test Assistant — Floating chat widget lets owners preview their AI assistant (calls public /api/chat/:slug endpoint)
  • Sidebar persistence — Collapse state saved to localStorage
  • Auth persistence — User, token, and tenant state persists to localStorage (concierge:user, concierge:token, concierge:tenant)

Environment Variables (wrangler.jsonc)

Variable Value
ENVIRONMENT development
DARAJA_BASE_URL https://sandbox.safaricom.co.ke
DARAJA_ENV sandbox
DARAJA_TRANSACTION_TYPE CustomerPayBillOnline
TELEGRAM_API https://api.telegram.org
ALLOWED_ORIGINS http://localhost:3000,http://localhost:5173

Secrets (set via wrangler secret put)

DARAJA_CONSUMER_KEY          # Safaricom sandbox consumer key
DARAJA_CONSUMER_SECRET       # Safaricom sandbox consumer secret
DARAJA_SHORTCODE             # Sandbox shortcode (174379)
DARAJA_PASSKEY               # Sandbox passkey
DARAJA_CALLBACK_URL          # STK push callback URL
TELEGRAM_BOT_TOKEN           # Telegram bot token
SANDBOX_API_KEY              # Sandbox API key
WHATSAPP_VERIFY_TOKEN        # WhatsApp webhook verify token
WHATSAPP_API_TOKEN           # WhatsApp Business API token
CF_ACCESS_TEAM_DOMAIN        # Cloudflare Access team domain
CF_ACCESS_AUD                # Cloudflare Access audience tag
CONCIERGE_INTERNAL_SECRET        # Internal agent auth
LANGOPAY_A2A_SECRET          # LangoPay A2A auth
PAYSTACK_SECRET_KEY          # Paystack API secret
PAYSTACK_WEBHOOK_SECRET      # Paystack webhook signing secret

Frontend .env (packages/ui/.env)

VITE_API_URL=https://concierge-ai.pmutua.workers.dev   # Or leave empty for local proxy

Codex Multi-Agent Workflow

This project uses OpenAI Codex with custom subagents for exploration, review, tests, documentation lookup, and Git/CI workflow support. Configuration lives in .codex/.

Available Agents

Agent File Purpose
reviewer .codex/agents/reviewer.toml Code review — correctness, security, tenant isolation, missing tests
test_writer .codex/agents/test-writer.toml Writes Vitest tests following project patterns
explorer .codex/agents/explorer.toml Read-only codebase exploration and context gathering
docs_researcher .codex/agents/docs-researcher.toml Up-to-date docs lookup for Hono, Cloudflare Workers, Vitest, React, and Tailwind
gitops .codex/agents/gitops.toml Safe Git workflow, commit, PR readiness, and CI/CD troubleshooting

How to Use (in Codex CLI or IDE)

# Review your current changes
Spawn the reviewer agent to review packages/worker/src/features/

# Add tests for a feature
Use the test_writer agent to add tests for the receipt-generator

# Understand code before changing it
Use the explorer agent to find how M-Pesa flows from webhook to database

# Verify library or platform docs
Use the docs_researcher agent to verify the correct D1 batch API for Workers

# Prepare Git workflow and PR handoff
Use the gitops agent to prepare a safe commit and PR description for the current changes

# Parallel multi-agent review (advanced)
Spawn one agent per concern: security (reviewer), tests (test_writer), architecture (explorer)

Automatic Quality Gates

  • Stop hook (.codex/hooks/stop_verify.py) — Reminds Codex to run typecheck + tests before finishing
  • Rules (.codex/rules/project.rules) — Blocks git push --force, git reset --hard, rm -rf /; auto-allows npm, git, npx wrangler

Configuration

File Purpose
.codex/config.toml Enables hooks, sets max 6 concurrent agents
.codex/setup.sh Sandbox bootstrap (installs deps, warms caches)
.codex/hooks.json Wires the Stop verification hook
AGENTS.md Primary instructions loaded by Codex for every task
CAPSTONE_SPEC.md Structured task spec — all P0–P3 tasks with Goal/Context/Constraints/Verification

Test Hotel (Sandbox)

Seeded via migration 0006_seed_test_data.sql. Use for end-to-end testing.

Telegram Bot

Field Value
Bot @conciergeSME_bot
Bot ID 8753942766
Webhook https://concierge-ai.pmutua.workers.dev/webhooks/telegram

Telegram Edge Case Handling

Edge Case Behavior
Group/supergroup messages Silently ignored (private chats only)
Edited messages Ignored to prevent duplicate processing
Non-text messages (sticker, voice, photo, video, doc) Friendly reply: "I can only process text messages"
Empty/whitespace messages Silently dropped
Messages > 2000 chars Polite rejection with length hint
Invalid phone numbers E.164 validation before storing for M-Pesa
KV write failures (session/phone) User-friendly error + retry guidance
Rate limiting 12 messages/minute per chat via CACHE_KV
Webhook signature Constant-time comparison on X-Telegram-Bot-Api-Secret-Token

Test Business

Tenant ID Name Domain Plan Deep Link
ten_hotel_01 Savanna Hotel hotel starter t.me/conciergeSME_bot?start=savanna-hotel

Test Admin

Tenant Admin Email Phone
Savanna Hotel John Kamau admin@savannahotel.test +254700100001

Demo Login Credentials

Role Email Notes
Hotel Owner admin@savannahotel.test Savanna Hotel (ten_hotel_01)
Clinic Owner admin@dawaclinic.test Dawa Clinic (ten_clinic_01)
Realtor admin@nyumbarealtors.test Nyumba Realtors (ten_realestate_01)
Landlord admin@kijaniproperties.test Kijani Properties (ten_landlord_01)
Retailer admin@dukamart.test Duka Mart (ten_retail_01)

No password required — email-only login matches tenant by admin_email.

Admin Panel (Next.js — separate deploy)

Variable Value
NEXT_PUBLIC_API_URL https://concierge-ai.pmutua.workers.dev/api
NEXT_PUBLIC_ADMIN_TOKEN Set in Netlify env vars (use dev-token locally)

Admin panel uses token-based auth via Authorization: Bearer <token>. The token is set as a build-time env var.

End-to-End Test Steps

  1. Connect via deep link — Tap the Savanna Hotel deep link in Telegram
  2. Verify session — Send /status to confirm connected
  3. Book a room — Send "I need a room for 2 nights"
  4. Pay via M-Pesa — Confirm STK push flow
  5. Web chat — Visit https://concierge-ai.pmutua.workers.dev/api/chat/savanna-hotel/info

API Verification

# Health check
Invoke-RestMethod -Uri "https://concierge-ai.pmutua.workers.dev/api/health"

# Verify hotel tenant
Invoke-RestMethod -Uri "https://concierge-ai.pmutua.workers.dev/api/chat/savanna-hotel/info"

---

## Roadmap: Prototype → Production (Next 30 Days)

| Week | Milestone | Deliverable |
|------|-----------|-------------|
| 1 | WhatsApp Business API | Meta-verified business number, webhook integration, message templates |
| 2 | Pilot deployment | 3 hotels in Nairobi (Westlands, CBD, Karen) on production Cloudflare |
| 3 | Payment reconciliation | Real-time M-Pesa settlement dashboard, daily KES reports |
| 4 | Multi-language expansion | Sheng + Kikuyu intent detection, language auto-detect |

### Beyond 30 Days

- **Horizontal scaling:** Queue-based booking engine for 100+ concurrent hotels
- **Revenue model:** KES 2,000/month per hotel (freemium tier: 50 bookings/month free)
- **Open-source Codex config:** Fork-friendly `.codex/` setup for clinics, restaurants, salons
- **Kenya Tourism Authority integration:** Auto-report occupancy rates

---

## License

Proprietary — All rights reserved.

About

AI-powered hotel concierge for East African SMEs, it automates room bookings and guest queries via WhatsApp(wip), Telegram, and Web(wip), featuring integrated M-Pesa payment processing.

Resources

Contributing

Stars

3 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages