Main
This commit is contained in:
parent
7d79b8a3ec
commit
3f02b1b146
6 changed files with 283 additions and 256 deletions
13
.env.example
13
.env.example
|
|
@ -9,20 +9,21 @@
|
|||
# - Leave this variable out to use the model's default setting.
|
||||
GEMINI_THINKING_BUDGET=
|
||||
|
||||
# Set to "gemini" to use the Gemini API or "openai" for OpenAI (If empty it will default to openai.)
|
||||
# Set to "gemini" to use the Gemini API or "openai" for OpenAI-compatible APIs (If empty it will default to openai.)
|
||||
API_PROVIDER=openai
|
||||
|
||||
#API link, leave blank to use OpenAI API
|
||||
# API URL, leave blank to use OpenAI API.
|
||||
# Nvidia example: "https://integrate.api.nvidia.com/v1/"
|
||||
api=""
|
||||
|
||||
#API key
|
||||
# API key
|
||||
key=""
|
||||
|
||||
#Oranization key, make something up for self hosted or other API
|
||||
#Oranization key, make something up for self hosted or other API. If using Nvidia API, leave it blank or it can get wonky
|
||||
organization=""
|
||||
|
||||
#LLM model name, use gpt-3.5-turbo-1106 or gpt-3.5-turbo or gpt-4-1106-preview for OpenAI API
|
||||
#For text generation webui use gpt-3.5-turbo, for other API's consult their documentation
|
||||
# LLM model name.
|
||||
# Default below works for OpenAI; for Gemini/Nvidia set your provider model name.
|
||||
model="gpt-4.1"
|
||||
|
||||
#The language to translate TO, Don't forget to change the prompt
|
||||
|
|
|
|||
2
.gitignore
vendored
2
.gitignore
vendored
|
|
@ -1,4 +1,4 @@
|
|||
.env
|
||||
|
||||
*.tmp
|
||||
*.json
|
||||
*.js
|
||||
|
|
|
|||
|
|
@ -109,9 +109,11 @@ This means Python wasn't added to your PATH. You have two options:
|
|||
|
||||
1. Inside the tool folder, find `.env.example` and make a copy of it named `.env`.
|
||||
2. Open `.env` in any text editor (Notepad works fine) and fill in your API details:
|
||||
- `api` — Your API base URL (for Nvidia use `https://integrate.api.nvidia.com/v1/`).
|
||||
- `key` — Your API key.
|
||||
- `organization` — Your organization key (make something up if using a self-hosted or non-OpenAI API).
|
||||
- `API_PROVIDER` — Set to `openai` or `gemini` depending on your provider.
|
||||
- `API_PROVIDER` — Use `openai` for OpenAI-compatible providers (including Nvidia), or `gemini` for Gemini.
|
||||
- `model` — For Nvidia/custom OpenAI-compatible endpoints, enter the model name manually (example: `deepseek-ai/deepseek-v4-pro`).
|
||||
3. The rest of the settings (wordwrap, batch size, etc.) can be left as defaults for now. You can tweak them later.
|
||||
|
||||
### 3. Launch the GUI
|
||||
|
|
|
|||
|
|
@ -137,6 +137,7 @@ class ConfigTab(QWidget):
|
|||
self.reset_to_defaults()
|
||||
else:
|
||||
self.load_from_env()
|
||||
self._update_model_placeholder()
|
||||
|
||||
# Connect auto-save after initial load
|
||||
self.connect_auto_save()
|
||||
|
|
@ -144,6 +145,20 @@ class ConfigTab(QWidget):
|
|||
# Fetch latest models in the background once the UI is shown
|
||||
QTimer.singleShot(0, lambda: self.fetch_models(silent=True))
|
||||
|
||||
def _is_nvidia_api_url(self, api_url: str) -> bool:
|
||||
"""Return True when the configured URL points to Nvidia's OpenAI-compatible API."""
|
||||
return "integrate.api.nvidia.com" in (api_url or "").strip().lower()
|
||||
|
||||
def _update_model_placeholder(self):
|
||||
"""Show a manual model-entry hint only when Nvidia API is selected."""
|
||||
line_edit = self.model_combo.lineEdit()
|
||||
if not line_edit:
|
||||
return
|
||||
if self._is_nvidia_api_url(self.api_url_edit.text()):
|
||||
line_edit.setPlaceholderText("Enter Nvidia model name (e.g., deepseek-ai/deepseek-v4-pro)")
|
||||
else:
|
||||
line_edit.setPlaceholderText("")
|
||||
|
||||
def init_ui(self):
|
||||
"""Initialize the user interface with horizontal icon navigation at top."""
|
||||
main_layout = QVBoxLayout()
|
||||
|
|
@ -326,11 +341,13 @@ class ConfigTab(QWidget):
|
|||
("Claude (Anthropic)", "https://api.anthropic.com/v1"),
|
||||
("Gemini", "https://generativelanguage.googleapis.com/v1beta/openai/"),
|
||||
("DeepSeek", "https://api.deepseek.com/v1/"),
|
||||
("Nvidia", "https://integrate.api.nvidia.com/v1/"),
|
||||
]
|
||||
for _name, _url in _url_presets:
|
||||
_action = api_url_menu.addAction(_name)
|
||||
_action.triggered.connect(lambda checked, u=_url: self.api_url_edit.setText(u))
|
||||
api_url_preset_btn.setMenu(api_url_menu)
|
||||
self.api_url_edit.textChanged.connect(self._update_model_placeholder)
|
||||
|
||||
api_url_layout.addWidget(self.api_url_edit)
|
||||
api_url_layout.addWidget(api_url_preset_btn)
|
||||
|
|
|
|||
|
|
@ -88,6 +88,13 @@ def _write_request_debug_log(provider, request_payload, usage):
|
|||
except Exception:
|
||||
pass
|
||||
|
||||
def _normalize_openai_base_url(url: str) -> str:
|
||||
"""Ensure OpenAI SDK global base_url has a trailing slash."""
|
||||
_url = (url or "").strip()
|
||||
if _url and not _url.endswith("/"):
|
||||
_url += "/"
|
||||
return _url
|
||||
|
||||
# Tracks which distinct batch sizes have already been cache-written during this estimate run.
|
||||
# Each unique numLines value maps to a distinct output_config schema → one write per size.
|
||||
# Persisted to disk so sequential GUI subprocesses share state.
|
||||
|
|
@ -329,17 +336,17 @@ def validate_translation_content(original_items, translated_items, langRegex):
|
|||
return is_valid, invalid_indices, reasons
|
||||
|
||||
# Load .env, strip accidental whitespace, set base URL / org / API key.
|
||||
# Handles the Gemini compatibility layer as a special case.
|
||||
# Gemini uses its compatibility endpoint only when no custom API URL is set.
|
||||
load_dotenv()
|
||||
api_provider = os.getenv("API_PROVIDER", "openai").lower()
|
||||
env_api = os.getenv("api", "").strip()
|
||||
if api_provider == "gemini":
|
||||
# Use Google Generative Language compatibility endpoint when running Gemini
|
||||
if api_provider == "gemini" and not env_api:
|
||||
# Use Google Generative Language compatibility endpoint only as fallback.
|
||||
openai.base_url = "https://generativelanguage.googleapis.com/v1beta/openai/"
|
||||
openai.organization = None
|
||||
else:
|
||||
if env_api:
|
||||
openai.base_url = env_api
|
||||
openai.base_url = _normalize_openai_base_url(env_api)
|
||||
# Support both 'organization' (gui/.env.example) and legacy 'org' names
|
||||
org = os.getenv("organization") or os.getenv("org")
|
||||
if org:
|
||||
|
|
@ -1182,10 +1189,10 @@ def translateText(system, user, history, penalty, formatType, model, numLines=No
|
|||
_live_api = os.getenv("api", "").strip()
|
||||
_live_key = os.getenv("key", "").strip()
|
||||
_live_provider = os.getenv("API_PROVIDER", "openai").lower()
|
||||
if _live_provider == "gemini":
|
||||
if _live_provider == "gemini" and not _live_api:
|
||||
openai.base_url = "https://generativelanguage.googleapis.com/v1beta/openai/"
|
||||
elif _live_api:
|
||||
openai.base_url = _live_api
|
||||
openai.base_url = _normalize_openai_base_url(_live_api)
|
||||
if _live_key:
|
||||
openai.api_key = _live_key
|
||||
|
||||
|
|
|
|||
Loading…
Reference in a new issue