# B2B Support Triage OpenEnv Benchmark - Complete Project Overview ## 1) What this project is This project is a complete OpenEnv simulation environment designed for **real-world B2B SaaS support triage**. Instead of a toy game, it models a workflow support engineers actually perform: - classify an incoming ticket - set urgency/priority - route to the correct team queue - define SLA expectation - (hard task) provide policy-compliant customer communication It exposes the standard OpenEnv contract: - `reset(...)` - `step(action)` - `state()` with typed Pydantic models and deterministic graders. --- ## 2) Why this environment is useful ### Practical utility This environment can evaluate agent quality on an enterprise operation where correctness, consistency, and policy compliance matter. ### Deterministic benchmarking All tasks are fixture-driven and deterministic, so model comparisons are reproducible. ### Multi-step reasoning Agents must make a sequence of structured decisions, not just one-shot classification. --- ## 3) High-level architecture ### Main components 1. **Environment runtime** - File: `server/support_triage_environment.py` - Implements environment state machine and reward shaping. 2. **Typed schemas** - File: `models.py` - Defines action, observation, state, and reward-breakdown models. 3. **Task fixtures** - File: `fixtures/tasks.json` - Defines easy/medium/hard scenarios, allowed values, answer keys, and policy hints. 4. **Grader logic** - File: `graders.py` - Computes normalized score in `[0,1]` using weighted criteria per task. 5. **OpenEnv API server wiring** - File: `server/app.py` - Binds environment + typed models into OpenEnv HTTP/WebSocket endpoints. 6. **Inference baseline** - File: `inference.py` - Runs all tasks using OpenAI client and emits required structured logs. 7. **Client adapter** - File: `client.py` - Converts typed Python actions/observations to/from wire payloads. --- ## 4) OpenEnv contract and endpoint behavior ### Manifest - File: `openenv.yaml` - Declares: - `name: b2b_support_triage_env` - `runtime: fastapi` - `app: server.app:app` - `port: 8000` ### Runtime endpoints - `POST /reset` - `POST /step` - `GET /state` - `GET /health` - `GET /schema` ### Environment lifecycle 1. `reset(task_id=..., seed=...)` - loads selected task fixture - clears previous episode state - returns initial observation with visible ticket + dynamic plan hints 2. `step(action)` - validates action semantics and allowed values - updates decision state - computes score delta and shaped reward - checks done conditions (`submit` or max steps) 3. `state()` - returns current internal state object (episode info, step count, cumulative reward, history) --- ## 5) Data model design (typed) ## 5.1 Action model File: `models.py` `B2BSupportTriageAction` fields: - `action_type`: enum - `classify` - `set_priority` - `route` - `draft_reply` - `submit` - `ticket_id`: required for non-`submit` - `payload`: action-specific content `payload` supports: - `category` - `priority` - `route_queue` - `sla_minutes` - `escalate` - `reply_text` ### Validation rules - non-submit requires `ticket_id` - required fields per action: - `classify -> category` - `set_priority -> priority` - `route -> route_queue + sla_minutes` - `draft_reply -> reply_text` - `submit -> none` This enforces structured behavior and prevents ambiguous free-text action control. ## 5.2 Observation model `B2BSupportTriageObservation` includes: - `task_id`, `step_index`, `max_steps` - `visible_ticket` - `current_plan` (next actions + policy hints) - `applied_decisions` - `last_action_error` - `progress_score` (grader score in `[0,1]`) - `reward_breakdown`: - `correctness_delta` - `policy_bonus` - `repeat_penalty` - `invalid_penalty` - `terminal_bonus` - inherited OpenEnv fields `reward`, `done`, `metadata` ## 5.3 State model `B2BSupportTriageState` tracks: - episode metadata (`episode_id`, `step_count`, `task_id`, `seed`) - `max_steps` - `cumulative_reward` - `applied_decisions` - `action_history` - `completion_flags` --- ## 6) Task system (easy -> medium -> hard) Defined in `fixtures/tasks.json`. ## 6.1 Easy Goal: - correct category + priority for one billing ticket Hidden answer key includes: - `category=billing` - `priority=medium` - plus routing defaults ## 6.2 Medium Goal: - category + priority + queue routing + SLA Hidden answer key includes: - `category=billing` - `priority=high` - `route_queue=billing-l2` - `sla_minutes=120` ## 6.3 Hard Goal: - security incident handling with escalation + compliant customer response Hidden answer key includes: - `category=security` - `priority=urgent` - `route_queue=security-incident-response` - `sla_minutes=120` - `escalate=true` - required reply phrases --- ## 7) Grading mechanics File: `graders.py` Each task has deterministic weighted scoring. ## 7.1 Easy weighting - category: 0.6 - priority: 0.4 ## 7.2 Medium weighting - category: 0.35 - priority: 0.25 - route_queue: 0.25 - sla_minutes: 0.15 ## 7.3 Hard weighting - category: 0.15 - priority: 0.15 - route_queue: 0.15 - sla_minutes: 0.10 - escalate: 0.20 - reply_policy phrase coverage: 0.25 The result is clamped and normalized to `[0,1]`. ### Determinism The grader is pure: - no network calls - no random operations - same input decisions always yield same score --- ## 8) Reward shaping logic File: `server/support_triage_environment.py` Reward is step-wise, dense enough for learning signals, and punishes bad behavior. ### Positive components - `correctness_delta`: only when progress score increases - `policy_bonus`: bonus for substantive policy-style draft replies - `terminal_bonus`: `0.2 * final_score` when episode ends ### Penalty components - `invalid_penalty`: invalid ticket/value/action - `repeat_penalty`: - repeated identical action - contradiction penalties (changing already-set value) - no-progress streak penalties ### Episode boundaries - done on `submit` - done on max step limit - steps after done receive penalty (`episode_already_done`) This discourages looping and rewards incremental correctness. --- ## 9) Inference baseline design File: `inference.py` ## 9.1 Runtime setup Reads: - `HF_TOKEN` (required) - `API_BASE_URL` (default set) - `MODEL_NAME` (default set) - `LOCAL_IMAGE_NAME` (default set) ## 9.2 Task execution - runs tasks in fixed order: easy, medium, hard - fixed seeds per task for reproducibility ## 9.3 Action selection strategy - requests JSON action from model (OpenAI client call) - validates/coerces action - falls back to deterministic policy if output invalid or misaligned This keeps baseline robust and reproducible while still exercising LLM calls. ## 9.4 Required stdout format Per task episode: - `[START] ...` - multiple `[STEP] ...` - `[END] ...` Then aggregate score summary line. --- ## 10) Deployment and packaging ## 10.1 Containerization - Dockerfile: `server/Dockerfile` - builds runnable image exposing uvicorn on port 8000 - includes healthcheck on `/health` ## 10.2 Python packaging - `pyproject.toml` defines project metadata and dependencies - installs environment package editable in image ## 10.3 OpenEnv compatibility - `openenv validate -v` passes - simulation API surface is compliant --- ## 11) Testing strategy Files under `tests/` verify behavior: - `test_environment.py` - reset clean state - invalid ticket penalty - hard task can reach full score - max-step termination behavior - `test_graders.py` - perfect answer gives 1.0 - weighted partial score check - deterministic hard-task reply scoring - `test_inference_logging.py` - `[START]/[STEP]/[END]` formatting checks This coverage ensures both task semantics and evaluation fidelity. --- ## 12) How to use the project locally ## 12.1 End-to-end helper ```bash ./run_all_checks.sh ``` Runs tests, validation, docker build/run smoke checks, and optional inference. ## 12.2 Inference helper (prompts for token if missing) ```bash ./run_inference.sh ``` ## 12.3 Manual core commands ```bash pytest -q openenv validate -v docker build -t b2b_support_triage_env-env:latest -f server/Dockerfile . docker run --rm -p 8000:8000 b2b_support_triage_env-env:latest ``` Detailed runbook: `local_setup.md`. --- ## 13) Usability summary for your hackathon goal What this project gives you: - clear real-world domain - structured and typed agent action space - deterministic multi-level tasks - strong reward shaping (partial progress + anti-loop penalties) - reproducible baseline script with required logs - Docker + OpenEnv validation support This aligns well with your round requirements and helps reduce submission-time surprises. --- ## 14) Current limitations and next improvements ### Current limitations - single-ticket episode scope (per task) rather than multi-ticket queue backlog - deterministic phrase matching for hard reply policy (simple lexical strategy) - baseline includes deterministic fallback policy (useful for reliability, less pure model-only behavior) ### Next upgrades (optional) - multi-ticket routing episodes with queue-level capacity constraints - richer policy engine with explicit rule graph and violation tags - adversarial or noisy customer phrasing variants per seed - benchmark report exporter with per-criterion analytics --- ## 15) Security and publication posture - fixtures are synthetic - no hardcoded credentials - token usage is environment-variable based only - suitable for external publication, assuming you do not commit local secret files (`.env`, shell history, etc.)