Spaces:
Runtime error
Runtime error
| """Task source for the HR environment — bundled samples + optional API upgrade.""" | |
| from __future__ import annotations | |
| import logging | |
| import os | |
| import random | |
| from dataclasses import dataclass, field | |
| logger = logging.getLogger(__name__) | |
| COLLINEAR_PLATFORM_URL = "https://platform.collinear.ai" | |
| SCENARIO_MANAGER_API_URL = "https://rl-gym-api.collinear.ai" | |
| class Task: | |
| """A single HR task for the agent to complete.""" | |
| id: str | |
| instruction: str | |
| difficulty: str | |
| rubric: list[str] = field(default_factory=list) | |
| BUNDLED_TASKS: list[Task] = [ | |
| Task( | |
| id="hr-001", | |
| instruction=( | |
| "A new candidate, Priya Mehta, has applied for the Senior Software Engineer role. " | |
| "Create her employee record in the HRMS, schedule a phone screening for next " | |
| "Tuesday at 2 PM on the calendar, and send her a confirmation email at " | |
| "priya.mehta@gmail.com with the interview details." | |
| ), | |
| difficulty="medium", | |
| rubric=[ | |
| "Employee record created in HRMS for Priya Mehta", | |
| "Phone screening event scheduled on calendar for next Tuesday at 2 PM", | |
| "Confirmation email sent to priya.mehta@gmail.com with interview details", | |
| ], | |
| ), | |
| Task( | |
| id="hr-002", | |
| instruction=( | |
| "Employee James Wilson (EMP-0042) has requested 5 days of annual leave starting " | |
| "next Monday. Check his remaining leave balance in the HRMS, approve the request " | |
| "if he has sufficient days, and notify his manager Sarah Chen via Rocket.Chat." | |
| ), | |
| difficulty="easy", | |
| rubric=[ | |
| "Leave balance checked for employee EMP-0042", | |
| "Leave request approved or denied based on balance", | |
| "Manager Sarah Chen notified via RocketChat", | |
| ], | |
| ), | |
| Task( | |
| id="hr-003", | |
| instruction=( | |
| "Run a monthly attendance report: pull the attendance records for all employees " | |
| "from the HRMS for the current month, identify anyone with more than 2 absences, " | |
| "and send a summary email to hr-team@company.com with the findings." | |
| ), | |
| difficulty="medium", | |
| rubric=[ | |
| "Attendance records retrieved from HRMS", | |
| "Employees with >2 absences identified", | |
| "Summary email sent to hr-team@company.com", | |
| ], | |
| ), | |
| Task( | |
| id="hr-004", | |
| instruction=( | |
| "The recruiting team needs to schedule a panel interview for candidate Alex Rivera " | |
| "for the Product Manager position. Check the availability of three interviewers " | |
| "(Sarah Chen, Mike Johnson, Lisa Park) on the calendar for this week, find a " | |
| "1-hour slot that works for all three, book the meeting, and send calendar " | |
| "invites via email to all participants including the candidate at alex.rivera@email.com." | |
| ), | |
| difficulty="hard", | |
| rubric=[ | |
| "Availability checked for all three interviewers on the calendar", | |
| "Common 1-hour slot identified", | |
| "Meeting booked on the calendar", | |
| "Email invites sent to all participants including alex.rivera@email.com", | |
| ], | |
| ), | |
| Task( | |
| id="hr-005", | |
| instruction=( | |
| "Employee Maria Santos has been promoted from Junior Developer to Senior Developer. " | |
| "Update her designation and salary grade in the HRMS, send her a congratulatory " | |
| "email, and post an announcement in the #general channel on Rocket.Chat." | |
| ), | |
| difficulty="easy", | |
| rubric=[ | |
| "Designation updated in HRMS to Senior Developer", | |
| "Congratulatory email sent to Maria Santos", | |
| "Announcement posted in #general on RocketChat", | |
| ], | |
| ), | |
| Task( | |
| id="hr-006", | |
| instruction=( | |
| "A new employee, David Kim, is starting next Monday. Complete the onboarding " | |
| "checklist: create his employee record in the HRMS with department 'Engineering', " | |
| "send him a welcome email at david.kim@company.com with first-day instructions, " | |
| "schedule a 30-minute orientation meeting on his start date, and add him to the " | |
| "#engineering channel on Rocket.Chat." | |
| ), | |
| difficulty="hard", | |
| rubric=[ | |
| "Employee record created in HRMS with department Engineering", | |
| "Welcome email sent to david.kim@company.com", | |
| "Orientation meeting scheduled on calendar for start date", | |
| "Added to #engineering channel on RocketChat", | |
| ], | |
| ), | |
| Task( | |
| id="hr-007", | |
| instruction=( | |
| "Check how many open leave requests are pending approval in the HRMS. " | |
| "List them all and send a reminder email to the respective approving managers " | |
| "asking them to review the pending requests." | |
| ), | |
| difficulty="medium", | |
| rubric=[ | |
| "Pending leave requests retrieved from HRMS", | |
| "Approving managers identified for each request", | |
| "Reminder emails sent to respective managers", | |
| ], | |
| ), | |
| Task( | |
| id="hr-008", | |
| instruction=( | |
| "The quarterly performance review cycle is starting. Look up all employees " | |
| "in the Engineering department from the HRMS, schedule individual 45-minute " | |
| "review meetings with their manager for next week on the calendar, and " | |
| "send each employee an email notification about their scheduled review time." | |
| ), | |
| difficulty="hard", | |
| rubric=[ | |
| "Engineering department employees retrieved from HRMS", | |
| "Individual 45-minute review meetings scheduled on calendar", | |
| "Email notifications sent to each employee with their review time", | |
| ], | |
| ), | |
| ] | |
| def get_task(task_index: int | None = None) -> Task: | |
| """Return a task — from the API if COLLINEAR_API_KEY is set, else from bundled set.""" | |
| api_key = os.environ.get("COLLINEAR_API_KEY", "").strip() | |
| if api_key: | |
| try: | |
| return _fetch_api_task(api_key, task_index) | |
| except Exception: | |
| logger.warning( | |
| "Failed to fetch task from Scenario Manager API, falling back to bundled tasks.", | |
| exc_info=True, | |
| ) | |
| if task_index is not None: | |
| return BUNDLED_TASKS[task_index % len(BUNDLED_TASKS)] | |
| return random.choice(BUNDLED_TASKS) | |
| def _fetch_api_task(api_key: str, task_index: int | None) -> Task: | |
| """Fetch a task from the Collinear Scenario Manager API.""" | |
| import requests | |
| base_url = os.environ.get("SIMLAB_SCENARIO_MANAGER_API_URL", SCENARIO_MANAGER_API_URL).rstrip( | |
| "/" | |
| ) | |
| headers = {"Accept": "application/json", "API-Key": api_key} | |
| resp = requests.get(f"{base_url}/v1/scenarios", headers=headers, timeout=30) | |
| resp.raise_for_status() | |
| scenarios = resp.json() | |
| hr_scenario = None | |
| for s in scenarios: | |
| name = (s.get("name") or "").lower().replace(" ", "-").replace("_", "-") | |
| if "hr" in name or "human-resource" in name or "recruiting" in name: | |
| hr_scenario = s | |
| break | |
| if hr_scenario is None: | |
| raise ValueError("No HR scenario found in Scenario Manager") | |
| scenario_id = hr_scenario["scenario_id"] | |
| resp = requests.get( | |
| f"{base_url}/v1/scenarios/{scenario_id}/tasks", headers=headers, timeout=30 | |
| ) | |
| resp.raise_for_status() | |
| data = resp.json() | |
| tasks = data.get("tasks", []) | |
| if not tasks: | |
| raise ValueError(f"No tasks found for scenario {scenario_id}") | |
| if task_index is not None: | |
| api_task = tasks[task_index % len(tasks)] | |
| else: | |
| api_task = random.choice(tasks) | |
| return Task( | |
| id=api_task.get("task_id", "api-unknown"), | |
| instruction=api_task.get("description", ""), | |
| difficulty=api_task.get("difficulty", "unknown"), | |
| rubric=[], | |
| ) | |