PRANAV05092003 commited on
Commit
b870822
·
1 Parent(s): 0cca1b6

Final Commit

Browse files
Files changed (2) hide show
  1. inference.py +125 -0
  2. server.py +29 -6
inference.py CHANGED
@@ -220,6 +220,131 @@ def run_episode(client: Optional[OpenAI], task_id: str, episode_num: int) -> flo
220
  return task_score
221
 
222
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
223
  def main() -> None:
224
  if not ENV_URL:
225
  raise SystemExit("ENV_URL is required. Example: ENV_URL=http://localhost:7860")
 
220
  return task_score
221
 
222
 
223
+ def run_all_tasks() -> Dict[str, float]:
224
+ """
225
+ Run all three tasks and return deterministic scores.
226
+
227
+ This is used by the FastAPI server to show live demo results on the Space.
228
+ """
229
+
230
+ # Prefer local in-process execution when running inside the server (no ENV_URL needed).
231
+ try:
232
+ from acre.tasks.task_registry import TaskRegistry
233
+ from openenv_interface import OpenEnvRefactorEnv
234
+ except Exception:
235
+ TaskRegistry = None # type: ignore[assignment]
236
+ OpenEnvRefactorEnv = None # type: ignore[assignment]
237
+
238
+ registry = TaskRegistry() if TaskRegistry is not None else None
239
+ env = OpenEnvRefactorEnv(registry=registry) if OpenEnvRefactorEnv is not None else None
240
+
241
+ def _choose_action_name(code: str, task_id: str) -> int:
242
+ # Reuse the same heuristic logic (deterministic).
243
+ has_generic = re.search(r"\b(x|tmp|i)\b", code) is not None
244
+ has_if_false = re.search(r"\bif\s+False\b", code) is not None
245
+ has_if_true = re.search(r"\bif\s+True\b", code) is not None
246
+ has_append_loop = ".append(" in code and "for " in code
247
+ has_double_not = "not not" in code
248
+ has_add_call = "add(" in code
249
+
250
+ if task_id == "rename_variables":
251
+ if has_generic:
252
+ return 0
253
+ if has_if_false or "unused" in code:
254
+ return 1
255
+ if has_append_loop:
256
+ return 2
257
+ if has_if_true or has_double_not:
258
+ return 3
259
+ return 4
260
+
261
+ if task_id == "remove_dead_code":
262
+ if has_if_false or "unused" in code:
263
+ return 1
264
+ if has_append_loop:
265
+ return 2
266
+ if has_if_true or has_double_not:
267
+ return 3
268
+ if has_generic:
269
+ return 0
270
+ return 4
271
+
272
+ if has_generic:
273
+ return 0
274
+ if has_append_loop:
275
+ return 2
276
+ if has_if_false or has_if_true or has_double_not:
277
+ return 3
278
+ if has_add_call:
279
+ return 4
280
+ return 1
281
+
282
+ # Map tasks → nice names for demo output.
283
+ task_plan = [
284
+ ("easy_task", "rename_variables"),
285
+ ("medium_task", "remove_dead_code"),
286
+ ("hard_task", "full_refactor"),
287
+ ]
288
+
289
+ results: Dict[str, float] = {"easy": 0.0, "medium": 0.0, "hard": 0.0, "final": 0.0}
290
+ scores: List[float] = []
291
+
292
+ # If we have a local env, use it. Otherwise fall back to HTTP (requires ENV_URL).
293
+ if env is None or registry is None:
294
+ if not ENV_URL:
295
+ return results
296
+ # Use existing HTTP-driven path.
297
+ client: Optional[OpenAI] = None
298
+ for label, task_id in task_plan:
299
+ print(f"START {label}", flush=True)
300
+ reset_env(task_id)
301
+ for _ in range(5):
302
+ state = get_state()
303
+ action = _choose_action_name(str(state.get("current_code", "")), task_id)
304
+ action_name = ACTION_MEANINGS.get(int(action), "unknown")
305
+ print(f"STEP {action_name}", flush=True)
306
+ step_env(action)
307
+ final_state = get_state()
308
+ score = float(grade(task_id, final_state.get("current_code", "")))
309
+ print(f"END score: {score:.2f}", flush=True)
310
+ scores.append(score)
311
+ if task_id == "rename_variables":
312
+ results["easy"] = score
313
+ elif task_id == "remove_dead_code":
314
+ results["medium"] = score
315
+ else:
316
+ results["hard"] = score
317
+
318
+ results["final"] = float(sum(scores) / len(scores)) if scores else 0.0
319
+ return results
320
+
321
+ # Local in-process execution (fast + no network recursion).
322
+ for label, task_id in task_plan:
323
+ print(f"START {label}", flush=True)
324
+ env.reset(seed=0, task_id=task_id)
325
+ for _ in range(5):
326
+ st = env.state()
327
+ code = str(st.current_code)
328
+ action = int(_choose_action_name(code, task_id))
329
+ action_name = env.action_meanings.get(action, "unknown")
330
+ print(f"STEP {action_name}", flush=True)
331
+ env.step(action)
332
+ st = env.state()
333
+ task = registry.get_task(task_id)
334
+ score = float(task.grade_against_expected(st.current_code)) if task is not None else 0.0
335
+ print(f"END score: {score:.2f}", flush=True)
336
+ scores.append(score)
337
+ if task_id == "rename_variables":
338
+ results["easy"] = score
339
+ elif task_id == "remove_dead_code":
340
+ results["medium"] = score
341
+ else:
342
+ results["hard"] = score
343
+
344
+ results["final"] = float(sum(scores) / len(scores)) if scores else 0.0
345
+ return results
346
+
347
+
348
  def main() -> None:
