Skip to content

Commit 86899df

Browse files
committed
Merge branch 'dev'
2 parents e5e7ee4 + 0fe895a commit 86899df

30 files changed

+4101
-829
lines changed

README.md

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,15 +12,20 @@ Translate books, subtitles, and documents using AI - locally or in the cloud.
1212
1313
---
1414

15-
## Quick Start (Windows)
15+
## Quick Start
1616

1717
**Prerequisites:** [Python 3.8+](https://www.python.org/downloads/), [Ollama](https://ollama.com/), [Git](https://git-scm.com/)
1818

1919
```bash
2020
git clone https://github.com/hydropix/TranslateBookWithLLM.git
2121
cd TranslateBookWithLLM
2222
ollama pull qwen3:14b # Download a model
23-
start.bat # Launch (auto-installs dependencies)
23+
24+
# Windows
25+
start.bat
26+
27+
# Mac/Linux
28+
chmod +x start.sh && ./start.sh
2429
```
2530

2631
The web interface opens at **http://localhost:5000**

benchmark/translator.py

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -187,15 +187,15 @@ async def translate(self, request: TranslationRequest) -> TranslationResult:
187187
)
188188

189189
# Make the translation request
190-
response = await provider.generate(
190+
llm_response = await provider.generate(
191191
prompt=user_prompt,
192192
timeout=self.config.ollama.timeout,
193193
system_prompt=system_prompt
194194
)
195195

196196
elapsed_ms = int((time.perf_counter() - start_time) * 1000)
197197

198-
if not response:
198+
if not llm_response:
199199
return TranslationResult(
200200
source_text_id=request.text.id,
201201
target_language=request.target_language,
@@ -205,13 +205,16 @@ async def translate(self, request: TranslationRequest) -> TranslationResult:
205205
error="No response from Ollama"
206206
)
207207

208+
# Extract response content from LLMResponse object
209+
response_content = llm_response.content
210+
208211
# Extract translation from response
209-
translated_text = provider.extract_translation(response)
212+
translated_text = provider.extract_translation(response_content)
210213

211214
if not translated_text:
212215
# Fallback: use the raw response if extraction fails
213216
self._log("warning", f"Could not extract translation tags, using raw response")
214-
translated_text = response.strip()
217+
translated_text = response_content.strip()
215218

216219
return TranslationResult(
217220
source_text_id=request.text.id,

prompts/examples/helpers.py

Lines changed: 17 additions & 70 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
from typing import Any, Dict, Optional, Tuple
99

1010
from .constants import TAG0, TAG1, TAG2, IMG_MARKER
11-
from .placeholder_examples import PLACEHOLDER_EXAMPLES
11+
from .placeholder_examples import get_example_for_pair
1212
from .subtitle_examples import SUBTITLE_EXAMPLES
1313
from .output_examples import OUTPUT_FORMAT_EXAMPLES
1414

@@ -20,41 +20,14 @@ def get_placeholder_example(
2020
"""
2121
Get placeholder preservation example for a language pair.
2222
23-
Priority:
24-
1. Dynamically generated cache (technical_generator)
25-
2. Static fallback examples
26-
3. English->target or source->English fallback
23+
Generates examples dynamically for any language pair using
24+
pre-translated sentences in each supported language.
2725
2826
Returns:
2927
Tuple of (example_dict, actual_source_lang, actual_target_lang).
3028
"""
31-
key = (source_lang.lower(), target_lang.lower())
32-
33-
# 1. Check dynamic cache first
34-
try:
35-
from .technical_generator import get_cached_technical_example
36-
cached = get_cached_technical_example(source_lang, target_lang, "placeholder")
37-
if cached:
38-
return cached, source_lang, target_lang
39-
except ImportError:
40-
pass
41-
42-
# 2. Static fallback examples
43-
if key in PLACEHOLDER_EXAMPLES:
44-
return PLACEHOLDER_EXAMPLES[key], source_lang, target_lang
45-
46-
# 3. Fallback: English as source
47-
fallback_key = ("english", target_lang.lower())
48-
if fallback_key in PLACEHOLDER_EXAMPLES:
49-
return PLACEHOLDER_EXAMPLES[fallback_key], "English", target_lang
50-
51-
# 4. Fallback: target is English
52-
fallback_key = (source_lang.lower(), "english")
53-
if fallback_key in PLACEHOLDER_EXAMPLES:
54-
return PLACEHOLDER_EXAMPLES[fallback_key], source_lang, "English"
55-
56-
# 5. Ultimate fallback
57-
return PLACEHOLDER_EXAMPLES[("english", "chinese")], "English", "Chinese"
29+
example = get_example_for_pair(source_lang, target_lang)
30+
return example, source_lang, target_lang
5831

5932

6033
def get_subtitle_example(target_lang: str) -> str:
@@ -100,11 +73,11 @@ def build_placeholder_section(
10073
3. Maintain their EXACT position in the sentence structure
10174
4. Do NOT add spaces around them unless present in the source
10275
103-
**Example ({actual_source.title()} -> {actual_target.title()}):**
76+
**Example ({actual_source.title()} {actual_target.title()}):**
10477
105-
{actual_source.title()}: "{example['source']}"
106-
Correct: "{example['correct']}"
107-
WRONG: "{example['wrong']}" (placeholders removed)
78+
Source: "{example['source']}"
79+
Correct: "{example['correct']}"
80+
WRONG: "{example['wrong']}" (placeholders removed)
10881
"""
10982

11083

@@ -129,22 +102,12 @@ def build_image_placeholder_section(
129102

130103

131104
def has_example_for_pair(source_lang: str, target_lang: str) -> bool:
132-
"""Check if a placeholder example exists for the given language pair."""
133-
key = (source_lang.lower(), target_lang.lower())
105+
"""Check if a placeholder example exists for the given language pair.
134106
135-
# Check static examples
136-
if key in PLACEHOLDER_EXAMPLES:
137-
return True
138-
139-
# Check dynamic cache
140-
try:
141-
from .technical_generator import get_cached_technical_example
142-
if get_cached_technical_example(source_lang, target_lang, "placeholder"):
143-
return True
144-
except ImportError:
145-
pass
146-
147-
return False
107+
Always returns True since examples are generated dynamically
108+
with fallback to English for unsupported languages.
109+
"""
110+
return True
148111

149112

150113
async def ensure_example_ready(
@@ -155,23 +118,7 @@ async def ensure_example_ready(
155118
"""
156119
Ensure a placeholder example exists for the language pair.
157120
158-
If no example exists and a provider is given, generates one dynamically.
159-
160-
Returns:
161-
True if an example exists or was generated successfully.
121+
Always returns True since examples are generated dynamically
122+
with fallback to English for unsupported languages.
162123
"""
163-
if has_example_for_pair(source_lang, target_lang):
164-
return True
165-
166-
if provider is None:
167-
return False
168-
169-
try:
170-
from .technical_generator import generate_placeholder_example_async
171-
result = await generate_placeholder_example_async(source_lang, target_lang, provider)
172-
return result is not None
173-
except ImportError:
174-
return False
175-
except Exception as e:
176-
print(f"[WARNING] Failed to generate example: {e}")
177-
return False
124+
return True

0 commit comments

Comments
 (0)