billingsmoore Claude Sonnet 5 commited on
Commit
a8287eb
·
1 Parent(s): 448481b

Shrink translation batch size so results appear incrementally during Translate All

Browse files

Previously _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 CHANGED
@@ -29,7 +29,9 @@ DEFAULT_MODEL = CURATED_MODELS[0]
29
  _TIMEOUT = 120
30
  _MODELS_TIMEOUT = 10
31
  _BACKOFF_BASE = 2
32
- _BATCH_SIZE = 25
 
 
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
- segments = _segments(*[f"seg{i}" for i in range(60)]) # 60 > _BATCH_SIZE(25), needs 3 batches
 
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[59]["target"] == ""
154
 
155
 
156
  def test_translate_segments_progress_callback_invoked_per_batch():
157
- segments = _segments(*[f"seg{i}" for i in range(30)])
 
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
- assert progress_calls == [(0, 30), (25, 30)]
 
167
 
168
 
169
  def test_translate_segments_passes_recent_translations_as_preceding_context():
170
- segments = _segments(*[f"seg{i}" for i in range(30)])
 
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] == ["seg22", "seg23", "seg24"] # last 3 of the first batch
 
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