349
  if not ENV_URL:
350
  raise SystemExit("ENV_URL is required. Example: ENV_URL=http://localhost:7860")
server.py CHANGED
@@ -22,7 +22,7 @@ import uvicorn
22
  import numpy as np
23
  from fastapi import FastAPI, HTTPException
24
  from fastapi.middleware.cors import CORSMiddleware
25
- from fastapi.responses import HTMLResponse
26
  from openai import OpenAI
27
 
28
  PROJECT_ROOT = os.path.dirname(os.path.abspath(__file__))
@@ -468,10 +468,25 @@ def _demo_html() -> str:
468
  # Routes
469
  # ---------------------------------------------------------------------------
470
 
471
- @app.get("/", response_model=HealthResponse)
472
- def health() -> HealthResponse:
473
- """Health check — OpenEnv pings this URL to verify the Space is live."""
474
- return HealthResponse(status="ok", env="ACRE", version="1.0.0")
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
475
 
476
 
477
  @app.get("/health", response_model=CompatibilityHealthResponse)
@@ -480,7 +495,15 @@ def health_compat() -> CompatibilityHealthResponse:
480
  return CompatibilityHealthResponse(status="healthy", service="acre-env")
481
 
482
 
483
- @app.get("/demo", response_class=HTMLResponse)
 
 
 
 
 
 
 
 
484
  def demo_ui() -> HTMLResponse:
485
  """Simple UI to compare original and optimized code side-by-side."""
486
  return HTMLResponse(content=_demo_html())
 
22
  import numpy as np
23
  from fastapi import FastAPI, HTTPException
24
  from fastapi.middleware.cors import CORSMiddleware
25
+ from fastapi.responses import HTMLResponse, JSONResponse
26
  from openai import OpenAI
27
 
28
  PROJECT_ROOT = os.path.dirname(os.path.abspath(__file__))
 
468
  # Routes
469
  # ---------------------------------------------------------------------------
470
 
471
+ @app.get("/")
472
+ def root() -> JSONResponse:
473
+ """
474
+ Live demo root endpoint.
475
+
476
+ Hugging Face Spaces typically render the response from `/` in the preview.
477
+ We run a deterministic demo episode over all tasks and return the results.
478
+ """
479
+ from inference import run_all_tasks
480
+
481
+ results = run_all_tasks()
482
+ payload = {
483
+ "status": "ok",
484
+ "env": "ACRE",
485
+ "version": "1.0.0",
486
+ "message": "ACRE running successfully",
487
+ "results": results,
488
+ }
489
+ return JSONResponse(content=payload)
490
 
491
 
492
  @app.get("/health", response_model=CompatibilityHealthResponse)
 
495
  return CompatibilityHealthResponse(status="healthy", service="acre-env")
496
 
497
 
498
+ @app.get("/demo")
499
+ def demo() -> JSONResponse:
500
+ """Run all tasks and return JSON results."""
501
+ from inference import run_all_tasks
502
+
503
+ return JSONResponse(content={"results": run_all_tasks()})
504
+
505
+
506
+ @app.get("/ui", response_class=HTMLResponse)
507
  def demo_ui() -> HTMLResponse:
508
  """Simple UI to compare original and optimized code side-by-side."""
509
  return HTMLResponse(content=_demo_html())