MaRK012 commited on
Commit
f94b8ef
·
verified ·
1 Parent(s): 9b6b24a

Upload 2 files

Browse files
Files changed (2) hide show
  1. pyproject.toml +21 -0
  2. server/app.py +83 -0
pyproject.toml ADDED
@@ -0,0 +1,21 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ [build-system]
2
+ requires = ["setuptools>=61.0"]
3
+ build-backend = "setuptools.build_meta"
4
+
5
+ [project]
6
+ name = "logisticsflow-openenv"
7
+ version = "0.1.0"
8
+ description = "A real-world OpenEnv simulation."
9
+ readme = "README.md"
10
+ requires-python = ">=3.10"
11
+ dependencies = [
12
+ "fastapi",
13
+ "uvicorn",
14
+ "pydantic",
15
+ "openai",
16
+ "requests",
17
+ "openenv-core>=0.2.0"
18
+ ]
19
+
20
+ [project.scripts]
21
+ server = "server.app:main"
server/app.py ADDED
@@ -0,0 +1,83 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ from fastapi import FastAPI
2
+ from fastapi.responses import HTMLResponse
3
+ from pydantic import BaseModel
4
+ from typing import Optional
5
+ import json
6
+
7
+ from app.env import LogisticsEnv
8
+ from app.models import Action
9
+
10
+ app = FastAPI(title="LogisticsFlow OpenEnv")
11
+ env = LogisticsEnv()
12
+
13
+ # This tells the server it can accept a JSON body for the reset command
14
+ class ResetConfig(BaseModel):
15
+ level: str = "easy"
16
+
17
+ # --- THE DASHBOARD ---
18
+ @app.get("/", response_class=HTMLResponse)
19
+ def read_root():
20
+ # We grab the current state to display on the dashboard
21
+ current_state = env.state().model_dump()
22
+ state_json = json.dumps(current_state, indent=4)
23
+
24
+ return f"""
25
+ <html>
26
+ <head>
27
+ <title>LogisticsFlow Playground</title>
28
+ <style>
29
+ body {{ font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif; background-color: #0d1117; color: #c9d1d9; padding: 2rem; }}
30
+ .container {{ max-width: 800px; margin: auto; background: #161b22; padding: 30px; border-radius: 12px; border: 1px solid #30363d; }}
31
+ h1 {{ color: #58a6ff; margin-top: 0; }}
32
+ h3 {{ color: #2ea043; }}
33
+ pre {{ background: #010409; padding: 15px; border-radius: 8px; overflow-x: auto; border: 1px solid #30363d; color: #79c0ff; }}
34
+ .badge {{ background: #238636; color: white; padding: 4px 8px; border-radius: 2em; font-size: 12px; font-weight: bold; }}
35
+ </style>
36
+ </head>
37
+ <body>
38
+ <div class="container">
39
+ <h1>📦 LogisticsFlow Environment <span class="badge">ONLINE</span></h1>
40
+ <p>This is a headless OpenEnv API for AI Agent Evaluation. The environment simulates a dynamic supply chain.</p>
41
+ <hr style="border-color: #30363d; margin: 20px 0;">
42
+ <h3>📡 API Endpoints</h3>
43
+ <ul>
44
+ <li><code>POST /reset</code> - Initialize a new episode (Pass <code>{{"level": "hard"}}</code> to test out-of-stock crises).</li>
45
+ <li><code>POST /step</code> - Execute an <code>Action</code> (ship, restock).</li>
46
+ <li><code>GET /state</code> - Retrieve the current environment state.</li>
47
+ </ul>
48
+ <h3>📊 Live World State:</h3>
49
+ <pre><code>{state_json}</code></pre>
50
+ </div>
51
+ </body>
52
+ </html>
53
+ """
54
+
55
+ # --- THE OPENENV REQUIRED ENDPOINTS ---
56
+
57
+ # FIXED: Now accepts POST requests to pass the automated Validation Script
58
+ @app.post("/reset")
59
+ def reset_env_post(config: Optional[ResetConfig] = None):
60
+ level = config.level if config else "easy"
61
+ return env.reset(level)
62
+
63
+ # Kept the GET version just in case you want to test it in your browser URL bar
64
+ @app.get("/reset/{level}")
65
+ def reset_env_get(level: str):
66
+ return env.reset(level)
67
+
68
+ @app.post("/step")
69
+ def step_env(action: Action):
70
+ obs, reward, done, info = env.step(action)
71
+ return {"observation": obs, "reward": reward, "done": done, "info": info}
72
+
73
+ @app.get("/state")
74
+ def get_state():
75
+ return env.state()
76
+
77
+ # --- THE OPENENV MULTI-MODE ENTRY POINT ---
78
+ def main():
79
+ import uvicorn
80
+ uvicorn.run("server.app:app", host="0.0.0.0", port=7860)
81
+
82
+ if __name__ == "__main__":
83
+ main()