From dbdefa43c866011ec82ea6e8a38ae97431210199 Mon Sep 17 00:00:00 2001 From: debthemelon Date: Fri, 24 Apr 2026 13:33:56 +0100 Subject: [PATCH] fix: eliminate duplicate checkpoint entries and JSON-unsafe coercion batch_runner: completed_prompts_set is already fully populated by the time the aggregation loop runs (incremental updates happen at result collection time), so the subsequent extend() call re-added every completed prompt index a second time. Removed the redundant variable and extend, and write sorted(completed_prompts_set) directly to the final checkpoint instead. model_tools: _coerce_number returned Python float('inf')/float('nan') for inf/nan strings rather than the original string. json.dumps raises ValueError for these values, so any tool call where the model emitted "inf" or "nan" for a numeric parameter would crash at serialization. Changed the guard to return the original string, matching the function's documented "returns original string on failure" contract. --- batch_runner.py | 8 ++------ model_tools.py | 4 ++-- 2 files changed, 4 insertions(+), 8 deletions(-) diff --git a/batch_runner.py b/batch_runner.py index 7413ad59f..f3aaefa3d 100644 --- a/batch_runner.py +++ b/batch_runner.py @@ -951,13 +951,9 @@ class BatchRunner: root_logger.setLevel(original_level) # Aggregate all batch statistics and update checkpoint - all_completed_prompts = list(completed_prompts_set) total_reasoning_stats = {"total_assistant_turns": 0, "turns_with_reasoning": 0, "turns_without_reasoning": 0} - + for batch_result in results: - # Add newly completed prompts - all_completed_prompts.extend(batch_result.get("completed_prompts", [])) - # Aggregate tool stats for tool_name, stats in batch_result.get("tool_stats", {}).items(): if tool_name not in total_tool_stats: @@ -977,7 +973,7 @@ class BatchRunner: # Save final checkpoint (best-effort; incremental writes already happened) try: - checkpoint_data["completed_prompts"] = all_completed_prompts + checkpoint_data["completed_prompts"] = sorted(completed_prompts_set) self._save_checkpoint(checkpoint_data, lock=checkpoint_lock) except Exception as ckpt_err: print(f"⚠️ Warning: Failed to save final checkpoint: {ckpt_err}") diff --git a/model_tools.py b/model_tools.py index dbf7af064..36cea8f30 100644 --- a/model_tools.py +++ b/model_tools.py @@ -464,9 +464,9 @@ def _coerce_number(value: str, integer_only: bool = False): f = float(value) except (ValueError, OverflowError): return value - # Guard against inf/nan before int() conversion + # Guard against inf/nan — not JSON-serializable, keep original string if f != f or f == float("inf") or f == float("-inf"): - return f + return value # If it looks like an integer (no fractional part), return int if f == int(f): return int(f)