CoolFace
Apppublic

AMD21/codefixerenv

sourceHugging Faceupdated 6mo agoView on Hugging Face
0likes
inference.py176 linesDownload Raw Back to root
1"""2inference.py — CodeFixerEnv baseline agent.3 4Environment variables injected by the hackathon validator:5  API_BASE_URL  — LiteLLM proxy URL (used for ALL LLM calls)6  API_KEY       — LiteLLM proxy key7  MODEL_NAME    — model identifier (has default)8  ENV_BASE_URL  — CodeFixerEnv server URL (has default)9"""10 11import os12import sys13import json14import requests15from openai import OpenAI16 17# ── Env vars ──────────────────────────────────────────────────────────────────18API_BASE_URL = os.environ["API_BASE_URL"]19API_KEY      = os.environ["API_KEY"]20MODEL_NAME   = os.getenv("MODEL_NAME", "gpt-4o-mini")21ENV_BASE_URL = os.getenv("ENV_BASE_URL", "http://localhost:7860")22 23DIFFICULTIES = ["easy", "medium", "hard"]24MAX_STEPS    = 525 26# ── OpenAI client — MUST use injected API_BASE_URL + API_KEY ─────────────────27client = OpenAI(28    base_url=API_BASE_URL,29    api_key=API_KEY,30)31 32SYSTEM_PROMPT = """You are an expert Python debugger.33You will receive a buggy Python function and a description of what it should do.34Fix the code and return ONLY a valid JSON object with no markdown, no explanation:35{36  "action_type": "fix",37  "action_content": "<full corrected Python function>"38}39action_type must be one of: fix, explain, give_up40action_content must be the complete corrected function, not a diff.41"""42 43 44def log(msg: str):45    print(msg, flush=True)46    sys.stdout.flush()47 48 49def strict(value: float) -> float:50    """Strictly (0.0, 1.0) — 0.0 → 0.01, 1.0 → 0.99."""51    return round(max(0.01, min(0.99, float(value))), 4)52 53 54def call_env(endpoint: str, method: str = "GET", payload: dict = None) -> dict:55    url = f"{ENV_BASE_URL.rstrip('/')}/{endpoint}"56    if method == "POST":57        resp = requests.post(url, json=payload, timeout=30)58    else:59        resp = requests.get(url, timeout=30)60    resp.raise_for_status()61    return resp.json()62 63 64def call_model(obs: dict) -> tuple[str, str]:65    history_str = ""66    if obs.get("history"):67        history_str = "\n\nPrevious attempts:\n" + "\n".join(68            f"  Step {h['step']}: {h['feedback']}" for h in obs["history"]69        )70 71    user_prompt = (72        f"Task: {obs.get('context', '')}\n\n"73        f"Buggy code:\n{obs.get('input', '')}"74        f"{history_str}\n\n"75        f"Step {obs.get('step_number', 0) + 1} of {obs.get('max_steps', 5)}. Fix the code."76    )77 78    try:79        completion = client.chat.completions.create(80            model=MODEL_NAME,81            messages=[82                {"role": "system", "content": SYSTEM_PROMPT},83                {"role": "user",   "content": user_prompt},84            ],85            temperature=0.2,86            max_tokens=800,87        )88        raw = completion.choices[0].message.content or ""89        raw = raw.replace("```json", "").replace("```", "").strip()90        parsed = json.loads(raw)91        return parsed.get("action_type", "give_up"), parsed.get("action_content", "")92    except Exception as exc:93        log(f"[MODEL ERROR] {exc}")94        return "give_up", ""95 96 97def run_episode(difficulty: str) -> dict:98    # Start at 0.01 — never 0.099    final_score = 0.01100    step_num    = 1101 102    log(f"[START] task={difficulty}")103 104    try:105        obs = call_env("reset", "POST", {"difficulty": difficulty})106    except Exception as e:107        log(f"[ERROR] reset failed: {e}")108        log(f"[STEP] step=1 reward=0.0100")109        log(f"[END] task={difficulty} score=0.0100 steps=1")110        return {"difficulty": difficulty, "final_grader_score": 0.01}111 112    for step_num in range(1, MAX_STEPS + 1):113        action_type, action_content = call_model(obs)114 115        try:116            result     = call_env("step", "POST", {117                "action_type":    action_type,118                "action_content": action_content,119            })120            reward_val = result["reward"]["value"]121            done       = result["done"]122            info       = result["info"]123            obs        = result["observation"]124 125            # Always clamp grader_score to strict (0, 1)126            if "grader_score" in info and info["grader_score"] is not None:127                final_score = strict(info["grader_score"])128 129            step_reward = strict(reward_val)130 131        except Exception as e:132            log(f"[ERROR] step failed: {e}")133            step_reward = 0.01134            done = True135 136        # [STEP] reward must also be strictly in (0, 1)137        log(f"[STEP] step={step_num} reward={step_reward:.4f}")138 139        if done:140            break141 142    # [END] score strictly in (0, 1) — guaranteed by strict()143    log(f"[END] task={difficulty} score={final_score:.4f} steps={step_num}")144 145    return {146        "difficulty":         difficulty,147        "final_grader_score": final_score,148    }149 150 151def main():152    log(f"[INFO] API_BASE_URL={API_BASE_URL}")153    log(f"[INFO] MODEL_NAME={MODEL_NAME}")154    log(f"[INFO] ENV_BASE_URL={ENV_BASE_URL}")155 156    try:157        h = call_env("health")158        log(f"[INFO] Env server={h.get('status', 'ok')}")159    except Exception as e:160        log(f"[WARN] Env server unreachable: {e}")161 162    results = []163    for difficulty in DIFFICULTIES:164        result = run_episode(difficulty)165        results.append(result)166 167    avg = strict(sum(r["final_grader_score"] for r in results) / len(results))168    log(f"[SUMMARY] average_score={avg:.4f}")169 170    with open("inference_results.json", "w") as f:171        json.dump({"results": results, "average_score": avg}, f, indent=2)172    log("[INFO] Saved inference_results.json")173 174 175if __name__ == "__main__":176    main()