manikandan-n-07 commited on
Commit
3f66446
·
1 Parent(s): 67b5e93

Standardization: Applied mandatory inference and validation templates

Browse files
Dockerfile CHANGED
@@ -1,5 +1,5 @@
1
  # Use official lightweight Python image
2
- # REBUILD_TIMESTAMP: 2026-04-07 18:58 (Final Phase 2 Sync)
3
  FROM python:3.10-slim
4
 
5
  # Set working directory
@@ -27,4 +27,4 @@ ENV HF_HOME=/tmp/.cache
27
 
28
  # Command to run the FastAPI server
29
  # This calls the main function in server/app.py which starts uvicorn
30
- CMD ["python", "server/app.py", "--host", "0.0.0.0", "--port", "8000"]
 
1
  # Use official lightweight Python image
2
+ # REBUILD_TIMESTAMP: 2026-04-07 20:10 (Package Structure Fix)
3
  FROM python:3.10-slim
4
 
5
  # Set working directory
 
27
 
28
  # Command to run the FastAPI server
29
  # This calls the main function in server/app.py which starts uvicorn
30
+ CMD ["python", "drone_env/server/app.py", "--host", "0.0.0.0", "--port", "8000"]
README.md CHANGED
@@ -81,41 +81,39 @@ The framework supports three operational modes:
81
  The codebase follows a clean separation-of-concerns architecture across four distinct layers:
82
 
83
  ```
84
- drone_env/
85
- ├── core/ # Simulation Logic Layer
86
- │ ├── drone.py # Movement physics & battery drain
87
- │ ├── graders.py # Unified scoring logic (0.01 - 0.99)
88
- │ ├── grid_generator.py # Map generation logic
89
- │ ├── obstacles.py # Collision & terrain detection
90
- │ ├── state_manager.py # Episodic state management
91
- ── tasks.py # Mission difficulty configurations
92
- ── rl/ # Intelligence Layer
93
- │ ├── model.py # Neural network architecture (DQN)
94
- │ ├── policy.py # Action selection policies
95
- ── trainer.py # Path analytics & learning engine
96
- ── server/ # Interface Layer
97
- │ ├── app.py # FastAPI server & Grader discovery
98
- │ ├── grid_world_environment.py # Main simulation environment
99
- │ ├── map_generator.py # Procedural map generation
100
- ── static/ # Dashboard Assets
101
- ── index.html # Interactive dashboard layout
102
- ├── script.js # Frontend logic & Mission modal
103
- ├── style.css # Cyan/Amber aesthetic styles
104
- └── favicon.png # SkyRelic Branding (favicon)
105
  ├── data/ # Persistence Layer
106
  │ ├── memory.json # Historical episode logs (JSON)
107
  │ └── train.log # Neural training logs
108
  ├── tests/ # Validation Layer
109
  │ ├── test_api.py # Endpoint integration tests
110
  │ └── test_env.py # Physics & Grading unit tests
 
 
111
  ├── openenv.yaml # Mission Manifest (Tasks & Graders)
112
  ├── pyproject.toml # Python project & dependency config
113
- ├── models.py # Unified Pydantic data models
114
- ├── train.py # Neural training entry point
115
- ├── inference.py # LLM-guided inference entry point
116
- ├── client.py # CLI client for testing
117
  ├── Dockerfile # Deployment container manifest
118
- └── validate-submission.sh # Submission validation script
119
  ```
120
 
121
  ### Component Interaction Flow
@@ -350,7 +348,7 @@ python train.py --task hard_delivery --episodes 5000
350
  ### Python SDK Client
351
 
352
  ```python
353
- from client import DroneEnvClient
354
 
355
  with DroneEnvClient("http://localhost:8000") as client:
356
  # Check server health
@@ -506,8 +504,8 @@ And a concise per-step user prompt with position, battery, target, and distance.
506
  ### Build & Run Locally
507
 
508
  ```bash
509
- # Build from the server/ directory
510
- docker build -t drone-env -f server/Dockerfile .
511
 
512
  # Run with health check
513
  docker run -p 8000:8000 \
@@ -553,7 +551,7 @@ HEALTHCHECK --interval=30s --timeout=3s \
553
  CMD curl -f http://localhost:8000/health || exit 1
554
 
555
  # Entrypoint
556
- CMD ["sh", "-c", "cd /app/env && uvicorn server.app:app --host 0.0.0.0 --port 8000"]
557
  ```
558
 
559
  ---
@@ -567,7 +565,7 @@ spec_version: 1
567
  name: drone-env
568
  type: space
569
  runtime: fastapi
570
- app: server.app:app
571
  port: 8000
572
  tasks:
573
  - id: easy_delivery
 
81
  The codebase follows a clean separation-of-concerns architecture across four distinct layers:
82
 
83
  ```
84
+ .
85
+ ├── drone_env/ # Core Package Subdirectory
86
+ │ ├── core/ # Simulation Logic Layer
87
+ ├── drone.py # Movement physics & battery drain
88
+ ├── graders.py # Unified scoring logic (0.01 - 0.99)
89
+ ├── grid_generator.py # Map generation logic
90
+ ├── obstacles.py # Collision & terrain detection
91
+ │ ├── state_manager.py # Episodic state management
92
+ │ │ └── tasks.py # Mission difficulty configurations
93
+ │ ├── rl/ # Intelligence Layer
94
+ ├── model.py # Neural network architecture (DQN)
95
+ │ ├── policy.py # Action selection policies
96
+ │ │ └── trainer.py # Path analytics & learning engine
97
+ │ ├── server/ # Interface Layer
98
+ ├── app.py # FastAPI server & Grader discovery
99
+ ├── grid_world_environment.py # Main simulation environment
100
+ │ ├── map_generator.py # Procedural map generation
101
+ │ └── static/ # Dashboard Assets
102
+ ├── models.py # Unified Pydantic data models
103
+ ├── client.py # CLI client for testing
104
+ └── __init__.py # Package initialization
105
  ├── data/ # Persistence Layer
106
  │ ├── memory.json # Historical episode logs (JSON)
107
  │ └── train.log # Neural training logs
108
  ├── tests/ # Validation Layer
109
  │ ├── test_api.py # Endpoint integration tests
110
  │ └── test_env.py # Physics & Grading unit tests
111
+ ├── inference.py # Standardized Inference Entry Point
112
+ ├── validate-submission.sh # Submission validation script
113
  ├── openenv.yaml # Mission Manifest (Tasks & Graders)
114
  ├── pyproject.toml # Python project & dependency config
 
 
 
 
115
  ├── Dockerfile # Deployment container manifest
116
+ └── README.md # Documentation
117
  ```
118
 
119
  ### Component Interaction Flow
 
348
  ### Python SDK Client
349
 
350
  ```python
351
+ from drone_env.client import DroneEnvClient
352
 
353
  with DroneEnvClient("http://localhost:8000") as client:
354
  # Check server health
 
504
  ### Build & Run Locally
505
 
506
  ```bash
507
+ # Build from the root directory
508
+ docker build -t drone-env .
509
 
510
  # Run with health check
511
  docker run -p 8000:8000 \
 
551
  CMD curl -f http://localhost:8000/health || exit 1
552
 
553
  # Entrypoint
554
+ CMD ["python", "drone_env/server/app.py", "--host", "0.0.0.0", "--port", "8000"]
555
  ```
556
 
557
  ---
 
565
  name: drone-env
566
  type: space
567
  runtime: fastapi
568
+ app: drone_env.server.app:app
569
  port: 8000
570
  tasks:
571
  - id: easy_delivery
