SwapnilPatil28 commited on
Commit
1d7c05f
·
verified ·
1 Parent(s): e6e6d19

Upload folder using huggingface_hub

Browse files
Files changed (4) hide show
  1. inference.py +20 -42
  2. models.py +9 -7
  3. server/app.py +0 -1
  4. server/environment.py +27 -37
inference.py CHANGED
@@ -1,55 +1,33 @@
1
  import os
2
- import sys
3
  from openai import OpenAI
4
  from client import SupportEnvClient, SupportAction
5
 
6
- # Hackathon defined variables
7
  API_BASE_URL = os.getenv("API_BASE_URL", "https://router.huggingface.co/v1")
8
  MODEL_NAME = os.getenv("MODEL_NAME", "Qwen/Qwen2.5-72B-Instruct")
9
- API_KEY = os.getenv("HF_TOKEN") or os.getenv("API_KEY")
10
- BENCHMARK = "support_env"
11
 
12
  client = OpenAI(base_url=API_BASE_URL, api_key=API_KEY)
13
 
14
  def run_task(task_name: str):
15
- env_url = os.getenv("ENV_URL", "https://swapnilpatil28-support-env.hf.space")
16
- env = SupportEnvClient(base_url=env_url).sync()
 
17
 
18
- try:
19
- result = env.reset(task_name=task_name)
20
- print(f"[START] task={task_name} env={BENCHMARK} model={MODEL_NAME}", flush=True)
21
-
22
- step = 1
23
- rewards = []
24
-
25
- while not result.done:
26
- prompt = f"Ticket: '{result.observation.ticket_text}'. Reply ONLY with one word: Billing, Tech, or Sales."
27
- try:
28
- completion = client.chat.completions.create(
29
- model=MODEL_NAME,
30
- messages=[{"role": "user", "content": prompt}],
31
- max_tokens=10
32
- )
33
- action_str = completion.choices[0].message.content.strip().replace('.', '')
34
- except Exception as e:
35
- action_str = "Tech" # Fallback
36
-
37
- result = env.step(SupportAction(department=action_str))
38
- reward_val = float(result.reward or 0.0)
39
- rewards.append(reward_val)
40
-
41
- print(f"[STEP] step={step} action={action_str} reward={reward_val:.2f} done={str(result.done).lower()} error=null", flush=True)
42
- step += 1
43
- if step > 10: break # Safety break
44
-
45
- score = sum(rewards)
46
- success = "true" if score >= 0.99 else "false"
47
- rewards_str = ",".join([f"{r:.2f}" for r in rewards])
48
-
49
- print(f"[END] success={success} steps={step-1} score={score:.2f} rewards={rewards_str}", flush=True)
50
- finally:
51
- env.close()
52
 
53
  if __name__ == "__main__":
54
- for task in ["easy", "medium", "hard"]:
55
- run_task(task)
 
1
  import os
 
2
  from openai import OpenAI
3
  from client import SupportEnvClient, SupportAction
4
 
 
5
  API_BASE_URL = os.getenv("API_BASE_URL", "https://router.huggingface.co/v1")
6
  MODEL_NAME = os.getenv("MODEL_NAME", "Qwen/Qwen2.5-72B-Instruct")
7
+ API_KEY = os.getenv("HF_TOKEN") or os.getenv("OPENAI_API_KEY")
8
+ ENV_URL = os.getenv("ENV_URL", "https://swapnilpatil28-support-env.hf.space")
9
 
10
  client = OpenAI(base_url=API_BASE_URL, api_key=API_KEY)
11
 
12
  def run_task(task_name: str):
13
+ env = SupportEnvClient(base_url=ENV_URL).sync()
14
+ obs = env.reset(task_name=task_name)
15
+ print(f"[START] task={task_name} env=support_env model={MODEL_NAME}", flush=True)
16
 
