Raje19112003/Invoice_Dispute_Resolution_Environment
Invoice Dispute Resolution Environment
An 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.
Check out the configuration reference at https://huggingface.co/docs/hub/spaces-config-reference
๐ Quick Start
Local Development
# Create virtual environment
python3 -m venv venv
source venv/bin/activate
# Install dependencies
pip install -r server/requirements.txt
# Start FastAPI server
python -m uvicorn server.app:app --reload --port 7860The API will be available at http://localhost:7860
Interactive API Documentation
Once the server is running, visit:
- Swagger UI: http://localhost:7860/docs
- ReDoc: http://localhost:7860/redoc
๐ Environment Variables (OpenAI-Compatible)
The baseline agent uses the OpenAI Python client library, which works with ANY provider:
For Judges/Evaluation
Judges will inject these during evaluation:
API_KEY=<provided-by-judges> # API key for LLM provider
API_BASE_URL=<provided-by-judges> # Base URL for LLM provider
MODEL_NAME=<provided-by-judges> # Model name to useFor Local Development (Free Options)
Option 1: HuggingFace (Free)
export API_KEY="hf_..." # Your HuggingFace token (free)
export API_BASE_URL="https://router.huggingface.co/v1"
export MODEL_NAME="Qwen/Qwen2.5-72B-Instruct"Option 2: OpenAI (Paid)
export API_KEY="sk-..." # Your OpenAI API key
export API_BASE_URL="https://api.openai.com/v1"
export MODEL_NAME="gpt-3.5-turbo"Option 3: Legacy Support
export OPENAI_API_KEY="sk-..." # For backward compatibilityThen run baseline:
python inference.py๐ API Endpoints
1. Health Check
GET /healthResponse:
{
"status": "ok",
"env": "invoice-dispute-env"
}2. Reset Episode
POST /reset
Content-Type: application/json
{
"difficulty": "easy" // or "medium", "hard"
}Response: DisputeObservation object
3. Submit Decision
POST /step
Content-Type: application/json
{
"decision": "approve_full",
"response_text": "Your refund has been approved.",
"refund_amount": null
}Decision options:
full_refund- Approve 100% refundpartial_refund- Approve partial refund (requiresrefund_amount)reject- Deny disputeescalate- Escalate to humanrequest_info- Request more information
4. Get Current State
GET /stateResponse: DisputeState object with:
- Invoice details
- Customer information
- Dispute details
- Company policy
- Customer history
๐ฏ Difficulty Levels
๐๏ธ Project Structure
.
โโโ server/
โ โโโ app.py # FastAPI application
โ โโโ environment.py # Dispute environment logic
โ โโโ models.py # Pydantic models
โ โโโ __init__.py
โ โโโ requirements.txt # Python dependencies
โโโ inference.py # Baseline evaluation script
โโโ models.py # Shared models
โโโ openenv.yaml # OpenEnv configuration
โโโ Dockerfile # Docker configuration
โโโ README.md # This file
โโโ pyproject.toml๐ณ Docker Deployment
Build locally
docker build -t invoice-dispute:latest .Run locally
docker run -p 7860:7860 invoice-dispute:latestDeploy to Hugging Face Spaces
- Push to GitHub
- Create Space: https://huggingface.co/new-space
- Select Docker runtime
- Connect your GitHub repository
- Add secrets:
HF_TOKEN(optional)OPENAI_API_KEY(if using GPT)- Deploy!
๐ Running Baseline Evaluation
python inference.pyThis evaluates the environment baseline on all 3 difficulty levels:
- Easy: Expected ~0.80 reward
- Medium: Expected ~0.50 reward
- Hard: Expected ~0.30 reward
๐ง Testing Endpoints
Using curl
# Check health
curl http://localhost:7860/health
# Start episode (easy)
curl -X POST http://localhost:7860/reset \
-H "Content-Type: application/json" \
-d '{"difficulty": "easy"}'
# Get current state
curl http://localhost:7860/state
# Submit decision (full refund)
curl -X POST http://localhost:7860/step \
-H "Content-Type: application/json" \
-d '{
"decision": "full_refund",
"response_text": "Your refund has been approved.",
"refund_amount": null
}'Using Python
import requests
API_URL = "http://localhost:7860"
# Reset
response = requests.post(f"{API_URL}/reset", json={"difficulty": "medium"})
print(response.json())
# Get state
response = requests.get(f"{API_URL}/state")
print(response.json())
# Step
response = requests.post(f"{API_URL}/step", json={
"decision": "partial_refund",
"response_text": "Partial refund approved due to service delay.",
"refund_amount": 150.00
})
print(response.json())๐ Environment Variables
Optional configuration via .env:
HF_TOKEN=your_huggingface_token
OPENAI_API_KEY=your_openai_api_key
MODEL_NAME=meta-llama/Llama-2-7b-chat-hf๐ Data Types
DisputeObservation
Response from /step endpoint:
{
"reward": float, # Reward for this decision (-1 to 1)
"feedback": str, # Explanation of reward
"step_result": str, # What happened
"customer_reaction": str, # How customer reacted
"done": bool # Is episode finished?
}DisputeState
Response from /state endpoint:
{
"invoice_id": str,
"invoice_date": str,
"invoice_amount": float,
"dispute_type": str,
"customer_message": str,
"customer_tier": str, # standard, premium, enterprise
"line_items": list,
"customer_history": dict,
"policy": dict
}DisputeAction
Request to /step endpoint:
{
"decision": str, # one of the 5 decision types
"response_text": str, # Your message to customer
"refund_amount": float | null
}๐ ๏ธ Development
Creating virtual environment
python3 -m venv venv
source venv/bin/activate
pip install -r server/requirements.txtRunning tests
python -m pytestCode structure
server/app.py- FastAPI app with all endpointsserver/environment.py- Core environment logicserver/models.py- Pydantic data modelsinference.py- Example agent/baselinemodels.py- Shared type definitions
๐ Example Agent
See inference.py for a baseline agent that:
- Resets the environment
- Gets the current state
- Makes decisions based on simple rules
- Tracks rewards
You can modify this to test your own strategies!
๐ API Response Examples
Successful Reset
{
"invoice_id": "INV-2024-001",
"invoice_amount": 1500.00,
"customer_message": "I was charged twice for the same service...",
"dispute_type": "billing_error",
"reward": 0,
"feedback": "Episode started",
"step_result": "",
"customer_reaction": null,
"done": false
}Successful Step
{
"reward": 0.85,
"feedback": "Great decision! Customer was clearly overcharged and you recognized it quickly.",
"step_result": "Full refund of $1500.00 approved and processed.",
"customer_reaction": "Very satisfied! Thank you for resolving this quickly.",
"done": true
}๐จ Error Handling
All endpoints return proper HTTP status codes:
200- Success400- Bad request (invalid difficulty, missing fields, etc.)500- Server error
Error responses include a detail message:
{
"detail": "Difficulty must be: easy, medium, or hard"
}๐ Performance
- Average response time: 100-500ms per request
- Concurrent users: Tested with 1 user (stateful)
- Memory footprint: ~500MB (Python + models)
- Startup time: ~5 seconds
๐ค Contributing
- Fork the repository
- Create a feature branch
- Commit your changes
- Push to the branch
- Open a Pull Request
๐ License
MIT
๐ฅ Authors
OpenEV Hackathon Team
๐ Links
๐ฌ Support
For issues and questions, please create an issue on GitHub or reach out to the team.
Built with โค๏ธ for the OpenEV Hackathon
