Commit ·
508fec0
1
Parent(s): 33523d4
fix: Phase 2 validation - /health=healthy, add /metadata, /schema, /mcp, httpx dep, safe client import
Browse files- Dockerfile +1 -1
- __init__.py +9 -1
- data/memory.json +153 -398
- pyproject.toml +1 -0
- requirements.txt +1 -0
- server/app.py +53 -1
Dockerfile
CHANGED
|
@@ -1,5 +1,5 @@
|
|
| 1 |
# Use official lightweight Python image
|
| 2 |
-
# REBUILD_TIMESTAMP: 2026-04-07
|
| 3 |
FROM python:3.10-slim
|
| 4 |
|
| 5 |
# Set working directory
|
|
|
|
| 1 |
# Use official lightweight Python image
|
| 2 |
+
# REBUILD_TIMESTAMP: 2026-04-07 23:30 (Phase2 Fix: /health=healthy, /metadata, /schema, /mcp, httpx)
|
| 3 |
FROM python:3.10-slim
|
| 4 |
|
| 5 |
# Set working directory
|
__init__.py
CHANGED
|
@@ -1,6 +1,14 @@
|
|
| 1 |
-
from .client import DroneEnvClient
|
| 2 |
from .models import DroneAction, DroneObservation, DroneState
|
| 3 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 4 |
__all__ = [
|
| 5 |
"DroneAction",
|
| 6 |
"DroneObservation",
|
|
|
|
|
|
|
| 1 |
from .models import DroneAction, DroneObservation, DroneState
|
| 2 |
|
| 3 |
+
# Client import is optional — it requires httpx which may not be installed
|
| 4 |
+
# in all runtime environments. The graders must work independently.
|
| 5 |
+
try:
|
| 6 |
+
from .client import DroneEnvClient
|
| 7 |
+
_CLIENT_AVAILABLE = True
|
| 8 |
+
except ImportError:
|
| 9 |
+
_CLIENT_AVAILABLE = False
|
| 10 |
+
DroneEnvClient = None # type: ignore
|
| 11 |
+
|
| 12 |
__all__ = [
|
| 13 |
"DroneAction",
|
| 14 |
"DroneObservation",
|
data/memory.json
CHANGED
|
@@ -1,402 +1,4 @@
|
|
| 1 |
[
|
| 2 |
-
{
|
| 3 |
-
"task": "drone_env.core.graders:grade_easy",
|
| 4 |
-
"steps": [
|
| 5 |
-
{
|
| 6 |
-
"step": 1,
|
| 7 |
-
"x": 4,
|
| 8 |
-
"y": 9,
|
| 9 |
-
"action": "DOWN",
|
| 10 |
-
"reward": -0.05,
|
| 11 |
-
"battery": 0.9833
|
| 12 |
-
},
|
| 13 |
-
{
|
| 14 |
-
"step": 2,
|
| 15 |
-
"x": 3,
|
| 16 |
-
"y": 9,
|
| 17 |
-
"action": "LEFT",
|
| 18 |
-
"reward": 0.95,
|
| 19 |
-
"battery": 0.9667
|
| 20 |
-
}
|
| 21 |
-
],
|
| 22 |
-
"grid_meta": {
|
| 23 |
-
"width": 10,
|
| 24 |
-
"height": 10
|
| 25 |
-
},
|
| 26 |
-
"delivery_positions": [
|
| 27 |
-
[
|
| 28 |
-
3,
|
| 29 |
-
9
|
| 30 |
-
]
|
| 31 |
-
],
|
| 32 |
-
"deliveries_done": 1,
|
| 33 |
-
"total_reward": 0.9,
|
| 34 |
-
"total_steps": 2
|
| 35 |
-
},
|
| 36 |
-
{
|
| 37 |
-
"task": "drone_env.core.graders:grade_easy",
|
| 38 |
-
"steps": [
|
| 39 |
-
{
|
| 40 |
-
"step": 1,
|
| 41 |
-
"x": 4,
|
| 42 |
-
"y": 5,
|
| 43 |
-
"action": "DOWN",
|
| 44 |
-
"reward": -0.05,
|
| 45 |
-
"battery": 0.9833
|
| 46 |
-
},
|
| 47 |
-
{
|
| 48 |
-
"step": 2,
|
| 49 |
-
"x": 4,
|
| 50 |
-
"y": 6,
|
| 51 |
-
"action": "DOWN",
|
| 52 |
-
"reward": -0.05,
|
| 53 |
-
"battery": 0.9667
|
| 54 |
-
},
|
| 55 |
-
{
|
| 56 |
-
"step": 3,
|
| 57 |
-
"x": 4,
|
| 58 |
-
"y": 7,
|
| 59 |
-
"action": "DOWN",
|
| 60 |
-
"reward": -0.05,
|
| 61 |
-
"battery": 0.95
|
| 62 |
-
},
|
| 63 |
-
{
|
| 64 |
-
"step": 4,
|
| 65 |
-
"x": 5,
|
| 66 |
-
"y": 7,
|
| 67 |
-
"action": "RIGHT",
|
| 68 |
-
"reward": 0.95,
|
| 69 |
-
"battery": 0.9333
|
| 70 |
-
}
|
| 71 |
-
],
|
| 72 |
-
"grid_meta": {
|
| 73 |
-
"width": 10,
|
| 74 |
-
"height": 10
|
| 75 |
-
},
|
| 76 |
-
"delivery_positions": [
|
| 77 |
-
[
|
| 78 |
-
5,
|
| 79 |
-
7
|
| 80 |
-
]
|
| 81 |
-
],
|
| 82 |
-
"deliveries_done": 1,
|
| 83 |
-
"total_reward": 0.8,
|
| 84 |
-
"total_steps": 4
|
| 85 |
-
},
|
| 86 |
-
{
|
| 87 |
-
"task": "drone_env.core.graders:grade_medium",
|
| 88 |
-
"steps": [
|
| 89 |
-
{
|
| 90 |
-
"step": 1,
|
| 91 |
-
"x": 8,
|
| 92 |
-
"y": 12,
|
| 93 |
-
"action": "UP",
|
| 94 |
-
"reward": -0.05,
|
| 95 |
-
"battery": 0.99
|
| 96 |
-
},
|
| 97 |
-
{
|
| 98 |
-
"step": 2,
|
| 99 |
-
"x": 8,
|
| 100 |
-
"y": 11,
|
| 101 |
-
"action": "UP",
|
| 102 |
-
"reward": -0.05,
|
| 103 |
-
"battery": 0.98
|
| 104 |
-
},
|
| 105 |
-
{
|
| 106 |
-
"step": 3,
|
| 107 |
-
"x": 8,
|
| 108 |
-
"y": 10,
|
| 109 |
-
"action": "UP",
|
| 110 |
-
"reward": -0.05,
|
| 111 |
-
"battery": 0.97
|
| 112 |
-
},
|
| 113 |
-
{
|
| 114 |
-
"step": 4,
|
| 115 |
-
"x": 8,
|
| 116 |
-
"y": 9,
|
| 117 |
-
"action": "UP",
|
| 118 |
-
"reward": -0.05,
|
| 119 |
-
"battery": 0.96
|
| 120 |
-
},
|
| 121 |
-
{
|
| 122 |
-
"step": 5,
|
| 123 |
-
"x": 8,
|
| 124 |
-
"y": 8,
|
| 125 |
-
"action": "UP",
|
| 126 |
-
"reward": -0.05,
|
| 127 |
-
"battery": 0.95
|
| 128 |
-
},
|
| 129 |
-
{
|
| 130 |
-
"step": 6,
|
| 131 |
-
"x": 8,
|
| 132 |
-
"y": 7,
|
| 133 |
-
"action": "UP",
|
| 134 |
-
"reward": -0.05,
|
| 135 |
-
"battery": 0.94
|
| 136 |
-
},
|
| 137 |
-
{
|
| 138 |
-
"step": 7,
|
| 139 |
-
"x": 8,
|
| 140 |
-
"y": 6,
|
| 141 |
-
"action": "UP",
|
| 142 |
-
"reward": -0.05,
|
| 143 |
-
"battery": 0.93
|
| 144 |
-
},
|
| 145 |
-
{
|
| 146 |
-
"step": 8,
|
| 147 |
-
"x": 8,
|
| 148 |
-
"y": 5,
|
| 149 |
-
"action": "UP",
|
| 150 |
-
"reward": -0.05,
|
| 151 |
-
"battery": 0.92
|
| 152 |
-
},
|
| 153 |
-
{
|
| 154 |
-
"step": 9,
|
| 155 |
-
"x": 8,
|
| 156 |
-
"y": 4,
|
| 157 |
-
"action": "UP",
|
| 158 |
-
"reward": -0.05,
|
| 159 |
-
"battery": 0.91
|
| 160 |
-
},
|
| 161 |
-
{
|
| 162 |
-
"step": 10,
|
| 163 |
-
"x": 8,
|
| 164 |
-
"y": 3,
|
| 165 |
-
"action": "UP",
|
| 166 |
-
"reward": -0.05,
|
| 167 |
-
"battery": 0.9
|
| 168 |
-
},
|
| 169 |
-
{
|
| 170 |
-
"step": 11,
|
| 171 |
-
"x": 9,
|
| 172 |
-
"y": 3,
|
| 173 |
-
"action": "RIGHT",
|
| 174 |
-
"reward": -0.15,
|
| 175 |
-
"battery": 0.89
|
| 176 |
-
},
|
| 177 |
-
{
|
| 178 |
-
"step": 12,
|
| 179 |
-
"x": 9,
|
| 180 |
-
"y": 2,
|
| 181 |
-
"action": "UP",
|
| 182 |
-
"reward": -0.05,
|
| 183 |
-
"battery": 0.88
|
| 184 |
-
},
|
| 185 |
-
{
|
| 186 |
-
"step": 13,
|
| 187 |
-
"x": 10,
|
| 188 |
-
"y": 2,
|
| 189 |
-
"action": "RIGHT",
|
| 190 |
-
"reward": -0.05,
|
| 191 |
-
"battery": 0.87
|
| 192 |
-
},
|
| 193 |
-
{
|
| 194 |
-
"step": 14,
|
| 195 |
-
"x": 10,
|
| 196 |
-
"y": 1,
|
| 197 |
-
"action": "UP",
|
| 198 |
-
"reward": -0.05,
|
| 199 |
-
"battery": 0.86
|
| 200 |
-
},
|
| 201 |
-
{
|
| 202 |
-
"step": 15,
|
| 203 |
-
"x": 11,
|
| 204 |
-
"y": 1,
|
| 205 |
-
"action": "RIGHT",
|
| 206 |
-
"reward": -0.05,
|
| 207 |
-
"battery": 0.85
|
| 208 |
-
},
|
| 209 |
-
{
|
| 210 |
-
"step": 16,
|
| 211 |
-
"x": 11,
|
| 212 |
-
"y": 0,
|
| 213 |
-
"action": "UP",
|
| 214 |
-
"reward": -0.05,
|
| 215 |
-
"battery": 0.84
|
| 216 |
-
},
|
| 217 |
-
{
|
| 218 |
-
"step": 17,
|
| 219 |
-
"x": 12,
|
| 220 |
-
"y": 0,
|
| 221 |
-
"action": "RIGHT",
|
| 222 |
-
"reward": 0.75,
|
| 223 |
-
"battery": 0.83
|
| 224 |
-
},
|
| 225 |
-
{
|
| 226 |
-
"step": 18,
|
| 227 |
-
"x": 11,
|
| 228 |
-
"y": 0,
|
| 229 |
-
"action": "LEFT",
|
| 230 |
-
"reward": -0.05,
|
| 231 |
-
"battery": 0.82
|
| 232 |
-
},
|
| 233 |
-
{
|
| 234 |
-
"step": 19,
|
| 235 |
-
"x": 10,
|
| 236 |
-
"y": 0,
|
| 237 |
-
"action": "LEFT",
|
| 238 |
-
"reward": -0.05,
|
| 239 |
-
"battery": 0.81
|
| 240 |
-
},
|
| 241 |
-
{
|
| 242 |
-
"step": 20,
|
| 243 |
-
"x": 9,
|
| 244 |
-
"y": 0,
|
| 245 |
-
"action": "LEFT",
|
| 246 |
-
"reward": -0.05,
|
| 247 |
-
"battery": 0.8
|
| 248 |
-
},
|
| 249 |
-
{
|
| 250 |
-
"step": 21,
|
| 251 |
-
"x": 9,
|
| 252 |
-
"y": 1,
|
| 253 |
-
"action": "DOWN",
|
| 254 |
-
"reward": -0.05,
|
| 255 |
-
"battery": 0.79
|
| 256 |
-
},
|
| 257 |
-
{
|
| 258 |
-
"step": 22,
|
| 259 |
-
"x": 8,
|
| 260 |
-
"y": 1,
|
| 261 |
-
"action": "LEFT",
|
| 262 |
-
"reward": -0.05,
|
| 263 |
-
"battery": 0.78
|
| 264 |
-
},
|
| 265 |
-
{
|
| 266 |
-
"step": 23,
|
| 267 |
-
"x": 8,
|
| 268 |
-
"y": 2,
|
| 269 |
-
"action": "DOWN",
|
| 270 |
-
"reward": -0.05,
|
| 271 |
-
"battery": 0.77
|
| 272 |
-
},
|
| 273 |
-
{
|
| 274 |
-
"step": 24,
|
| 275 |
-
"x": 7,
|
| 276 |
-
"y": 2,
|
| 277 |
-
"action": "LEFT",
|
| 278 |
-
"reward": -0.05,
|
| 279 |
-
"battery": 0.76
|
| 280 |
-
},
|
| 281 |
-
{
|
| 282 |
-
"step": 25,
|
| 283 |
-
"x": 7,
|
| 284 |
-
"y": 3,
|
| 285 |
-
"action": "DOWN",
|
| 286 |
-
"reward": -0.1,
|
| 287 |
-
"battery": 0.75
|
| 288 |
-
},
|
| 289 |
-
{
|
| 290 |
-
"step": 26,
|
| 291 |
-
"x": 6,
|
| 292 |
-
"y": 3,
|
| 293 |
-
"action": "LEFT",
|
| 294 |
-
"reward": -0.05,
|
| 295 |
-
"battery": 0.74
|
| 296 |
-
},
|
| 297 |
-
{
|
| 298 |
-
"step": 27,
|
| 299 |
-
"x": 6,
|
| 300 |
-
"y": 4,
|
| 301 |
-
"action": "DOWN",
|
| 302 |
-
"reward": -0.05,
|
| 303 |
-
"battery": 0.73
|
| 304 |
-
},
|
| 305 |
-
{
|
| 306 |
-
"step": 28,
|
| 307 |
-
"x": 5,
|
| 308 |
-
"y": 4,
|
| 309 |
-
"action": "LEFT",
|
| 310 |
-
"reward": -0.05,
|
| 311 |
-
"battery": 0.72
|
| 312 |
-
},
|
| 313 |
-
{
|
| 314 |
-
"step": 29,
|
| 315 |
-
"x": 5,
|
| 316 |
-
"y": 5,
|
| 317 |
-
"action": "DOWN",
|
| 318 |
-
"reward": -0.05,
|
| 319 |
-
"battery": 0.71
|
| 320 |
-
},
|
| 321 |
-
{
|
| 322 |
-
"step": 30,
|
| 323 |
-
"x": 4,
|
| 324 |
-
"y": 5,
|
| 325 |
-
"action": "LEFT",
|
| 326 |
-
"reward": 0.75,
|
| 327 |
-
"battery": 0.7
|
| 328 |
-
},
|
| 329 |
-
{
|
| 330 |
-
"step": 31,
|
| 331 |
-
"x": 4,
|
| 332 |
-
"y": 6,
|
| 333 |
-
"action": "DOWN",
|
| 334 |
-
"reward": -0.05,
|
| 335 |
-
"battery": 0.69
|
| 336 |
-
},
|
| 337 |
-
{
|
| 338 |
-
"step": 32,
|
| 339 |
-
"x": 4,
|
| 340 |
-
"y": 7,
|
| 341 |
-
"action": "DOWN",
|
| 342 |
-
"reward": -0.05,
|
| 343 |
-
"battery": 0.68
|
| 344 |
-
},
|
| 345 |
-
{
|
| 346 |
-
"step": 33,
|
| 347 |
-
"x": 4,
|
| 348 |
-
"y": 8,
|
| 349 |
-
"action": "DOWN",
|
| 350 |
-
"reward": -0.05,
|
| 351 |
-
"battery": 0.67
|
| 352 |
-
},
|
| 353 |
-
{
|
| 354 |
-
"step": 34,
|
| 355 |
-
"x": 3,
|
| 356 |
-
"y": 8,
|
| 357 |
-
"action": "LEFT",
|
| 358 |
-
"reward": -0.05,
|
| 359 |
-
"battery": 0.66
|
| 360 |
-
},
|
| 361 |
-
{
|
| 362 |
-
"step": 35,
|
| 363 |
-
"x": 3,
|
| 364 |
-
"y": 9,
|
| 365 |
-
"action": "DOWN",
|
| 366 |
-
"reward": -0.05,
|
| 367 |
-
"battery": 0.65
|
| 368 |
-
},
|
| 369 |
-
{
|
| 370 |
-
"step": 36,
|
| 371 |
-
"x": 2,
|
| 372 |
-
"y": 9,
|
| 373 |
-
"action": "LEFT",
|
| 374 |
-
"reward": 0.75,
|
| 375 |
-
"battery": 0.64
|
| 376 |
-
}
|
| 377 |
-
],
|
| 378 |
-
"grid_meta": {
|
| 379 |
-
"width": 14,
|
| 380 |
-
"height": 14
|
| 381 |
-
},
|
| 382 |
-
"delivery_positions": [
|
| 383 |
-
[
|
| 384 |
-
12,
|
| 385 |
-
0
|
| 386 |
-
],
|
| 387 |
-
[
|
| 388 |
-
4,
|
| 389 |
-
5
|
| 390 |
-
],
|
| 391 |
-
[
|
| 392 |
-
2,
|
| 393 |
-
9
|
| 394 |
-
]
|
| 395 |
-
],
|
| 396 |
-
"deliveries_done": 3,
|
| 397 |
-
"total_reward": 0.45,
|
| 398 |
-
"total_steps": 36
|
| 399 |
-
},
|
| 400 |
{
|
| 401 |
"task": "drone_env.core.graders:grade_hard",
|
| 402 |
"steps": [
|
|
@@ -17944,5 +17546,158 @@
|
|
| 17944 |
"deliveries_done": 1,
|
| 17945 |
"total_reward": 1.35,
|
| 17946 |
"total_steps": 4
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 17947 |
}
|
| 17948 |
]
|
|
|
|
| 1 |
[
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 2 |
{
|
| 3 |
"task": "drone_env.core.graders:grade_hard",
|
| 4 |
"steps": [
|
|
|
|
| 17546 |
"deliveries_done": 1,
|
| 17547 |
"total_reward": 1.35,
|
| 17548 |
"total_steps": 4
|
| 17549 |
+
},
|
| 17550 |
+
{
|
| 17551 |
+
"task": "drone_env.core.graders:grade_easy",
|
| 17552 |
+
"steps": [
|
| 17553 |
+
{
|
| 17554 |
+
"step": 1,
|
| 17555 |
+
"x": 1,
|
| 17556 |
+
"y": 7,
|
| 17557 |
+
"action": "DOWN",
|
| 17558 |
+
"reward": 0.1,
|
| 17559 |
+
"battery": 0.9833,
|
| 17560 |
+
"message": "On road \ud83d\udee3\ufe0f"
|
| 17561 |
+
},
|
| 17562 |
+
{
|
| 17563 |
+
"step": 2,
|
| 17564 |
+
"x": 0,
|
| 17565 |
+
"y": 7,
|
| 17566 |
+
"action": "LEFT",
|
| 17567 |
+
"reward": 1.05,
|
| 17568 |
+
"battery": 0.9667,
|
| 17569 |
+
"message": "\u2705 Delivery 1/1 done!"
|
| 17570 |
+
}
|
| 17571 |
+
],
|
| 17572 |
+
"grid_meta": {
|
| 17573 |
+
"width": 10,
|
| 17574 |
+
"height": 10
|
| 17575 |
+
},
|
| 17576 |
+
"delivery_positions": [
|
| 17577 |
+
[
|
| 17578 |
+
0,
|
| 17579 |
+
7
|
| 17580 |
+
]
|
| 17581 |
+
],
|
| 17582 |
+
"deliveries_done": 1,
|
| 17583 |
+
"total_reward": 1.15,
|
| 17584 |
+
"total_steps": 2
|
| 17585 |
+
},
|
| 17586 |
+
{
|
| 17587 |
+
"task": "drone_env.core.graders:grade_easy",
|
| 17588 |
+
"steps": [
|
| 17589 |
+
{
|
| 17590 |
+
"step": 1,
|
| 17591 |
+
"x": 4,
|
| 17592 |
+
"y": 5,
|
| 17593 |
+
"action": "UP",
|
| 17594 |
+
"reward": 0.1,
|
| 17595 |
+
"battery": 0.9833,
|
| 17596 |
+
"message": "On road \ud83d\udee3\ufe0f"
|
| 17597 |
+
},
|
| 17598 |
+
{
|
| 17599 |
+
"step": 2,
|
| 17600 |
+
"x": 4,
|
| 17601 |
+
"y": 4,
|
| 17602 |
+
"action": "UP",
|
| 17603 |
+
"reward": 0.1,
|
| 17604 |
+
"battery": 0.9667,
|
| 17605 |
+
"message": "On road \ud83d\udee3\ufe0f"
|
| 17606 |
+
},
|
| 17607 |
+
{
|
| 17608 |
+
"step": 3,
|
| 17609 |
+
"x": 4,
|
| 17610 |
+
"y": 3,
|
| 17611 |
+
"action": "UP",
|
| 17612 |
+
"reward": 0.1,
|
| 17613 |
+
"battery": 0.95,
|
| 17614 |
+
"message": "On road \ud83d\udee3\ufe0f"
|
| 17615 |
+
},
|
| 17616 |
+
{
|
| 17617 |
+
"step": 4,
|
| 17618 |
+
"x": 4,
|
| 17619 |
+
"y": 2,
|
| 17620 |
+
"action": "UP",
|
| 17621 |
+
"reward": 0.1,
|
| 17622 |
+
"battery": 0.9333,
|
| 17623 |
+
"message": "On road \ud83d\udee3\ufe0f"
|
| 17624 |
+
},
|
| 17625 |
+
{
|
| 17626 |
+
"step": 5,
|
| 17627 |
+
"x": 3,
|
| 17628 |
+
"y": 2,
|
| 17629 |
+
"action": "LEFT",
|
| 17630 |
+
"reward": 1.05,
|
| 17631 |
+
"battery": 0.9167,
|
| 17632 |
+
"message": "\u2705 Delivery 1/1 done!"
|
| 17633 |
+
}
|
| 17634 |
+
],
|
| 17635 |
+
"grid_meta": {
|
| 17636 |
+
"width": 10,
|
| 17637 |
+
"height": 10
|
| 17638 |
+
},
|
| 17639 |
+
"delivery_positions": [
|
| 17640 |
+
[
|
| 17641 |
+
3,
|
| 17642 |
+
2
|
| 17643 |
+
]
|
| 17644 |
+
],
|
| 17645 |
+
"deliveries_done": 1,
|
| 17646 |
+
"total_reward": 1.45,
|
| 17647 |
+
"total_steps": 5
|
| 17648 |
+
},
|
| 17649 |
+
{
|
| 17650 |
+
"task": "drone_env.core.graders:grade_easy",
|
| 17651 |
+
"steps": [
|
| 17652 |
+
{
|
| 17653 |
+
"step": 1,
|
| 17654 |
+
"x": 3,
|
| 17655 |
+
"y": 3,
|
| 17656 |
+
"action": "UP",
|
| 17657 |
+
"reward": 0.1,
|
| 17658 |
+
"battery": 0.9833,
|
| 17659 |
+
"message": "On road \ud83d\udee3\ufe0f"
|
| 17660 |
+
},
|
| 17661 |
+
{
|
| 17662 |
+
"step": 2,
|
| 17663 |
+
"x": 3,
|
| 17664 |
+
"y": 2,
|
| 17665 |
+
"action": "UP",
|
| 17666 |
+
"reward": 0.1,
|
| 17667 |
+
"battery": 0.9667,
|
| 17668 |
+
"message": "Flying over a tree! \ud83c\udf33"
|
| 17669 |
+
},
|
| 17670 |
+
{
|
| 17671 |
+
"step": 3,
|
| 17672 |
+
"x": 3,
|
| 17673 |
+
"y": 1,
|
| 17674 |
+
"action": "UP",
|
| 17675 |
+
"reward": 0.1,
|
| 17676 |
+
"battery": 0.95,
|
| 17677 |
+
"message": "On road \ud83d\udee3\ufe0f"
|
| 17678 |
+
},
|
| 17679 |
+
{
|
| 17680 |
+
"step": 4,
|
| 17681 |
+
"x": 4,
|
| 17682 |
+
"y": 1,
|
| 17683 |
+
"action": "RIGHT",
|
| 17684 |
+
"reward": 1.05,
|
| 17685 |
+
"battery": 0.9333,
|
| 17686 |
+
"message": "\u2705 Delivery 1/1 done!"
|
| 17687 |
+
}
|
| 17688 |
+
],
|
| 17689 |
+
"grid_meta": {
|
| 17690 |
+
"width": 10,
|
| 17691 |
+
"height": 10
|
| 17692 |
+
},
|
| 17693 |
+
"delivery_positions": [
|
| 17694 |
+
[
|
| 17695 |
+
4,
|
| 17696 |
+
1
|
| 17697 |
+
]
|
| 17698 |
+
],
|
| 17699 |
+
"deliveries_done": 1,
|
| 17700 |
+
"total_reward": 1.35,
|
| 17701 |
+
"total_steps": 4
|
| 17702 |
}
|
| 17703 |
]
|
pyproject.toml
CHANGED
|
@@ -17,6 +17,7 @@ dependencies = [
|
|
| 17 |
"openenv-core[core]>=0.2.1",
|
| 18 |
"torch>=2.0.0",
|
| 19 |
"openai>=1.0.0",
|
|
|
|
| 20 |
"python-multipart>=0.0.9",
|
| 21 |
"fastapi>=0.115.0",
|
| 22 |
"uvicorn>=0.24.0",
|
|
|
|
| 17 |
"openenv-core[core]>=0.2.1",
|
| 18 |
"torch>=2.0.0",
|
| 19 |
"openai>=1.0.0",
|
| 20 |
+
"httpx>=0.27.0",
|
| 21 |
"python-multipart>=0.0.9",
|
| 22 |
"fastapi>=0.115.0",
|
| 23 |
"uvicorn>=0.24.0",
|
requirements.txt
CHANGED
|
@@ -2,6 +2,7 @@
|
|
| 2 |
openenv-core[core]>=0.2.1
|
| 3 |
torch>=2.0.0
|
| 4 |
openai>=1.0.0
|
|
|
|
| 5 |
fastapi>=0.115.0
|
| 6 |
uvicorn>=0.24.0
|
| 7 |
python-multipart>=0.0.9
|
|
|
|
| 2 |
openenv-core[core]>=0.2.1
|
| 3 |
torch>=2.0.0
|
| 4 |
openai>=1.0.0
|
| 5 |
+
httpx>=0.27.0
|
| 6 |
fastapi>=0.115.0
|
| 7 |
uvicorn>=0.24.0
|
| 8 |
python-multipart>=0.0.9
|
server/app.py
CHANGED
|
@@ -76,7 +76,59 @@ _env = DroneDeliveryEnvironment()
|
|
| 76 |
|
| 77 |
@app.get("/health")
|
| 78 |
async def health():
|
| 79 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 80 |
|
| 81 |
@app.post("/reset", response_model=DroneObservation)
|
| 82 |
async def reset(action: Optional[DroneAction] = None):
|
|
|
|
| 76 |
|
| 77 |
@app.get("/health")
|
| 78 |
async def health():
|
| 79 |
+
# OpenEnv validator requires status == "healthy"
|
| 80 |
+
return {"status": "healthy", "version": "0.2.1"}
|
| 81 |
+
|
| 82 |
+
|
| 83 |
+
@app.get("/metadata")
|
| 84 |
+
async def metadata():
|
| 85 |
+
"""OpenEnv spec: GET /metadata returns name and description."""
|
| 86 |
+
return {
|
| 87 |
+
"name": "drone_env",
|
| 88 |
+
"description": "SkyRelic Drone Delivery reinforcement-learning environment with easy/medium/hard delivery tasks on a grid world.",
|
| 89 |
+
"version": "0.2.1",
|
| 90 |
+
"tasks": [
|
| 91 |
+
{"id": "easy_delivery", "grader": "drone_env.core.graders:grade_easy"},
|
| 92 |
+
{"id": "medium_delivery", "grader": "drone_env.core.graders:grade_medium"},
|
| 93 |
+
{"id": "hard_delivery", "grader": "drone_env.core.graders:grade_hard"},
|
| 94 |
+
],
|
| 95 |
+
}
|
| 96 |
+
|
| 97 |
+
|
| 98 |
+
@app.get("/schema")
|
| 99 |
+
async def schema():
|
| 100 |
+
"""OpenEnv spec: GET /schema returns action, observation, and state schemas."""
|
| 101 |
+
return {
|
| 102 |
+
"action": DroneAction.model_json_schema(),
|
| 103 |
+
"observation": DroneObservation.model_json_schema(),
|
| 104 |
+
"state": DroneState.model_json_schema(),
|
| 105 |
+
}
|
| 106 |
+
|
| 107 |
+
|
| 108 |
+
@app.post("/mcp")
|
| 109 |
+
async def mcp(request: Request):
|
| 110 |
+
"""OpenEnv spec: POST /mcp returns JSON-RPC 2.0 payload."""
|
| 111 |
+
body = {}
|
| 112 |
+
try:
|
| 113 |
+
body = await request.json()
|
| 114 |
+
except Exception:
|
| 115 |
+
pass
|
| 116 |
+
method = body.get("method", "tools/list")
|
| 117 |
+
req_id = body.get("id", 1)
|
| 118 |
+
if method == "tools/list":
|
| 119 |
+
result = {
|
| 120 |
+
"tools": [
|
| 121 |
+
{"name": "reset", "description": "Reset the drone environment"},
|
| 122 |
+
{"name": "step", "description": "Take one step in the environment"},
|
| 123 |
+
{"name": "state", "description": "Get current environment state"},
|
| 124 |
+
{"name": "grade", "description": "Get current task score"},
|
| 125 |
+
]
|
| 126 |
+
}
|
| 127 |
+
elif method == "tools/call":
|
| 128 |
+
result = {"content": [{"type": "text", "text": "Use /reset, /step, /state, or /grade endpoints."}]}
|
| 129 |
+
else:
|
| 130 |
+
result = {"message": "OpenEnv drone_env MCP bridge"}
|
| 131 |
+
return {"jsonrpc": "2.0", "id": req_id, "result": result}
|
| 132 |
|
| 133 |
@app.post("/reset", response_model=DroneObservation)
|
| 134 |
async def reset(action: Optional[DroneAction] = None):
|