Auto: feature/streaming-translation #12

Merged
claude-bot merged 6 commits from feature/streaming-translation into main 2026-03-01 14:15:16 -07:00
Collaborator

Automated PR for branch feature/streaming-translation.

Automated PR for branch `feature/streaming-translation`.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Existing tests now configure generate_content_stream alongside
generate_content since text/image translations route through streaming.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
test: add streaming translation integration tests
Some checks failed
Auto PR Review / review (push) Failing after 2m1s
36f45626e8
Tests cover: streaming for text/image, non-streaming for image+caption,
fallback after retries, ValueError chunk handling, deleted message
tolerance, and token estimation when metadata is missing.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Author
Collaborator

Changes Requested

Well-structured streaming implementation with good error handling, retry logic, fallback to non-streaming, and solid test coverage. One bug to fix: the streaming callback escapes text for HTML but doesn't tell Telegram to parse it as HTML.

Warnings

  • handlers/translation.py: _make_streaming_callback calls safe_html(accumulated_text) which escapes <, >, & into HTML entities (&lt;, &gt;, &amp;), but bot.edit_message_text is called without parse_mode="HTML". Telegram treats the message as plain text, so users will see literal &amp;, &lt; etc. during streaming if their text contains those characters. Fix: add parse_mode="HTML" to the edit_message_text call. Note: the test test_streaming_stops_edits_on_deleted_message uses the absence of parse_mode to distinguish streaming edits from final edits — that test logic will also need updating.

Suggestions

  • handlers/translation.py: The _retryable_errors dict is rebuilt on every call to _perform_streaming_translation. Since it's static, consider making it a module-level constant (same pattern as in _perform_single_model_translation if applicable) to avoid repeated allocation.
## Changes Requested Well-structured streaming implementation with good error handling, retry logic, fallback to non-streaming, and solid test coverage. One bug to fix: the streaming callback escapes text for HTML but doesn't tell Telegram to parse it as HTML. ### Warnings - **handlers/translation.py**: `_make_streaming_callback` calls `safe_html(accumulated_text)` which escapes `<`, `>`, `&` into HTML entities (`&lt;`, `&gt;`, `&amp;`), but `bot.edit_message_text` is called without `parse_mode="HTML"`. Telegram treats the message as plain text, so users will see literal `&amp;`, `&lt;` etc. during streaming if their text contains those characters. Fix: add `parse_mode="HTML"` to the `edit_message_text` call. Note: the test `test_streaming_stops_edits_on_deleted_message` uses the absence of `parse_mode` to distinguish streaming edits from final edits — that test logic will also need updating. ### Suggestions - **handlers/translation.py**: The `_retryable_errors` dict is rebuilt on every call to `_perform_streaming_translation`. Since it's static, consider making it a module-level constant (same pattern as in `_perform_single_model_translation` if applicable) to avoid repeated allocation.
fix: add parse_mode=HTML to streaming edits so HTML entities render correctly
All checks were successful
Auto PR Review / review (push) Successful in 2m44s
df88e2edd9
The streaming callback uses safe_html() which escapes <, >, & into HTML
entities. Without parse_mode="HTML", Telegram displays literal &amp; etc.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Author
Collaborator

Approved

Clean, well-implemented streaming translation feature with good resilience patterns. Timeout covers full stream iteration, chunk errors are gracefully skipped, Telegram edits are throttled and capped, retries disable streaming edits to avoid UX jank, and non-streaming fallback provides a last resort. Security is handled via safe_html before HTML-mode edits. Test coverage is thorough across happy path, error, and edge cases.

Suggestions

  • handlers/translation.py: The _retryable_errors dict is recreated on every call to _perform_streaming_translation. Since it's static, it could be a module-level constant (like _STREAMING_RETRYABLE_ERRORS) to make it clearer that it doesn't depend on runtime state.
  • tests/integration/conftest.py: The _fake_stream_iterator helper is imported as a private function (_ prefix) from conftest into the test file. Consider renaming it to fake_stream_iterator (no underscore) since it's part of the test utilities' public API used across test modules.
  • handlers/translation.py: The safety-net code after the for loop (lines ~567-574) is unreachable — every loop iteration ends with a return or continue. This is harmless defensive code but could be annotated with a # pragma: no cover if you track coverage.
## Approved Clean, well-implemented streaming translation feature with good resilience patterns. Timeout covers full stream iteration, chunk errors are gracefully skipped, Telegram edits are throttled and capped, retries disable streaming edits to avoid UX jank, and non-streaming fallback provides a last resort. Security is handled via safe_html before HTML-mode edits. Test coverage is thorough across happy path, error, and edge cases. ### Suggestions - **handlers/translation.py**: The `_retryable_errors` dict is recreated on every call to `_perform_streaming_translation`. Since it's static, it could be a module-level constant (like `_STREAMING_RETRYABLE_ERRORS`) to make it clearer that it doesn't depend on runtime state. - **tests/integration/conftest.py**: The `_fake_stream_iterator` helper is imported as a private function (`_` prefix) from conftest into the test file. Consider renaming it to `fake_stream_iterator` (no underscore) since it's part of the test utilities' public API used across test modules. - **handlers/translation.py**: The safety-net code after the `for` loop (lines ~567-574) is unreachable — every loop iteration ends with a `return` or `continue`. This is harmless defensive code but could be annotated with a `# pragma: no cover` if you track coverage.
claude-bot deleted branch feature/streaming-translation 2026-03-01 14:15:17 -07:00
Sign in to join this conversation.
No reviewers
No labels
No milestone
No project
No assignees
2 participants
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
bittabola/tarjimon!12
No description provided.