optichain-env / README.md
Padmanava's picture
Update README.md
b980505 verified
|
Raw
History Blame Contribute Delete
8.58 kB
metadata
title: Optichain-Inventory-V1 Environment Server
emoji: πŸ”Š
colorFrom: blue
colorTo: indigo
sdk: docker
pinned: false
app_port: 7860
tags:
  - openenv

OptiChain-Env: AI-Native Supply Chain Optimization

A Meta OpenEnv Hackathon Submission (2026)

FastAPI OpenEnv License: MIT

OptiChain-Env is a high-fidelity inventory management environment built strictly to the Meta OpenEnv specification. It challenges AI agents to act as Supply Chain Managers, navigating varying demand signals, shipping disruptions, and strict liquidity constraints over a 30-day simulation.

Unlike standard CLI-only environments, OptiChain ships with a live dashboard that visualises the agent's reasoning, JSON action schema, and per-step newsvendor rewards in real-time.


Environment Description

OptiChain simulates a single-SKU retailer running a 30-day episode. Each day the agent observes current stock, cash, shipment pipeline, and yesterday's sales, then decides how many units to order and whether to expedite shipping. Orders are deducted from cash immediately; inventory arrives after the lead time. At end-of-day, stochastic customer demand is served from on-hand stock β€” any unmet demand is lost (stockout) and any leftover stock incurs holding cost.

Core mechanics:

  • Episode length: 30 days (fixed)
  • Product: SKU-LAPTOP β€” order cost $800, margin $400/unit, holding cost $2/unit/day, stockout penalty $100/unit
  • Lead times: Standard 2 days (4 days under crisis), Expedited 1 day ($100 surcharge/unit)
  • Demand: Stochastic Poisson-like variation around task-specific base demand
  • Cash constraint: Orders exceeding available cash are partially or fully rejected β€” the observation reports accepted/rejected quantities so the agent can react

Reward β€” Newsvendor Inspired

Each step returns a bounded [0, 1] reward based on the classic newsvendor overage/underage tradeoff:

Scenario Formula Rewards
Overage (stockout == 0) 1 - (remaining / stock_before) Efficient sell-through
Underage (stockout > 0) 1 - (missed / demand) High service level
  • step_reward: [0, 1] β€” newsvendor score for the day
  • total_reward: cumulative sum of all step rewards (max 30)
  • grader_score: total_reward / max_days β€” normalised to [0, 1], this is the official hackathon score

The success threshold is grader_score >= 0.1.


Action Space

class PurchaseOrder(BaseModel):
    product_id: str                 # e.g. "SKU-LAPTOP"
    quantity: int                   # >= 0
    expedite_shipping: bool         # True = 1-day, False = standard

class SupplyChainAction(Action):
    orders: List[PurchaseOrder]     # empty list = do nothing

Example action (order 15 units, standard shipping):

{ "orders": [ { "product_id": "SKU-LAPTOP", "quantity": 15, "expedite_shipping": false } ] }

Observation Space

class ProductStatus(BaseModel):
    product_id: str
    current_stock: int                      # on-hand inventory
    incoming_shipments: Dict[int, int]      # {days_until_arrival: qty}
    sales_yesterday: int
    lost_sales_yesterday: int
    holding_cost_per_unit: float
    stockout_penalty_per_unit: float
    margin_per_unit: float

class SupplyChainObservation(Observation):
    current_day: int                        # 1..30
    total_days: int                         # always 30
    cash_balance: float
    warehouse_status: List[ProductStatus]
    market_trend_signal: str                # task-specific forecast hint
    last_order_accepted: int                # units accepted last step
    last_order_rejected: int                # units rejected (insufficient cash)
    reward: float                           # last step_reward
    done: bool

Task Curriculum

Task ID Name Starting Cash Initial Stock Challenge
task_01_easy Stable Demand $30,000 50 Constant ~10 units/day demand. Baseline reasoning test.
task_02_medium Holiday Spike $50,000 20 Black Friday spike (10 β†’ 40 units/day) on Day 10. Requires pre-loading.
task_03_hard Supply Crisis $30,000 30 Standard lead time jumps from 2 to 4 days. Expedited option costs $100/unit extra.

