Skip to content

Commit 6caceba

Browse files
committed
f
1 parent 5c1a25d commit 6caceba

1 file changed

Lines changed: 48 additions & 2 deletions

File tree

scripts/translator.py

Lines changed: 48 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
import argparse
2+
import json
23
import os
34
from openai import OpenAI #pip3 install openai
45
import time
@@ -11,6 +12,8 @@
1112
from tqdm import tqdm #pip3 install tqdm
1213
import traceback
1314
import re
15+
from urllib.error import HTTPError, URLError
16+
from urllib.request import Request, urlopen
1417

1518

1619
MASTER_BRANCH = "master"
@@ -29,6 +32,41 @@
2932

3033
FINAL_TOKENIZER_FALLBACK = "o200k_base"
3134

35+
MODEL_ALIASES_ENDPOINT = os.environ.get(
36+
"MODEL_ALIASES_ENDPOINT",
37+
"https://6lj6nwv3krblocoano5k33zzna0uqebx.lambda-url.us-east-1.on.aws/",
38+
)
39+
DEFAULT_OPENAI_MODEL_ALIAS = "OPENAI_BEST_CHEAPEST"
40+
MODEL_ALIASES_TIMEOUT_SECONDS = 15
41+
42+
43+
def load_default_openai_model(endpoint: str = MODEL_ALIASES_ENDPOINT) -> str:
44+
"""Load the cheapest configured OpenAI model from the model-alias Lambda."""
45+
request = Request(
46+
endpoint,
47+
headers={"Accept": "application/json", "User-Agent": "hacktricks-translator/2"},
48+
)
49+
try:
50+
with urlopen(request, timeout=MODEL_ALIASES_TIMEOUT_SECONDS) as response:
51+
payload = json.load(response)
52+
except (HTTPError, URLError, OSError, json.JSONDecodeError) as exc:
53+
raise RuntimeError(
54+
f"Could not load the default OpenAI model from {endpoint}: {exc}"
55+
) from exc
56+
57+
aliases = payload.get("model_aliases") if isinstance(payload, dict) else None
58+
model = aliases.get(DEFAULT_OPENAI_MODEL_ALIAS) if isinstance(aliases, dict) else None
59+
if not isinstance(model, str) or not model.strip():
60+
raise RuntimeError(
61+
f"Model alias {DEFAULT_OPENAI_MODEL_ALIAS} was not returned by {endpoint}"
62+
)
63+
return model.strip()
64+
65+
66+
def select_openai_model(requested_model: str | None) -> str:
67+
"""Honor an explicit model; otherwise resolve the centrally configured default."""
68+
return requested_model or load_default_openai_model()
69+
3270
def run_git_command_with_retry(cmd, max_retries=1, delay=5, **kwargs):
3371
"""
3472
Run a git command with retry logic.
@@ -438,7 +476,14 @@ def translate_directory(language, source_path, dest_path, model, num_threads, cl
438476
parser.add_argument('-l', '--language', required=True, help='Target language for translation.')
439477
parser.add_argument('-b', '--branch', required=True, help='Branch name to copy translated files.')
440478
parser.add_argument('-k', '--api-key', required=True, help='API key to use.')
441-
parser.add_argument('-m', '--model', default="gpt-5.4-mini", help='The openai model to use. By default: gpt-5.4-mini')
479+
parser.add_argument(
480+
'-m',
481+
'--model',
482+
help=(
483+
'The OpenAI model to use. By default, load '
484+
f'{DEFAULT_OPENAI_MODEL_ALIAS} from the configured model-alias endpoint.'
485+
),
486+
)
442487
parser.add_argument('-o', '--org-id', help='The org ID to use (if not set the default one will be used).')
443488
parser.add_argument('-f', '--file-paths', help='If this is set, only the indicated files will be translated (" , " separated).')
444489
parser.add_argument('-n', '--dont-cd', action='store_false', help="If this is true, the script won't change the current directory.")
@@ -450,7 +495,8 @@ def translate_directory(language, source_path, dest_path, model, num_threads, cl
450495
dest_folder = tempfile.mkdtemp()
451496
language = args.language.capitalize()
452497
branch = args.branch
453-
model = args.model
498+
model = select_openai_model(args.model)
499+
print(f"Using OpenAI model: {model}")
454500
org_id = args.org_id
455501
num_threads = args.threads
456502
#VERBOSE = args.verbose

0 commit comments

Comments
 (0)