[Add] translation_gemini: Integrate Gemini translation model and authentication; [Update] controller: Implement methods for managing Gemini models and auth keys; [Update] mainloop: Add routes for Gemini model and auth key management; [Update] translation: Enhance Translator class for Gemini API support; [Update] translation_languages: Add Gemini language mappings

This commit is contained in:
misyaguziya
2025-09-15 17:42:09 +09:00
parent e3555d204e
commit 224eaf3cef
7 changed files with 234 additions and 32 deletions

View File

@@ -10,6 +10,7 @@ from device_manager import device_manager
from models.translation.translation_languages import translation_lang from models.translation.translation_languages import translation_lang
from models.translation.translation_utils import ctranslate2_weights from models.translation.translation_utils import ctranslate2_weights
from models.translation.translation_plamo import _MODELS as plamo_models from models.translation.translation_plamo import _MODELS as plamo_models
from models.translation.translation_gemini import _MODELS as gemini_models
from models.transcription.transcription_languages import transcription_lang from models.transcription.transcription_languages import transcription_lang
from models.transcription.transcription_whisper import _MODELS as whisper_models from models.transcription.transcription_whisper import _MODELS as whisper_models
from utils import errorLogging, validateDictStructure from utils import errorLogging, validateDictStructure
@@ -124,6 +125,10 @@ class Config:
def SELECTABLE_PLAMO_MODEL_LIST(self): def SELECTABLE_PLAMO_MODEL_LIST(self):
return self._SELECTABLE_PLAMO_MODEL_LIST return self._SELECTABLE_PLAMO_MODEL_LIST
@property
def SELECTABLE_GEMINI_MODEL_LIST(self):
return self._SELECTABLE_GEMINI_MODEL_LIST
@property @property
def SELECTABLE_TRANSCRIPTION_ENGINE_LIST(self): def SELECTABLE_TRANSCRIPTION_ENGINE_LIST(self):
return self._SELECTABLE_TRANSCRIPTION_ENGINE_LIST return self._SELECTABLE_TRANSCRIPTION_ENGINE_LIST
@@ -843,6 +848,18 @@ class Config:
self._PLAMO_MODEL = value self._PLAMO_MODEL = value
self.saveConfig(inspect.currentframe().f_code.co_name, value) self.saveConfig(inspect.currentframe().f_code.co_name, value)
@property
@json_serializable('GEMINI_MODEL')
def GEMINI_MODEL(self):
return self._GEMINI_MODEL
@GEMINI_MODEL.setter
def GEMINI_MODEL(self, value):
if isinstance(value, str):
if value in self.SELECTABLE_GEMINI_MODEL_LIST:
self._GEMINI_MODEL = value
self.saveConfig(inspect.currentframe().f_code.co_name, value)
@property @property
@json_serializable('AUTO_CLEAR_MESSAGE_BOX') @json_serializable('AUTO_CLEAR_MESSAGE_BOX')
def AUTO_CLEAR_MESSAGE_BOX(self): def AUTO_CLEAR_MESSAGE_BOX(self):
@@ -1061,6 +1078,7 @@ class Config:
self._SELECTABLE_WHISPER_WEIGHT_TYPE_LIST = whisper_models.keys() self._SELECTABLE_WHISPER_WEIGHT_TYPE_LIST = whisper_models.keys()
self._SELECTABLE_TRANSLATION_ENGINE_LIST = translation_lang.keys() self._SELECTABLE_TRANSLATION_ENGINE_LIST = translation_lang.keys()
self._SELECTABLE_PLAMO_MODEL_LIST = plamo_models self._SELECTABLE_PLAMO_MODEL_LIST = plamo_models
self._SELECTABLE_GEMINI_MODEL_LIST = gemini_models
self._SELECTABLE_TRANSCRIPTION_ENGINE_LIST = list(transcription_lang[list(transcription_lang.keys())[0]].values())[0].keys() self._SELECTABLE_TRANSCRIPTION_ENGINE_LIST = list(transcription_lang[list(transcription_lang.keys())[0]].values())[0].keys()
self._SELECTABLE_UI_LANGUAGE_LIST = ["en", "ja", "ko", "zh-Hant", "zh-Hans"] self._SELECTABLE_UI_LANGUAGE_LIST = ["en", "ja", "ko", "zh-Hant", "zh-Hans"]
self._COMPUTE_MODE = "cuda" if torch.cuda.is_available() else "cpu" self._COMPUTE_MODE = "cuda" if torch.cuda.is_available() else "cpu"
@@ -1203,6 +1221,7 @@ class Config:
self._AUTH_KEYS = { self._AUTH_KEYS = {
"DeepL_API": None, "DeepL_API": None,
"Plamo_API": None, "Plamo_API": None,
"Gemini_API": None,
} }
self._USE_EXCLUDE_WORDS = True self._USE_EXCLUDE_WORDS = True
self._SELECTED_TRANSLATION_COMPUTE_DEVICE = copy.deepcopy(self.SELECTABLE_COMPUTE_DEVICE_LIST[0]) self._SELECTED_TRANSLATION_COMPUTE_DEVICE = copy.deepcopy(self.SELECTABLE_COMPUTE_DEVICE_LIST[0])
@@ -1210,6 +1229,7 @@ class Config:
self._CTRANSLATE2_WEIGHT_TYPE = "m2m100_418M-ct2-int8" self._CTRANSLATE2_WEIGHT_TYPE = "m2m100_418M-ct2-int8"
self._WHISPER_WEIGHT_TYPE = "base" self._WHISPER_WEIGHT_TYPE = "base"
self._PLAMO_MODEL = "plamo-2.0-prime" self._PLAMO_MODEL = "plamo-2.0-prime"
self._GEMINI_MODEL = "gemini-2.5-flash-lite"
self._AUTO_CLEAR_MESSAGE_BOX = True self._AUTO_CLEAR_MESSAGE_BOX = True
self._SEND_ONLY_TRANSLATED_MESSAGES = False self._SEND_ONLY_TRANSLATED_MESSAGES = False
self._OVERLAY_SMALL_LOG = False self._OVERLAY_SMALL_LOG = False

