Tarun Claude Sonnet 4.6 commited on
Commit ·
caeca79
1
Parent(s): 63dab28
Fix inference.py unhandled exception crash
Browse filesget_action() was propagating API errors (network, auth, timeout) which
crashed run_episode → main → non-zero exit. Fix:
- get_action() now catches ALL exceptions, logs them to stdout, and
returns fallback action + error string (error appears in [STEP] log)
- run_episode() logs step_error in [STEP] output
- main() wraps each task in try/except so one failing task doesn't
kill the remaining two — emits [END] with minimum score instead
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- inference.py +15 -17
inference.py
CHANGED
|
@@ -217,22 +217,15 @@ async def call_api_model(state: dict, client: AsyncOpenAI, user_prompt: str) ->
|
|
| 217 |
else:
|
| 218 |
raise ValueError(f"No JSON object detected in response. Raw response: {text}")
|
| 219 |
|
| 220 |
-
async def get_action(state: dict, client: AsyncOpenAI, user_prompt: str) -> SupportAction:
|
| 221 |
-
|
| 222 |
-
# indicate a misconfigured proxy and must surface so the episode fails visibly.
|
| 223 |
-
# Only fall back on JSON parse/decode issues where the API was reached but returned
|
| 224 |
-
# malformed output.
|
| 225 |
try:
|
| 226 |
data = await call_api_model(state, client, user_prompt)
|
| 227 |
-
|
| 228 |
-
|
| 229 |
-
|
| 230 |
-
|
| 231 |
-
return SupportAction(**
|
| 232 |
-
# All other exceptions (openai.APIConnectionError, openai.AuthenticationError,
|
| 233 |
-
# httpx errors, etc.) propagate — they will be caught in main() and abort the run
|
| 234 |
-
# with a visible error, preventing silent fallback-only episodes.
|
| 235 |
-
return SupportAction(**data)
|
| 236 |
|
| 237 |
async def run_episode(task_name: str, client: AsyncOpenAI) -> None:
|
| 238 |
"""Run one full episode for the given task and emit START/STEP/END logs."""
|
|
@@ -260,7 +253,7 @@ async def run_episode(task_name: str, client: AsyncOpenAI) -> None:
|
|
| 260 |
"message": obs.message,
|
| 261 |
"sentiment": obs.sentiment,
|
| 262 |
}
|
| 263 |
-
action = await get_action(state_dict, client, user_prompt)
|
| 264 |
action_str = json.dumps(action.model_dump())
|
| 265 |
|
| 266 |
result = await env.step(action)
|
|
@@ -271,7 +264,7 @@ async def run_episode(task_name: str, client: AsyncOpenAI) -> None:
|
|
| 271 |
rewards.append(reward)
|
| 272 |
steps_taken = step
|
| 273 |
|
| 274 |
-
log_step(step=step, action=action_str, reward=reward, done=done, error=
|
| 275 |
history.append(f"Step {step}: {action_str} -> reward {reward:+.2f}")
|
| 276 |
|
| 277 |
if done:
|
|
@@ -301,7 +294,12 @@ async def main() -> None:
|
|
| 301 |
# Always run all three tasks so the validator can enumerate tasks and
|
| 302 |
# verify each grader produces scores in [0.002, 0.998].
|
| 303 |
for task in ["easy", "medium", "hard"]:
|
| 304 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 305 |
|
| 306 |
|
| 307 |
if __name__ == "__main__":
|
|
|
|
| 217 |
else:
|
| 218 |
raise ValueError(f"No JSON object detected in response. Raw response: {text}")
|
| 219 |
|
| 220 |
+
async def get_action(state: dict, client: AsyncOpenAI, user_prompt: str) -> tuple[SupportAction, Optional[str]]:
|
| 221 |
+
"""Returns (action, error_message). error_message is None on success."""
|
|
|
|
|
|
|
|
|
|
| 222 |
try:
|
| 223 |
data = await call_api_model(state, client, user_prompt)
|
| 224 |
+
return SupportAction(**data), None
|
| 225 |
+
except Exception as exc:
|
| 226 |
+
err = f"{type(exc).__name__}: {exc}"
|
| 227 |
+
print(f"[DEBUG] ⚠️ API/parse error: {err}", flush=True)
|
| 228 |
+
return SupportAction(**fallback_policy(state)), err
|
|
|
|
|
|
|
|
|
|
|
|
|
| 229 |
|
| 230 |
async def run_episode(task_name: str, client: AsyncOpenAI) -> None:
|
| 231 |
"""Run one full episode for the given task and emit START/STEP/END logs."""
|
|
|
|
| 253 |
"message": obs.message,
|
| 254 |
"sentiment": obs.sentiment,
|
| 255 |
}
|
| 256 |
+
action, step_error = await get_action(state_dict, client, user_prompt)
|
| 257 |
action_str = json.dumps(action.model_dump())
|
| 258 |
|
| 259 |
result = await env.step(action)
|
|
|
|
| 264 |
rewards.append(reward)
|
| 265 |
steps_taken = step
|
| 266 |
|
| 267 |
+
log_step(step=step, action=action_str, reward=reward, done=done, error=step_error)
|
| 268 |
history.append(f"Step {step}: {action_str} -> reward {reward:+.2f}")
|
| 269 |
|
| 270 |
if done:
|
|
|
|
| 294 |
# Always run all three tasks so the validator can enumerate tasks and
|
| 295 |
# verify each grader produces scores in [0.002, 0.998].
|
| 296 |
for task in ["easy", "medium", "hard"]:
|
| 297 |
+
try:
|
| 298 |
+
await run_episode(task, client)
|
| 299 |
+
except Exception as exc:
|
| 300 |
+
print(f"[DEBUG] ⚠️ Episode failed for task={task}: {type(exc).__name__}: {exc}", flush=True)
|
| 301 |
+
log_end(success=False, steps=0, score=0.002, rewards=[0.002])
|
| 302 |
+
continue
|
| 303 |
|
| 304 |
|
| 305 |
if __name__ == "__main__":
|