Spaces:
Sleeping
Sleeping
nadellaroshni commited on
Commit ·
2646de7
1
Parent(s): 4400763
Add Docker + OpenEnv config updates and remaining changes
Browse files- README.md +100 -179
- env/extraction.py +2 -2
- planner.py +13 -6
- requirements-train.txt +3 -0
README.md
CHANGED
|
@@ -3,73 +3,56 @@ title: Smart Sprint Planner
|
|
| 3 |
emoji: "🗂️"
|
| 4 |
colorFrom: blue
|
| 5 |
colorTo: green
|
| 6 |
-
# Force rebuild - ensures latest code is deployed
|
| 7 |
sdk: docker
|
| 8 |
app_port: 7860
|
| 9 |
---
|
| 10 |
|
| 11 |
# Smart Sprint Planner
|
| 12 |
|
| 13 |
-
|
| 14 |
|
| 15 |
Core pipeline:
|
| 16 |
-
`audio or transcript ->
|
| 17 |
|
| 18 |
-
|
| 19 |
|
| 20 |
-
|
| 21 |
|
| 22 |
-
|
|
|
|
|
|
|
|
|
|
| 23 |
|
| 24 |
-
|
| 25 |
-
- assign work under team capacity constraints
|
| 26 |
-
- respond to urgent work, capacity loss, and dependency changes
|
| 27 |
-
- maximize completion, timeliness, workload balance, and adaptability
|
| 28 |
|
| 29 |
-
|
| 30 |
-
|
| 31 |
-
## Tasks And Difficulty
|
| 32 |
|
| 33 |
There are 3 graded tasks:
|
| 34 |
|
| 35 |
-
|
| 36 |
-
|
| 37 |
-
|
| 38 |
-
|
| 39 |
-
|
| 40 |
-
|
| 41 |
-
|
| 42 |
-
|
| 43 |
-
|
| 44 |
-
|
| 45 |
-
|
| 46 |
-
|
| 47 |
-
|
| 48 |
-
|
| 49 |
-
|
| 50 |
-
|
| 51 |
-
|
| 52 |
-
|
| 53 |
-
|
| 54 |
-
|
| 55 |
-
|
| 56 |
-
|
| 57 |
-
|
| 58 |
-
|
| 59 |
-
## Observation And Action Space
|
| 60 |
-
|
| 61 |
-
Observation includes:
|
| 62 |
-
|
| 63 |
-
- meeting text
|
| 64 |
-
- extracted work items
|
| 65 |
-
- active JIRA tickets
|
| 66 |
-
- developer pool
|
| 67 |
-
- completed task ids
|
| 68 |
-
- sprint day
|
| 69 |
-
- metrics and event history
|
| 70 |
-
- pending and recent disruption signals
|
| 71 |
-
|
| 72 |
-
Action is one assignment:
|
| 73 |
|
| 74 |
```json
|
| 75 |
{
|
|
@@ -78,172 +61,114 @@ Action is one assignment:
|
|
| 78 |
}
|
| 79 |
```
|
| 80 |
|
| 81 |
-
##
|
| 82 |
-
|
| 83 |
-
Each extracted item can include:
|
| 84 |
-
|
| 85 |
-
- `task`
|
| 86 |
-
- `description`
|
| 87 |
-
- `deadline`
|
| 88 |
-
- `priority`
|
| 89 |
-
- `category`
|
| 90 |
-
- `tags`
|
| 91 |
-
- `acceptance_criteria`
|
| 92 |
-
- `dependency_hints`
|
| 93 |
-
- `owner_hint`
|
| 94 |
-
- `urgency_reason`
|
| 95 |
-
- `raw_text`
|
| 96 |
|
| 97 |
-
|
| 98 |
|
| 99 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 100 |
|
| 101 |
-
|
| 102 |
|
| 103 |
-
|
| 104 |
-
- specialization or skill-match reward
|
| 105 |
-
- priority-aware completion reward
|
| 106 |
-
- penalties for invalid, blocked, and over-capacity actions
|
| 107 |
-
- adaptation reward for disruption-created work
|
| 108 |
-
- future-feasibility shaping for preserving replanning options
|
| 109 |
|
| 110 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 111 |
|
| 112 |
-
|
| 113 |
-
- on-time rate
|
| 114 |
-
- extraction quality
|
| 115 |
-
- workload balance
|
| 116 |
-
- efficiency
|
| 117 |
-
- adaptability
|
| 118 |
|
| 119 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 120 |
|
| 121 |
## Baseline Inference
|
| 122 |
|
| 123 |
-
The required root-level baseline script is [inference.py](C:/Users/ASUS/Documents/GitHub/smart_sprint_planner/inference.py).
|
| 124 |
|
| 125 |
It:
|
| 126 |
|
| 127 |
-
- uses the OpenAI client for LLM calls
|
| 128 |
-
- reads `API_BASE_URL`, `MODEL_NAME`, and `
|
| 129 |
-
- also accepts `
|
| 130 |
-
-
|
| 131 |
-
-
|
| 132 |
-
- `[START]`
|
| 133 |
-
- `[STEP]`
|
| 134 |
-
- `[END]`
|
| 135 |
|
| 136 |
Example:
|
| 137 |
|
| 138 |
```bash
|
| 139 |
-
API_BASE_URL=https://router.huggingface.co/v1
|
| 140 |
-
```
|
| 141 |
-
|
| 142 |
-
Run all tasks:
|
| 143 |
-
|
| 144 |
-
```bash
|
| 145 |
-
API_BASE_URL=https://router.huggingface.co/v1 API_KEY=... python inference.py
|
| 146 |
```
|
| 147 |
|
| 148 |
-
|
| 149 |
-
|
| 150 |
-
- the script makes live proxy-backed LLM calls for all three tasks
|
| 151 |
-
- task names emitted in logs are `easy`, `medium`, and `hard`
|
| 152 |
-
- API failures are surfaced instead of being silently swallowed
|
| 153 |
-
|
| 154 |
-
## Learned Planner
|
| 155 |
|
| 156 |
-
|
| 157 |
|
| 158 |
-
|
| 159 |
-
-
|
| 160 |
-
|
|
|
|
|
|
|
|
|
|
| 161 |
|
| 162 |
-
|
| 163 |
|
| 164 |
-
|
| 165 |
-
- DDQN: `0.897`
|
| 166 |
|
| 167 |
-
|
| 168 |
-
|
| 169 |
-
Train:
|
| 170 |
|
| 171 |
```bash
|
| 172 |
-
python
|
| 173 |
-
|
| 174 |
-
|
| 175 |
-
Evaluate:
|
| 176 |
-
|
| 177 |
-
```bash
|
| 178 |
-
python eval.py --checkpoint checkpoints/best --scenario-source dataset-eval
|
| 179 |
```
|
| 180 |
|
| 181 |
-
|
| 182 |
-
|
| 183 |
-
The full product-facing path is exposed through [planner.py](C:/Users/ASUS/Documents/GitHub/smart_sprint_planner/planner.py) and `POST /plan`.
|
| 184 |
-
|
| 185 |
-
Run locally from transcript:
|
| 186 |
|
| 187 |
-
```
|
| 188 |
-
python
|
|
|
|
|
|
|
| 189 |
```
|
| 190 |
|
| 191 |
-
|
| 192 |
-
|
| 193 |
-
## API Server
|
| 194 |
-
|
| 195 |
-
Start the server:
|
| 196 |
|
| 197 |
```bash
|
| 198 |
-
uvicorn server.app:app --
|
| 199 |
```
|
| 200 |
|
| 201 |
-
|
| 202 |
-
|
| 203 |
-
- `GET /health`
|
| 204 |
-
- `POST /reset`
|
| 205 |
-
- `POST /step`
|
| 206 |
-
- `GET /state`
|
| 207 |
-
- `GET /render`
|
| 208 |
-
- `GET /grade`
|
| 209 |
-
- `POST /plan`
|
| 210 |
-
|
| 211 |
-
## Setup
|
| 212 |
|
| 213 |
```bash
|
| 214 |
-
python -
|
| 215 |
-
source venv/bin/activate
|
| 216 |
-
pip install -r requirements.txt
|
| 217 |
-
```
|
| 218 |
-
|
| 219 |
-
Windows:
|
| 220 |
-
|
| 221 |
-
```powershell
|
| 222 |
-
python -m venv venv
|
| 223 |
-
venv\Scripts\activate
|
| 224 |
-
pip install -r requirements.txt
|
| 225 |
```
|
| 226 |
|
| 227 |
-
##
|
| 228 |
-
|
| 229 |
-
Run tests:
|
| 230 |
|
| 231 |
```bash
|
| 232 |
python -m pytest tests -v
|
| 233 |
```
|
| 234 |
|
| 235 |
-
Run OpenEnv
|
| 236 |
|
| 237 |
-
```
|
| 238 |
-
|
| 239 |
```
|
| 240 |
|
| 241 |
-
Current local status:
|
| 242 |
-
|
| 243 |
-
- the main automated tests live in `tests/`
|
| 244 |
-
- `openenv validate` should be run from an environment with `openenv-core` installed
|
| 245 |
-
- baseline inference is submission-oriented and requires proxy credentials
|
| 246 |
-
|
| 247 |
## Docker
|
| 248 |
|
| 249 |
Build:
|
|
@@ -258,13 +183,9 @@ Run:
|
|
| 258 |
docker run -p 7860:7860 smart-sprint-planner
|
| 259 |
```
|
| 260 |
|
| 261 |
-
##
|
| 262 |
-
|
| 263 |
-
Environment metadata lives in [openenv.yaml](C:/Users/ASUS/Documents/GitHub/smart_sprint_planner/openenv.yaml).
|
| 264 |
-
|
| 265 |
-
Before final submission, the remaining non-code checklist is:
|
| 266 |
|
| 267 |
-
|
| 268 |
-
|
| 269 |
-
|
| 270 |
-
|
|
|
|
| 3 |
emoji: "🗂️"
|
| 4 |
colorFrom: blue
|
| 5 |
colorTo: green
|
|
|
|
| 6 |
sdk: docker
|
| 7 |
app_port: 7860
|
| 8 |
---
|
| 9 |
|
| 10 |
# Smart Sprint Planner
|
| 11 |
|
| 12 |
+
Smart Sprint Planner is an OpenEnv environment for a real software-delivery task: planning and replanning an engineering sprint from meeting context, backlog pressure, team capacity, and changing sprint conditions.
|
| 13 |
|
| 14 |
Core pipeline:
|
| 15 |
+
`audio or transcript -> extracted action items -> JIRA-style tickets -> developer assignments -> disruptions -> grading`
|
| 16 |
|
| 17 |
+
## Why This Environment
|
| 18 |
|
| 19 |
+
This environment simulates the kind of planning work an engineering manager, scrum lead, or delivery owner actually performs:
|
| 20 |
|
| 21 |
+
- convert planning discussion into structured work
|
| 22 |
+
- assign tickets under capacity and specialization constraints
|
| 23 |
+
- react to urgent work, lost capacity, and dependency changes
|
| 24 |
+
- preserve feasibility while maximizing delivery value
|
| 25 |
|
| 26 |
+
It is deliberately not a toy game. The task is operational planning under uncertainty.
|
|
|
|
|
|
|
|
|
|
| 27 |
|
| 28 |
+
## Tasks
|
|
|
|
|
|
|
| 29 |
|
| 30 |
There are 3 graded tasks:
|
| 31 |
|
| 32 |
+
| Task | Difficulty | Max Steps | Description |
|
| 33 |
+
|------|------------|-----------|-------------|
|
| 34 |
+
| `easy` | Easy | 10 | Static sprint planning with fixed backlog and no disruptions |
|
| 35 |
+
| `medium` | Medium | 15 | Replanning after one mid-sprint disruption |
|
| 36 |
+
| `hard` | Hard | 20 | Multi-disruption planning with shifting capacity and dependencies |
|
| 37 |
+
|
| 38 |
+
## Observation Space
|
| 39 |
+
|
| 40 |
+
Each `reset()` and `step()` returns a typed [`Observation`](C:/Users/ASUS/Documents/GitHub/smart_sprint_planner/env/models.py) containing:
|
| 41 |
+
|
| 42 |
+
- `meeting_text`
|
| 43 |
+
- `extracted_items`
|
| 44 |
+
- `jira_tickets`
|
| 45 |
+
- `developers`
|
| 46 |
+
- `completed_task_ids`
|
| 47 |
+
- `sprint_day`
|
| 48 |
+
- `metrics`
|
| 49 |
+
- `difficulty`
|
| 50 |
+
- `recent_events`
|
| 51 |
+
- `pending_events`
|
| 52 |
+
|
| 53 |
+
## Action Space
|
| 54 |
+
|
| 55 |
+
The action is a typed [`Action`](C:/Users/ASUS/Documents/GitHub/smart_sprint_planner/env/models.py) with one assignment:
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 56 |
|
| 57 |
```json
|
| 58 |
{
|
|
|
|
| 61 |
}
|
| 62 |
```
|
| 63 |
|
| 64 |
+
## Reward Design
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 65 |
|
| 66 |
+
Dense reward signals are used throughout the trajectory:
|
| 67 |
|
| 68 |
+
- positive reward for on-time completion
|
| 69 |
+
- positive reward for skill-matched assignment
|
| 70 |
+
- positive reward for high-priority completion
|
| 71 |
+
- adaptation reward for disruption-created work
|
| 72 |
+
- penalties for invalid ids, blocked work, and over-capacity assignments
|
| 73 |
+
- episode bonus for full completion, balance, efficiency, and disruption handling
|
| 74 |
|
| 75 |
+
Final graders return normalized scores in `[0.0, 1.0]`.
|
| 76 |
|
| 77 |
+
## Project Structure
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 78 |
|
| 79 |
+
- [`env/models.py`](C:/Users/ASUS/Documents/GitHub/smart_sprint_planner/env/models.py): typed Pydantic contracts
|
| 80 |
+
- [`env/tasks.py`](C:/Users/ASUS/Documents/GitHub/smart_sprint_planner/env/tasks.py): scenario registry and fallback datasets
|
| 81 |
+
- [`env/extraction.py`](C:/Users/ASUS/Documents/GitHub/smart_sprint_planner/env/extraction.py): transcript-to-work extraction
|
| 82 |
+
- [`env/jira.py`](C:/Users/ASUS/Documents/GitHub/smart_sprint_planner/env/jira.py): JIRA-style ticket generation
|
| 83 |
+
- [`env/environment.py`](C:/Users/ASUS/Documents/GitHub/smart_sprint_planner/env/environment.py): `reset()`, `step()`, `state()`
|
| 84 |
+
- [`env/graders.py`](C:/Users/ASUS/Documents/GitHub/smart_sprint_planner/env/graders.py): dense reward and final task graders
|
| 85 |
+
- [`server/app.py`](C:/Users/ASUS/Documents/GitHub/smart_sprint_planner/server/app.py): FastAPI runtime
|
| 86 |
+
- [`inference.py`](C:/Users/ASUS/Documents/GitHub/smart_sprint_planner/inference.py): baseline OpenAI-client inference script
|
| 87 |
|
| 88 |
+
## API Endpoints
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 89 |
|
| 90 |
+
- `GET /health`
|
| 91 |
+
- `GET /tasks`
|
| 92 |
+
- `POST /reset`
|
| 93 |
+
- `POST /step`
|
| 94 |
+
- `GET /state`
|
| 95 |
+
- `GET /render`
|
| 96 |
+
- `GET /grade`
|
| 97 |
+
- `POST /plan`
|
| 98 |
|
| 99 |
## Baseline Inference
|
| 100 |
|
| 101 |
+
The required root-level baseline script is [`inference.py`](C:/Users/ASUS/Documents/GitHub/smart_sprint_planner/inference.py).
|
| 102 |
|
| 103 |
It:
|
| 104 |
|
| 105 |
+
- uses the OpenAI client for all LLM calls
|
| 106 |
+
- reads `API_BASE_URL`, `MODEL_NAME`, and `HF_TOKEN`
|
| 107 |
+
- also accepts `API_KEY` or `OPENAI_API_KEY` as fallbacks for local testing
|
| 108 |
+
- emits only the required `[START]`, `[STEP]`, and `[END]` log lines
|
| 109 |
+
- uses an LLM to choose among valid assignment candidates at every step
|
|
|
|
|
|
|
|
|
|
| 110 |
|
| 111 |
Example:
|
| 112 |
|
| 113 |
```bash
|
| 114 |
+
API_BASE_URL=https://router.huggingface.co/v1 MODEL_NAME=Qwen/Qwen2.5-72B-Instruct HF_TOKEN=... python inference.py
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 115 |
```
|
| 116 |
|
| 117 |
+
## Baseline Scores
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 118 |
|
| 119 |
+
Current deterministic baseline scores from the built-in heuristic policy on the default scenarios:
|
| 120 |
|
| 121 |
+
| Task | Score |
|
| 122 |
+
|------|-------|
|
| 123 |
+
| `easy` | `0.833` |
|
| 124 |
+
| `medium` | `0.734` |
|
| 125 |
+
| `hard` | `0.761` |
|
| 126 |
+
| **overall mean** | **`0.776`** |
|
| 127 |
|
| 128 |
+
These numbers are also reflected in [`openenv.yaml`](C:/Users/ASUS/Documents/GitHub/smart_sprint_planner/openenv.yaml).
|
| 129 |
|
| 130 |
+
## Local Usage
|
|
|
|
| 131 |
|
| 132 |
+
### Setup
|
|
|
|
|
|
|
| 133 |
|
| 134 |
```bash
|
| 135 |
+
python -m venv .venv
|
| 136 |
+
source .venv/bin/activate
|
| 137 |
+
pip install -r requirements.txt
|
|
|
|
|
|
|
|
|
|
|
|
|
| 138 |
```
|
| 139 |
|
| 140 |
+
Windows:
|
|
|
|
|
|
|
|
|
|
|
|
|
| 141 |
|
| 142 |
+
```powershell
|
| 143 |
+
python -m venv .venv
|
| 144 |
+
.venv\Scripts\activate
|
| 145 |
+
pip install -r requirements.txt
|
| 146 |
```
|
| 147 |
|
| 148 |
+
### Run Server
|
|
|
|
|
|
|
|
|
|
|
|
|
| 149 |
|
| 150 |
```bash
|
| 151 |
+
uvicorn server.app:app --host 0.0.0.0 --port 7860
|
| 152 |
```
|
| 153 |
|
| 154 |
+
### Run Planner From Transcript
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 155 |
|
| 156 |
```bash
|
| 157 |
+
python planner.py --difficulty medium --strategy heuristic --transcript "Fix checkout today, then finish analytics after auth."
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 158 |
```
|
| 159 |
|
| 160 |
+
### Run Tests
|
|
|
|
|
|
|
| 161 |
|
| 162 |
```bash
|
| 163 |
python -m pytest tests -v
|
| 164 |
```
|
| 165 |
|
| 166 |
+
### Run OpenEnv Validation
|
| 167 |
|
| 168 |
+
```bash
|
| 169 |
+
openenv validate
|
| 170 |
```
|
| 171 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 172 |
## Docker
|
| 173 |
|
| 174 |
Build:
|
|
|
|
| 183 |
docker run -p 7860:7860 smart-sprint-planner
|
| 184 |
```
|
| 185 |
|
| 186 |
+
## Submission Notes
|
|
|
|
|
|
|
|
|
|
|
|
|
| 187 |
|
| 188 |
+
- keep [`inference.py`](C:/Users/ASUS/Documents/GitHub/smart_sprint_planner/inference.py) at the repo root
|
| 189 |
+
- do not change the `[START]`, `[STEP]`, `[END]` stdout format
|
| 190 |
+
- ensure your Hugging Face Space responds to `POST /reset`
|
| 191 |
+
- ensure `openenv validate` passes before submission
|
env/extraction.py
CHANGED
|
@@ -118,7 +118,7 @@ def _get_client():
|
|
| 118 |
|
| 119 |
# CRITICAL: Use ONLY the validator-injected credentials
|
| 120 |
# NO fallbacks - if these are missing, gracefully degrade to unavailable
|
| 121 |
-
api_key = os.environ.get("API_KEY") or os.environ.get("
|
| 122 |
api_base_url = os.environ.get("API_BASE_URL")
|
| 123 |
|
| 124 |
if not api_key or not api_base_url:
|
|
@@ -150,7 +150,7 @@ def _call_llm(transcript: str) -> List[dict]:
|
|
| 150 |
if client == "unavailable":
|
| 151 |
raise RuntimeError("LLM client not available")
|
| 152 |
|
| 153 |
-
model = os.getenv("MODEL_NAME", "
|
| 154 |
|
| 155 |
if hasattr(client, "responses"):
|
| 156 |
response = client.responses.create(
|
|
|
|
| 118 |
|
| 119 |
# CRITICAL: Use ONLY the validator-injected credentials
|
| 120 |
# NO fallbacks - if these are missing, gracefully degrade to unavailable
|
| 121 |
+
api_key = os.environ.get("HF_TOKEN") or os.environ.get("API_KEY") or os.environ.get("OPENAI_API_KEY")
|
| 122 |
api_base_url = os.environ.get("API_BASE_URL")
|
| 123 |
|
| 124 |
if not api_key or not api_base_url:
|
|
|
|
| 150 |
if client == "unavailable":
|
| 151 |
raise RuntimeError("LLM client not available")
|
| 152 |
|
| 153 |
+
model = os.getenv("MODEL_NAME", "Qwen/Qwen2.5-72B-Instruct")
|
| 154 |
|
| 155 |
if hasattr(client, "responses"):
|
| 156 |
response = client.responses.create(
|
planner.py
CHANGED
|
@@ -7,9 +7,8 @@ from __future__ import annotations
|
|
| 7 |
import argparse
|
| 8 |
import json
|
| 9 |
from pathlib import Path
|
| 10 |
-
from typing import Optional, Tuple
|
| 11 |
|
| 12 |
-
from agent.dqn_agent import DDQNAgent
|
| 13 |
from agent.heuristic_agent import HeuristicAgent
|
| 14 |
from env.environment import SprintEnv
|
| 15 |
from env.graders import grade
|
|
@@ -21,6 +20,9 @@ from env.models import (
|
|
| 21 |
PlanResponse,
|
| 22 |
)
|
| 23 |
|
|
|
|
|
|
|
|
|
|
| 24 |
|
| 25 |
def _load_agent(strategy: str, checkpoint: Optional[str]) -> Tuple[object, str]:
|
| 26 |
normalized = strategy.lower()
|
|
@@ -30,16 +32,21 @@ def _load_agent(strategy: str, checkpoint: Optional[str]) -> Tuple[object, str]:
|
|
| 30 |
if normalized == "ddqn":
|
| 31 |
ckpt = checkpoint or "checkpoints/best"
|
| 32 |
if (Path(ckpt) / "online.pkl").exists():
|
| 33 |
-
|
| 34 |
-
|
| 35 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 36 |
normalized = "heuristic"
|
| 37 |
|
| 38 |
return HeuristicAgent(), normalized
|
| 39 |
|
| 40 |
|
| 41 |
def _choose_action(agent: object, obs: Observation) -> Optional[Action]:
|
| 42 |
-
if
|
| 43 |
return agent.act(obs, deterministic=True)
|
| 44 |
if isinstance(agent, HeuristicAgent):
|
| 45 |
return agent.act(obs)
|
|
|
|
| 7 |
import argparse
|
| 8 |
import json
|
| 9 |
from pathlib import Path
|
| 10 |
+
from typing import TYPE_CHECKING, Optional, Tuple
|
| 11 |
|
|
|
|
| 12 |
from agent.heuristic_agent import HeuristicAgent
|
| 13 |
from env.environment import SprintEnv
|
| 14 |
from env.graders import grade
|
|
|
|
| 20 |
PlanResponse,
|
| 21 |
)
|
| 22 |
|
| 23 |
+
if TYPE_CHECKING:
|
| 24 |
+
from agent.dqn_agent import DDQNAgent
|
| 25 |
+
|
| 26 |
|
| 27 |
def _load_agent(strategy: str, checkpoint: Optional[str]) -> Tuple[object, str]:
|
| 28 |
normalized = strategy.lower()
|
|
|
|
| 32 |
if normalized == "ddqn":
|
| 33 |
ckpt = checkpoint or "checkpoints/best"
|
| 34 |
if (Path(ckpt) / "online.pkl").exists():
|
| 35 |
+
try:
|
| 36 |
+
from agent.dqn_agent import DDQNAgent
|
| 37 |
+
except ImportError:
|
| 38 |
+
normalized = "heuristic"
|
| 39 |
+
else:
|
| 40 |
+
agent = DDQNAgent()
|
| 41 |
+
agent.load(ckpt)
|
| 42 |
+
return agent, "ddqn"
|
| 43 |
normalized = "heuristic"
|
| 44 |
|
| 45 |
return HeuristicAgent(), normalized
|
| 46 |
|
| 47 |
|
| 48 |
def _choose_action(agent: object, obs: Observation) -> Optional[Action]:
|
| 49 |
+
if agent.__class__.__name__ == "DDQNAgent":
|
| 50 |
return agent.act(obs, deterministic=True)
|
| 51 |
if isinstance(agent, HeuristicAgent):
|
| 52 |
return agent.act(obs)
|
requirements-train.txt
ADDED
|
@@ -0,0 +1,3 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
-r requirements.txt
|
| 2 |
+
numpy>=1.26,<3
|
| 3 |
+
torch==2.6.0
|