View File

@@ -1515,6 +1515,90 @@ class Controller:
self.updateTranslationEngineAndEngineList() self.updateTranslationEngineAndEngineList()
return {"status":200, "result":config.AUTH_KEYS[translator_name]} return {"status":200, "result":config.AUTH_KEYS[translator_name]}
def getGeminiModelList(self, *args, **kwargs) -> dict:
return {"status":200, "result": config.SELECTABLE_GEMINI_MODEL_LIST}
def setGeminiModel(self, data, *args, **kwargs) -> dict:
printLog("Set Gemini Model", data)
try:
data = str(data)
result = model.authenticationTranslatorGeminiAuthKey(auth_key=config.AUTH_KEYS["Gemini_API"], model_name=data)
if result is True:
config.GEMINI_MODEL = data
response = {"status":200, "result":config.GEMINI_MODEL}
else:
response = {
"status":400,
"result":{
"message":"Gemini model is not valid",
"data": config.GEMINI_MODEL
}
}
except Exception as e:
errorLogging()
response = {
"status":400,
"result":{
"message":f"Error {e}",
"data": config.GEMINI_MODEL
}
}
return response
def getGeminiAuthKey(self, *args, **kwargs) -> dict:
return {"status":200, "result":config.AUTH_KEYS["Gemini_API"]}
def setGeminiAuthKey(self, data, *args, **kwargs) -> dict:
printLog("Set Gemini Auth Key", data)
translator_name = "Gemini_API"
try:
data = str(data)
if len(data) >= 20:
result = model.authenticationTranslatorGeminiAuthKey(auth_key=data, model_name=config.GEMINI_MODEL)
if result is True:
key = data
auth_keys = config.AUTH_KEYS
auth_keys[translator_name] = key
config.AUTH_KEYS = auth_keys
config.SELECTABLE_TRANSLATION_ENGINE_STATUS[translator_name] = True
self.updateTranslationEngineAndEngineList()
response = {"status":200, "result":config.AUTH_KEYS[translator_name]}
else:
response = {
"status":400,
"result":{
"message":"Authentication failure of gemini auth key",
"data": config.AUTH_KEYS[translator_name]
}
}
else:
response = {
"status":400,
"result":{
"message":"Gemini auth key length is not correct",
"data": config.AUTH_KEYS[translator_name]
}
}
except Exception as e:
errorLogging()
response = {
"status":400,
"result":{
"message":f"Error {e}",
"data": config.AUTH_KEYS[translator_name]
}
}
return response
def delGeminiAuthKey(self, *args, **kwargs) -> dict:
translator_name = "Gemini_API"
auth_keys = config.AUTH_KEYS
auth_keys[translator_name] = None
config.AUTH_KEYS = auth_keys
config.SELECTABLE_TRANSLATION_ENGINE_STATUS[translator_name] = False
self.updateTranslationEngineAndEngineList()
return {"status":200, "result":config.AUTH_KEYS[translator_name]}
@staticmethod @staticmethod
def getCtranslate2WeightType(*args, **kwargs) -> dict: def getCtranslate2WeightType(*args, **kwargs) -> dict:
return {"status":200, "result":config.CTRANSLATE2_WEIGHT_TYPE} return {"status":200, "result":config.CTRANSLATE2_WEIGHT_TYPE}

