Mourya234/openenv-ticket-triage
OpenEnv: Support Ticket Triage Environment
Submission links
- GitHub repository: https://github.com/Mourya611/openEV_round1
- Hugging Face Space: https://hf.co/spaces/Mourya234/openenv-ticket-triage
- Hugging Face app URL: https://mourya234-openenv-ticket-triage.hf.space
This project implements a complete real-world OpenEnv-style environment where an agent learns to triage customer support tickets.
Why this environment
Support triage is a real operational workflow in SaaS teams. Agents must balance urgency, policy, customer context, and technical uncertainty. This environment captures that with deterministic scoring and progressive task difficulty.
Problem modeled
- Domain: customer support operations
- Goal: choose the right triage action for each ticket
- Realism:
- Different issue types (
billing,security,integration,compliance,bug) - Tier-aware urgency context
- Policy-sensitive escalations for security/compliance scenarios
OpenEnv interface
The environment exposes:
POST /reset-> starts a fresh episode (optionally by task name)POST /step-> applies one agent actionGET /state-> returns full internal stateGET /tasks-> lists task metadataGET /grade-> returns the current task score and grader breakdown
The environment core class is SupportTicketTriageEnv in envs/environment.py, with:
reset(task_name: Optional[str])step(action: TriageAction)state()grade(task_name: Optional[str])
Typed models are implemented via Pydantic in envs/models.py.
Action space
TriageAction fields:
ticket_id: strdecision: resolve | escalate | request_info | deferpriority: low | medium | high | urgentresponse_template: short | empathetic | technical | compliancenotes: str(required rationale text)
Observation space
ObservationModel includes:
task_nameobjectivecurrent_ticket(ornull)queue_remainingprocessed_countprogress(reported inside(0, 1)to avoid boundary-value validator issues)last_feedback- allowed decisions/priorities/templates
Reward design
Per-step reward is reported strictly inside (0, 1) and combines:
- Local action quality from deterministic rubric matching:
- decision correctness
- priority correctness
- response template correctness
- keyword coverage in notes
- Global trajectory progress bonus
Formula:
reward = 0.75 * action_quality + 0.25 * projected_progress, clamped into (0,1).
This provides dense, partial-progress signals and discourages random behavior.
Tasks and graders
Three deterministic tasks are included:
ticket-triage-easy(2 tickets)ticket-triage-medium(3 tickets)ticket-triage-hard(4 tickets)
Task definitions: envs/tasks.py Graders: envs/graders.py Episode final score: normalized deterministic grade reported strictly inside (0, 1).
Inference baseline (required)
The required root script inference.py:
- Uses OpenAI client for all LLM calls
- Falls back to a deterministic built-in policy if the OpenAI client or token is unavailable
- Reads the validator-required env vars
API_BASE_URL,MODEL_NAME, andHF_TOKEN - Emits structured stdout logs:
[START][STEP][END]- Uses validator-compatible
[END] success=... steps=... score=... rewards=...output - Formats scores and rewards to 2 decimal places and emits only validator-compatible line types
Environment variables
Create .env from .env.example:
API_BASE_URL=https://api.openai.com/v1
MODEL_NAME=gpt-5-mini
HF_TOKEN=your_hf_token
ENV_BASE_URL=http://localhost:7860API_BASE_URL and MODEL_NAME include defaults in inference.py. If HF_TOKEN is not set, the script falls back to the deterministic local policy so the validator can still execute the run.
Local run
pip install -r requirements.txt
uvicorn app:app --host 0.0.0.0 --port 7860In another terminal:
python inference.pyDocker
docker build -t openenv-ticket-triage .
docker run --rm -p 7860:7860 openenv-ticket-triageQuick precheck
After starting the app:
powershell -ExecutionPolicy Bypass -File .\scripts\precheck.ps1Hugging Face Spaces deployment
- Push this repository to GitHub.
- Create a Docker Space on Hugging Face.
- Connect the repo.
- Add secrets in Space settings:
API_BASE_URL(optional if you want to override the default)MODEL_NAMEHF_TOKENENV_BASE_URL(if your Space serves the env on a non-default URL)- Ensure Space responds on
/health,/reset,/step,/state,/tasks, and/grade.
Project structure
.
├── app.py
├── inference.py
├── openenv.yaml
├── Dockerfile
├── requirements.txt
├── .env.example
├── envs
│ ├── __init__.py
│ ├── models.py
│ ├── tasks.py
│ ├── graders.py
│ └── environment.py
└── scripts
└── precheck.ps1