17
+ step, rewards = 1, []
18
+ while not obs.done:
19
+ prompt = f"Ticket: {obs.observation.content}. Details: {obs.observation.search_result or 'None'}. Output one word: Billing, Tech, or Sales."
20
+ completion = client.chat.completions.create(model=MODEL_NAME, messages=[{"role": "user", "content": prompt}], max_tokens=10)
21
+ dept = completion.choices[0].message.content.strip().strip('.')
22
+
23
+ res = env.step(SupportAction(action_type="route", department=dept))
24
+ r = float(res.reward or 0.0)
25
+ rewards.append(r)
26
+ print(f"[STEP] step={step} action={dept} reward={r:.2f} done={str(res.done).lower()} error=null", flush=True)
27
+ obs, step = res, step + 1
28
+
29
+ print(f"[END] success={str(sum(rewards)>0).lower()} steps={step-1} score={sum(rewards)/len(rewards):.2f} rewards={','.join([f'{r:.2f}' for r in rewards])}", flush=True)
30
+ env.close()
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
31
 
32
  if __name__ == "__main__":
33
+ for task in ["easy", "medium", "hard"]: run_task(task)
 
models.py CHANGED
@@ -1,15 +1,17 @@
1
- from typing import List, Optional, Dict
2
  from openenv.core.env_server import Action, Observation, State
 
3
 
4
  class SupportAction(Action):
5
- department: str
 
6
 
7
  class SupportObservation(Observation):
8
  ticket_id: str
9
- ticket_text: str
10
- message: str
 
11
 
12
  class SupportState(State):
13
- task_name: str = "easy"
14
- total_tickets: int = 1
15
- tickets_routed: int = 0
 
1
+ from typing import List, Optional, Literal
2
  from openenv.core.env_server import Action, Observation, State
3
+ from pydantic import Field
4
 
5
  class SupportAction(Action):
6
+ action_type: Literal["search", "route"] = Field(..., description="Action to take")
7
+ department: Optional[str] = Field(None, description="Required for route action")
8
 
9
  class SupportObservation(Observation):
10
  ticket_id: str
11
+ content: str
12
+ search_result: Optional[str] = None
13
+ available_departments: List[str] = ["Billing", "Tech", "Sales"]
14
 
15
  class SupportState(State):
16
+ task_id: str = "easy"
17
+ current_ticket_index: int = 0
 
server/app.py CHANGED
@@ -3,7 +3,6 @@ from models import SupportAction, SupportObservation
3
  from server.environment import SupportEnvironment
4
  import uvicorn
5
 
6
- # OpenEnv factory: Pass the CLASS
7
  app = create_fastapi_app(SupportEnvironment, SupportAction, SupportObservation)
8
 
9
  def main():
 
3
  from server.environment import SupportEnvironment
4
  import uvicorn
5
 
 
6
  app = create_fastapi_app(SupportEnvironment, SupportAction, SupportObservation)
7
 
8
  def main():
server/environment.py CHANGED
@@ -1,56 +1,46 @@
1
  import uuid
2
  from typing import List, Dict
3
- from openenv.core.env_server import Observation, Environment
4
  from models import SupportAction, SupportObservation, SupportState
5
 
6
  class SupportEnvironment(Environment):
7
  def __init__(self):
8
  super().__init__()
9
- self._state = SupportState()
10
- self._current_queue: List[Dict[str, str]] = []
11
- self._current_ticket = None
 
 
12
  self.tasks = {
13
- "easy": [{"id": "T1", "text": "Can I get a refund for my last invoice?", "dept": "Billing"}],
14
- "medium": [{"id": "T2", "text": "My screen is flickering.", "dept": "Tech"},
15
- {"id": "T3", "text": "I want to upgrade.", "dept": "Sales"}],
16
- "hard": [{"id": "T4", "text": "Update credit card?", "dept": "Billing"},
17
- {"id": "T5", "text": "Enterprise discount?", "dept": "Sales"},
18
- {"id": "T6", "text": "API 500 error on POST.", "dept": "Tech"}]
19
  }
20
 
21
  def reset(self, task_name: str = "easy") -> SupportObservation:
