Spaces:
Running on Zero
Running on Zero
Commit ·
a8287eb
1
Parent(s): 448481b
Shrink translation batch size so results appear incrementally during Translate All
Browse filesPreviously _BATCH_SIZE (25) matched a full page, so with <=25 segments the
whole page translated in a single call/inference pass and all translations
appeared at once at the end. Smaller batches mean the UI's polling loop (which
already re-renders the page every 0.5s) picks up newly finished segments in
waves as each batch completes, instead of only after the last one.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
- engine/openrouter_backend.py +3 -1
- tests/test_translate.py +11 -6
engine/openrouter_backend.py
CHANGED
|
@@ -29,7 +29,9 @@ DEFAULT_MODEL = CURATED_MODELS[0]
|
|
| 29 |
_TIMEOUT = 120
|
| 30 |
_MODELS_TIMEOUT = 10
|
| 31 |
_BACKOFF_BASE = 2
|
| 32 |
-
|
|
|
|
|
|
|
| 33 |
|
| 34 |
_RETRYABLE_STATUS = {408, 429, 500, 502, 503, 504}
|
| 35 |
|
|
|
|
| 29 |
_TIMEOUT = 120
|
| 30 |
_MODELS_TIMEOUT = 10
|
| 31 |
_BACKOFF_BASE = 2
|
| 32 |
+
# Kept small (rather than e.g. one batch per page) so the UI can show translated
|
| 33 |
+
# segments as each batch finishes instead of the whole page appearing at once.
|
| 34 |
+
_BATCH_SIZE = 5
|
| 35 |
|
| 36 |
_RETRYABLE_STATUS = {408, 429, 500, 502, 503, 504}
|
| 37 |
|
tests/test_translate.py
CHANGED
|
@@ -135,7 +135,8 @@ def test_translate_segments_per_segment_fallback_records_errors_and_continues():
|
|
| 135 |
|
| 136 |
def test_translate_segments_respects_stop_event_between_batches():
|
| 137 |
stop = threading.Event()
|
| 138 |
-
|
|
|
|
| 139 |
|
| 140 |
call_count = {"n": 0}
|
| 141 |
|
|
@@ -150,11 +151,12 @@ def test_translate_segments_respects_stop_event_between_batches():
|
|
| 150 |
|
| 151 |
assert call_count["n"] == 1 # stopped before the second batch
|
| 152 |
assert result[0]["target"] == "SEG0"
|
| 153 |
-
assert result[
|
| 154 |
|
| 155 |
|
| 156 |
def test_translate_segments_progress_callback_invoked_per_batch():
|
| 157 |
-
|
|
|
|
| 158 |
progress_calls = []
|
| 159 |
|
| 160 |
with patch("engine.translate.openrouter_backend.translate_batch", side_effect=lambda texts, *a, **kw: texts):
|
|
@@ -163,11 +165,13 @@ def test_translate_segments_progress_callback_invoked_per_batch():
|
|
| 163 |
progress_callback=lambda i, total: progress_calls.append((i, total)),
|
| 164 |
)
|
| 165 |
|
| 166 |
-
|
|
|
|
| 167 |
|
| 168 |
|
| 169 |
def test_translate_segments_passes_recent_translations_as_preceding_context():
|
| 170 |
-
|
|
|
|
| 171 |
seen_preceding = []
|
| 172 |
|
| 173 |
def fake_batch(texts, api_key, model, template, preceding=None):
|
|
@@ -177,5 +181,6 @@ def test_translate_segments_passes_recent_translations_as_preceding_context():
|
|
| 177 |
with patch("engine.translate.openrouter_backend.translate_batch", side_effect=fake_batch):
|
| 178 |
tr.translate_segments(segments, "key", "model")
|
| 179 |
|
|
|
|
| 180 |
assert seen_preceding[0] is None # nothing translated yet for the first batch
|
| 181 |
-
assert seen_preceding[1] ==
|
|
|
|
| 135 |
|
| 136 |
def test_translate_segments_respects_stop_event_between_batches():
|
| 137 |
stop = threading.Event()
|
| 138 |
+
total = tr._BATCH_SIZE * 3 # several batches' worth, so stopping mid-way is observable
|
| 139 |
+
segments = _segments(*[f"seg{i}" for i in range(total)])
|
| 140 |
|
| 141 |
call_count = {"n": 0}
|
| 142 |
|
|
|
|
| 151 |
|
| 152 |
assert call_count["n"] == 1 # stopped before the second batch
|
| 153 |
assert result[0]["target"] == "SEG0"
|
| 154 |
+
assert result[-1]["target"] == ""
|
| 155 |
|
| 156 |
|
| 157 |
def test_translate_segments_progress_callback_invoked_per_batch():
|
| 158 |
+
total = tr._BATCH_SIZE * 2 + 1 # forces (at least) 3 batches
|
| 159 |
+
segments = _segments(*[f"seg{i}" for i in range(total)])
|
| 160 |
progress_calls = []
|
| 161 |
|
| 162 |
with patch("engine.translate.openrouter_backend.translate_batch", side_effect=lambda texts, *a, **kw: texts):
|
|
|
|
| 165 |
progress_callback=lambda i, total: progress_calls.append((i, total)),
|
| 166 |
)
|
| 167 |
|
| 168 |
+
expected = [(i, total) for i in range(0, total, tr._BATCH_SIZE)]
|
| 169 |
+
assert progress_calls == expected
|
| 170 |
|
| 171 |
|
| 172 |
def test_translate_segments_passes_recent_translations_as_preceding_context():
|
| 173 |
+
total = tr._BATCH_SIZE * 2
|
| 174 |
+
segments = _segments(*[f"seg{i}" for i in range(total)])
|
| 175 |
seen_preceding = []
|
| 176 |
|
| 177 |
def fake_batch(texts, api_key, model, template, preceding=None):
|
|
|
|
| 181 |
with patch("engine.translate.openrouter_backend.translate_batch", side_effect=fake_batch):
|
| 182 |
tr.translate_segments(segments, "key", "model")
|
| 183 |
|
| 184 |
+
last_of_first_batch = [f"seg{i}" for i in range(tr._BATCH_SIZE)][-3:]
|
| 185 |
assert seen_preceding[0] is None # nothing translated yet for the first batch
|
| 186 |
+
assert seen_preceding[1] == last_of_first_batch
|