diff --git a/tools/sprite-generation/tools/advance.py b/tools/sprite-generation/tools/advance.py index c6b30a3f..d04e552a 100644 --- a/tools/sprite-generation/tools/advance.py +++ b/tools/sprite-generation/tools/advance.py @@ -27,6 +27,10 @@ import json import os import sys import time + +# Force line-buffered output so progress is visible when stdout is redirected +if hasattr(sys.stdout, "reconfigure"): + sys.stdout.reconfigure(line_buffering=True) from concurrent.futures import ProcessPoolExecutor from pathlib import Path @@ -215,8 +219,9 @@ async def stage_score( tier_summaries.append(_tier_summary(scorer.name, total, 0, 0, 0, 0)) continue - # Fire ALL items at once — semaphore in Scorer limits concurrency. - # Results stream back via as_completed inside score_batch. + # Fire ALL items concurrently — semaphore in Scorer limits actual + # concurrency per backend. Results stream back as each completes, + # so DB commits happen immediately without waiting for the full batch. items: list[tuple[str, dict]] = [ (v["_score_path"], v) for v in eligible ] @@ -227,16 +232,14 @@ async def stage_score( errors = 0 start = time.time() - batch_results = await scorer.score_batch(items) - - for idx, result in batch_results: - v = eligible[idx] - vid = v["id"] - - if result is None: + async for idx, result in scorer.score_stream(items): + if idx == -1 or result is None: errors += 1 continue + v = eligible[idx] + vid = v["id"] + reg.store_score( variant_id=vid, scorer_name=scorer.name, @@ -437,7 +440,7 @@ def main() -> None: parser.add_argument("--score-only", action="store_true", help="Only run scoring (skip reconcile + process)") parser.add_argument("--scorers", nargs="+", metavar="SCORER", - choices=["qwen3", "haiku", "opus"], + choices=["qwen3", "haiku", "sonnet", "opus"], help="Only run these scorers (e.g. --scorers qwen3 haiku)") parser.add_argument("--rescore", action="store_true", help="Re-score variants that already have a latest score (inserts new rows)")