Spaces:
Sleeping
Sleeping
- inference.py +82 -6
inference.py
CHANGED
|
@@ -7,12 +7,19 @@ import subprocess
|
|
| 7 |
import sys
|
| 8 |
import textwrap
|
| 9 |
import time
|
|
|
|
|
|
|
| 10 |
from pathlib import Path
|
| 11 |
from typing import Any
|
| 12 |
|
| 13 |
from openai import OpenAI
|
| 14 |
from openenv.core.generic_client import GenericEnvClient
|
| 15 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 16 |
|
| 17 |
API_BASE_URL = os.getenv("API_BASE_URL", "https://router.huggingface.co/v1")
|
| 18 |
MODEL_NAME = os.getenv("MODEL_NAME", "Qwen/Qwen2.5-72B-Instruct")
|
|
@@ -103,6 +110,14 @@ def log_error(stage: str, error: Exception) -> None:
|
|
| 103 |
)
|
| 104 |
|
| 105 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 106 |
def log_info(stage: str, message: str) -> None:
|
| 107 |
print(
|
| 108 |
f"[INFO] stage={_sanitize_field(stage)} message={_sanitize_field(message)}",
|
|
@@ -110,6 +125,63 @@ def log_info(stage: str, message: str) -> None:
|
|
| 110 |
)
|
| 111 |
|
| 112 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 113 |
def estimate_max_flow_score(timeline: list[int]) -> float:
|
| 114 |
slot_count = len(timeline)
|
| 115 |
if slot_count <= 0:
|
|
@@ -300,7 +372,7 @@ def stop_local_server() -> None:
|
|
| 300 |
process.wait(timeout=5)
|
| 301 |
|
| 302 |
|
| 303 |
-
async def create_env() -> tuple[
|
| 304 |
if OPENENV_BASE_URL:
|
| 305 |
return await _connect_env(OPENENV_BASE_URL), "remote"
|
| 306 |
|
|
@@ -312,11 +384,12 @@ async def create_env() -> tuple[GenericEnvClient, str]:
|
|
| 312 |
log_info("docker", "Falling back to bundled local server")
|
| 313 |
|
| 314 |
else:
|
| 315 |
-
log_info("startup", "LOCAL_IMAGE_NAME not set; using bundled
|
| 316 |
|
| 317 |
-
|
| 318 |
-
|
| 319 |
-
|
|
|
|
| 320 |
|
| 321 |
|
| 322 |
async def main() -> None:
|
|
@@ -331,6 +404,7 @@ async def main() -> None:
|
|
| 331 |
observation: dict[str, Any] = {}
|
| 332 |
|
| 333 |
log_start(TASK_NAME, BENCHMARK, MODEL_NAME)
|
|
|
|
| 334 |
|
| 335 |
try:
|
| 336 |
if HF_TOKEN:
|
|
@@ -379,6 +453,7 @@ async def main() -> None:
|
|
| 379 |
success = score > 0.0
|
| 380 |
except Exception as error:
|
| 381 |
log_error("runtime", error)
|
|
|
|
| 382 |
finally:
|
| 383 |
if env is not None:
|
| 384 |
try:
|
|
@@ -392,6 +467,7 @@ async def main() -> None:
|
|
| 392 |
if __name__ == "__main__":
|
| 393 |
try:
|
| 394 |
asyncio.run(main())
|
| 395 |
-
except
|
| 396 |
log_error("fatal", error)
|
|
|
|
| 397 |
log_end(success=False, steps=0, score=0.0, rewards=[])
|
|
|
|
| 7 |
import sys
|
| 8 |
import textwrap
|
| 9 |
import time
|
| 10 |
+
import traceback
|
| 11 |
+
from dataclasses import dataclass
|
| 12 |
from pathlib import Path
|
| 13 |
from typing import Any
|
| 14 |
|
| 15 |
from openai import OpenAI
|
| 16 |
from openenv.core.generic_client import GenericEnvClient
|
| 17 |
|
| 18 |
+
try:
|
| 19 |
+
from server.engineer_manager_environment import EngineerManagerEnvironment
|
| 20 |
+
except ImportError:
|
| 21 |
+
EngineerManagerEnvironment = None # type: ignore[assignment]
|
| 22 |
+
|
| 23 |
|
| 24 |
API_BASE_URL = os.getenv("API_BASE_URL", "https://router.huggingface.co/v1")
|
| 25 |
MODEL_NAME = os.getenv("MODEL_NAME", "Qwen/Qwen2.5-72B-Instruct")
|
|
|
|
| 110 |
)
|
| 111 |
|
| 112 |
|
| 113 |
+
def log_traceback(stage: str, error: BaseException) -> None:
|
| 114 |
+
traceback_text = "".join(
|
| 115 |
+
traceback.format_exception(type(error), error, error.__traceback__)
|
| 116 |
+
).rstrip()
|
| 117 |
+
print(f"[TRACEBACK] stage={_sanitize_field(stage)}", flush=True)
|
| 118 |
+
print(traceback_text, flush=True)
|
| 119 |
+
|
| 120 |
+
|
| 121 |
def log_info(stage: str, message: str) -> None:
|
| 122 |
print(
|
| 123 |
f"[INFO] stage={_sanitize_field(stage)} message={_sanitize_field(message)}",
|
|
|
|
| 125 |
)
|
| 126 |
|
| 127 |
|
| 128 |
+
def log_env_status() -> None:
|
| 129 |
+
env_fields = {
|
| 130 |
+
"API_BASE_URL": API_BASE_URL,
|
| 131 |
+
"MODEL_NAME": MODEL_NAME,
|
| 132 |
+
"HF_TOKEN": "<set>" if HF_TOKEN else "<missing>",
|
| 133 |
+
"LOCAL_IMAGE_NAME": LOCAL_IMAGE_NAME or "<missing>",
|
| 134 |
+
"OPENENV_BASE_URL": OPENENV_BASE_URL or "<missing>",
|
| 135 |
+
"TASK_NAME": TASK_NAME,
|
| 136 |
+
"BENCHMARK": BENCHMARK,
|
| 137 |
+
"MAX_STEPS": MAX_STEPS,
|
| 138 |
+
"TEMPERATURE": TEMPERATURE,
|
| 139 |
+
"MAX_TOKENS": MAX_TOKENS,
|
| 140 |
+
"LOCAL_SERVER_HOST": LOCAL_SERVER_HOST,
|
| 141 |
+
"LOCAL_SERVER_STARTUP_TIMEOUT": LOCAL_SERVER_STARTUP_TIMEOUT,
|
| 142 |
+
}
|
| 143 |
+
formatted = ", ".join(
|
| 144 |
+
f"{name}={_sanitize_field(value)}" for name, value in env_fields.items()
|
| 145 |
+
)
|
| 146 |
+
log_info("env", formatted)
|
| 147 |
+
|
| 148 |
+
|
| 149 |
+
@dataclass
|
| 150 |
+
class _EnvResult:
|
| 151 |
+
observation: dict[str, Any]
|
| 152 |
+
reward: float | None
|
| 153 |
+
done: bool
|
| 154 |
+
|
| 155 |
+
|
| 156 |
+
class _InProcessEnvClient:
|
| 157 |
+
def __init__(self) -> None:
|
| 158 |
+
if EngineerManagerEnvironment is None:
|
| 159 |
+
raise RuntimeError("Bundled EngineerManagerEnvironment is unavailable")
|
| 160 |
+
self._env = EngineerManagerEnvironment()
|
| 161 |
+
|
| 162 |
+
async def connect(self) -> None:
|
| 163 |
+
return None
|
| 164 |
+
|
| 165 |
+
async def reset(self) -> _EnvResult:
|
| 166 |
+
observation = self._env.reset().model_dump()
|
| 167 |
+
return _EnvResult(
|
| 168 |
+
observation=dict(observation),
|
| 169 |
+
reward=float(observation.get("reward") or 0.0),
|
| 170 |
+
done=bool(observation.get("done")),
|
| 171 |
+
)
|
| 172 |
+
|
| 173 |
+
async def step(self, action: dict[str, int]) -> _EnvResult:
|
| 174 |
+
observation = self._env.step(type("Action", (), action)()).model_dump()
|
| 175 |
+
return _EnvResult(
|
| 176 |
+
observation=dict(observation),
|
| 177 |
+
reward=float(observation.get("reward") or 0.0),
|
| 178 |
+
done=bool(observation.get("done")),
|
| 179 |
+
)
|
| 180 |
+
|
| 181 |
+
async def close(self) -> None:
|
| 182 |
+
return None
|
| 183 |
+
|
| 184 |
+
|
| 185 |
def estimate_max_flow_score(timeline: list[int]) -> float:
|
| 186 |
slot_count = len(timeline)
|
| 187 |
if slot_count <= 0:
|
|
|
|
| 372 |
process.wait(timeout=5)
|
| 373 |
|
| 374 |
|
| 375 |
+
async def create_env() -> tuple[Any, str]:
|
| 376 |
if OPENENV_BASE_URL:
|
| 377 |
return await _connect_env(OPENENV_BASE_URL), "remote"
|
| 378 |
|
|
|
|
| 384 |
log_info("docker", "Falling back to bundled local server")
|
| 385 |
|
| 386 |
else:
|
| 387 |
+
log_info("startup", "LOCAL_IMAGE_NAME not set; using in-process bundled environment")
|
| 388 |
|
| 389 |
+
local_env = _InProcessEnvClient()
|
| 390 |
+
await local_env.connect()
|
| 391 |
+
log_info("env", "Using in-process bundled environment")
|
| 392 |
+
return local_env, "in-process"
|
| 393 |
|
| 394 |
|
| 395 |
async def main() -> None:
|
|
|
|
| 404 |
observation: dict[str, Any] = {}
|
| 405 |
|
| 406 |
log_start(TASK_NAME, BENCHMARK, MODEL_NAME)
|
| 407 |
+
log_env_status()
|
| 408 |
|
| 409 |
try:
|
| 410 |
if HF_TOKEN:
|
|
|
|
| 453 |
success = score > 0.0
|
| 454 |
except Exception as error:
|
| 455 |
log_error("runtime", error)
|
| 456 |
+
log_traceback("runtime", error)
|
| 457 |
finally:
|
| 458 |
if env is not None:
|
| 459 |
try:
|
|
|
|
| 467 |
if __name__ == "__main__":
|
| 468 |
try:
|
| 469 |
asyncio.run(main())
|
| 470 |
+
except BaseException as error:
|
| 471 |
log_error("fatal", error)
|
| 472 |
+
log_traceback("fatal", error)
|
| 473 |
log_end(success=False, steps=0, score=0.0, rewards=[])
|