data/memory.json CHANGED
@@ -1,136 +1,4 @@
1
  [
2
- {
3
- "task": "drone_env.core.graders:grade_easy",
4
- "steps": [
5
- {
6
- "step": 1,
7
- "x": 9,
8
- "y": 8,
9
- "action": "RIGHT",
10
- "reward": -0.25,
11
- "battery": 0.9833
12
- },
13
- {
14
- "step": 2,
15
- "x": 9,
16
- "y": 8,
17
- "action": "RIGHT",
18
- "reward": -0.25,
19
- "battery": 0.9667
20
- },
21
- {
22
- "step": 3,
23
- "x": 9,
24
- "y": 8,
25
- "action": "RIGHT",
26
- "reward": -0.25,
27
- "battery": 0.95
28
- },
29
- {
30
- "step": 4,
31
- "x": 9,
32
- "y": 8,
33
- "action": "RIGHT",
34
- "reward": -0.25,
35
- "battery": 0.9333
36
- },
37
- {
38
- "step": 5,
39
- "x": 9,
40
- "y": 8,
41
- "action": "RIGHT",
42
- "reward": -0.25,
43
- "battery": 0.9167
44
- }
45
- ],
46
- "grid_meta": {
47
- "width": 10,
48
- "height": 10
49
- },
50
- "delivery_positions": [
51
- [
52
- 7,
53
- 3
54
- ]
55
- ],
56
- "deliveries_done": 0,
57
- "total_reward": -1.25,
58
- "total_steps": 5
59
- },
60
- {
61
- "task": "drone_env.core.graders:grade_easy",
62
- "steps": [
63
- {
64
- "step": 1,
65
- "x": 8,
66
- "y": 6,
67
- "action": "UP",
68
- "reward": -0.05,
69
- "battery": 0.9833
70
- },
71
- {
72
- "step": 2,
73
- "x": 9,
74
- "y": 6,
75
- "action": "RIGHT",
76
- "reward": -0.05,
77
- "battery": 0.9667
78
- },
79
- {
80
- "step": 3,
81
- "x": 9,
82
- "y": 7,
83
- "action": "DOWN",
84
- "reward": -0.05,
85
- "battery": 0.95
86
- },
87
- {
88
- "step": 4,
89
- "x": 8,
90
- "y": 7,
91
- "action": "LEFT",
92
- "reward": -0.05,
93
- "battery": 0.9333
94
- },
95
- {
96
- "step": 5,
97
- "x": 8,
98
- "y": 7,
99
- "action": "WAIT",
100
- "reward": -0.1,
101
- "battery": 0.9167
102
- },
103
- {
104
- "step": 6,
105
- "x": 8,
106
- "y": 6,
107
- "action": "UP",
108
- "reward": -0.05,
109
- "battery": 0.9
110
- },
111
- {
112
- "step": 7,
113
- "x": 9,
114
- "y": 6,
115
- "action": "RIGHT",
116
- "reward": -0.05,
117
- "battery": 0.8833
118
- }
119
- ],
120
- "grid_meta": {
121
- "width": 10,
122
- "height": 10
123
- },
124
- "delivery_positions": [
125
- [
126
- 3,
127
- 8
128
- ]
129
- ],
130
- "deliveries_done": 0,
131
- "total_reward": -0.4,
132
- "total_steps": 7
133
- },
134
  {
135
  "task": "drone_env.core.graders:grade_easy",
136
  "steps": [
@@ -17192,5 +17060,1121 @@
17192
  "deliveries_done": 5,
17193
  "total_reward": 13.5,
17194
  "total_steps": 37
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
17195
  }
17196
  ]
 
1
  [
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
2
  {
3
  "task": "drone_env.core.graders:grade_easy",
4
  "steps": [
 
17060
  "deliveries_done": 5,
17061
  "total_reward": 13.5,
17062
  "total_steps": 37
17063
+ },
17064
+ {
17065
+ "task": "drone_env.core.graders:grade_easy",
17066
+ "steps": [
17067
+ {
17068
+ "step": 1,
17069
+ "x": 9,
17070
+ "y": 0,
17071
+ "action": "WAIT",
17072
+ "reward": 0.1,
17073
+ "battery": 0.9833,
17074
+ "message": "Drone is idling (WAIT)... \ud83d\udd0b"
17075
+ },
17076
+ {
17077
+ "step": 2,
17078
+ "x": 9,
17079
+ "y": 0,
17080
+ "action": "WAIT",
17081
+ "reward": 0.1,
17082
+ "battery": 0.9667,
17083
+ "message": "Drone is idling (WAIT)... \ud83d\udd0b"
17084
+ },
17085
+ {
17086
+ "step": 3,
17087
+ "x": 9,
17088
+ "y": 0,
17089
+ "action": "WAIT",
17090
+ "reward": 0.1,
17091
+ "battery": 0.95,
17092
+ "message": "Drone is idling (WAIT)... \ud83d\udd0b"
17093
+ },
17094
+ {
17095
+ "step": 4,
17096
+ "x": 9,
17097
+ "y": 0,
17098
+ "action": "WAIT",
17099
+ "reward": 0.1,
17100
+ "battery": 0.9333,
17101
+ "message": "Drone is idling (WAIT)... \ud83d\udd0b"
17102
+ },
17103
+ {
17104
+ "step": 5,
17105
+ "x": 9,
17106
+ "y": 0,
17107
+ "action": "WAIT",
17108
+ "reward": 0.1,
17109
+ "battery": 0.9167,
17110
+ "message": "Drone is idling (WAIT)... \ud83d\udd0b"
17111
+ },
17112
+ {
17113
+ "step": 6,
17114
+ "x": 9,
17115
+ "y": 0,
17116
+ "action": "WAIT",
17117
+ "reward": 0.1,
17118
+ "battery": 0.9,
17119
+ "message": "Drone is idling (WAIT)... \ud83d\udd0b"
17120
+ },
17121
+ {
17122
+ "step": 7,
17123
+ "x": 9,
17124
+ "y": 0,
17125
+ "action": "WAIT",
17126
+ "reward": 0.1,
17127
+ "battery": 0.8833,
17128
+ "message": "Drone is idling (WAIT)... \ud83d\udd0b"
17129
+ },
17130
+ {
17131
+ "step": 8,
17132
+ "x": 9,
17133
+ "y": 0,
17134
+ "action": "WAIT",
17135
+ "reward": 0.1,
17136
+ "battery": 0.8667,
17137
+ "message": "Drone is idling (WAIT)... \ud83d\udd0b"
17138
+ },
17139
+ {
17140
+ "step": 9,
17141
+ "x": 9,
17142
+ "y": 0,
17143
+ "action": "WAIT",
17144
+ "reward": 0.1,
17145
+ "battery": 0.85,
17146
+ "message": "Drone is idling (WAIT)... \ud83d\udd0b"
17147
+ },
17148
+ {
17149
+ "step": 10,
17150
+ "x": 9,
17151
+ "y": 0,
17152
+ "action": "WAIT",
17153
+ "reward": 0.1,
17154
+ "battery": 0.8333,
17155
+ "message": "Drone is idling (WAIT)... \ud83d\udd0b"
17156
+ },
17157
+ {
17158
+ "step": 11,
17159
+ "x": 9,
17160
+ "y": 0,
17161
+ "action": "WAIT",
17162
+ "reward": 0.1,
17163
+ "battery": 0.8167,
17164
+ "message": "Drone is idling (WAIT)... \ud83d\udd0b"
17165
+ },
17166
+ {
17167
+ "step": 12,
17168
+ "x": 9,
17169
+ "y": 0,
17170
+ "action": "WAIT",
17171
+ "reward": 0.1,
17172
+ "battery": 0.8,
17173
+ "message": "Drone is idling (WAIT)... \ud83d\udd0b"
17174
+ },
17175
+ {
17176
+ "step": 13,
17177
+ "x": 9,
17178
+ "y": 0,
17179
+ "action": "WAIT",
17180
+ "reward": 0.1,
17181
+ "battery": 0.7833,
17182
+ "message": "Drone is idling (WAIT)... \ud83d\udd0b"
17183
+ },
17184
+ {
17185
+ "step": 14,
17186
+ "x": 9,
17187
+ "y": 0,
17188
+ "action": "WAIT",
17189
+ "reward": 0.1,
17190
+ "battery": 0.7667,
17191
+ "message": "Drone is idling (WAIT)... \ud83d\udd0b"
17192
+ },
17193
+ {
17194
+ "step": 15,
17195
+ "x": 9,
17196
+ "y": 0,
17197
+ "action": "WAIT",
17198
+ "reward": 0.1,
17199
+ "battery": 0.75,
17200
+ "message": "Drone is idling (WAIT)... \ud83d\udd0b"
17201
+ },
17202
+ {
17203
+ "step": 16,
17204
+ "x": 9,
17205
+ "y": 0,
17206
+ "action": "WAIT",
17207
+ "reward": 0.1,
17208
+ "battery": 0.7333,
17209
+ "message": "Drone is idling (WAIT)... \ud83d\udd0b"
17210
+ },
17211
+ {
17212
+ "step": 17,
17213
+ "x": 9,
17214
+ "y": 0,
17215
+ "action": "WAIT",
17216
+ "reward": 0.1,
17217
+ "battery": 0.7167,
17218
+ "message": "Drone is idling (WAIT)... \ud83d\udd0b"
17219
+ },
17220
+ {
17221
+ "step": 18,
17222
+ "x": 9,
17223
+ "y": 0,
17224
+ "action": "WAIT",
17225
+ "reward": 0.1,
17226
+ "battery": 0.7,
17227
+ "message": "Drone is idling (WAIT)... \ud83d\udd0b"
17228
+ },
17229
+ {
17230
+ "step": 19,
17231
+ "x": 9,
17232
+ "y": 0,
17233
+ "action": "WAIT",
17234
+ "reward": 0.1,
17235
+ "battery": 0.6833,
17236
+ "message": "Drone is idling (WAIT)... \ud83d\udd0b"
17237
+ },
17238
+ {
17239
+ "step": 20,
17240
+ "x": 9,
17241
+ "y": 0,
17242
+ "action": "WAIT",
17243
+ "reward": 0.1,
17244
+ "battery": 0.6667,
17245
+ "message": "Drone is idling (WAIT)... \ud83d\udd0b"
17246
+ },
17247
+ {
17248
+ "step": 21,
17249
+ "x": 9,
17250
+ "y": 0,
17251
+ "action": "WAIT",
17252
+ "reward": 0.1,
17253
+ "battery": 0.65,
17254
+ "message": "Drone is idling (WAIT)... \ud83d\udd0b"
17255
+ },
17256
+ {
17257
+ "step": 22,
17258
+ "x": 9,
17259
+ "y": 0,
17260
+ "action": "WAIT",
17261
+ "reward": 0.1,
17262
+ "battery": 0.6333,
17263
+ "message": "Drone is idling (WAIT)... \ud83d\udd0b"
17264
+ },
17265
+ {
17266
+ "step": 23,
17267
+ "x": 9,
17268
+ "y": 0,
17269
+ "action": "WAIT",
17270
+ "reward": 0.1,
17271
+ "battery": 0.6167,
17272
+ "message": "Drone is idling (WAIT)... \ud83d\udd0b"
17273
+ },
17274
+ {
17275
+ "step": 24,
17276
+ "x": 9,
17277
+ "y": 0,
17278
+ "action": "WAIT",
17279
+ "reward": 0.1,
17280
+ "battery": 0.6,
17281
+ "message": "Drone is idling (WAIT)... \ud83d\udd0b"
17282
+ },
17283
+ {
17284
+ "step": 25,
17285
+ "x": 9,
17286
+ "y": 0,
17287
+ "action": "WAIT",
17288
+ "reward": 0.1,
17289
+ "battery": 0.5833,
17290
+ "message": "Drone is idling (WAIT)... \ud83d\udd0b"
17291
+ },
17292
+ {
17293
+ "step": 26,
17294
+ "x": 9,
17295
+ "y": 0,
17296
+ "action": "WAIT",
17297
+ "reward": 0.1,
17298
+ "battery": 0.5667,
17299
+ "message": "Drone is idling (WAIT)... \ud83d\udd0b"
17300
+ },
17301
+ {
17302
+ "step": 27,
17303
+ "x": 9,
17304
+ "y": 0,
17305
+ "action": "WAIT",
17306
+ "reward": 0.1,
17307
+ "battery": 0.55,
17308
+ "message": "Drone is idling (WAIT)... \ud83d\udd0b"
17309
+ },
17310
+ {
17311
+ "step": 28,
17312
+ "x": 9,
17313
+ "y": 0,
17314
+ "action": "WAIT",
17315
+ "reward": 0.1,
17316
+ "battery": 0.5333,
17317
+ "message": "Drone is idling (WAIT)... \ud83d\udd0b"
17318
+ },
17319
+ {
17320
+ "step": 29,
17321
+ "x": 9,
17322
+ "y": 0,
17323
+ "action": "WAIT",
17324
+ "reward": 0.1,
17325
+ "battery": 0.5167,
17326
+ "message": "Drone is idling (WAIT)... \ud83d\udd0b"
17327
+ },
17328
+ {
17329
+ "step": 30,
17330
+ "x": 9,
17331
+ "y": 0,
17332
+ "action": "WAIT",
17333
+ "reward": 0.1,
17334
+ "battery": 0.5,
17335
+ "message": "Drone is idling (WAIT)... \ud83d\udd0b"
17336
+ },
17337
+ {
17338
+ "step": 31,
17339
+ "x": 9,
17340
+ "y": 0,
17341
+ "action": "WAIT",
17342
+ "reward": 0.1,
17343
+ "battery": 0.4833,
17344
+ "message": "Drone is idling (WAIT)... \ud83d\udd0b"
17345
+ },
17346
+ {
17347
+ "step": 32,
17348
+ "x": 9,
17349
+ "y": 0,
17350
+ "action": "WAIT",
17351
+ "reward": 0.1,
17352
+ "battery": 0.4667,
17353
+ "message": "Drone is idling (WAIT)... \ud83d\udd0b"
17354
+ },
17355
+ {
17356
+ "step": 33,
17357
+ "x": 9,
17358
+ "y": 0,
17359
+ "action": "WAIT",
17360
+ "reward": 0.1,
17361
+ "battery": 0.45,
17362
+ "message": "Drone is idling (WAIT)... \ud83d\udd0b"
17363
+ },
17364
+ {
17365
+ "step": 34,
17366
+ "x": 9,
17367
+ "y": 0,
17368
+ "action": "WAIT",
17369
+ "reward": 0.1,
17370
+ "battery": 0.4333,
17371
+ "message": "Drone is idling (WAIT)... \ud83d\udd0b"
17372
+ },
17373
+ {
17374
+ "step": 35,
17375
+ "x": 9,
17376
+ "y": 0,
17377
+ "action": "WAIT",
17378
+ "reward": 0.1,
17379
+ "battery": 0.4167,
17380
+ "message": "Drone is idling (WAIT)... \ud83d\udd0b"
17381
+ },
17382
+ {
17383
+ "step": 36,
17384
+ "x": 9,
17385
+ "y": 0,
17386
+ "action": "WAIT",
17387
+ "reward": 0.1,
17388
+ "battery": 0.4,
17389
+ "message": "Drone is idling (WAIT)... \ud83d\udd0b"
17390
+ },
17391
+ {
17392
+ "step": 37,
17393
+ "x": 9,
17394
+ "y": 0,
17395
+ "action": "WAIT",
17396
+ "reward": 0.1,
17397
+ "battery": 0.3833,
17398
+ "message": "Drone is idling (WAIT)... \ud83d\udd0b"
17399
+ },
17400
+ {
17401
+ "step": 38,
17402
+ "x": 9,
17403
+ "y": 0,
17404
+ "action": "WAIT",
17405
+ "reward": 0.1,
17406
+ "battery": 0.3667,
17407
+ "message": "Drone is idling (WAIT)... \ud83d\udd0b"
17408
+ },
17409
+ {
17410
+ "step": 39,
17411
+ "x": 9,
17412
+ "y": 0,
17413
+ "action": "WAIT",
17414
+ "reward": 0.1,
17415
+ "battery": 0.35,
17416
+ "message": "Drone is idling (WAIT)... \ud83d\udd0b"
17417
+ },
17418
+ {
17419
+ "step": 40,
17420
+ "x": 9,
17421
+ "y": 0,
17422
+ "action": "WAIT",
17423
+ "reward": 0.1,
17424
+ "battery": 0.3333,
17425
+ "message": "Drone is idling (WAIT)... \ud83d\udd0b"
17426
+ },
17427
+ {
17428
+ "step": 41,
17429
+ "x": 9,
17430
+ "y": 0,
17431
+ "action": "WAIT",
17432
+ "reward": 0.1,
17433
+ "battery": 0.3167,
17434
+ "message": "Drone is idling (WAIT)... \ud83d\udd0b"
17435
+ },
17436
+ {
17437
+ "step": 42,
17438
+ "x": 9,
17439
+ "y": 0,
17440
+ "action": "WAIT",
17441
+ "reward": 0.1,
17442
+ "battery": 0.3,
17443
+ "message": "Drone is idling (WAIT)... \ud83d\udd0b"
17444
+ },
17445
+ {
17446
+ "step": 43,
17447
+ "x": 9,
17448
+ "y": 0,
17449
+ "action": "WAIT",
17450
+ "reward": 0.1,
17451
+ "battery": 0.2833,
17452
+ "message": "Drone is idling (WAIT)... \ud83d\udd0b"
17453
+ },
17454
+ {
17455
+ "step": 44,
17456
+ "x": 9,
17457
+ "y": 0,
17458
+ "action": "WAIT",
17459
+ "reward": 0.1,
17460
+ "battery": 0.2667,
17461
+ "message": "Drone is idling (WAIT)... \ud83d\udd0b"
17462
+ },
17463
+ {
17464
+ "step": 45,
17465
+ "x": 9,
17466
+ "y": 0,
17467
+ "action": "WAIT",
17468
+ "reward": 0.1,
17469
+ "battery": 0.25,
17470
+ "message": "Drone is idling (WAIT)... \ud83d\udd0b"
17471
+ },
17472
+ {
17473
+ "step": 46,
17474
+ "x": 9,
17475
+ "y": 0,
17476
+ "action": "WAIT",
17477
+ "reward": 0.1,
17478
+ "battery": 0.2333,
17479
+ "message": "Drone is idling (WAIT)... \ud83d\udd0b"
17480
+ },
17481
+ {
17482
+ "step": 47,
17483
+ "x": 9,
17484
+ "y": 0,
17485
+ "action": "WAIT",
17486
+ "reward": 0.1,
17487
+ "battery": 0.2167,
17488
+ "message": "Drone is idling (WAIT)... \ud83d\udd0b"
17489
+ },
17490
+ {
17491
+ "step": 48,
17492
+ "x": 9,
17493
+ "y": 0,
17494
+ "action": "WAIT",
17495
+ "reward": 0.1,
17496
+ "battery": 0.2,
17497
+ "message": "Drone is idling (WAIT)... \ud83d\udd0b"
17498
+ },
17499
+ {
17500
+ "step": 49,
17501
+ "x": 9,
17502
+ "y": 0,
17503
+ "action": "WAIT",
17504
+ "reward": 0.1,
17505
+ "battery": 0.1833,
17506
+ "message": "Drone is idling (WAIT)... \ud83d\udd0b"
17507
+ },
17508
+ {
17509
+ "step": 50,
17510
+ "x": 9,
17511
+ "y": 0,
17512
+ "action": "WAIT",
17513
+ "reward": 0.1,
17514
+ "battery": 0.1667,
17515
+ "message": "Drone is idling (WAIT)... \ud83d\udd0b"
17516
+ },
17517
+ {
17518
+ "step": 51,
17519
+ "x": 9,
17520
+ "y": 0,
17521
+ "action": "WAIT",
17522
+ "reward": 0.1,
17523
+ "battery": 0.15,
17524
+ "message": "Drone is idling (WAIT)... \ud83d\udd0b"
17525
+ },
17526
+ {
17527
+ "step": 52,
17528
+ "x": 9,
17529
+ "y": 0,
17530
+ "action": "WAIT",
17531
+ "reward": 0.1,
17532
+ "battery": 0.1333,
17533
+ "message": "Drone is idling (WAIT)... \ud83d\udd0b"
17534
+ },
17535
+ {
17536
+ "step": 53,
17537
+ "x": 9,
17538
+ "y": 0,
17539
+ "action": "WAIT",
17540
+ "reward": 0.1,
17541
+ "battery": 0.1167,
17542
+ "message": "Drone is idling (WAIT)... \ud83d\udd0b"
17543
+ },
17544
+ {
17545
+ "step": 54,
17546
+ "x": 9,
17547
+ "y": 0,
17548
+ "action": "WAIT",
17549
+ "reward": 0.1,
17550
+ "battery": 0.1,
17551
+ "message": "Drone is idling (WAIT)... \ud83d\udd0b"
17552
+ },
17553
+ {
17554
+ "step": 55,
17555
+ "x": 9,
17556
+ "y": 0,
17557
+ "action": "WAIT",
17558
+ "reward": 0.1,
17559
+ "battery": 0.0833,
17560
+ "message": "Drone is idling (WAIT)... \ud83d\udd0b"
17561
+ },
17562
+ {
17563
+ "step": 56,
17564
+ "x": 9,
17565
+ "y": 0,
17566
+ "action": "WAIT",
17567
+ "reward": 0.1,
17568
+ "battery": 0.0667,
17569
+ "message": "Drone is idling (WAIT)... \ud83d\udd0b"
17570
+ },
17571
+ {
17572
+ "step": 57,
17573
+ "x": 9,
17574
+ "y": 0,
17575
+ "action": "WAIT",
17576
+ "reward": 0.1,
17577
+ "battery": 0.05,
17578
+ "message": "Drone is idling (WAIT)... \ud83d\udd0b"
17579
+ },
17580
+ {
17581
+ "step": 58,
17582
+ "x": 9,
17583
+ "y": 0,
17584
+ "action": "WAIT",
17585
+ "reward": 0.1,
17586
+ "battery": 0.0333,
17587
+ "message": "Drone is idling (WAIT)... \ud83d\udd0b"
17588
+ },
17589
+ {
17590
+ "step": 59,
17591
+ "x": 9,
17592
+ "y": 0,
17593
+ "action": "WAIT",
17594
+ "reward": 0.1,
17595
+ "battery": 0.0167,
17596
+ "message": "Drone is idling (WAIT)... \ud83d\udd0b"
17597
+ },
17598
+ {
17599
+ "step": 60,
17600
+ "x": 9,
17601
+ "y": 0,
17602
+ "action": "WAIT",
17603
+ "reward": 0.1,
17604
+ "battery": 0.0,
17605
+ "message": "Drone is idling (WAIT)... \ud83d\udd0b"
17606
+ }
17607
+ ],
17608
+ "grid_meta": {
17609
+ "width": 10,
17610
+ "height": 10
17611
+ },
17612
+ "delivery_positions": [
17613
+ [
17614
+ 0,
17615
+ 7
17616
+ ]
17617
+ ],
17618
+ "deliveries_done": 0,
17619
+ "total_reward": 6.1,
17620
+ "total_steps": 60
17621
+ },
17622
+ {
17623
+ "task": "drone_env.core.graders:grade_easy",
17624
+ "steps": [
17625
+ {
17626
+ "step": 1,
17627
+ "x": 8,
17628
+ "y": 7,
17629
+ "action": "LEFT",
17630
+ "reward": 0.1,
17631
+ "battery": 0.9833,
17632
+ "message": "On road \ud83d\udee3\ufe0f"
17633
+ },
17634
+ {
17635
+ "step": 2,
17636
+ "x": 8,
17637
+ "y": 8,
17638
+ "action": "DOWN",
17639
+ "reward": 0.1,
17640
+ "battery": 0.9667,
17641
+ "message": "On road \ud83d\udee3\ufe0f"
17642
+ },
17643
+ {
17644
+ "step": 3,
17645
+ "x": 7,
17646
+ "y": 8,
17647
+ "action": "LEFT",
17648
+ "reward": 0.1,
17649
+ "battery": 0.95,
17650
+ "message": "On road \ud83d\udee3\ufe0f"
17651
+ },
17652
+ {
17653
+ "step": 4,
17654
+ "x": 8,
17655
+ "y": 8,
17656
+ "action": "RIGHT",
17657
+ "reward": 0.1,
17658
+ "battery": 0.9333,
17659
+ "message": "On road \ud83d\udee3\ufe0f"
17660
+ },
17661
+ {
17662
+ "step": 5,
17663
+ "x": 7,
17664
+ "y": 8,
17665
+ "action": "LEFT",
17666
+ "reward": 0.1,
17667
+ "battery": 0.9167,
17668
+ "message": "On road \ud83d\udee3\ufe0f"
17669
+ },
17670
+ {
17671
+ "step": 6,
17672
+ "x": 8,
17673
+ "y": 8,
17674
+ "action": "RIGHT",
17675
+ "reward": 0.1,
17676
+ "battery": 0.9,
17677
+ "message": "On road \ud83d\udee3\ufe0f"
17678
+ },
17679
+ {
17680
+ "step": 7,
17681
+ "x": 7,
17682
+ "y": 8,
17683
+ "action": "LEFT",
17684
+ "reward": 0.1,
17685
+ "battery": 0.8833,
17686
+ "message": "On road \ud83d\udee3\ufe0f"
17687
+ },
17688
+ {
17689
+ "step": 8,
17690
+ "x": 7,
17691
+ "y": 8,
17692
+ "action": "WAIT",
17693
+ "reward": 0.1,
17694
+ "battery": 0.8667,
17695
+ "message": "Drone is idling (WAIT)... \ud83d\udd0b"
17696
+ },
17697
+ {
17698
+ "step": 9,
17699
+ "x": 7,
17700
+ "y": 8,
17701
+ "action": "WAIT",
17702
+ "reward": 0.1,
17703
+ "battery": 0.85,
17704
+ "message": "Drone is idling (WAIT)... \ud83d\udd0b"
17705
+ },
17706
+ {
17707
+ "step": 10,
17708
+ "x": 7,
17709
+ "y": 8,
17710
+ "action": "WAIT",
17711
+ "reward": 0.1,
17712
+ "battery": 0.8333,
17713
+ "message": "Drone is idling (WAIT)... \ud83d\udd0b"
17714
+ },
17715
+ {
17716
+ "step": 11,
17717
+ "x": 7,
17718
+ "y": 8,
17719
+ "action": "WAIT",
17720
+ "reward": 0.1,
17721
+ "battery": 0.8167,
17722
+ "message": "Drone is idling (WAIT)... \ud83d\udd0b"
17723
+ },
17724
+ {
17725
+ "step": 12,
17726
+ "x": 7,
17727
+ "y": 8,
17728
+ "action": "WAIT",
17729
+ "reward": 0.1,
17730
+ "battery": 0.8,
17731
+ "message": "Drone is idling (WAIT)... \ud83d\udd0b"
17732
+ },
17733
+ {
17734
+ "step": 13,
17735
+ "x": 7,
17736
+ "y": 8,
17737
+ "action": "WAIT",
17738
+ "reward": 0.1,
17739
+ "battery": 0.7833,
17740
+ "message": "Drone is idling (WAIT)... \ud83d\udd0b"
17741
+ },
17742
+ {
17743
+ "step": 14,
17744
+ "x": 7,
17745
+ "y": 8,
17746
+ "action": "WAIT",
17747
+ "reward": 0.1,
17748
+ "battery": 0.7667,
17749
+ "message": "Drone is idling (WAIT)... \ud83d\udd0b"
17750
+ },
17751
+ {
17752
+ "step": 15,
17753
+ "x": 7,
17754
+ "y": 8,
17755
+ "action": "WAIT",
17756
+ "reward": 0.1,
17757
+ "battery": 0.75,
17758
+ "message": "Drone is idling (WAIT)... \ud83d\udd0b"
17759
+ },
17760
+ {
17761
+ "step": 16,
17762
+ "x": 7,
17763
+ "y": 8,
17764
+ "action": "WAIT",
17765
+ "reward": 0.1,
17766
+ "battery": 0.7333,
17767
+ "message": "Drone is idling (WAIT)... \ud83d\udd0b"
17768
+ },
17769
+ {
17770
+ "step": 17,
17771
+ "x": 7,
17772
+ "y": 8,
17773
+ "action": "WAIT",
17774
+ "reward": 0.1,
17775
+ "battery": 0.7167,
17776
+ "message": "Drone is idling (WAIT)... \ud83d\udd0b"
17777
+ },
17778
+ {
17779
+ "step": 18,
17780
+ "x": 7,
17781
+ "y": 8,
17782
+ "action": "WAIT",
17783
+ "reward": 0.1,
17784
+ "battery": 0.7,
17785
+ "message": "Drone is idling (WAIT)... \ud83d\udd0b"
17786
+ },
17787
+ {
17788
+ "step": 19,
17789
+ "x": 7,
17790
+ "y": 8,
17791
+ "action": "WAIT",
17792
+ "reward": 0.1,
17793
+ "battery": 0.6833,
17794
+ "message": "Drone is idling (WAIT)... \ud83d\udd0b"
17795
+ },
17796
+ {
17797
+ "step": 20,
17798
+ "x": 7,
17799
+ "y": 8,
17800
+ "action": "WAIT",
17801
+ "reward": 0.1,
17802
+ "battery": 0.6667,
17803
+ "message": "Drone is idling (WAIT)... \ud83d\udd0b"
17804
+ },
17805
+ {
17806
+ "step": 21,
17807
+ "x": 7,
17808
+ "y": 8,
17809
+ "action": "WAIT",
17810
+ "reward": 0.1,
17811
+ "battery": 0.65,
17812
+ "message": "Drone is idling (WAIT)... \ud83d\udd0b"
17813
+ },
17814
+ {
17815
+ "step": 22,
17816
+ "x": 7,
17817
+ "y": 8,
17818
+ "action": "WAIT",
17819
+ "reward": 0.1,
17820
+ "battery": 0.6333,
17821
+ "message": "Drone is idling (WAIT)... \ud83d\udd0b"
17822
+ },
17823
+ {
17824
+ "step": 23,
17825
+ "x": 7,
17826
+ "y": 8,
17827
+ "action": "WAIT",
17828
+ "reward": 0.1,
17829
+ "battery": 0.6167,
17830
+ "message": "Drone is idling (WAIT)... \ud83d\udd0b"
17831
+ },
17832
+ {
17833
+ "step": 24,
17834
+ "x": 7,
17835
+ "y": 8,
17836
+ "action": "WAIT",
17837
+ "reward": 0.1,
17838
+ "battery": 0.6,
17839
+ "message": "Drone is idling (WAIT)... \ud83d\udd0b"
17840
+ },
17841
+ {
17842
+ "step": 25,
17843
+ "x": 7,
17844
+ "y": 8,
17845
+ "action": "WAIT",
17846
+ "reward": 0.1,
17847
+ "battery": 0.5833,
17848
+ "message": "Drone is idling (WAIT)... \ud83d\udd0b"
17849
+ },
17850
+ {
17851
+ "step": 26,
17852
+ "x": 7,
17853
+ "y": 8,
17854
+ "action": "WAIT",
17855
+ "reward": 0.1,
17856
+ "battery": 0.5667,
17857
+ "message": "Drone is idling (WAIT)... \ud83d\udd0b"
17858
+ },
17859
+ {
17860
+ "step": 27,
17861
+ "x": 7,
17862
+ "y": 8,
17863
+ "action": "WAIT",
17864
+ "reward": 0.1,
17865
+ "battery": 0.55,
17866
+ "message": "Drone is idling (WAIT)... \ud83d\udd0b"
17867
+ },
17868
+ {
17869
+ "step": 28,
17870
+ "x": 7,
17871
+ "y": 8,
17872
+ "action": "WAIT",
17873
+ "reward": 0.1,
17874
+ "battery": 0.5333,
17875
+ "message": "Drone is idling (WAIT)... \ud83d\udd0b"
17876
+ },
17877
+ {
17878
+ "step": 29,
17879
+ "x": 7,
17880
+ "y": 8,
17881
+ "action": "WAIT",
17882
+ "reward": 0.1,
17883
+ "battery": 0.5167,
17884
+ "message": "Drone is idling (WAIT)... \ud83d\udd0b"
17885
+ },
17886
+ {
17887
+ "step": 30,
17888
+ "x": 7,
17889
+ "y": 8,
17890
+ "action": "WAIT",
17891
+ "reward": 0.1,
17892
+ "battery": 0.5,
17893
+ "message": "Drone is idling (WAIT)... \ud83d\udd0b"
17894
+ },
17895
+ {
17896
+ "step": 31,
17897
+ "x": 7,
17898
+ "y": 8,
17899
+ "action": "WAIT",
17900
+ "reward": 0.1,
17901
+ "battery": 0.4833,
17902
+ "message": "Drone is idling (WAIT)... \ud83d\udd0b"
17903
+ },
17904
+ {
17905
+ "step": 32,
17906
+ "x": 7,
17907
+ "y": 8,
17908
+ "action": "WAIT",
17909
+ "reward": 0.1,
17910
+ "battery": 0.4667,
17911
+ "message": "Drone is idling (WAIT)... \ud83d\udd0b"
17912
+ },
17913
+ {
17914
+ "step": 33,
17915
+ "x": 7,
17916
+ "y": 8,
17917
+ "action": "WAIT",
17918
+ "reward": 0.1,
17919
+ "battery": 0.45,
17920
+ "message": "Drone is idling (WAIT)... \ud83d\udd0b"
17921
+ },
17922
+ {
17923
+ "step": 34,
17924
+ "x": 7,
17925
+ "y": 8,
17926
+ "action": "WAIT",
17927
+ "reward": 0.1,
17928
+ "battery": 0.4333,
17929
+ "message": "Drone is idling (WAIT)... \ud83d\udd0b"
17930
+ },
17931
+ {
17932
+ "step": 35,
17933
+ "x": 7,
17934
+ "y": 8,
17935
+ "action": "WAIT",
17936
+ "reward": 0.1,
17937
+ "battery": 0.4167,
17938
+ "message": "Drone is idling (WAIT)... \ud83d\udd0b"
17939
+ },
17940
+ {
17941
+ "step": 36,
17942
+ "x": 7,
17943
+ "y": 8,
17944
+ "action": "WAIT",
17945
+ "reward": 0.1,
17946
+ "battery": 0.4,
17947
+ "message": "Drone is idling (WAIT)... \ud83d\udd0b"
17948
+ },
17949
+ {
17950
+ "step": 37,
17951
+ "x": 7,
17952
+ "y": 8,
17953
+ "action": "WAIT",
17954
+ "reward": 0.1,
17955
+ "battery": 0.3833,
17956
+ "message": "Drone is idling (WAIT)... \ud83d\udd0b"
17957
+ },
17958
+ {
17959
+ "step": 38,
17960
+ "x": 7,
17961
+ "y": 8,
17962
+ "action": "WAIT",
17963
+ "reward": 0.1,
17964
+ "battery": 0.3667,
17965
+ "message": "Drone is idling (WAIT)... \ud83d\udd0b"
17966
+ },
17967
+ {
17968
+ "step": 39,
17969
+ "x": 7,
17970
+ "y": 8,
17971
+ "action": "WAIT",
17972
+ "reward": 0.1,
17973
+ "battery": 0.35,
17974
+ "message": "Drone is idling (WAIT)... \ud83d\udd0b"
17975
+ },
17976
+ {
17977
+ "step": 40,
17978
+ "x": 7,
17979
+ "y": 8,
17980
+ "action": "WAIT",
17981
+ "reward": 0.1,
17982
+ "battery": 0.3333,
17983
+ "message": "Drone is idling (WAIT)... \ud83d\udd0b"
17984
+ },
17985
+ {
17986
+ "step": 41,
17987
+ "x": 7,
17988
+ "y": 8,
17989
+ "action": "WAIT",
17990
+ "reward": 0.1,
17991
+ "battery": 0.3167,
17992
+ "message": "Drone is idling (WAIT)... \ud83d\udd0b"
17993
+ },
17994
+ {
17995
+ "step": 42,
17996
+ "x": 7,
17997
+ "y": 8,
17998
+ "action": "WAIT",
17999
+ "reward": 0.1,
18000
+ "battery": 0.3,
18001
+ "message": "Drone is idling (WAIT)... \ud83d\udd0b"
18002
+ },
18003
+ {
18004
+ "step": 43,
18005
+ "x": 7,
18006
+ "y": 8,
18007
+ "action": "WAIT",
18008
+ "reward": 0.1,
18009
+ "battery": 0.2833,
18010
+ "message": "Drone is idling (WAIT)... \ud83d\udd0b"
18011
+ },
18012
+ {
18013
+ "step": 44,
18014
+ "x": 7,
18015
+ "y": 8,
18016
+ "action": "WAIT",
18017
+ "reward": 0.1,
18018
+ "battery": 0.2667,
18019
+ "message": "Drone is idling (WAIT)... \ud83d\udd0b"
18020
+ },
18021
+ {
18022
+ "step": 45,
18023
+ "x": 7,
18024
+ "y": 8,
18025
+ "action": "WAIT",
18026
+ "reward": 0.1,
18027
+ "battery": 0.25,
18028
+ "message": "Drone is idling (WAIT)... \ud83d\udd0b"
18029
+ },
18030
+ {
18031
+ "step": 46,
18032
+ "x": 7,
18033
+ "y": 8,
18034
+ "action": "WAIT",
18035
+ "reward": 0.1,
18036
+ "battery": 0.2333,
18037
+ "message": "Drone is idling (WAIT)... \ud83d\udd0b"
18038
+ },
18039
+ {
18040
+ "step": 47,
18041
+ "x": 7,
18042
+ "y": 8,
18043
+ "action": "WAIT",
18044
+ "reward": 0.1,
18045
+ "battery": 0.2167,
18046
+ "message": "Drone is idling (WAIT)... \ud83d\udd0b"
18047
+ },
18048
+ {
18049
+ "step": 48,
18050
+ "x": 7,
18051
+ "y": 8,
18052
+ "action": "WAIT",
18053
+ "reward": 0.1,
18054
+ "battery": 0.2,
18055
+ "message": "Drone is idling (WAIT)... \ud83d\udd0b"
18056
+ },
18057
+ {
18058
+ "step": 49,
18059
+ "x": 7,
18060
+ "y": 8,
18061
+ "action": "WAIT",
18062
+ "reward": 0.1,
18063
+ "battery": 0.1833,
18064
+ "message": "Drone is idling (WAIT)... \ud83d\udd0b"
18065
+ },
18066
+ {
18067
+ "step": 50,
18068
+ "x": 7,
18069
+ "y": 8,
18070
+ "action": "WAIT",
18071
+ "reward": 0.1,
18072
+ "battery": 0.1667,
18073
+ "message": "Drone is idling (WAIT)... \ud83d\udd0b"
18074
+ },
18075
+ {
18076
+ "step": 51,
18077
+ "x": 7,
18078
+ "y": 8,
18079
+ "action": "WAIT",
18080
+ "reward": 0.1,
18081
+ "battery": 0.15,
18082
+ "message": "Drone is idling (WAIT)... \ud83d\udd0b"
18083
+ },
18084
+ {
18085
+ "step": 52,
18086
+ "x": 7,
18087
+ "y": 8,
18088
+ "action": "WAIT",
18089
+ "reward": 0.1,
18090
+ "battery": 0.1333,
18091
+ "message": "Drone is idling (WAIT)... \ud83d\udd0b"
18092
+ },
18093
+ {
18094
+ "step": 53,
18095
+ "x": 7,
18096
+ "y": 8,
18097
+ "action": "WAIT",
18098
+ "reward": 0.1,
18099
+ "battery": 0.1167,
18100
+ "message": "Drone is idling (WAIT)... \ud83d\udd0b"
18101
+ },
18102
+ {
18103
+ "step": 54,
18104
+ "x": 7,
18105
+ "y": 8,
18106
+ "action": "WAIT",
18107
+ "reward": 0.1,
18108
+ "battery": 0.1,
18109
+ "message": "Drone is idling (WAIT)... \ud83d\udd0b"
18110
+ },
18111
+ {
18112
+ "step": 55,
18113
+ "x": 7,
18114
+ "y": 8,
18115
+ "action": "WAIT",
18116
+ "reward": 0.1,
18117
+ "battery": 0.0833,
18118
+ "message": "Drone is idling (WAIT)... \ud83d\udd0b"
18119
+ },
18120
+ {
18121
+ "step": 56,
18122
+ "x": 7,
18123
+ "y": 8,
18124
+ "action": "WAIT",
18125
+ "reward": 0.1,
18126
+ "battery": 0.0667,
18127
+ "message": "Drone is idling (WAIT)... \ud83d\udd0b"
18128
+ },
18129
+ {
18130
+ "step": 57,
18131
+ "x": 7,
18132
+ "y": 8,
18133
+ "action": "WAIT",
18134
+ "reward": 0.1,
18135
+ "battery": 0.05,
18136
+ "message": "Drone is idling (WAIT)... \ud83d\udd0b"
18137
+ },
18138
+ {
18139
+ "step": 58,
18140
+ "x": 7,
18141
+ "y": 8,
18142
+ "action": "WAIT",
18143
+ "reward": 0.1,
18144
+ "battery": 0.0333,
18145
+ "message": "Drone is idling (WAIT)... \ud83d\udd0b"
18146
+ },
18147
+ {
18148
+ "step": 59,
18149
+ "x": 7,
18150
+ "y": 7,
18151
+ "action": "UP",
18152
+ "reward": 0.1,
18153
+ "battery": 0.0167,
18154
+ "message": "On road \ud83d\udee3\ufe0f"
18155
+ },
18156
+ {
18157
+ "step": 60,
18158
+ "x": 8,
18159
+ "y": 7,
18160
+ "action": "RIGHT",
18161
+ "reward": 0.1,
18162
+ "battery": 0.0,
18163
+ "message": "On road \ud83d\udee3\ufe0f"
18164
+ }
18165
+ ],
18166
+ "grid_meta": {
18167
+ "width": 10,
18168
+ "height": 10
18169
+ },
18170
+ "delivery_positions": [
18171
+ [
18172
+ 8,
18173
+ 5
18174
+ ]
18175
+ ],
18176
+ "deliveries_done": 0,
18177
+ "total_reward": 6.1,
18178
+ "total_steps": 60
18179
  }
18180
  ]
__init__.py → drone_env/__init__.py RENAMED
File without changes
client.py → drone_env/client.py RENAMED
File without changes
drone_env/core/__init__.py ADDED
@@ -0,0 +1,4 @@
 
 
 
 
 
1
+ # drone_env.core package
2
+ from .graders import grade_easy, grade_medium, grade_hard
3
+
4
+ __all__ = ["grade_easy", "grade_medium", "grade_hard"]
{core → drone_env/core}/drone.py RENAMED
File without changes
{core → drone_env/core}/graders.py RENAMED
File without changes
{core → drone_env/core}/grid_generator.py RENAMED
File without changes
{core → drone_env/core}/obstacles.py RENAMED
File without changes
{core → drone_env/core}/state_manager.py RENAMED
File without changes
{core → drone_env/core}/tasks.py RENAMED
File without changes
models.py → drone_env/models.py RENAMED
File without changes
drone_env/rl/__init__.py ADDED
@@ -0,0 +1,6 @@
 
 
 
 
 
 
 
1
+ # drone_env.rl package
2
+ from .model import PathQNet
3
+ from .policy import EpsilonGreedyPolicy
4
+ from .trainer import PathLearner
5
+
6
+ __all__ = ["PathQNet", "EpsilonGreedyPolicy", "PathLearner"]
{rl → drone_env/rl}/model.py RENAMED
File without changes
{rl → drone_env/rl}/policy.py RENAMED
File without changes
{rl → drone_env/rl}/trainer.py RENAMED
File without changes
{server → drone_env/server}/Dockerfile RENAMED
File without changes
{server → drone_env/server}/__init__.py RENAMED
File without changes
{server → drone_env/server}/app.py RENAMED
@@ -17,24 +17,16 @@ import time
17
  import json
18
 
19
  # Add root to sys.path for local imports
20
- BASE_DIR = Path(__file__).parent.parent
21
  if str(BASE_DIR) not in sys.path:
22
  sys.path.insert(0, str(BASE_DIR))
23
 
24
- # Unified Imports - Root-relative
25
- # We use try/except to handle different execution environments (uv run vs direct python)
26
- try:
27
- from drone_env.models import DroneAction, DroneObservation, DroneState
28
- from drone_env.server.grid_world_environment import DroneDeliveryEnvironment
29
- from drone_env.core.tasks import TASK_CONFIG
30
- from drone_env.core.graders import GRADERS
31
- from drone_env.rl.trainer import PathLearner, get_action_from_policy
32
- except ImportError:
33
- from models import DroneAction, DroneObservation, DroneState
34
- from server.grid_world_environment import DroneDeliveryEnvironment
35
- from core.tasks import TASK_CONFIG
36
- from core.graders import GRADERS
37
- from rl.trainer import PathLearner, get_action_from_policy
38
 
39
  app = FastAPI(
40
  title="Drone Delivery OpenEnv",
 
17
  import json
18
 
19
  # Add root to sys.path for local imports
20
+ BASE_DIR = Path(__file__).parent.parent.parent
21
  if str(BASE_DIR) not in sys.path:
22
  sys.path.insert(0, str(BASE_DIR))
23
 
24
+ # Unified Imports - Canonical Package Paths
25
+ from drone_env.models import DroneAction, DroneObservation, DroneState
26
+ from drone_env.server.grid_world_environment import DroneDeliveryEnvironment
27
+ from drone_env.core.tasks import TASK_CONFIG
28
+ from drone_env.core.graders import GRADERS
29
+ from drone_env.rl.trainer import PathLearner, get_action_from_policy
 
 
 
 
 
 
 
 
30
 
31
  app = FastAPI(
32
  title="Drone Delivery OpenEnv",
{server → drone_env/server}/drone_env_environment.py.bak RENAMED
File without changes
{server → drone_env/server}/grid_world_environment.py RENAMED
File without changes
{server → drone_env/server}/map_generator.py RENAMED
File without changes
{server → drone_env/server}/static/index.html RENAMED
File without changes
{server → drone_env/server}/static/script.js RENAMED
File without changes
{server → drone_env/server}/static/style.css RENAMED
File without changes
inference.py CHANGED
@@ -1,96 +1,98 @@
 
 
 
 
 
 
 
 
 
1
  import asyncio
2
  import os
3
  import textwrap
4
- from typing import List, Optional
5
  import sys
 
6
  from pathlib import Path
7
 
8
- # Add core directories to sys.path
 
 
9
  ROOT_DIR = Path(__file__).parent
10
- sys.path.insert(0, str(ROOT_DIR))
 
11
 
12
- # Manual .env loading helper (replaces python-dotenv for simplicity)
13
  def load_dotenv(path: Path):
14
  if path.exists():
15
- try:
16
- for line in path.read_text().splitlines():
17
- line = line.strip()
18
- if not line or line.startswith("#"): continue
19
- if "=" not in line: continue
20
- k, v = line.split("=", 1)
21
- os.environ[k.strip()] = v.strip().strip('"').strip("'")
22
- except Exception as e:
23
- print(f"[DEBUG] .env load error: {e}", file=sys.stderr)
24
-
25
  load_dotenv(ROOT_DIR / ".env")
26
 
27
- from openai import OpenAI
28
  from drone_env.server.grid_world_environment import DroneDeliveryEnvironment
29
- from drone_env.models import DroneAction
30
 
31
- # MANDATORY Environment Variables
32
- # Defaults are set ONLY for API_BASE_URL and MODEL_NAME as per checklist
33
- HF_TOKEN = os.getenv("HF_TOKEN")
34
- API_BASE_URL = os.getenv("API_BASE_URL", "https://router.huggingface.co/v1/")
35
- MODEL_NAME = os.getenv("MODEL_NAME", "Qwen/Qwen2.5-7B-Instruct")
36
 
37
- # For local testing if no HF_TOKEN is provided but OPENAI_API_KEY is
38
- OPENAI_KEY = os.getenv("OPENAI_API_KEY") or os.getenv("API_KEY")
 
39
 
40
- # Final API_KEY selection (Must not have a hardcoded default)
41
- API_KEY = HF_TOKEN if HF_TOKEN else OPENAI_KEY
42
-
43
- # Optional variables
44
- DRONE_TASK = os.getenv("DRONE_TASK", "drone_env.core.graders:grade_easy")
45
  BENCHMARK = os.getenv("DRONE_BENCHMARK", "drone_env_v1")
46
- LOCAL_IMAGE_NAME = os.getenv("LOCAL_IMAGE_NAME") # Optional for Docker testing
47
 
48
- # Hyperparameters
49
  MAX_STEPS = 60
50
- TEMPERATURE = 0.0 # Set to 0 for deterministic navigation with Qwen
51
- MAX_TOKENS = 30 # Increased slightly for Qwen reasoning
52
- SUCCESS_SCORE_THRESHOLD = 0.5 # 50% score for success
53
 
54
  SYSTEM_PROMPT = textwrap.dedent(
55
  """
56
- You are a drone navigation AI. Your goal is to deliver all packages to their destinations.
57
- Each step, you will see the drone's position, battery level, current target position, and distance.
58
- Actions: UP, DOWN, LEFT, RIGHT, WAIT.
59
- Format: Respond with exactly ONE action name in uppercase.
60
- Example: UP
61
  """
62
  ).strip()
63
 
 
64
  def log_start(task: str, env: str, model: str) -> None:
65
  print(f"[START] task={task} env={env} model={model}", flush=True)
66
 
67
  def log_step(step: int, action: str, reward: float, done: bool, error: Optional[str]) -> None:
68
  error_val = error if error else "null"
69
  done_val = str(done).lower()
 
70
  print(
71
  f"[STEP] step={step} action={action} reward={reward:.2f} done={done_val} error={error_val}",
72
  flush=True,
73
  )
74
 
75
  def log_end(success: bool, steps: int, score: float, rewards: List[float]) -> None:
 
76
  rewards_str = ",".join(f"{r:.2f}" for r in rewards)
77
- # The format required by benchmarks
78
  print(f"[END] success={str(success).lower()} steps={steps} score={score:.3f} rewards={rewards_str}", flush=True)
79
 
80
- def build_user_prompt(obs) -> str:
 
81
  return textwrap.dedent(
82
  f"""
83
  Pos: ({obs.drone_x}, {obs.drone_y})
84
  Battery: {obs.battery:.2f}
85
  Target: {obs.current_target}
86
  Distance: {obs.distance_to_target:.1f}
87
- Message: {obs.message}
88
  Available Actions: UP, DOWN, LEFT, RIGHT, WAIT
89
- Action?
90
  """
91
  ).strip()
92
 
93
- def get_model_action(client: OpenAI, obs) -> str:
94
  user_prompt = build_user_prompt(obs)
95
  try:
96
  completion = client.chat.completions.create(
@@ -103,69 +105,67 @@ def get_model_action(client: OpenAI, obs) -> str:
103
  max_tokens=MAX_TOKENS,
104
  stream=False,
105
  )
106
- action = (completion.choices[0].message.content or "").strip().upper()
107
- # Validation for allowed actions
108
- if action not in ["UP", "DOWN", "LEFT", "RIGHT", "WAIT"]:
109
  return "WAIT"
110
- return action
111
  except Exception as exc:
112
- # In case of API failure, log to stderr and return WAIT
113
  print(f"[DEBUG] Model request failed: {exc}", file=sys.stderr, flush=True)
114
  return "WAIT"
115
 
 
116
  async def main() -> None:
117
- # Initialize OpenAI client according to benchmarks
118
  client = OpenAI(base_url=API_BASE_URL, api_key=API_KEY)
119
-
120
- # Initialize our environment locally
 
 
121
  env = DroneDeliveryEnvironment()
122
 
 
123
  rewards: List[float] = []
124
  steps_taken = 0
125
- score_val = 0.0
126
  success = False
127
 
128
- log_start(task=DRONE_TASK, env=BENCHMARK, model=MODEL_NAME)
129
 
130
  try:
131
  # Initial reset
132
- obs = env.reset(DroneAction(task_name=DRONE_TASK))
133
-
134
- # Use dynamic max_steps from environment config
135
- current_max_steps = int(obs.max_steps) if obs.max_steps else MAX_STEPS
136
 
137
- for step in range(1, current_max_steps + 1):
 
 
 
138
  if obs.done:
139
  break
140
 
141
- # Get action from model
142
  action_str = get_model_action(client, obs)
143
 
144
- # Execution in environment
145
  obs = env.step(DroneAction(direction=action_str))
146
 
147
- reward = obs.reward_last
148
- done = obs.done
149
- error = None # Error field as per benchmark (normally handled via exceptions)
150
 
151
  rewards.append(reward)
152
  steps_taken = step
153
-
154
- # Step logging
155
  log_step(step=step, action=action_str, reward=reward, done=done, error=error)
156
 
157
  if done:
158
  break
159
 
160
- # Calculate final metrics
161
- score_val = float(obs.score) # Graded score is already normalized to [0.01, 0.99]
162
- success = (obs.deliveries_done == obs.deliveries_total) if obs.deliveries_total > 0 else False
163
 
164
- except Exception as e:
165
- print(f"[DEBUG] Error during inference: {e}", file=sys.stderr, flush=True)
166
  finally:
167
- # Always output the [END] line
168
- log_end(success=success, steps=steps_taken, score=score_val, rewards=rewards)
 
169
 
170
  if __name__ == "__main__":
171
  asyncio.run(main())
 
1
+ """
2
+ SkyRelic Drone Delivery: Standardized Inference Script
3
+ ===================================================
4
+ MANDATORY
5
+ - Environment variables: HF_TOKEN, API_BASE_URL, MODEL_NAME
6
+ - STDOUT FORMAT: [START], [STEP], [END]
7
+ - Participants must use OpenAI Client for all LLM calls.
8
+ """
9
+
10
  import asyncio
11
  import os
12
  import textwrap
 
13
  import sys
14
+ from typing import List, Optional
15
  from pathlib import Path
16
 
17
+ from openai import OpenAI
18
+
19
+ # Local Project Imports
20
  ROOT_DIR = Path(__file__).parent
21
+ if str(ROOT_DIR) not in sys.path:
22
+ sys.path.insert(0, str(ROOT_DIR))
23
 
24
+ # Load .env for local development convenience
25
  def load_dotenv(path: Path):
26
  if path.exists():
27
+ for line in path.read_text().splitlines():
28
+ line = line.strip()
29
+ if not line or line.startswith("#") or "=" not in line: continue
30
+ k, v = line.split("=", 1)
31
+ os.environ[k.strip()] = v.strip().strip('"').strip("'")
 
 
 
 
 
32
  load_dotenv(ROOT_DIR / ".env")
33
 
34
+ # Use the established Drone Environment
35
  from drone_env.server.grid_world_environment import DroneDeliveryEnvironment
36
+ from drone_env.models import DroneAction, DroneObservation
37
 
38
+ # --- Configuration ------------------------------------------------------------
39
+ IMAGE_NAME = os.getenv("IMAGE_NAME") or os.getenv("LOCAL_IMAGE_NAME")
40
+ # Use a placeholder if no key is found to prevent initialization crash during local tests
41
+ API_KEY = os.getenv("HF_TOKEN") or os.getenv("API_KEY") or os.getenv("OPENAI_API_KEY") or "EMPTY_KEY"
 
42
 
43
+ # Defaults are set only for API_BASE_URL and MODEL_NAME as per requirements
44
+ API_BASE_URL = os.getenv("API_BASE_URL") or "https://router.huggingface.co/v1"
45
+ MODEL_NAME = os.getenv("MODEL_NAME") or "Qwen/Qwen2.5-7B-Instruct"
46
 
47
+ TASK_NAME = os.getenv("DRONE_TASK", "drone_env.core.graders:grade_easy")
 
 
 
 
48
  BENCHMARK = os.getenv("DRONE_BENCHMARK", "drone_env_v1")
 
49
 
 
50
  MAX_STEPS = 60
51
+ TEMPERATURE = 0.0
52
+ MAX_TOKENS = 50
53
+ SUCCESS_SCORE_THRESHOLD = 0.5
54
 
55
  SYSTEM_PROMPT = textwrap.dedent(
56
  """
57
+ You are a drone navigation AI. Your goal is to deliver packages to targets.
58
+ Each turn, you receive the drone's position, battery, target, and distance.
59
+ Valid Actions: UP, DOWN, LEFT, RIGHT, WAIT.
60
+ Respond with exactly one action name in uppercase. No quotes.
 
61
  """
62
  ).strip()
63
 
64
+ # --- Logging Helpers ---------------------------------------------------------
65
  def log_start(task: str, env: str, model: str) -> None:
66
  print(f"[START] task={task} env={env} model={model}", flush=True)
67
 
68
  def log_step(step: int, action: str, reward: float, done: bool, error: Optional[str]) -> None:
69
  error_val = error if error else "null"
70
  done_val = str(done).lower()
71
+ # Format reward to 2 decimal places as per requirement
72
  print(
73
  f"[STEP] step={step} action={action} reward={reward:.2f} done={done_val} error={error_val}",
74
  flush=True,
75
  )
76
 
77
  def log_end(success: bool, steps: int, score: float, rewards: List[float]) -> None:
78
+ # Format rewards to 2 decimal places as per requirement
79
  rewards_str = ",".join(f"{r:.2f}" for r in rewards)
 
80
  print(f"[END] success={str(success).lower()} steps={steps} score={score:.3f} rewards={rewards_str}", flush=True)
81
 
82
+ # --- Agent Logic -------------------------------------------------------------
83
+ def build_user_prompt(obs: DroneObservation) -> str:
84
  return textwrap.dedent(
85
  f"""
86
  Pos: ({obs.drone_x}, {obs.drone_y})
87
  Battery: {obs.battery:.2f}
88
  Target: {obs.current_target}
89
  Distance: {obs.distance_to_target:.1f}
90
+ Status: {obs.message}
91
  Available Actions: UP, DOWN, LEFT, RIGHT, WAIT
 
92
  """
93
  ).strip()
94
 
95
+ def get_model_action(client: OpenAI, obs: DroneObservation) -> str:
96
  user_prompt = build_user_prompt(obs)
97
  try:
98
  completion = client.chat.completions.create(
 
105
  max_tokens=MAX_TOKENS,
106
  stream=False,
107
  )
108
+ text = (completion.choices[0].message.content or "").strip().upper()
109
+ if text not in ["UP", "DOWN", "LEFT", "RIGHT", "WAIT"]:
 
110
  return "WAIT"
111
+ return text
112
  except Exception as exc:
 
113
  print(f"[DEBUG] Model request failed: {exc}", file=sys.stderr, flush=True)
114
  return "WAIT"
115
 
116
+ # --- Run Loop ----------------------------------------------------------------
117
  async def main() -> None:
 
118
  client = OpenAI(base_url=API_BASE_URL, api_key=API_KEY)
119
+
120
+ # Initialize environment locally
121
+ # Note: the sample template uses docker integration, but for local
122
+ # hackathon development, we initialize the DroneDeliveryEnvironment directly.
123
  env = DroneDeliveryEnvironment()
124
 
125
+ history: List[str] = []
126
  rewards: List[float] = []
127
  steps_taken = 0
128
+ score = 0.010
129
  success = False
130
 
131
+ log_start(task=TASK_NAME, env=BENCHMARK, model=MODEL_NAME)
132
 
133
  try:
134
  # Initial reset
135
+ obs = env.reset(DroneAction(task_name=TASK_NAME))
 
 
 
136
 
137
+ # Max steps from environment or local constant
138
+ max_limit = int(obs.max_steps) if obs.max_steps else MAX_STEPS
139
+
140
+ for step in range(1, max_limit + 1):
141
  if obs.done:
142
  break
143
 
 
144
  action_str = get_model_action(client, obs)
145
 
146
+ # Step environment
147
  obs = env.step(DroneAction(direction=action_str))
148
 
149
+ reward = float(obs.reward_last)
150
+ done = bool(obs.done)
151
+ error = None
152
 
153
  rewards.append(reward)
154
  steps_taken = step
155
+
 
156
  log_step(step=step, action=action_str, reward=reward, done=done, error=error)
157
 
158
  if done:
159
  break
160
 
161
+ # Final score (already normalized by the environment's grader [0.01, 0.99])
162
+ score = float(obs.score) if obs.score is not None else 0.010
163
+ success = (obs.deliveries_done == obs.deliveries_total) and obs.deliveries_total > 0
164
 
 
 
165
  finally:
166
+ # Mandatory close and log emission
167
+ log_end(success=success, steps=steps_taken, score=score, rewards=rewards)
168
+
169
 
170
  if __name__ == "__main__":
171
  asyncio.run(main())
openenv.yaml CHANGED
@@ -2,7 +2,7 @@ spec_version: 1
2
  name: drone_env
3
  type: space
4
  runtime: fastapi
5
- app: server.app:app
6
  port: 8000
7
  tasks:
8
  - id: easy_delivery
 
2
  name: drone_env
3
  type: space
4
  runtime: fastapi
5
+ app: drone_env.server.app:app
6
  port: 8000
7
  tasks:
8
  - id: easy_delivery
pyproject.toml CHANGED
@@ -34,5 +34,4 @@ server = "drone_env.server.app:main"
34
 
35
  [tool.setuptools]
36
  include-package-data = true
37
- packages = ["drone_env", "drone_env.server", "drone_env.core", "drone_env.rl"]
38
- package-dir = { "drone_env" = ".", "drone_env.server" = "server", "drone_env.core" = "core", "drone_env.rl" = "rl" }
 
34
 
35
  [tool.setuptools]
36
  include-package-data = true
37
+ packages = ["drone_env", "drone_env.server", "drone_env.core", "drone_env.rl"]
 
validate-submission.sh CHANGED
@@ -59,8 +59,7 @@ run_with_timeout() {
59
 
60
  portable_mktemp() {
61
  local prefix="${1:-validate}"
62
- # Use current directory for temp file on Windows/bash compatibility
63
- mktemp "${prefix}-XXXXXX" 2>/dev/null || mktemp
64
  }
65
 
66
  CLEANUP_FILES=()
 
59
 
60
  portable_mktemp() {
61
  local prefix="${1:-validate}"
62
+ mktemp "${TMPDIR:-/tmp}/${prefix}-XXXXXX" 2>/dev/null || mktemp
 
63
  }
64
 
65
  CLEANUP_FILES=()