Back to projects Project · AI Agent

AI Appointment Scheduler

A full-stack, AI-powered scheduling system for a hair salon: customers book appointments through a natural-language chat interface instead of a traditional form.

Agentic AI LangGraph ReAct Chat booking

What it does

Customers describe what they need in plain English (“I'd like highlights next Saturday at 2pm”) and a conversational AI agent handles the entire booking flow — checking availability, confirming details, and optionally collecting payment — all in a single chat thread.

Key engineering highlights

1

LangGraph ReAct agent

A tool-calling loop (check availability → book → request payment), compiled once at startup and shared across all concurrent sessions via checkpoint-keyed conversation state.

2

Dual request-path architecture

The agent handles customer interactions while admin reads bypass the LLM entirely for direct, low-latency service access.

3

Structured payment trigger

The agent emits a structured sentinel via a tool response; the backend extracts it and the frontend renders an inline payment modal — with no client-side prompt parsing.

4

Clean service boundary

All persistence logic lives in a single service class, making the storage layer swappable without touching the agent or the API.

5

Natural-language dates

With python-dateparser, the agent passes the user’s phrasing verbatim to tools rather than forcing ISO format on the customer.

Architecture

┌──────────────────────────────────────────────────────────────┐
│                          BROWSER                             │
│   ┌────────────────────────┐   ┌────────────────────────┐    │
│   │   client-app  :4200    │   │   admin-app  :4201     │    │
│   │   SchedulingPrompt     │   │   AppointmentList      │    │
│   │   • chat UI            │   │   • live table         │    │
│   │   • threadId (UUID)    │   │   • loading / error    │    │
│   │   • payment modal      │   │                        │    │
│   └───────────┬────────────┘   └───────────┬────────────┘    │
└───────────────│────────────────────────────│────────────────┘
        POST /chat                    GET /appointments
        POST /appointments/{id}/pay   POST /appointments/{id}/pay
                │                            │
┌───────────────▼────────────────────────────▼────────────────┐
│                       FastAPI  :8000                         │
│   ┌────────────────────────┐   ┌────────────────────────┐    │
│   │        chat.py         │   │     appointments.py    │    │
│   │   rate limiter         │   │   GET  /appointments   │    │
│   │   (20 req/60s/thread)  │   │   GET  /…/{id}         │    │
│   │        │               │   │   POST /appointments   │    │
│   │        ▼               │   │   POST /…/{id}/pay     │    │
│   │   graph.ainvoke()      │   └───────────┬────────────┘    │
│   │   scan ToolMessages    │               │                 │
│   │   → extract            │               │                 │
│   │     payment_request    │               │                 │
│   └───────────┬────────────┘               │                 │
└───────────────│────────────────────────────│────────────────┘
                ▼                            │
┌───────────────────────────────┐            │
│      LangGraph StateGraph     │            │
│    (compiled once at startup) │            │
│    ┌─────────┐  tool_calls?   │            │
│    │  agent  │───────────────►│            │
│    │  node   │◄───────────────│            │
│    └────┬────┘   ┌─────────┐  │            │
│         │        │  tools  │  │            │
│         ▼        │  node   │  │            │
│        END       └────┬────┘  │            │
│    MemorySaver        │       │            │
│    (thread_id key)    │       │            │
└───────────────────────│───────┘            │
                        ▼                    ▼
┌──────────────────────────────────────────────────────────────┐
│                     AppointmentService                        │
│                (single owner of all storage)                  │
│   check_availability │ book_appointment │ cancel │ mark_paid  │
│                _store: dict[id → Appointment]                 │
│                      (in-memory, PoC)                         │
└───────────────────────────────┬──────────────────────────────┘
                                │  (DATABASE_URL wired, not yet used)
                                ▼
                       ┌──────────────────┐
                       │   PostgreSQL     │
                       │   port 5433      │
                       │   (Docker)       │
                       └──────────────────┘

The key architectural insight is the payment trigger: the agent emits a payment_request sentinel via a tool response, extracted on the backend — the frontend renders a payment modal without ever parsing the LLM’s text.

Tech stack

AI / Agent

  • LangGraph (ReAct)
  • LangChain
  • Claude — Anthropic
  • Custom agent tools

Backend

  • Python
  • FastAPI
  • Pydantic Settings
  • python-dateparser

Frontend

  • Angular 21
  • TypeScript
  • Signals reactivity
  • ngx-markdown

Infrastructure

  • Docker
  • PostgreSQL

Want an AI agent for your business?

Let's talk about how I can design conversational AI agents that automate your customer journeys.