Spaces:
Sleeping
Sleeping
| name: FlexTime | |
| version: "1.0.0" | |
| description: > | |
| FlexTime is a real-world AI workforce scheduling environment where agents | |
| learn to optimally assign employees to shifts while satisfying hard constraints | |
| (skill matching, availability, max hours) and soft constraints (fairness, | |
| preferences). Modeled after the genuine scheduling problem faced by operations | |
| managers in retail, healthcare, and logistics every day. | |
| author: FlexTime Team | |
| license: MIT | |
| tags: | |
| - openenv | |
| - scheduling | |
| - workforce | |
| - operations | |
| - real-world | |
| - optimization | |
| entrypoint: "uvicorn app.main:app --host 0.0.0.0 --port 7860" | |
| observation_space: | |
| type: object | |
| description: > | |
| Current scheduling state: employees, shifts, assignments, | |
| unmet demand, constraint violations, and computed metrics. | |
| fields: | |
| week_id: {type: string, description: "Episode identifier"} | |
| task_id: {type: string, description: "Active task id"} | |
| employees: {type: array, description: "Roster with skills, availability, hours"} | |
| shifts: {type: array, description: "Shifts needing coverage"} | |
| assignments: {type: array, description: "Active employee→shift assignments"} | |
| unassigned_shifts: {type: array, description: "Shift IDs with no assignment yet"} | |
| conflicts: {type: array, description: "Active constraint violations"} | |
| metrics: {type: object, description: "Coverage, fairness, violations, demand"} | |
| done: {type: boolean, description: "True when episode is complete"} | |
| step_count: {type: integer, description: "Steps taken so far"} | |
| max_steps: {type: integer, description: "Episode step limit"} | |
| action_space: | |
| type: object | |
| description: > | |
| A scheduling operation: assign one employee to one shift, | |
| remove an assignment, swap two employees, or take no action. | |
| fields: | |
| action_type: | |
| type: string | |
| enum: [assign, remove, swap, noop] | |
| description: "Operation to perform (required)" | |
| employee_id: | |
| type: string | |
| description: "Employee ID — required for assign, remove, swap" | |
| shift_id: | |
| type: string | |
| description: "Shift ID — required for assign, remove" | |
| target_employee_id: | |
| type: string | |
| description: "Second employee ID — required for swap" | |
| reward: | |
| type: dense_shaped | |
| range: [-1.0, 1.0] | |
| description: > | |
| Shaped reward at every step. Rewards partial progress. | |
| Penalizes constraint violations and invalid actions. | |
| components: | |
| shift_covered: {value: "+0.15 × Δcoverage", description: "New shift filled"} | |
| demand_signal: {value: "+0.05 × Δdemand", description: "Demand-weighted coverage gain"} | |
| constraint_violated: {value: "-0.20 per violation", description: "New hard constraint broken"} | |
| constraint_resolved: {value: "+0.10 per fix", description: "Hard violation removed"} | |
| fairness: {value: "±0.03 × Δfairness", description: "Hour fairness change"} | |
| conflict_resolved: {value: "+0.10 bonus", description: "Pre-seeded conflict cleared"} | |
| invalid_action: {value: "-0.05", description: "Non-existent IDs etc."} | |
| noop: {value: "0.0", description: "No-operation"} | |
| tasks: | |
| - id: task_easy | |
| name: "Basic Shift Coverage" | |
| difficulty: easy | |
| description: > | |
| Assign employees to all 5 open morning shifts for a single day. | |
| All employees are available and skills match every shift. | |
| Agent must fill all slots without creating overlaps. | |
| max_steps: 20 | |
| target_score: 1.0 | |
| n_employees: 5 | |
| n_shifts: 5 | |
| - id: task_medium | |
| name: "Weekly Schedule with Constraints" | |
| difficulty: medium | |
| description: > | |
| Build a complete weekly schedule for 8 employees across 30 shifts. | |
| Must respect skill requirements, availability windows, and the 40-hour | |
| weekly maximum. Soft fairness constraint: max-min hours delta ≤ 4h. | |
| Partial coverage scored proportionally. | |
| max_steps: 60 | |
| target_score: 0.85 | |
| n_employees: 8 | |
| n_shifts: 30 | |
| - id: task_hard | |
| name: "Fair Optimization Under Pressure" | |
| difficulty: hard | |
| description: > | |
| 12 employees, 50 shifts, 3 pre-seeded conflicts to resolve. | |
| All sub-scores (coverage, fairness, constraint satisfaction, demand) | |
| must simultaneously exceed 0.75 — missing any threshold triggers penalty. | |
| Requires coordinated optimization across all constraint layers. | |
| max_steps: 120 | |
| target_score: 0.75 | |
| n_employees: 12 | |
| n_shifts: 50 | |
| endpoints: | |
| reset: {method: POST, path: /reset, description: "Initialize episode, returns Observation"} | |
| step: {method: POST, path: /step, description: "Apply action, returns StepResult"} | |
| state: {method: GET, path: /state, description: "Current Observation without state change"} | |
| tasks: {method: GET, path: /tasks, description: "Task list + action schema"} | |
| grader: {method: GET, path: /grader, description: "Episode score 0.0–1.0"} | |
| baseline: {method: POST, path: /baseline, description: "Run baseline agent on all 3 tasks"} | |
| health: {method: GET, path: /health, description: "Health check — returns 200"} | |
| baseline: | |
| agent: GreedyBaseline | |
| seed: 42 | |
| scores: | |
| task_easy: 0.95 | |
| task_medium: 0.72 | |
| task_hard: 0.48 | |
| mean: 0.72 | |