| import os |
| from typing import Any, Dict, List, Optional |
|
|
| from openai import OpenAI |
|
|
| from src.env import CodeGuardEnv |
|
|
|
|
| def _get_env_var(name: str, default: Optional[str] = None, required: bool = False) -> str: |
| value = os.getenv(name, default) |
| if required and not value: |
| raise ValueError(f"Missing required environment variable: {name}") |
| return value or "" |
|
|
|
|
| def _format_bool(value: bool) -> str: |
| return "true" if value else "false" |
|
|
|
|
| def _safe_str(value: Optional[str]) -> str: |
| if value is None: |
| return "null" |
| return str(value) |
|
|
|
|
| def _get_api_key() -> str: |
| |
| for name in ("HF_TOKEN", "API_KEY", "GEMINI_API_KEY", "OPENAI_API_KEY"): |
| value = os.getenv(name) |
| if value: |
| return value |
| raise ValueError( |
| "Missing API key. Set one of: HF_TOKEN, API_KEY, GEMINI_API_KEY, OPENAI_API_KEY" |
| ) |
|
|
|
|
| def _resolve_base_url(api_key: str) -> str: |
| explicit_base_url = os.getenv("API_BASE_URL") or os.getenv("BASE_URL") |
| if explicit_base_url: |
| return explicit_base_url |
|
|
| |
| |
| if api_key.startswith("hf_"): |
| return "https://router.huggingface.co/v1" |
| if api_key.startswith("AIza"): |
| return "https://generativelanguage.googleapis.com/v1beta/openai" |
| return "https://router.huggingface.co/v1" |
|
|
|
|
| def _resolve_model(base_url: str) -> str: |
| explicit_model = os.getenv("MODEL_NAME") or os.getenv("MODEL") |
| if explicit_model: |
| return explicit_model |
|
|
| if "router.huggingface.co" in base_url: |
| return "Qwen/Qwen2.5-72B-Instruct" |
| if "generativelanguage.googleapis.com" in base_url: |
| return "gemini-1.5-flash" |
| return "gpt-4.1-mini" |
|
|
|
|
| def _clamp_score(value: float) -> float: |
| return max(0.0, min(1.0, value)) |
|
|
|
|
| def main() -> None: |
| success: bool = False |
| rewards: List[float] = [] |
| step_count: int = 0 |
| score: float = 0.0 |
|
|
| try: |
| |
| api_key: str = _get_api_key() |
| base_url: str = _resolve_base_url(api_key) |
| model: str = _resolve_model(base_url) |
| task_name: str = _get_env_var("TASK", "easy") |
|
|
| |
| client = OpenAI(base_url=base_url, api_key=api_key) |
|
|
| |
| env = CodeGuardEnv() |
| state: Dict[str, Any] = env.reset() |
|
|
| |
| print(f"[START] task={task_name} env=codeguard model={model}") |
|
|
| done: bool = False |
|
|
| while not done: |
| step_count += 1 |
|
|
| |
| try: |
| response = client.chat.completions.create( |
| model=model, |
| messages=[ |
| {"role": "system", "content": "You are a code-fixing agent."}, |
| {"role": "user", "content": str(state)}, |
| ], |
| temperature=0.0, |
| ) |
| action: str = response.choices[0].message.content.strip() |
| error_msg: Optional[str] = None |
| except Exception as e: |
| action = "" |
| error_msg = str(e) |
|
|
| |
| next_state, reward, done, info = env.step(action) |
|
|
| rewards.append(reward) |
|
|
| |
| error_output: Optional[str] = error_msg or info.get("error") |
|
|
| |
| print( |
| f"[STEP] step={step_count} action={action} " |
| f"reward={reward:.2f} done={_format_bool(done)} " |
| f"error={_safe_str(error_output)}" |
| ) |
|
|
| state = next_state |
|
|
| |
| score = _clamp_score(float(state.get("score", 0.0))) |
|
|
| |
| if done and reward >= env.threshold: |
| success = True |
|
|
| |
| reward_str = ",".join(f"{r:.2f}" for r in rewards) |
| print( |
| f"[END] success={_format_bool(success)} steps={step_count} " |
| f"score={score:.2f} rewards={reward_str}" |
| ) |
|
|
| except Exception as e: |
| |
| _ = str(e) |
| reward_str = ",".join(f"{r:.2f}" for r in rewards) if rewards else "0.00" |
| print(f"[END] success=false steps={step_count} score=0.00 rewards={reward_str}") |
|
|
|
|
| if __name__ == "__main__": |
| main() |
|
|
|
|