View File

@@ -174,6 +174,12 @@ mapping = {
"/set/data/plamo_auth_key": {"status": False, "variable":controller.setPlamoAuthKey}, "/set/data/plamo_auth_key": {"status": False, "variable":controller.setPlamoAuthKey},
"/delete/data/plamo_auth_key": {"status": False, "variable":controller.delPlamoAuthKey}, "/delete/data/plamo_auth_key": {"status": False, "variable":controller.delPlamoAuthKey},
"/get/data/gemini_model_list": {"status": True, "variable":controller.getGeminiModelList},
"/set/data/gemini_model": {"status": True, "variable":controller.setGeminiModel},
"/get/data/gemini_auth_key": {"status": True, "variable":controller.getGeminiAuthKey},
"/set/data/gemini_auth_key": {"status": True, "variable":controller.setGeminiAuthKey},
"/delete/data/gemini_auth_key": {"status": True, "variable":controller.delGeminiAuthKey},
"/get/data/convert_message_to_romaji": {"status": True, "variable":controller.getConvertMessageToRomaji}, "/get/data/convert_message_to_romaji": {"status": True, "variable":controller.getConvertMessageToRomaji},
"/set/enable/convert_message_to_romaji": {"status": True, "variable":controller.setEnableConvertMessageToRomaji}, "/set/enable/convert_message_to_romaji": {"status": True, "variable":controller.setEnableConvertMessageToRomaji},
"/set/disable/convert_message_to_romaji": {"status": True, "variable":controller.setDisableConvertMessageToRomaji}, "/set/disable/convert_message_to_romaji": {"status": True, "variable":controller.setDisableConvertMessageToRomaji},

View File

@@ -144,6 +144,10 @@ class Model:
result = self.translator.authenticationPlamoAuthKey(auth_key, model=model) result = self.translator.authenticationPlamoAuthKey(auth_key, model=model)
return result return result
def authenticationTranslatorGeminiAuthKey(self, auth_key: str, model: str) -> bool:
result = self.translator.authenticationGeminiAuthKey(auth_key, model=model)
return result
def startLogger(self): def startLogger(self):
os_makedirs(config.PATH_LOGS, exist_ok=True) os_makedirs(config.PATH_LOGS, exist_ok=True)
file_name = os_path.join(config.PATH_LOGS, f"{datetime.now().strftime('%Y-%m-%d_%H-%M-%S')}.log") file_name = os_path.join(config.PATH_LOGS, f"{datetime.now().strftime('%Y-%m-%d_%H-%M-%S')}.log")

View File

@@ -1,10 +1,14 @@
import logging
from langchain_google_genai import ChatGoogleGenerativeAI from langchain_google_genai import ChatGoogleGenerativeAI
from langchain_core.messages import HumanMessage from langchain_core.messages import HumanMessage
logger = logging.getLogger("langchain_google_genai")
logger.setLevel(logging.ERROR)
_MODELS = [ _MODELS = [
"gemini-2.5-pro", "gemini-2.5-pro",
"gemini-2.5-flash", "gemini-2.5-flash",
"gemini-2.5-flash-lite", "gemini-2.5-flash-lite", # default
"gemini-2.0-flash", "gemini-2.0-flash",
"gemini-2.0-flash-lite", "gemini-2.0-flash-lite",
"gemini-1.5-pro", "gemini-1.5-pro",
@@ -13,7 +17,7 @@ _MODELS = [
] ]
class GeminiClient: class GeminiClient:
def __init__(self, api_key: str = "", model: str = "gemini-2.5-flash"): def __init__(self, api_key: str = "", model: str = "gemini-2.5-flash-lite"):
self.api_key = api_key self.api_key = api_key
self.model = model self.model = model
self.prompt_template = """ self.prompt_template = """
@@ -93,7 +97,7 @@ if __name__ == "__main__":
input_lang = "Japanese" input_lang = "Japanese"
output_lang = "English" output_lang = "English"
gemini_client = GeminiClient(api_key=AUTH_KEY, model="gemini-1.5-flash") gemini_client = GeminiClient(api_key=AUTH_KEY, model="gemini-2.5-flash-lite")
print("model list:", gemini_client.getListModels()) print("model list:", gemini_client.getListModels())
print("AuthKey:", gemini_client.getAuthKey()) print("AuthKey:", gemini_client.getAuthKey())
@@ -110,41 +114,55 @@ if __name__ == "__main__":
supported_languages = """ supported_languages = """
English
Japanese
Korean
French
German
Spanish
Portuguese
Russian
Italian
Dutch
Polish
Turkish
Arabic Arabic
Hindi Bengali
Thai Bulgarian
Vietnamese
Indonesian
Malay
Filipino
Swedish
Finnish
Danish
Norwegian
Romanian
Czech
Hungarian
Greek
Hebrew
Simplified Chinese Simplified Chinese
Traditional Chinese Traditional Chinese
Croatian
Czech
Danish
Dutch
English
Estonian
Finnish
French
German
Greek
Hebrew
Hindi
Hungarian
Indonesian
Italian
Japanese
Korean
Latvian
Lithuanian
Norwegian
Polish
Portuguese
Romanian
Russian
Serbian
Slovak
Slovenian
Spanish
Swahili
Swedish
Thai
Turkish
Ukrainian
Vietnamese
""" """
for lang in supported_languages.split("\n"): for lang in supported_languages.split("\n"):
if lang == "": if lang == "":
continue continue
print (f"Translating to {lang}:") print (f"Translating to {lang}:")
translated_text = gemini_client.translate(text, input_lang, lang) try:
print(f"Translated text: {translated_text}") translated_text = gemini_client.translate(text, input_lang, lang)
print(f"Translated text: {translated_text}")
except Exception as e:
print(f"Error translating to {lang} api limit")
print(f"Error reason: {e}")
break

View File

@@ -641,4 +641,51 @@ dict_plamo_languages = {
translation_lang["Plamo_API"] = { translation_lang["Plamo_API"] = {
"source":dict_plamo_languages, "source":dict_plamo_languages,
"target":dict_plamo_languages, "target":dict_plamo_languages,
}
dict_gemini_languages = {
"Arabic": "Arabic",
"Bengali": "Bengali",
"Bulgarian": "Bulgarian",
"Simplified Chinese": "Simplified Chinese",
"Traditional Chinese": "Traditional Chinese",
"Croatian": "Croatian",
"Czech": "Czech",
"Danish": "Danish",
"Dutch": "Dutch",
"English": "English",
"Estonian": "Estonian",
"Finnish": "Finnish",
"French": "French",
"German": "German",
"Greek": "Greek",
"Hebrew": "Hebrew",
"Hindi": "Hindi",
"Hungarian": "Hungarian",
"Indonesian": "Indonesian",
"Italian": "Italian",
"Japanese": "Japanese",
"Korean": "Korean",
"Latvian": "Latvian",
"Lithuanian": "Lithuanian",
"Norwegian": "Norwegian",
"Polish": "Polish",
"Portuguese": "Portuguese",
"Romanian": "Romanian",
"Russian": "Russian",
"Serbian": "Serbian",
"Slovak": "Slovak",
"Slovenian": "Slovenian",
"Spanish": "Spanish",
"Swahili": "Swahili",
"Swedish": "Swedish",
"Thai": "Thai",
"Turkish": "Turkish",
"Ukrainian": "Ukrainian",
"Vietnamese": "Vietnamese",
}
translation_lang["Gemini_API"] = {
"source":dict_gemini_languages,
"target":dict_gemini_languages,
} }

View File

@@ -10,6 +10,7 @@ try:
from .translation_languages import translation_lang from .translation_languages import translation_lang
from .translation_utils import ctranslate2_weights from .translation_utils import ctranslate2_weights
from .translation_plamo import PlamoClient from .translation_plamo import PlamoClient
from .translation_gemini import GeminiClient
except Exception: except Exception:
import sys import sys
print(os_path.dirname(os_path.dirname(os_path.dirname(os_path.abspath(__file__))))) print(os_path.dirname(os_path.dirname(os_path.dirname(os_path.abspath(__file__)))))
@@ -17,6 +18,7 @@ except Exception:
from translation_languages import translation_lang from translation_languages import translation_lang
from translation_utils import ctranslate2_weights from translation_utils import ctranslate2_weights
from translation_plamo import PlamoClient from translation_plamo import PlamoClient
from translation_gemini import GeminiClient
import ctranslate2 import ctranslate2
import transformers import transformers
@@ -30,6 +32,7 @@ class Translator():
def __init__(self): def __init__(self):
self.deepl_client = None self.deepl_client = None
self.plamo_client = None self.plamo_client = None
self.gemini_client = None
self.ctranslate2_translator = None self.ctranslate2_translator = None
self.ctranslate2_tokenizer = None self.ctranslate2_tokenizer = None
self.is_loaded_ctranslate2_model = False self.is_loaded_ctranslate2_model = False
@@ -57,6 +60,17 @@ class Translator():
result = False result = False
return result return result
def authenticationGeminiAuthKey(self, auth_key: str, model: str) -> bool:
result = True
try:
self.gemini_client = GeminiClient(auth_key, model=model)
self.gemini_client.checkAuthKey()
except Exception:
errorLogging()
self.gemini_client = None
result = False
return result
def changeCTranslate2Model(self, path, model_type, device="cpu", device_index=0): def changeCTranslate2Model(self, path, model_type, device="cpu", device_index=0):
self.is_loaded_ctranslate2_model = False self.is_loaded_ctranslate2_model = False
directory_name = ctranslate2_weights[model_type]["directory_name"] directory_name = ctranslate2_weights[model_type]["directory_name"]
@@ -158,6 +172,15 @@ class Translator():
input_lang=source_language, input_lang=source_language,
output_lang=target_language, output_lang=target_language,
) )
case "Gemini_API":
if self.gemini_client is None:
result = False
else:
result = self.gemini_client.translate(
message,
input_lang=source_language,
output_lang=target_language,
)
case "Google": case "Google":
if self.is_enable_translators is True: if self.is_enable_translators is True:
result = other_web_Translator( result = other_web_Translator(