22
- if task_name not in self.tasks:
23
- task_name = "easy"
24
- self._current_queue = self.tasks[task_name].copy()
25
- self._state = SupportState(
26
- episode_id=str(uuid.uuid4()), step_count=0, task_name=task_name,
27
- total_tickets=len(self._current_queue), tickets_routed=0
28
- )
29
- self._current_ticket = self._current_queue.pop(0)
30
- return SupportObservation(
31
- done=False, reward=0.0, ticket_id=self._current_ticket["id"],
32
- ticket_text=self._current_ticket["text"], message="New ticket arrived."
33
- )
34
 
35
  def step(self, action: SupportAction) -> SupportObservation:
36
  self._state.step_count += 1
37
- is_correct = action.department.strip().lower() == self._current_ticket["dept"].lower()
38
 
39
- # Normalized reward: 1.0 / total_tickets for each correct step
40
- reward = (1.0 / self._state.total_tickets) if is_correct else 0.0
41
- self._state.tickets_routed += 1
42
 
43
- if len(self._current_queue) > 0:
44
- self._current_ticket = self._current_queue.pop(0)
45
- return SupportObservation(
46
- done=False, reward=reward, ticket_id=self._current_ticket["id"],
47
- ticket_text=self._current_ticket["text"], message=f"Routed. Correct: {is_correct}"
48
- )
49
- else:
50
- return SupportObservation(
51
- done=True, reward=reward, ticket_id="None",
52
- ticket_text="Queue is empty.", message="All tickets processed."
53
- )
54
 
55
  @property
56
  def state(self) -> SupportState:
 
1
  import uuid
2
  from typing import List, Dict
3
+ from openenv.core.env_server import Environment
4
  from models import SupportAction, SupportObservation, SupportState
5
 
6
  class SupportEnvironment(Environment):
7
  def __init__(self):
8
  super().__init__()
9
+ self._db = {
10
+ "T1": "Customer History: Frequent refunder. Status: Valid invoice.",
11
+ "T4": "System Log: Payment gateway timed out. Card ending in 4242.",
12
+ "T6": "Dev Log: 500 error on /api/auth. Cluster: us-east-1."
13
+ }
14
  self.tasks = {
15
+ "easy": [{"id": "T1", "text": "Refund status?", "dept": "Billing"}],
16
+ "medium": [{"id": "T2", "text": "Upgrade account?", "dept": "Sales"},
17
+ {"id": "T3", "text": "App keeps crashing.", "dept": "Tech"}],
18
+ "hard": [{"id": "T4", "text": "Payment failed!", "dept": "Billing"},
19
+ {"id": "T5", "text": "Bulk pricing?", "dept": "Sales"},
20
+ {"id": "T6", "text": "API Auth failure.", "dept": "Tech"}]
21
  }
22
 
23
  def reset(self, task_name: str = "easy") -> SupportObservation:
24
+ self.current_task = self.tasks.get(task_name, self.tasks["easy"])
25
+ self._state = SupportState(episode_id=str(uuid.uuid4()), task_id=task_name)
26
+ t = self.current_task[0]
27
+ return SupportObservation(done=False, reward=0.0, ticket_id=t["id"], content=t["text"])
 
 
 
 
 
 
 
 
28
 
29
  def step(self, action: SupportAction) -> SupportObservation:
30
  self._state.step_count += 1
31
+ ticket = self.current_task[self._state.current_ticket_index]
32
 
33
+ if action.action_type == "search":
34
+ return SupportObservation(done=False, reward=-0.05, ticket_id=ticket["id"], content=ticket["text"], search_result=self._db.get(ticket["id"], "No record."))
 
35
 
36
+ correct = action.department.strip().lower() == ticket["dept"].lower()
37
+ reward = 1.0 if correct else 0.0
38
+ self._state.current_ticket_index += 1
39
+
40
+ if self._state.current_ticket_index < len(self.current_task):
41
+ t = self.current_task[self._state.current_ticket_index]
42
+ return SupportObservation(done=False, reward=reward, ticket_id=t["id"], content=t["text"])
43
+ return SupportObservation(done=True, reward=reward, ticket_id="EOF", content="Done.")
 
 
 
44
 
45
  @property
46
  def state(self) -> SupportState: