Add gemini (#157)

* add ginimi

* 更改Prompt

* 1. 更改Prompt
2. 删除打包bat
3. 添加Proxy 和重试
4. 当有额外错误时提供基本的FinishedReason输出
5. 添加Model参数
pull/168/head
HalfMAI 8 months ago committed by GitHub
parent 8134313f48
commit 21a06e68b1
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194

@ -160,6 +160,13 @@ class AppConfig:
translator_config['target_language'] = section['target_language']
translator_config['app_id'] = section['app_id']
translator_config['secret'] = section['secret']
elif type_ == 'GeminiTranslate':
translator_config['app_id'] = section['app_id']
translator_config['prompt'] = section['prompt']
translator_config['temperature'] = section['temperature']
translator_config['model_name'] = section['model_name']
translator_config['is_use_proxy'] = section.getboolean('is_use_proxy')
translator_config['proxy'] = section['proxy']
else:
raise ValueError(f'Invalid translator type: {type_}')
except Exception: # noqa

@ -146,6 +146,28 @@ target_language = jp
app_id =
secret =
[gemini_translate]
# 文档https://blog.google/technology/ai/gemini-api-developers-cloud/
# https://ai.google.dev/tutorials/rest_quickstart
# https://ai.google.dev/models/gemini?hl=zh-cn#model-versions
type = GeminiTranslate
# 请求间隔时间(秒),等于 1 / QPS
# 如果直播间里其实并不是很多弹幕,可以适当减少请求间隔值
query_interval = 1
# 代理地址
is_use_proxy = false
proxy = http://127.0.0.1:1087
# Model versions
# https://ai.google.dev/models/gemini?hl=zh-cn#model-versions
model_name = gemini-1.0-pro-latest
app_id = xxxxxx
temperature = 0.4
prompt = "As an advanced translation software, your role is to provide accurate translations that respect the original content's meaning and tone. If the input text includes brackets, ensure that these are retained in the translation. Aim to deliver the translated text in a polite and gentle tone, as per the preferences of the audience.\n\nBelow are some examples to guide you:\n\nExamples:\nInput1:\n来拉(莱拉) 设置一下吧\nOutput1:\nライラちゃん、設定してみましょうか。\n\nInput2:\n我来拉一下各位进队伍\nOutput2:\n皆さんをチームに入れさせていただきます。\n\nInput3:\n死了w\nOutput3:\n死んじゃったわw\n\nInput4:\n每天来宝这里打个卡\nOutput4:\n毎日、ここに来て宝さんにチェックインしま\n\n\nPlease keep in mind that accurate translation is not just about linguistic conversion; it is about conveying the same sentiment and meaning as the original input. Pay special attention to internet vernaculars and colloquial expressions to maintain the nuances of the source language.\n\nNow, proceed with the translation of the following Chinese comment text into Japanese, ensuring accuracy and preservation of the original message:\nInput:\n{{original_text}}\nOutput ONLY:\n"
# 傻逼B站获取表情都要登录开放平台也不发文本表情的URL我服了
[text_emoticon_mappings]

@ -90,6 +90,11 @@ def create_translate_provider(cfg):
cfg['query_interval'], cfg['source_language'], cfg['target_language'],
cfg['app_id'], cfg['secret']
)
elif type_ == 'GeminiTranslate':
return GeminiTranslate(
cfg['query_interval'], cfg['app_id'], cfg['prompt'], cfg['temperature'],
cfg['model_name'], cfg['is_use_proxy'], cfg['proxy']
)
return None
@ -675,3 +680,106 @@ class BaiduTranslate(TranslateProvider):
def _on_cool_down_timeout(self):
self._cool_down_timer_handle = None
self._on_availability_change()
class GeminiTranslate(TranslateProvider):
def __init__(self, query_interval, app_id, prompt, temperature=0.9, model_name="gemini-1.0-pro", is_use_proxy=False, proxy=None):
super().__init__(query_interval)
self._app_id = app_id
self._prompt = prompt
self._temperature = temperature
self._model_name = model_name
self._is_use_proxy = is_use_proxy
self._proxy = proxy
async def _do_translate(self, text) -> Optional[str]:
api_endpoint = f'https://generativelanguage.googleapis.com/v1beta/models/{self._model_name}:generateContent'
api_key = self._app_id
final_prompt = self._prompt.replace('{{original_text}}', text)
payload = {
'contents': [
{
'role': 'user',
'parts': [{'text': final_prompt}]
},
],
'safetySettings': [
{
'category': 'HARM_CATEGORY_SEXUALLY_EXPLICIT',
'threshold': 'BLOCK_NONE'
},
{
'category': 'HARM_CATEGORY_HATE_SPEECH',
'threshold': 'BLOCK_NONE'
},
{
'category': 'HARM_CATEGORY_HARASSMENT',
'threshold': 'BLOCK_NONE'
},
{
'category': 'HARM_CATEGORY_DANGEROUS_CONTENT',
'threshold': 'BLOCK_NONE'
}
],
'generationConfig': {
'temperature': str(self._temperature),
'topP': '1',
'topK': '32',
'candidateCount': '1',
'maxOutputTokens': '8192'
}
}
headers = {
'Content-Type': 'application/json',
}
if self._is_use_proxy:
proxy = self._proxy
else:
proxy = None
max_retries = 3
retry_delay = 1
attempts = 0 # 初始化尝试计数
while attempts < max_retries:
try:
# 设置超时时间为10秒
timeout = aiohttp.ClientTimeout(total=10)
async with utils.request.http_session.post(
f'{api_endpoint}?key={api_key}',
headers=headers,
json=payload,
proxy=proxy,
timeout=timeout
) as r:
if r.status == 200:
data = await r.json()
try:
translated_text = data['candidates'][0]['content']['parts'][0]['text']
return translated_text # 成功获取翻译文本,返回结果
except (KeyError, IndexError):
logger.warning('Failed to process the response correctly: %s', data)
# 如果响应结构有误,则退出循环
return None
else:
logger.warning('Request failed with status %d: %s', r.status, r.reason)
except asyncio.TimeoutError as toe:
logger.warning('Request timeout occurred: %s', str(toe))
except Exception as e:
log_str = f'{str(e)}\ndata:\n{data}'
logger.error('An error occurred during the request: %s', log_str)
try:
logger.error('FinishReason: ' + {data['candidates'][0]['finishReason']})
except:
pass
# 未成功获取翻译文本,增加尝试次数并等待重新尝试
attempts += 1
if attempts < max_retries:
logger.info('Retrying request (%d/%d)...', attempts, max_retries)
await asyncio.sleep(retry_delay)
# 如果所有重试尝试后还未成功,则记录日志并返回 None
logger.error('All retry attempts failed.')
return None
Loading…
Cancel
Save