-
Notifications
You must be signed in to change notification settings - Fork 316
Expand file tree
/
Copy path.env.example
More file actions
353 lines (308 loc) · 16.4 KB
/
Copy path.env.example
File metadata and controls
353 lines (308 loc) · 16.4 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
# Translation API Configuration
# Legacy API endpoint (deprecated, kept for backward compatibility)
# Use provider-specific endpoints below instead
API_ENDPOINT=http://localhost:11434/api/generate
# Provider-specific API endpoints (recommended)
# Ollama local server endpoint
OLLAMA_API_ENDPOINT=http://localhost:11434/api/generate
# OpenAI-compatible endpoint (OpenAI, LM Studio, llama.cpp, etc.)
OPENAI_API_ENDPOINT=https://api.openai.com/v1/chat/completions
DEFAULT_MODEL=qwen3:14b
# Server Configuration
PORT=5000 # Port for the web interface
HOST=127.0.0.1 # Server host (127.0.0.1 for localhost only, 0.0.0.0 for all network interfaces)
OUTPUT_DIR=translated_files # Directory for translated output files
# Output filename pattern (naming convention)
# Placeholders: {originalName}, {targetLang}, {sourceLang}, {model}, {date}, {datetime}, {ext}
# {date} → YYYY-MM-DD
# {datetime} → YYYY-MM-DD_HH-MM-SS
# {model} → sanitized (e.g., "anthropic/claude-4.5-haiku" → "anthropic_claude-4.5-haiku")
# Example for model A/B testing: {originalName} ({targetLang}) ({model})_{date}.{ext}
OUTPUT_FILENAME_PATTERN={originalName} ({targetLang}).{ext}
# LLM Provider Settings
# Options: ollama, poe, gemini, openai, openrouter, mistral, deepseek, nim
LLM_PROVIDER=ollama
# =============================================================================
# Multi-key support (works for any cloud provider)
# =============================================================================
# All *_API_KEY variables below accept either a single key OR several keys
# separated by commas. When multiple keys are provided, the rotation pool
# automatically switches to the next key on HTTP 429 (rate-limit) — useful for
# chaining several free-tier accounts to extend daily quotas, or distributing
# load across paid keys.
#
# Single key (default behavior):
# GEMINI_API_KEY=AIza...your-key
#
# Multiple keys (rotation enabled):
# GEMINI_API_KEY=AIza...key1,AIza...key2,AIza...key3
#
# How it works:
# - Round-robin selection: each request uses the next key in the list
# - On HTTP 429: the failing key is marked throttled (using the API's
# Retry-After / X-RateLimit-Reset header) and the next available key is
# used immediately — no sleep added
# - When all keys are throttled: sleep until the earliest one recovers
# - When all retries are exhausted: translation auto-pauses and saves a
# checkpoint (resume with the same command later)
#
# Limitations:
# - Rotation does NOT parallelize — translation stays sequential
# - Keys from the same account share quotas; use keys from DIFFERENT accounts
# to actually multiply your effective limits
# - Throttle state is not persisted across restarts (rate-limit windows are
# usually short, so this is rarely a problem in practice)
#
# Full guide: docs/API_KEY_ROTATION.md
# =============================================================================
# Your Google Gemini API key (required if using gemini provider)
GEMINI_API_KEY=
GEMINI_MODEL=gemini-2.0-flash
# Gemini safety filter threshold for HARASSMENT / HATE_SPEECH / SEXUALLY_EXPLICIT /
# DANGEROUS_CONTENT. Default is BLOCK_NONE because the tool translates adult-themed
# novels where the API default (BLOCK_MEDIUM_AND_ABOVE) silently strips chunks and
# produces empty responses. Valid values: BLOCK_NONE, BLOCK_ONLY_HIGH,
# BLOCK_MEDIUM_AND_ABOVE, BLOCK_LOW_AND_ABOVE.
GEMINI_SAFETY_THRESHOLD=BLOCK_NONE
# Your OpenAI API key (required if using openai provider)
OPENAI_API_KEY=
# OpenRouter Settings (access to 200+ models: Claude, GPT-4, Llama, Mistral, etc.)
# Your OpenRouter API key (from https://openrouter.ai/keys)
OPENROUTER_API_KEY=
OPENROUTER_MODEL=anthropic/claude-4.5-haiku
# See all models at https://openrouter.ai/models (text-only models are auto-filtered in the UI)
# Mistral AI Settings
# Your Mistral API key (from https://console.mistral.ai)
MISTRAL_API_KEY=
MISTRAL_MODEL=mistral-large-latest
# Available models: mistral-large-latest (128K), mistral-medium-latest (128K),
# mistral-small-latest (32K), codestral-latest (32K)
# MISTRAL_API_ENDPOINT=https://api.mistral.ai/v1/chat/completions # Optional, default endpoint
# DeepSeek Settings (Chinese LLM, very cost-effective)
# Get your API key at: https://platform.deepseek.com/
DEEPSEEK_API_KEY=
DEEPSEEK_MODEL=deepseek-v4-pro
# Available models: deepseek-v4-pro, deepseek-v4-flash
# Legacy aliases deepseek-chat and deepseek-reasoner are scheduled for deprecation on 2026-07-24.
# DEEPSEEK_API_ENDPOINT=https://api.deepseek.com/chat/completions # Optional, default endpoint
# V4 models (deepseek-v4-*) support thinking mode. Leave true to disable it for translation;
# set false to keep reasoning enabled.
DEEPSEEK_DISABLE_THINKING=true
# Poe Settings (Multi-provider access: Claude, GPT, Gemini, Llama, Grok, and more)
# Get your API key at: https://poe.com/api_key
POE_API_KEY=
POE_MODEL=Claude-Sonnet-4
# Popular models: Claude-Sonnet-4, Claude-Opus-4.1, GPT-4o, Gemini-2.5-Pro, Llama-3.1-405B, Grok-4
# Poe also provides access to millions of community-created bots
# Most Poe bots reason by default, which multiplies output tokens for no gain on
# translation. Leave true to request each bot's lowest reasoning setting;
# set false to keep reasoning enabled.
POE_DISABLE_THINKING=true
# Some Poe bots also search the web by default, inflating the prompt of every
# chunk with results a self-contained book never needs. Set false to allow it.
POE_DISABLE_WEB_SEARCH=true
# NVIDIA NIM Settings (Hosted cloud API for Llama, Mistral, and other models)
# Get your API key at: https://build.nvidia.com/
NIM_API_KEY=
NIM_MODEL=meta/llama-3.1-8b-instruct
# Available models: meta/llama-3.1-8b-instruct, meta/llama-3.1-70b-instruct,
# meta/llama-3.1-405b-instruct, mistralai/mixtral-8x7b-instruct-v0.1
# See all models at: https://build.nvidia.com/explore/discover
# NIM_API_ENDPOINT=https://integrate.api.nvidia.com/v1/chat/completions # Optional, default endpoint
# Translation Settings
# Source language: leave empty to auto-detect from file content (langdetect)
# Target language: leave empty to use the browser language in the web UI
# Both can still be overridden from the UI/CLI at translation time.
DEFAULT_SOURCE_LANGUAGE=
DEFAULT_TARGET_LANGUAGE=
REQUEST_TIMEOUT=300 # API timeout in seconds (raise for slow local Ollama / large chunks)
# Sampling temperature for cloud LLM providers (gemini, openai, openrouter,
# mistral, deepseek, poe, nim). Lower = more consistent translations, higher =
# more variation. Ollama is unaffected (it uses its own server-side defaults).
TEMPERATURE=0.3
# Token-based Chunking
# All file types use token-based chunking with tiktoken for consistent chunk sizes
# MAX_TOKENS_PER_CHUNK is also editable in the web UI (Settings) and applies to
# new jobs without a restart. Floored at 50, no upper bound: the practical limit
# is the provider's context window and how well the model holds a long passage
# together. 450 is safest, 800 suits tag-heavy EPUB/DOCX, 1500-2000 works for
# plain prose on a large-context cloud model.
MAX_TOKENS_PER_CHUNK=450 # Maximum tokens per chunk (hard limit)
SOFT_LIMIT_RATIO=0.8 # Start looking for boundaries at 80% of max tokens
# Context Management (IMPORTANT)
# Formula: required_ctx = prompt_tokens + (MAX_TOKENS_PER_CHUNK * 2) + 50
# - prompt_tokens ≈ 500 (instructions) + MAX_TOKENS_PER_CHUNK (source text)
# - Response buffer = MAX_TOKENS_PER_CHUNK * 2 (translation can be 2x longer for some languages)
# - +50 for <Translated> tags
# Examples:
# - MAX_TOKENS_PER_CHUNK=450 → needs ~2048 context
# - MAX_TOKENS_PER_CHUNK=700 → needs ~4096 context
# - MAX_TOKENS_PER_CHUNK=800 → needs ~4096 context
OLLAMA_NUM_CTX=4096
# Automatic Context Optimization (Ollama only)
# When enabled, the runtime starts at ADAPTIVE_CONTEXT_INITIAL and grows the
# context window by ADAPTIVE_CONTEXT_STEP whenever the prompt would not fit,
# instead of always allocating OLLAMA_NUM_CTX upfront.
AUTO_ADJUST_CONTEXT=true
ADAPTIVE_CONTEXT_INITIAL=2048 # Starting context size for non-thinking models
ADAPTIVE_CONTEXT_STEP=2048 # Step size when the context needs to grow
# Advanced
MAX_TRANSLATION_ATTEMPTS=3
# Parallel translation: number of chunks translated concurrently.
# 1 (default) = fully sequential, identical to the legacy behavior including
# cross-chunk context chaining. Higher values dispatch that many LLM requests
# at once (faster on cloud providers, but may hit rate limits and drop the
# per-chunk "previous translation" context). Local providers (Ollama) ignore
# this and always run 1, since a single instance serializes requests anyway.
PARALLEL_TRANSLATIONS=1
MAX_PARALLEL_TRANSLATIONS=16 # Upper bound for the CLI flag and web UI control
# Extra hostnames the LLM endpoint validator accepts, comma-separated.
# The known provider hosts and every endpoint configured above are already
# allowed, as is anything on your own network: localhost, private/LAN
# addresses, a single-label hostname like 'ollama', the .local / .lan /
# .home.arpa / .internal / .ts.net style suffixes, and any hostname that
# resolves to a private address. Add an entry only for a self-hosted gateway
# that answers on a public address. Not editable from the web UI on
# purpose: widening the allowlist from the browser would reopen the
# credential-exfiltration path this guard closes.
# LLM_ENDPOINT_ALLOWLIST=llm.internal.example.com,gateway.example.org
# Web UI default for the "Don't auto-pause on rate limit" checkbox. Mirror of
# AUTO_PAUSE_ON_RATE_LIMIT (true here ⇔ AUTO_PAUSE_ON_RATE_LIMIT=false for new
# jobs). Persisted separately so the UI can show the checkbox state across
# restarts without touching the request-level setting.
DISABLE_AUTO_PAUSE=false
# Auto-pause on HTTP 429 rate limit
# true (default): pause translation after retries are exhausted, user resumes manually
# false: wait `Retry-After` seconds (or RATE_LIMIT_AUTO_RESUME_DELAY) and auto-resume
# from the last checkpoint. Useful for long novels on free-tier APIs.
AUTO_PAUSE_ON_RATE_LIMIT=true
RATE_LIMIT_AUTO_RESUME_DELAY=60
EPUB_TOKEN_ALIGNMENT_ENABLED=true
# Options: true (enable Phase 2 fallback), false (use old behavior with only Phase 1 + Phase 3)
EPUB_TOKEN_ALIGNMENT_METHOD=proportional
# Options:
# proportional - Position-based alignment (fast, no dependencies)
# advanced - Future: ML-based alignment (requires additional libraries)
# Neutralizes source-script (CJK) typography left over from a Chinese/Japanese/
# Korean-authored EPUB translated to a non-CJK target: rewrites CJK font stacks,
# paragraph indent, leading, vertical writing mode and CJK line-breaking rules
# in stylesheets and inline styles, and drops reader-specific font-override OPF
# metas (e.g. Duokan). Embedded fonts are never deleted, only unreferenced.
EPUB_SCRIPT_NORMALIZATION_ENABLED=true
# Localizes the packaging metadata of a translated EPUB: one extra LLM call per
# book translates the OPF dc:title and dc:description, and the translated title
# is propagated to every NCX docTitle so library shelves and reader "book
# information" panels stop showing the source-language title. The author
# (dc:creator) is never translated, a description longer than 4000 characters is
# skipped, and a result that fails validation keeps the original value.
EPUB_TRANSLATE_METADATA_ENABLED=true
# SRT-specific configuration
# Subtitles per LLM block, shared by translate and refine. Block sizing is
# fixed-count (no char cap) so every block sent to the model has the same
# shape — keeps [N] marker accounting predictable.
# Lower for tiny models (e.g. 5 for 4B params), higher for big-context models.
SRT_LINES_PER_BLOCK=10
# Debug Mode
# Enable verbose logging for troubleshooting configuration and connection issues.
# Set to 'true' to see detailed logs about .env loading, API calls, and configuration values.
# Useful when models are not detected or languages are not applied correctly.
DEBUG_MODE=false
# Translation Attribution
# Adds a discrete attribution to your translations (metadata for EPUB, footer for
# TXT, comment for SRT). Please consider keeping this enabled to support the
# project and help others discover this free tool! The attribution is
# non-intrusive and placed at the end of files. Thank you for your support!
# (SIGNATURE_ENABLED is still accepted as a legacy alias.)
ATTRIBUTION_ENABLED=true
# Appends a short attribution page at the end of translated EPUBs, in addition to
# the OPF metadata. Ignored when ATTRIBUTION_ENABLED is false.
ATTRIBUTION_PAGE_ENABLED=true
# TTS (Text-to-Speech) Configuration
# Generate audio narration of translated documents
# Requires ffmpeg installed on the system for Opus encoding
TTS_ENABLED=false
# TTS Provider Selection
# Available providers:
# - edge-tts: Microsoft Edge neural voices (free, cloud-based, no GPU required)
# - chatterbox: Chatterbox TTS (local, GPU-accelerated, voice cloning support)
TTS_PROVIDER=edge-tts
# Voice selection (leave empty for auto-selection based on target language)
# Edge-TTS examples: zh-CN-XiaoxiaoNeural (Chinese female), zh-CN-YunxiNeural (Chinese male)
# Chatterbox: Uses language codes (e.g., "en", "zh", "fr") - see CHATTERBOX_VOICES below
# See Edge-TTS voices: https://speech.microsoft.com/portal/voicegallery
TTS_VOICE=
# Speech rate adjustment (-50% to +100%, e.g., "+10%", "-20%")
TTS_RATE=+0%
# Opus bitrate for output audio (e.g., 48k, 64k, 96k, 128k)
TTS_BITRATE=64k
# Output format (opus recommended for compact file size)
TTS_OUTPUT_FORMAT=opus
# ===== Chatterbox TTS Configuration =====
# Chatterbox is a GPU-accelerated local TTS with voice cloning capabilities
# GitHub: https://github.com/resemble-ai/chatterbox
# Install: pip install chatterbox-tts torch torchaudio
# GPU/CUDA Requirements:
# - NVIDIA GPU with CUDA support (recommended: 6GB+ VRAM)
# - CUDA Toolkit 11.8 or 12.x installed
# - PyTorch with CUDA support
# - Falls back to CPU if no GPU available (significantly slower)
# Voice prompt for voice cloning (optional)
# Path to a reference audio file (WAV, MP3, etc.) for voice cloning
# Leave empty to use the default Chatterbox voice
TTS_VOICE_PROMPT_PATH=
# Emotion exaggeration level (0.0 to 1.0)
# 0.0 = neutral/flat, 1.0 = highly expressive
# Default: 0.5 for balanced expressiveness
TTS_EXAGGERATION=0.5
# Classifier-free guidance weight (0.0 to 1.0)
# Higher values = more stable/predictable output
# Lower values = more varied but potentially less consistent
# Default: 0.5 for balanced stability
TTS_CFG_WEIGHT=0.5
# Chatterbox supported languages (23 languages):
# en (English), es (Spanish), fr (French), de (German), it (Italian),
# pt (Portuguese), pl (Polish), tr (Turkish), ru (Russian), nl (Dutch),
# cs (Czech), ar (Arabic), zh (Chinese), ja (Japanese), hu (Hungarian),
# ko (Korean), hi (Hindi), vi (Vietnamese), sv (Swedish), da (Danish),
# fi (Finnish), id (Indonesian), el (Greek)
# =============================================================================
# WEBHOOK NOTIFICATIONS
# =============================================================================
# Send an HTTP request to a webhook (gotify, ntfy, Discord, Slack,
# Healthchecks, custom endpoint, ...) when a translation reaches a terminal
# state. Disabled by default; set NOTIFY_WEBHOOK_URL to enable.
#
# Placeholders available in URL, headers and payload via {name}:
# {event}, {file}, {output}, {duration_seconds}, {provider}, {model},
# {source_lang}, {target_lang}, {error}, {translation_id}
#
# Quick recipes (uncomment ONE):
#
# 1) ntfy.sh push to mobile (free, just install the ntfy app and subscribe
# to a unique topic):
# NOTIFY_WEBHOOK_URL=https://ntfy.sh/your-unique-topic-here
#
# 2) Self-hosted gotify server (the use case from issue #167):
# NOTIFY_WEBHOOK_URL=https://gotify.example.com/message?token=YOUR_TOKEN_HERE
#
# 3) Discord channel webhook:
# NOTIFY_WEBHOOK_URL=https://discord.com/api/webhooks/XXXXX/YYYYY
# NOTIFY_WEBHOOK_PAYLOAD={"content":"Translation **{event}**: `{file}` in {duration_seconds:.0f}s"}
#
# 4) Slack incoming webhook:
# NOTIFY_WEBHOOK_URL=https://hooks.slack.com/services/XXX/YYY/ZZZ
# NOTIFY_WEBHOOK_PAYLOAD={"text":"Translation {event}: {file} ({duration_seconds:.0f}s)"}
#
# 5) Custom endpoint with auth header:
# NOTIFY_WEBHOOK_URL=https://api.example.com/notify
# NOTIFY_WEBHOOK_HEADERS={"Authorization":"Bearer YOUR_TOKEN_HERE"}
#
# See docs/NOTIFICATIONS.md for the full reference.
NOTIFY_WEBHOOK_URL=
NOTIFY_WEBHOOK_METHOD=POST
NOTIFY_WEBHOOK_HEADERS=
NOTIFY_WEBHOOK_PAYLOAD=
NOTIFY_ON_SUCCESS=true
NOTIFY_ON_FAILURE=true
NOTIFY_ON_INTERRUPTION=false
NOTIFY_TIMEOUT_SECONDS=5