Raje19112003/Invoice_Dispute_Resolution_Environment
0
1---2title: Invoice Dispute Resolution3emoji: ๐ผ4colorFrom: blue5colorTo: purple6sdk: docker7app_file: server/app.py8python_version: "3.10"9pinned: false10---11 12# Invoice Dispute Resolution Environment13 14An AI-powered system for resolving billing disputes using reinforcement learning. The environment supports 3 difficulty levels and evaluates agent performance on correctness, efficiency, and policy compliance.15 16Check out the configuration reference at https://huggingface.co/docs/hub/spaces-config-reference17 18## ๐ Quick Start19 20### Local Development21 22```bash23# Create virtual environment24python3 -m venv venv25source venv/bin/activate26 27# Install dependencies28pip install -r server/requirements.txt29 30# Start FastAPI server31python -m uvicorn server.app:app --reload --port 786032```33 34The API will be available at `http://localhost:7860`35 36### Interactive API Documentation37 38Once the server is running, visit:39- **Swagger UI**: http://localhost:7860/docs40- **ReDoc**: http://localhost:7860/redoc41 42## ๐ Environment Variables (OpenAI-Compatible)43 44The baseline agent uses the **OpenAI Python client library**, which works with ANY provider:45 46### For Judges/Evaluation47Judges will inject these during evaluation:48```bash49API_KEY=<provided-by-judges> # API key for LLM provider50API_BASE_URL=<provided-by-judges> # Base URL for LLM provider51MODEL_NAME=<provided-by-judges> # Model name to use52```53 54### For Local Development (Free Options)55 56**Option 1: HuggingFace (Free)**57```bash58export API_KEY="hf_..." # Your HuggingFace token (free)59export API_BASE_URL="https://router.huggingface.co/v1"60export MODEL_NAME="Qwen/Qwen2.5-72B-Instruct"61```62 63**Option 2: OpenAI (Paid)**64```bash65export API_KEY="sk-..." # Your OpenAI API key66export API_BASE_URL="https://api.openai.com/v1"67export MODEL_NAME="gpt-3.5-turbo"68```69 70**Option 3: Legacy Support**71```bash72export OPENAI_API_KEY="sk-..." # For backward compatibility73```74 75Then run baseline:76```bash77python inference.py78```79 80## ๐ API Endpoints81 82### 1. Health Check83```bash84GET /health85```86**Response:**87```json88{89 "status": "ok",90 "env": "invoice-dispute-env"91}92```93 94### 2. Reset Episode95```bash96POST /reset97Content-Type: application/json98 99{100 "difficulty": "easy" // or "medium", "hard"101}102```103 104**Response:** `DisputeObservation` object105 106### 3. Submit Decision107```bash108POST /step109Content-Type: application/json110 111{112 "decision": "approve_full",113 "response_text": "Your refund has been approved.",114 "refund_amount": null115}116```117 118**Decision options:**119- `full_refund` - Approve 100% refund120- `partial_refund` - Approve partial refund (requires `refund_amount`)121- `reject` - Deny dispute122- `escalate` - Escalate to human123- `request_info` - Request more information124 125### 4. Get Current State126```bash127GET /state128```129 130**Response:** `DisputeState` object with:131- Invoice details132- Customer information133- Dispute details134- Company policy135- Customer history136 137## ๐ฏ Difficulty Levels138 139| Level | Description | Features |140|-------|-------------|----------|141| **Easy** | Clear-cut disputes | Obvious correct answer, 80%+ baseline reward |142| **Medium** | Ambiguous cases | Requires careful analysis, 50%+ baseline reward |143| **Hard** | Complex scenarios | Multiple perspectives, 30%+ baseline reward |144 145## ๐๏ธ Project Structure146 147```148.149โโโ server/150โ โโโ app.py # FastAPI application151โ โโโ environment.py # Dispute environment logic152โ โโโ models.py # Pydantic models153โ โโโ __init__.py154โ โโโ requirements.txt # Python dependencies155โโโ inference.py # Baseline evaluation script156โโโ models.py # Shared models157โโโ openenv.yaml # OpenEnv configuration158โโโ Dockerfile # Docker configuration159โโโ README.md # This file160โโโ pyproject.toml161```162 163## ๐ณ Docker Deployment164 165### Build locally166```bash167docker build -t invoice-dispute:latest .168```169 170### Run locally171```bash172docker run -p 7860:7860 invoice-dispute:latest173```174 175### Deploy to Hugging Face Spaces1761. Push to GitHub1772. Create Space: https://huggingface.co/new-space1783. Select **Docker** runtime1794. Connect your GitHub repository1805. Add secrets:181 - `HF_TOKEN` (optional)182 - `OPENAI_API_KEY` (if using GPT)1836. Deploy!184 185## ๐ Running Baseline Evaluation186 187```bash188python inference.py189```190 191This evaluates the environment baseline on all 3 difficulty levels:192- Easy: Expected ~0.80 reward193- Medium: Expected ~0.50 reward194- Hard: Expected ~0.30 reward195 196## ๐ง Testing Endpoints197 198### Using curl199 200```bash201# Check health202curl http://localhost:7860/health203 204# Start episode (easy)205curl -X POST http://localhost:7860/reset \206 -H "Content-Type: application/json" \207 -d '{"difficulty": "easy"}'208 209# Get current state210curl http://localhost:7860/state211 212# Submit decision (full refund)213curl -X POST http://localhost:7860/step \214 -H "Content-Type: application/json" \215 -d '{216 "decision": "full_refund",217 "response_text": "Your refund has been approved.",218 "refund_amount": null219 }'220```221 222### Using Python223 224```python225import requests226 227API_URL = "http://localhost:7860"228 229# Reset230response = requests.post(f"{API_URL}/reset", json={"difficulty": "medium"})231print(response.json())232 233# Get state234response = requests.get(f"{API_URL}/state")235print(response.json())236 237# Step238response = requests.post(f"{API_URL}/step", json={239 "decision": "partial_refund",240 "response_text": "Partial refund approved due to service delay.",241 "refund_amount": 150.00242})243print(response.json())244```245 246## ๐ Environment Variables247 248Optional configuration via `.env`:249 250```bash251HF_TOKEN=your_huggingface_token252OPENAI_API_KEY=your_openai_api_key253MODEL_NAME=meta-llama/Llama-2-7b-chat-hf254```255 256## ๐ Data Types257 258### DisputeObservation259Response from `/step` endpoint:260```python261{262 "reward": float, # Reward for this decision (-1 to 1)263 "feedback": str, # Explanation of reward264 "step_result": str, # What happened265 "customer_reaction": str, # How customer reacted266 "done": bool # Is episode finished?267}268```269 270### DisputeState271Response from `/state` endpoint:272```python273{274 "invoice_id": str,275 "invoice_date": str,276 "invoice_amount": float,277 "dispute_type": str,278 "customer_message": str,279 "customer_tier": str, # standard, premium, enterprise280 "line_items": list,281 "customer_history": dict,282 "policy": dict283}284```285 286### DisputeAction287Request to `/step` endpoint:288```python289{290 "decision": str, # one of the 5 decision types291 "response_text": str, # Your message to customer292 "refund_amount": float | null293}294```295 296## ๐ ๏ธ Development297 298### Creating virtual environment299 300```bash301python3 -m venv venv302source venv/bin/activate303pip install -r server/requirements.txt304```305 306### Running tests307 308```bash309python -m pytest310```311 312### Code structure313 314- `server/app.py` - FastAPI app with all endpoints315- `server/environment.py` - Core environment logic316- `server/models.py` - Pydantic data models317- `inference.py` - Example agent/baseline318- `models.py` - Shared type definitions319 320## ๐ Example Agent321 322See `inference.py` for a baseline agent that:3231. Resets the environment3242. Gets the current state3253. Makes decisions based on simple rules3264. Tracks rewards327 328You can modify this to test your own strategies!329 330## ๐ API Response Examples331 332### Successful Reset333```json334{335 "invoice_id": "INV-2024-001",336 "invoice_amount": 1500.00,337 "customer_message": "I was charged twice for the same service...",338 "dispute_type": "billing_error",339 "reward": 0,340 "feedback": "Episode started",341 "step_result": "",342 "customer_reaction": null,343 "done": false344}345```346 347### Successful Step348```json349{350 "reward": 0.85,351 "feedback": "Great decision! Customer was clearly overcharged and you recognized it quickly.",352 "step_result": "Full refund of $1500.00 approved and processed.",353 "customer_reaction": "Very satisfied! Thank you for resolving this quickly.",354 "done": true355}356```357 358## ๐จ Error Handling359 360All endpoints return proper HTTP status codes:361- `200` - Success362- `400` - Bad request (invalid difficulty, missing fields, etc.)363- `500` - Server error364 365Error responses include a detail message:366```json367{368 "detail": "Difficulty must be: easy, medium, or hard"369}370```371 372## ๐ Performance373 374- **Average response time**: 100-500ms per request375- **Concurrent users**: Tested with 1 user (stateful)376- **Memory footprint**: ~500MB (Python + models)377- **Startup time**: ~5 seconds378 379## ๐ค Contributing380 3811. Fork the repository3822. Create a feature branch3833. Commit your changes3844. Push to the branch3855. Open a Pull Request386 387## ๐ License388 389MIT390 391## ๐ฅ Authors392 393OpenEV Hackathon Team394 395## ๐ Links396 397- [Hugging Face Spaces](https://huggingface.co/spaces)398- [FastAPI Documentation](https://fastapi.tiangolo.com/)399- [Uvicorn Documentation](https://www.uvicorn.org/)400 401## ๐ฌ Support402 403For issues and questions, please create an issue on GitHub or reach out to the team.404 405---406 407**Built with โค๏ธ for the OpenEV Hackathon**408 