OpenEnv Endpoints

The environment exposes the full OpenEnv HTTP API:

Method Path Purpose
POST /reset Start a new episode. Body: { "task_id": "...", "seed": 42 }
POST /step Submit a SupplyChainAction. Returns observation, reward breakdown, done flag, info
GET /state Current episode metadata without side effects
GET /grader Normalised episode score [0, 1]
GET /health Liveness probe for Hugging Face Spaces
GET /tasks List all available tasks and action schema
GET /schema JSON schemas for Action / Observation / Reward / State
GET / Live dashboard UI
POST /demo/step_sim Dashboard bridge: run LLM agent β†’ step env β†’ return both

Project Structure

OptiChain-Env/
β”œβ”€β”€ env/
β”‚   β”œβ”€β”€ core.py              # Simulation engine (inherits openenv Environment)
β”‚   └── schemas.py           # Pydantic Action/Observation/Reward/State models
β”œβ”€β”€ server/
β”‚   └── app.py               # FastAPI server β€” canonical OpenEnv entry point
β”œβ”€β”€ static/
β”‚   └── index.html           # Real-time dashboard UI
β”œβ”€β”€ app/
β”‚   └── main.py              # Legacy re-export shim (server.app:app)
β”œβ”€β”€ inference.py             # Multi-agent LLM baseline (Analyst + Executor + guardrails)
β”œβ”€β”€ openenv.yaml             # OpenEnv spec (spec_version: 1)
β”œβ”€β”€ pyproject.toml           # Build config + dependencies
β”œβ”€β”€ requirements.txt         # pip install target
β”œβ”€β”€ Dockerfile               # HF Spaces deployment image
└── .env.example             # LLM API config template

Setup Instructions

1. Clone and install

git clone https://github.com/YOUR_USERNAME/OptiChain-Env.git
cd OptiChain-Env
python -m venv .venv
source .venv/bin/activate        # Windows: .venv\Scripts\activate
pip install -r requirements.txt

Python 3.11+ is required.

2. Validate the OpenEnv spec

openenv validate .

Expected output: [OK] : Ready for multi-mode deployment.

3. Run the server locally

uvicorn server.app:app --host 0.0.0.0 --port 7860 --reload

4. (Optional) Configure the LLM baseline

The bundled multi-agent baseline in inference.py is OpenAI-compatible. Copy .env.example to .env and set:

API_BASE_URL=https://api.groq.com/openai/v1     # or http://localhost:11434/v1 for Ollama
API_KEY=your_key_here
MODEL_NAME=llama-3.3-70b-versatile               # or llama3.2:3b for Ollama

Run the baseline end-to-end:

python inference.py

Structured logs ([START], [STEP], [END]) are emitted to stdout.

5. Deploy to Hugging Face Spaces

openenv push --repo-id YOUR_USERNAME/optichain-env

Then add API_BASE_URL, API_KEY, and MODEL_NAME as Space Secrets (Settings β†’ Repository secrets).


Multi-Agent Baseline

inference.py implements a Planner β†’ Executor β†’ Guardrails pipeline to keep small/local LLMs reliable:

  1. Analyst agent β€” free-form reasoning over observation + order feedback loop
  2. Executor agent β€” converts Analyst reasoning to strict SupplyChainAction JSON
  3. Python guardrails β€” clip orders to min(affordable_qty, demand_based_useful_qty) and gate by lead time near episode end

This pattern defeats three failure modes common in small-LLM supply-chain agents:

  • Ghost orders β€” silently-rejected orders the LLM believes succeeded
  • Logic-tag dissonance β€” reasoning says "order 10" but JSON outputs quantity: 51
  • Overstocking β€” hoarding cash and inventory far beyond demand horizon

License

MIT β€” see LICENSE.