The Problem
Retail support teams spend manual effort handling repetitive queries about order status, return policies, and escalation to human agents. Those interactions are high‑volume, low‑complexity, and often cause delays that hurt customer satisfaction.
What This Does
The repository implements Ari, an agentic chatbot that interprets user intent with Google Gemini and routes the request to a dedicated agent.
src/agents/contains the intent‑specific agents (order_status_agent.py,return_policy_agent.py,human_rep_agent.py). Each agent declares the services it needs viaget_required_service_keys()and implements aprocess()method.- Business‑logic lives in
src/services/– e.g.order_service.pyformats order details from the SQLite DB, whilepolicy_service.pyreadsdata/policies.json. - Core conversation handling is in
src/core/conversation.py, which creates aConversationManager, loads agents, and maintains per‑session state (src/core/state.py). - The UI is a Gradio web app (
src/ui/gradio_app.py) that forwards user messages to the manager and streams LLM responses.
How It Is Wired
Execution starts at app.py (line 18) where ensure_database() creates the SQLite schema (src/db/setup_db.py → create_tables) and loads sample orders (load_orders_from_csv). The Flask‑style entry point is src/ui/gradio_app.py – the Gradio server runs main() (line 519) which instantiates ConversationManager from src/core/conversation.py.
Message flow:
handle_message(src/core/conversation.py) is invoked for each user turn. It updates the conversation state (src/core/state.py → update_state) and logs the exchange.- The manager calls
determine_intent(src/llm/fallback_llm_service.py) which delegates to the configured LLM service (src/llm/gemini_service.pyor the fallbackgroq_service.py). - Intent routing selects an agent (
src/agents/base_agent.py → _load_agents). The chosen agent’sprocess()accesses required services (e.g.,OrderService.get_order_status_by_id) and returns a response string. - The response is sent back through Gradio to the browser.
Key blast‑radius nodes:
src/core/conversation.handle_message– called from 7 places, touches state and agent loading.src/llm/fallback_llm_service.determine_intent– called from 4 places, performs the only outbound network call (LLM API).src/services/order_service.format_order_details– used in 6 callers, central to order‑status output.
No circular import cycles were detected; the import graph is shallow (63 edges, 0 cycles). The most connected module is src/core/conversation (instability 0.75), indicating it is a change hotspot.
How To Use It
# 1. Clone the repo
git clone https://github.com/moses-y/ecommerce-chatbot.git
cd ecommerce-chatbot
# 2. Create a venv and activate it
python3 -m venv venv
source venv/bin/activate # Windows: .\venv\Scripts\activate
# 3. Install the fast installer (optional) and dependencies
pip install uv
uv pip install -r requirements.txt # or: pip install -r requirements.txt
# 4. Provide a Gemini API key (copy .env.example → .env and fill GEMINI_API_KEY)
cp .env.example .env
# 5. Launch the Gradio UI
python app.py # starts Flask‑style init, then Gradio server
The UI is reachable at http://127.0.0.1:7860. No additional configuration files are required beyond the .env key.
Real‑World Use
A customer types “Where is my order #AB12CD34EF56GH78IJ90KL12MN34OP56?” → the message reaches handle_message, the LLM tags it as order_status, the OrderStatusAgent queries OrderService, and the bot replies with a formatted status. If the user asks for a human hand‑off, HumanRepAgent records contact info via ContactService and confirms escalation.
Code Health & Issues
- Critical –
gradio@5.22.0has CVE‑2026‑27167. Fix: upgrade to the patched version and add a lockfile. - High –
python-dotenv@1.0.1,pytest@7.4.0,bleach@6.2.0each carry published advisories. Fix: upgrade and commit a lockfile. - Medium – Enable Dependabot/Renovate; pin Docker base image by digest; add a dependency‑scan step in CI; move
data/cached_orders.csv(7.9 MB) to Git LFS; setpersist-credentials: falseon checkout; add a non‑rootUSERin Dockerfile; set workflowtimeout-minutes. - Low – Add job timeouts to GitHub Actions workflow.
Additional measured findings: deep nesting (max depth 8) in src/llm/interface.py, human_rep_agent.py, gemini_service.py; high branching density in src/core/config.py, src/db/database.py, src/services/order_service.py; duplicated 6‑line blocks across LLM service files. All issues stem from static analysis and include concrete fix suggestions.
The Bottom Line
Ari provides a clear, modular chatbot that ties LLM intent detection to concrete e‑commerce services, with a lightweight Flask/Gradio front‑end. The codebase is functional but suffers from outdated, vulnerable dependencies and several maintainability hotspots (deep nesting, duplicated LLM logic). It is suitable for teams that need a quick prototype and are willing to invest in dependency hygiene and refactoring before production deployment.