Files changed (2) hide show
  1. customer_support_environment.py +21 -1
  2. tasks.py +9 -5
customer_support_environment.py CHANGED
@@ -5,11 +5,12 @@ from typing import Any, Optional
5
  from uuid import uuid4
6
 
7
  from openenv.core.env_server.interfaces import Environment
 
8
 
9
  from data_loader import build_expected, load_dataset, split_difficulty
10
  from kb import build_knowledge_base
11
  from models import SupportAction, SupportObservation, SupportState
12
- from tasks import grade_task, task_for_difficulty
13
 
14
 
15
  class CustomerSupportEnvironment(Environment[SupportAction, SupportObservation, SupportState]):
@@ -167,6 +168,23 @@ class CustomerSupportEnvironment(Environment[SupportAction, SupportObservation,
167
  def state(self) -> SupportState:
168
  return self._state
169
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
170
  def _make_observation(self, reward: float, done: bool, feedback: str) -> SupportObservation:
171
  if self._expected is None:
172
  raise RuntimeError("Environment is not initialized")
@@ -182,6 +200,8 @@ class CustomerSupportEnvironment(Environment[SupportAction, SupportObservation,
182
  reward=reward,
183
  feedback=feedback,
184
  metadata={
 
 
185
  "expected_category": self._expected["expected_category"],
186
  "expected_action": self._expected["expected_action"],
187
  "expected_response": self._expected["expected_response"],
 
5
  from uuid import uuid4
6
 
7
  from openenv.core.env_server.interfaces import Environment
8
+ from openenv.core.env_server.types import EnvironmentMetadata
9
 
10
  from data_loader import build_expected, load_dataset, split_difficulty
11
  from kb import build_knowledge_base
12
  from models import SupportAction, SupportObservation, SupportState
13
+ from tasks import TASKS_WITH_GRADERS, grade_task, task_for_difficulty
14
 
15
 
16
  class CustomerSupportEnvironment(Environment[SupportAction, SupportObservation, SupportState]):
 
168
  def state(self) -> SupportState:
169
  return self._state
170
 
171
+ def get_metadata(self) -> EnvironmentMetadata:
172
+ task_lines = "\n".join(
173
+ f"- {t['task_id']} | difficulty={t['difficulty']} | grader={t['grader']}"
174
+ for t in TASKS_WITH_GRADERS
175
+ )
176
+ readme = (
177
+ "Customer support benchmark with deterministic task graders.\n\n"
178
+ "Tasks with graders:\n"
179
+ f"{task_lines}\n"
180
+ )
181
+ return EnvironmentMetadata(
182
+ name="customer_support_benchmark",
183
+ description="Customer support simulation with 3 graded tasks.",
184
+ version="1.0.0",
185
+ readme_content=readme,
186
+ )
187
+
188
  def _make_observation(self, reward: float, done: bool, feedback: str) -> SupportObservation:
189
  if self._expected is None:
190
  raise RuntimeError("Environment is not initialized")
 
200
  reward=reward,
201
  feedback=feedback,
202
  metadata={
203
+ "tasks_with_graders": TASKS_WITH_GRADERS,
204
+ "grader": task_for_difficulty(self._expected["difficulty"]).grader_name,
205
  "expected_category": self._expected["expected_category"],
206
  "expected_action": self._expected["expected_action"],
207
  "expected_response": self._expected["expected_response"],
tasks.py CHANGED
@@ -13,7 +13,7 @@ class TaskSpec:
13
  grader_name: str
14
 
15
 
16
- TASKS: Dict[str, TaskSpec] = {
17
  "easy_classify_respond": TaskSpec(
18
  task_id="easy_classify_respond",
19
  difficulty="easy",
@@ -41,17 +41,21 @@ TASKS_WITH_GRADERS: List[dict] = [
41
  "difficulty": task.difficulty,
42
  "objective": task.objective,
43
  "grader": task.grader_name,
 
44
  }
45
- for task in TASKS.values()
46
  ]
47
 
 
 
 
48
 
49
  def task_for_difficulty(difficulty: str) -> TaskSpec:
50
  normalized = difficulty.strip().lower()
51
- for task in TASKS.values():
52
  if task.difficulty == normalized:
53
  return task
54
- return TASKS["easy_classify_respond"]
55
 
56
 
57
  def grade_easy(expected: dict, history: List[dict]) -> float:
@@ -91,7 +95,7 @@ GRADERS: Dict[str, Callable[[dict, List[dict]], float]] = {
91
 
92
 
93
  def grade_task(task_id: str, expected: dict, history: List[dict]) -> float:
94
- task = TASKS[task_id]
95
  grader = GRADERS[task.grader_name]
96
  return grader(expected, history)
97
 
 
13
  grader_name: str
14
 
15
 
16
+ TASK_MAP: Dict[str, TaskSpec] = {
17
  "easy_classify_respond": TaskSpec(
18
  task_id="easy_classify_respond",
19
  difficulty="easy",
 
41
  "difficulty": task.difficulty,
42
  "objective": task.objective,
43
  "grader": task.grader_name,
44
+ "grader_name": task.grader_name,
45
  }
46
+ for task in TASK_MAP.values()
47
  ]
48
 
49
+ # Additional compatibility export used by some validators.
50
+ TASKS: List[dict] = list(TASKS_WITH_GRADERS)
51
+
52
 
53
  def task_for_difficulty(difficulty: str) -> TaskSpec:
54
  normalized = difficulty.strip().lower()
55
+ for task in TASK_MAP.values():
56
  if task.difficulty == normalized:
57
  return task
58
+ return TASK_MAP["easy_classify_respond"]
59
 
60
 
61
  def grade_easy(expected: dict, history: List[dict]) -> float:
 
95
 
96
 
97
  def grade_task(task_id: str, expected: dict, history: List[dict]) -> float:
98
+ task = TASK_MAP[task_id]
99
  grader = GRADERS[task.grader_name]
100
  return grader(expected, history)
101