11import argparse
2+ import json
23import os
34from openai import OpenAI #pip3 install openai
45import time
1112from tqdm import tqdm #pip3 install tqdm
1213import traceback
1314import re
15+ from urllib .error import HTTPError , URLError
16+ from urllib .request import Request , urlopen
1417
1518
1619MASTER_BRANCH = "master"
2932
3033FINAL_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+
3270def 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