RohanExploit/Meta-hackathon
0
1---2title: Multi-Channel Retail Environment3emoji: πͺ4colorFrom: blue5colorTo: green6sdk: docker7app_port: 80008tags:9 - openenv10pinned: false11---12 13# πͺ Multi-Channel Retail Environment with Disruption Recovery14 15> **OpenEnv Scaler Hackathon Submission** β A production-grade, OpenEnv-compliant environment that challenges AI agents to manage a realistic multi-channel retail operation under supply chain disruptions, demand shocks, and stochastic supplier behavior.16 17[](https://huggingface.co/spaces/RohanExploit/Meta-hackathon)18[](https://www.python.org/)19[]()20[]()21 22---23 24## π― What Problem Does This Solve?25 26Retail operations managers face a daily challenge that no toy environment captures: **simultaneously optimizing pricing, inventory, and promotions across multiple customer segments while dealing with unpredictable supply chain disruptions.**27 28This environment faithfully simulates the real-world tradeoffs:29 30- A **demand collapse** hits your bestseller β do you slash prices or run a promotion? 31- Your supplier delivers only **80% of orders** β how much buffer stock do you carry? 32- Luxury customers will pay 2Γ but buy less β how do you **allocate limited inventory** between segments? 33- Holding costs eat into margins β when exactly should you reorder? 34 35These are genuine decisions that cost retailers billions annually. This is not a game.36 37---38 39## ποΈ Architecture40 41```42βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ43β FastAPI Server (server/app.py) β44β POST /reset Β· POST /step Β· GET /state Β· POST /evaluate β45β GET /tasks Β· GET /health Β· POST /live/start Β· /stop Β· ... β46βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ€47β Core Environment β48β environment/retail_env.py β MultiChannelRetailEnv β49β environment/models.py β Pydantic: Action, Obs, State β50β environment/grader.py β Deterministic scoring [0,1] β51β environment/tasks.py β 5 difficulty tiers β52βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ€53β Baseline Agent (inference.py) β54β OpenAI-compatible client β observe β reason β act loop β55βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ56```57 58---59 60## πΉοΈ Action Space61 62The agent selects **one action per step** from five typed Pydantic models:63 64| Action | JSON Schema | Purpose |65|--------|------------|---------|66| **Allocate** | `{"action": "allocate", "product": "str", "luxury_units": int, "budget_units": int}` | Assign inventory between luxury (high-margin) and budget (high-volume) segments |67| **Set Price** | `{"action": "set_price", "product": "str", "segment": "luxury\|budget", "new_price": float}` | Dynamic pricing within bounds β higher price reduces demand but increases margin |68| **Order** | `{"action": "order", "product": "str", "quantity": int}` | Purchase from supplier β cost deducted immediately, delivery has stochastic lead time |69| **Promote** | `{"action": "promote", "product": "str", "budget_allocated": float}` | Run a promotional campaign β upfront cash cost to stimulate demand |70| **NoOp** | `{"action": "noop"}` | Hold current strategy β wait and observe |71 72---73 74## ποΈ Observation Space75 76The agent receives a **partial observation** (true demand patterns are hidden):77 78```python79RetailObservation(80 day: int, # Current day [0, horizon)81 cash: float, # Available funds82 inventory: Dict[str, int], # Current stock by product83 recent_demand_luxury: Dict, # Rolling 3-day average of realized luxury demand84 recent_demand_budget: Dict, # Rolling 3-day average of realized budget demand85 recent_stockouts: Dict, # Per-product stockout count (steps with unmet demand)86 prices_luxury: Dict, # Current luxury prices87 prices_budget: Dict, # Current budget prices88 disruption_active: bool, # Is a disruption currently happening?89 disruption_severity: float, # Severity [0.0β1.0]90 market_confidence: float, # Decaying confidence indicator [0.0β1.0]91)92```93 94The agent must infer hidden demand patterns from noisy signals β this is a partially observable environment by design.95 96---97 98## π Tasks (5 Difficulty Tiers)99 100| Task | Horizon | Products | Supplier Reliability | Key Challenge | Baseline Profit |101|------|---------|----------|---------------------|---------------|-----------------|102| `easy` | 10 days | 1 | 100% | Stable demand, no disruptions | $50 |103| `medium_simple` | 14 days | 2 | 95% | Variable demand, occasional disruptions | $100 |104| `medium_challenge` | 14 days | 2 | 88% | Supply delays, demand elasticity shifts | $80 |105| `hard` | 21 days | 3 | 85% | Frequent disruptions, tight margins | $120 |106| `expert` | 30 days | 4 | 80% | Extreme chaos: multi-product, high variance | $200 |107 108Each task has a **fixed seed** for reproducible evaluation.109 110---111 112## π Grading System113 114The grader (`environment/grader.py`) is **deterministic, transparent, and stateless**. It computes a composite score in `[0.0, 1.0]`:115 116```117score = 0.5 Γ profit_score + 0.3 Γ fill_rate_score + 0.2 Γ efficiency_score118```119 120| Component | Formula | Weight | Rationale |121|-----------|---------|--------|-----------|122| **Profit Score** | `clamp(profit / baseline_profit, 0, 1)` | 50% | Primary business metric |123| **Fill Rate Score** | `clamp(total_sales / total_demand, 0, 1)` | 30% | Customer satisfaction proxy |124| **Efficiency Score** | `clamp(1 - holding_cost / max_possible_holding_cost, 0, 1)` | 20% | Capital efficiency |125 126### Anti-Gaming Guardrail127 128If `fill_rate < 0.6`, the final score is **halved**. This prevents agents from exploiting high-margin strategies that ignore customer demand.129 130### Multi-Seed Aggregation131 132The `/evaluate` endpoint supports multi-seed evaluation with optional variance penalty:133 134```135adjusted_score = mean_score - variance_penalty Γ variance(seed_scores)136```137 138---139 140## π Installation & Quick Start141 142### Prerequisites143- **Python 3.10+** (if running locally)144- **Docker** (optional, if running via containerized setup)145- **Hugging Face Token / API Key** (to run the baseline inference agent)146 147### Local Installation & Development148 149```bash150# Clone the repository151git clone https://github.com/RohanExploit/Meta-hackathon.git152cd Meta-hackathon153 154# Setup155python -m venv .venv156source .venv/bin/activate # Linux/Mac157# .venv\Scripts\activate # Windows158 159pip install --upgrade pip160pip install -e .161 162# Start the environment server163uvicorn server.app:app --host 0.0.0.0 --port 8000164```165 166### Run Baseline Inference167 168In a second terminal:169 170```bash171export API_BASE_URL=https://router.huggingface.co/v1172export MODEL_NAME=NousResearch/Nous-Hermes-2-Mistral-7B-DPO173export OPENAI_API_KEY=<your-hf-token>174 175python inference.py176```177 178### Docker179 180```bash181docker build -t retail-env .182 183docker run -p 8000:8000 \184 -e API_BASE_URL="https://router.huggingface.co/v1" \185 -e MODEL_NAME="NousResearch/Nous-Hermes-2-Mistral-7B-DPO" \186 -e OPENAI_API_KEY="<token>" \187 retail-env188```189 190### Hugging Face Spaces191 192This repository is deployed live at **[huggingface.co/spaces/RohanExploit/Meta-hackathon](https://huggingface.co/spaces/RohanExploit/Meta-hackathon)**. The Space auto-builds from the root `Dockerfile` and starts serving the API immediately.193 194---195 196## π‘ API Reference197 198All endpoints are served by FastAPI with automatic OpenAPI docs at `/docs`.199 200| Endpoint | Method | Description |201|----------|--------|-------------|202| `/health` | GET | Health check β `{"status": "healthy"}` |203| `/tasks` | GET | List all 5 tasks with metadata |204| `/reset` | POST | Reset environment to a task: `{"task_name": "easy", "seed": 42}` |205| `/step` | POST | Execute action: `{"action": {"action": "order", "product": "Product_A", "quantity": 5}}` |206| `/state` | GET | Full internal state + episode metrics (for debugging and scoring) |207| `/evaluate` | POST | Score an episode summary or batch of summaries |208| `/live/start` | POST | Start real-time continuous stepping (heuristic or noop mode) |209| `/live/stop` | POST | Stop real-time stepping |210| `/live/status` | GET | Real-time runner status |211| `/live/latest` | GET | Latest real-time tick observation |212| `/live/stream` | GET | **Server-Sent Events** stream of live runner ticks (real-time push, no polling needed) |213| `/dashboard` | GET | Modern visual dashboard UI (Chart.js charts, manual actions, live runner) |214| `/` | GET | Classic terminal-style UI |215 216### Example: Full Episode217 218```bash219# 1. Reset to easy task220curl -s -X POST http://localhost:8000/reset \221 -H "Content-Type: application/json" \222 -d '{"task_name": "easy", "seed": 42}'223 224# 2. Take an action225curl -s -X POST http://localhost:8000/step \226 -H "Content-Type: application/json" \227 -d '{"action": {"action": "order", "product": "Product_A", "quantity": 3}}'228 229# 3. Evaluate230curl -s -X POST http://localhost:8000/evaluate \231 -H "Content-Type: application/json" \232 -d '{"summary": {"profit": 80, "baseline_profit": 100, "total_demand": 100, "total_sales": 75}}'233```234 235---236 237## π§ͺ Testing & Validation238 239### Compliance Tests (6 tests)240 241```bash242python -m pytest tests/test_compliance.py -v243```244 245Validates: OpenEnv YAML contract, HF Spaces config, task count, API endpoints, grader bounds, anti-gaming behavior.246 247### Smoke Tests248 249```bash250python test_env.py # Environment lifecycle251python test_api.py # API simulation252```253 254### Health Check (all-in-one)255 256```bash257python scripts/health_check.py258```259 260Runs compile checks β test suite β smoke scripts β pre-submission checks.261 262### Pre-Submission Check263 264```bash265python scripts/pre_submission_check.py266```267 268Validates: task count β₯ 3, inference env vars, Docker availability, OpenEnv CLI.269 270### Reproducibility Benchmark271 272```bash273# Requires running server + API credentials274python scripts/benchmark_inference.py275```276 277Runs inference twice, compares scores for determinism.278 279### Verified Baseline Scores280 281Tested with `llama-3.1-8b-instant` via Groq (seed=42):282 283| Task | Score | Profit Score | Fill Rate | Efficiency | Final Cash |284|------|-------|-------------|-----------|------------|------------|285| easy | **0.43** | 0.00 | 1.00 | 0.67 | $57.60 |286| medium_simple | **0.95** | 1.00 | 1.00 | 0.77 | $437.18 |287| medium_challenge | **0.91** | 1.00 | 0.74 | 0.92 | $609.46 |288| hard | **0.42** | 1.00 | 0.47 | 0.95 | $917.84 |289| expert | **0.39** | 1.00 | 0.26 | 0.97 | $987.71 |290| **Mean** | **0.62** | | | | |291 292> The agent achieves 100% fill rate on easy/medium tasks. Harder tasks have lower fill rates due to multi-product inventory splitting across 3-4 products with a single action per step.293 294---295 296## π Repository Structure297 298```299Meta-hackathon/300βββ Dockerfile # Root-level Docker config (HF Spaces uses this)301βββ README.md # This file302βββ app.spaces.yaml # HF Spaces auto-config (sdk: docker, tag: openenv)303βββ openenv.yaml # OpenEnv environment metadata304βββ pyproject.toml # Dependencies + entry points305βββ uv.lock # Locked dependency versions306βββ inference.py # Baseline LLM agent (OpenAI-compatible)307β308βββ environment/ # Core environment package309β βββ __init__.py310β βββ models.py # Pydantic: RetailAction, RetailObservation, RetailState311β βββ retail_env.py # MultiChannelRetailEnv (reset, step, state)312β βββ grader.py # Deterministic scoring [0, 1]313β βββ tasks.py # 5 task definitions (easy β expert)314β315βββ pipeline/ # NVIDIA-inspired RAG pipeline (optional layer)316β βββ config.py # Centralized model registry + tuning knobs317β βββ safety.py # Llama Guard 3 input/output guardrails318β βββ router.py # NIM-style Router Agent (query classification)319β βββ retriever.py # Two-stage: FAISS dense retrieval + LLM reranking320β βββ chain.py # LCEL orchestrator (safetyβrouterβretrievalβgen)321β βββ ingest.py # SemanticChunker document ingestion322β323βββ server/ # FastAPI server package324β βββ __init__.py325β βββ app.py # 12 API endpoints + LiveRunner + SSE stream326β βββ ui/327β βββ index.html # Terminal-style web UI (/)328β βββ dashboard.html # Modern visual dashboard (/dashboard) β Chart.js charts, live runner329β βββ chart.umd.min.js # Bundled Chart.js (served at /static/chart.js)330β331βββ tests/332β βββ test_compliance.py # 6 compliance tests333β334βββ scripts/335β βββ health_check.py # All-in-one validation336β βββ pre_submission_check.py # Rubric-mapped checks337β βββ benchmark_inference.py # Reproducibility benchmark338β βββ run_tests.py # Isolated test runner339β340βββ test_env.py # Environment smoke test341βββ test_api.py # API smoke test342βββ .github/workflows/ci.yml # GitHub Actions CI343```344 345---346 347## π Key Design Decisions348 349### Why Multi-Segment Pricing?350Real retailers optimize per customer tier. Luxury customers accept premium prices with lower volume; budget customers demand high volume at thin margins. This creates a genuine tradeoff that doesn't exist in single-price environments.351 352### Why Disruptions?353Supply chain disruptions (demand collapses, supply delays, demand spikes) occur with ~15% probability per step. They test whether agents can **adapt and recover** β a capability critical in real-world retail operations.354 355### Why Transparent Grading?356The grader formula is fully documented and deterministic. Agents can learn that profit matters most (50% weight), customer satisfaction is essential (30%), and capital efficiency rounds out performance (20%). No hidden weights.357 358### Why Partial Observability?359Agents see demand signals, not true demand distributions. This mirrors reality: retailers observe sales data and stockout counts, not the underlying customer arrival process.360 361---362 363## π Expected Baseline Scores364 365| Task | Heuristic Agent | LLM Agent (7B) | Optimal Estimate |366|------|----------------|-----------------|------------------|367| easy | ~0.85 | ~0.90 | ~0.95 |368| medium_simple | ~0.55 | ~0.70 | ~0.85 |369| medium_challenge | ~0.45 | ~0.60 | ~0.80 |370| hard | ~0.30 | ~0.45 | ~0.70 |371| expert | ~0.20 | ~0.35 | ~0.60 |372 373---374 375## π Reproducibility376 377- All randomness is **seeded** (`np.random.seed`, `random.seed`) via task config378- Inference uses `temperature=0` for deterministic LLM output379- Each task has a **fixed grading seed** for reproducible evaluation380- Episode metrics are fully logged in the terminal step info381- Docker build is deterministic with pinned dependencies (`uv.lock`)382 383---384 385## βοΈ Environment Variables386 387| Variable | Required | Description |388|----------|----------|-------------|389| `API_BASE_URL` | For inference | LLM API endpoint (e.g., `https://router.huggingface.co/v1`) |390| `MODEL_NAME` | For inference | Model identifier (e.g., `NousResearch/Nous-Hermes-2-Mistral-7B-DPO`) |391| `OPENAI_API_KEY` | For inference | API key / HF token for authentication |392| `PORT` | Optional | Server port (default: `8000`) |393| `ENV_BASE_URL` | For inference | Environment server base URL (default: `http://127.0.0.1:8000`) |394 395---396 397## π Hackathon Checklist398 399| Requirement | Status | Evidence |400|-------------|--------|----------|401| Real-world task simulation | β
| Multi-channel retail with disruptions |402| Full OpenEnv spec (typed models, step/reset/state, openenv.yaml) | β
| Pydantic models + 10 API endpoints |403| Minimum 3 tasks (easy β hard, scores 0.0β1.0) | β
| 5 tasks with graded difficulty |404| Meaningful reward function with partial progress signals | β
| Per-step: revenue β stockout penalty β holding costs |405| Baseline inference script with reproducible scores | β
| `inference.py` with seeded episodes |406| Deploy to HF Spaces + working Dockerfile | β
| [Live Space](https://huggingface.co/spaces/RohanExploit/Meta-hackathon) |407| README with environment description, spaces, setup | β
| This document |408| Agent graders (scores 0.0β1.0) | β
| `environment/grader.py` β deterministic, bounded |409| CI/CD | β
| `.github/workflows/ci.yml` |410 411---412 413## π License414 415MIT416 417---418 419*Built for the Meta OpenEnv Scaler Hackathon 2026.*420 