An AI agent that lets telecom customers query their bills, understand charges, dispute line items, and change plans — all through a natural-language conversation. A Python FastAPI service hosts the LangChain ReAct agent; two Spring Boot microservices (billing and provisioning) own the BSS data.
graph LR
C([Customer Browser]) -->|HTTP| WU
subgraph web-ui [:3001]
WU[nginx Static SPA]
end
WU -->|POST /auth/demo-token\nPOST /chat/session\nPOST /chat| AS
subgraph agent-service [:8000]
AS[FastAPI + LangChain ReAct\nLangGraph Session State]
end
AS -->|REST + X-Internal-Token| BS
AS -->|REST + X-Internal-Token| PS
subgraph billing-service [:8081]
BS[Spring WebFlux\nR2DBC · PostgreSQL]
end
subgraph provisioning-service [:8082]
PS[Spring MVC\nJPA · PostgreSQL]
end
| Layer | Technology |
|---|---|
| Web UI | nginx alpine, HTML, vanilla JS |
| Agent service | Python 3.11, FastAPI, LangChain, LangGraph; supports Google Gemini, Anthropic Claude, OpenAI, and Ollama (local) |
| Billing service | Java 21, Spring WebFlux 3.x, R2DBC, Flyway |
| Provisioning service | Java 21, Spring MVC 3.x, JPA, Flyway |
| Database | PostgreSQL 15 (schemas: billing, provisioning) |
| Observability | LangSmith, Micrometer, Prometheus, Grafana |
- TDD: Red → Green → Refactor for all logic
- Conventional Commits (
feat:,fix:,docs:, …) - CI runs on every PR (tests, SAST via SonarQube)
- DAST (OWASP ZAP) runs on merge to main
For users who want to run and experiment with the application. Only Docker is required — no Java or Python install needed.
- Docker 24+ and Docker Compose v2
Copy .env.example to .env. Most values are pre-configured for Docker Compose — only these require action:
| Variable | How to obtain |
|---|---|
INTERNAL_TOKEN |
Auto-generated by setup-secrets.sh (see step 3 below). |
JWT_SECRET |
Auto-generated by setup-secrets.sh (see step 3 below). |
LLM_PROVIDER |
Choose your LLM backend: google (default), anthropic, openai, or ollama. |
LLM_MODEL |
Model name for the chosen provider. Leave empty to use the provider default (see table below). |
LLM_API_KEY |
API key for the selected cloud provider. Not needed when LLM_PROVIDER=ollama. |
LLM_BASE_URL |
Base URL for local/self-hosted LLM servers (Ollama, LM Studio, vLLM, …). Default: http://localhost:11434. Only used when LLM_PROVIDER=ollama. |
LANGCHAIN_API_KEY |
smith.langchain.com → Settings → API Keys. Optional — set LANGCHAIN_TRACING_V2=false to disable tracing. |
Provider defaults and where to get an API key:
LLM_PROVIDER |
Default LLM_MODEL |
Free tier | API key source |
|---|---|---|---|
google |
gemini-2.5-flash-lite |
Yes (no credit card) | aistudio.google.com |
anthropic |
claude-opus-4-7 |
No | console.anthropic.com |
openai |
gpt-4o |
No | platform.openai.com |
ollama |
llama3.2 |
Local — no key needed | ollama.com |
Note on Gemini free tier:
gemini-2.5-flashhas a 20 RPD quota; usegemini-2.5-flash-litefor local development to avoid hitting the limit quickly.
- Clone the repository
git clone <repo-url>
cd smart-billing-assistant- Set up environment
cp .env.example .env- Generate INTERNAL_TOKEN and JWT_SECRET and write them into .env automatically
./scripts/setup-secrets.sh
# Secrets written to .env:
# INTERNAL_TOKEN=a1b2c3...
# JWT_SECRET=d4e5f6...- Fill in the remaining secrets manually in .env:
# LLM_PROVIDER → google | anthropic | openai | ollama (default: google)
# LLM_API_KEY → API key for the chosen provider (see provider table above)
# LANGCHAIN_API_KEY → https://smith.langchain.com (OPTIONAL, set LANGCHAIN_TRACING_V2=false to skip)- Start all services
docker compose up-
Using the Chat UI
Open http://localhost:3001 — the app connects automatically and drops you straight into the chat.
The browser UI is enabled by
DEMO_MODE=truein.env. The default isfalse— set it totrueto activate the/auth/demo-tokenendpoint that the UI relies on.
Example messages you can send:
| Intent | Example message |
|---|---|
| View current invoice | "What is my current bill?" |
| Understand charges | "Why is my bill so high this month?" |
| Dispute a charge | "I want to dispute this data overage charge" |
| Change plan | "Show me cheaper plans" |
| Check payment status | "Did you receive my payment?" |
| Follow-up | "Why was it higher than last month?" |
The agent-service at http://localhost:8000 is the entry point for API calls.
Step 1 — Generate a JWT
All requests require a signed JWT. Run the helper script — it reads JWT_SECRET from your .env automatically:
./scripts/generate-token.sh
# eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...Copy the printed token and use it as the Bearer value in all subsequent requests.
Step 2 — Create a session:
curl -X POST http://localhost:8000/chat/session \
-H "Authorization: Bearer <your-jwt>"
# Returns: { "session_id": "uuid..." }Step 3 — Chat naturally:
curl -X POST http://localhost:8000/chat \
-H "Authorization: Bearer <your-jwt>" \
-H "Content-Type: application/json" \
-d '{"session_id": "<session_id>", "message": "What is my current bill?"}'For contributors building, testing, or modifying the services.
- Docker 24+ and Docker Compose v2
- Java 21 (for local Gradle builds)
- Python 3.11 (for local agent-service development)
# agent-service
cd agent-service
python3.11 -m venv .venv && source .venv/bin/activate
pip install -e ".[dev]"
pytest
# billing-service
cd billing-service
./gradlew test
# provisioning-service
cd provisioning-service
./gradlew test| Service | URL | Notes |
|---|---|---|
| Chat UI | http://localhost:3001 | Browser-based customer chat interface (requires DEMO_MODE=true) |
| Swagger UI — billing-service | http://localhost:8081/swagger-ui.html | No auth header required — publicly accessible |
| Swagger UI — provisioning-service | http://localhost:8082/swagger-ui.html | No auth header required — publicly accessible |
| Grafana dashboards | http://localhost:3000 | Default credentials: admin / admin |
| Prometheus | http://localhost:9090 | Scrapes /actuator/prometheus on both Java services |
| LangSmith | https://smith.langchain.com | Sign in with your account; select the project name set in LANGCHAIN_PROJECT (default: smart-billing-assistant); click on Monitoring |
| Google AI Studio | https://aistudio.google.com | Google Gemini API keys and usage dashboard (when LLM_PROVIDER=google) |
| Service | Endpoint | Description |
|---|---|---|
| agent-service | POST /auth/demo-token |
Issue a demo JWT for a customer ID (DEMO_MODE=true only) |
| agent-service | POST /chat/session |
Create a new conversation session (JWT required) |
| agent-service | POST /chat |
Send a message, receive agent response (JWT required) |
| agent-service | GET /health |
Health check |
| billing-service | GET /api/v1/billing/invoices/current |
Latest invoice with line items |
| billing-service | GET /api/v1/billing/invoices/comparison |
Current vs. prior cycle comparison with overage and one-time charge flags |
| billing-service | GET /api/v1/billing/payments/status |
Payment status (PAID / PENDING / OUTSTANDING); includes lastUpdatedAt timestamp and overdue flag when past due |
| billing-service | GET /api/v1/billing/disputes/{disputeId} |
Dispute status by ID |
| billing-service | POST /api/v1/billing/disputes |
File a dispute |
| provisioning-service | GET /api/v1/provisioning/plans/eligible |
Eligible plans |
| provisioning-service | POST /api/v1/provisioning/plans/change |
Change plan |
