CoolFace
Apppublic

RohanExploit/Meta-hackathon

sourceHugging Faceupdated 5mo agoView on Hugging Face
0likes
README.md420 linesDownload Raw Back to root
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[![Live on HF Spaces](https://img.shields.io/badge/πŸ€—-Live%20on%20Spaces-blue)](https://huggingface.co/spaces/RohanExploit/Meta-hackathon)18[![Python 3.10+](https://img.shields.io/badge/python-3.10%2B-blue)](https://www.python.org/)19[![OpenEnv Compliant](https://img.shields.io/badge/OpenEnv-compliant-green)]()20[![Tests](https://img.shields.io/badge/tests-6%2F6%20pass-brightgreen)]()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