Akshaya0810/invoice-processing-env
InvoiceProcessingEnv ๐งพ
OpenEnv benchmark for Accounts Payable Automation โ the first open environment that mirrors the full SAP Ariba / Coupa AP clerk workflow: extract โ match โ verify โ approve/flag/reject.
  
๐ฏ Motivation
Every company's finance team processes hundreds of invoices daily. Real-world AP automation platforms (SAP Ariba, Coupa, Oracle Fusion) handle exactly this workflow โ yet no existing OpenEnv environment touches document-to-payment pipelines.
InvoiceProcessingEnv fills that gap:
๐๏ธ Architecture
Agent (inference.py)
โ OpenAI API (JSON actions)
โผ
FastAPI Server POST /reset POST /step GET /state GET /health
โ
โผ
InvoiceProcessingEnv (app/env.py)
โโโ State machine per invoice (PENDING โ โฆ โ APPROVED/REJECTED/FLAGGED)
โโโ 6 automatic fraud detectors
โโโ RewardCalculator (app/reward.py)
โโโ Deterministic graders (app/graders/)๐ Observation Space
Every call to /step returns a structured Observation:
โก Action Space
Seven typed actions with an optional JSON payload:
Valid flag reasons: TAX_RATE_MISMATCH ยท DUPLICATE_INVOICE ยท OVER_INVOICING ยท UNREGISTERED_VENDOR ยท CURRENCY_MISMATCH ยท EXCEEDS_PO_AMOUNT ยท MISSING_PO_REFERENCE
Sequence enforcement: The environment validates action order. Attempting APPROVE_PAYMENT on a PENDING invoice returns a โ0.05 penalty and an error in last_action_error.
๐ Tasks
๐ข Easy (max 10 steps)
Single clean invoice (INV-EASY-001) from registered vendor Acme Supplies Ltd. Correct 18% GST on HSN 2710. Matching PO within budget. Perfect score = 1.0 if all key fields extracted and payment approved with zero flags.
๐ก Medium (max 20 steps)
Three invoices designed to test anomaly detection:
Grader: Extraction 40% ยท Correct decisions 40% ยท No false positives 20%
๐ด Hard (max 40 steps)
Eight-invoice batch with intentional fraud and FX edge cases:
Grader: 0.125 per correct decision ยท โ0.30 missed fraud ยท โ0.10 false positive ยท +0.15 bonus if under 30 steps
๐ฐ Reward Function
Dense signal every step โ agents get feedback on every action, not just at episode end.
Final score = grader_score from /state (independent of cumulative reward). Always in (0, 1).
๐ Setup & Usage
Local (no Docker)
cd invoice-processing-env
pip install -r requirements.txt
uvicorn app.main:app --host 0.0.0.0 --port 7860Docker
docker build -t invoice-processing-env .
docker run -p 7860:7860 invoice-processing-envRun inference
Note: The inference script connects to a running environment server. Start the server first (in a separate terminal), then run inference.
# Terminal 1 โ start the environment server
uvicorn app.main:app --host 0.0.0.0 --port 7860# Terminal 2 โ run the inference agent
export HF_TOKEN=hf_xxxx
export MODEL_NAME=Qwen/Qwen2.5-72B-Instruct
export TASK_NAME=easy # easy | medium | hard
export ENV_BASE_URL=http://localhost:7860
python inference.pyRun all three tasks:
RUN_ALL_TASKS=true python inference.pyRun tests
pip install pytest
python -m pytest tests/ -v๐ก API Reference
`/reset` accepts empty body `{}` โ defaults to easy, satisfying the OpenEnv validator ping.
๐ Baseline Scores (Qwen2.5-72B Zero-shot)
๐๏ธ Repository Structure
invoice-processing-env/
โโโ openenv.yaml # OpenEnv spec
โโโ Dockerfile # HF Space container (port 7860)
โโโ requirements.txt
โโโ inference.py # Mandatory inference script
โโโ README.md
โโโ app/
โ โโโ main.py # FastAPI app
โ โโโ env.py # Core state machine
โ โโโ models.py # Pydantic models
โ โโโ actions.py # Action enum + sequence rules
โ โโโ reward.py # Reward calculator
โ โโโ graders/
โ โ โโโ __init__.py # Grader dispatcher
โ โ โโโ easy_grader.py
โ โ โโโ medium_grader.py
โ โ โโโ hard_grader.py
โ โโโ data/
โ โโโ vendors.json # Vendor master (5 registered, V_FAKE absent)
โ โโโ currency_rates.json
โ โโโ invoices/
โ โโโ easy_task.json
โ โโโ medium_task.json
โ โโโ hard_task.json
โโโ tests/
โโโ test_env.py # 15 pytest teststitle: Invoice Processing Env emoji: ๐ฅ colorFrom: purple colorTo: purple sdk: docker pinned: false license: mit ---
Check out the configuration reference at https://huggingface.co/docs/hub/spaces-config-reference
