From c041559c4f14dffe3e9ea73e0f7bd8d802a8f5e9 Mon Sep 17 00:00:00 2001 From: xunbu Date: Fri, 5 Sep 2025 17:30:49 +0800 Subject: [PATCH] =?UTF-8?q?api-key=E4=B8=BA=E9=9D=9E=E5=BF=85=E5=A1=AB?= =?UTF-8?q?=E9=A1=B9=EF=BC=8C=E4=B8=94AgentConfig=E7=9A=84=E5=AD=97?= =?UTF-8?q?=E6=AE=B5=E6=94=B9=E5=90=8D=E4=B8=BAconcurrent?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- docutranslate/agents/agent.py | 10 +++--- docutranslate/app.py | 32 +++++++++++-------- docutranslate/static/index.html | 2 +- .../translator/ai_translator/base.py | 18 ++++------- .../ai_translator/docx_translator.py | 2 +- .../ai_translator/epub_translator.py | 2 +- .../ai_translator/html_translator.py | 2 +- .../ai_translator/json_translator.py | 2 +- .../translator/ai_translator/md_translator.py | 2 +- .../ai_translator/srt_translator.py | 2 +- .../ai_translator/txt_translator.py | 2 +- .../ai_translator/xlsx_translator.py | 2 +- 12 files changed, 40 insertions(+), 38 deletions(-) diff --git a/docutranslate/agents/agent.py b/docutranslate/agents/agent.py index de466f1..c9bd261 100644 --- a/docutranslate/agents/agent.py +++ b/docutranslate/agents/agent.py @@ -42,10 +42,10 @@ class PartialAgentResultError(ValueError): class AgentConfig: logger: logging.Logger base_url: str - api_key: str + api_key: str | None = None model_id: str temperature: float = 0.7 - max_concurrent: int = 30 + concurrent: int = 30 timeout: int = 2000 thinking: ThinkingMode = "default" @@ -114,11 +114,11 @@ class Agent: if self.baseurl.endswith("/"): self.baseurl = self.baseurl[:-1] self.domain = urlparse(self.baseurl).netloc - self.key = config.api_key.strip() or "xx" + self.key = config.api_key.strip() if config.api_key else "xx" self.model_id = config.model_id.strip() self.system_prompt = "" self.temperature = config.temperature - self.max_concurrent = config.max_concurrent + self.max_concurrent = config.concurrent self.timeout = config.timeout self.thinking = config.thinking self.logger = config.logger or global_logger @@ -437,4 +437,4 @@ class Agent: if __name__ == '__main__': - pass \ No newline at end of file + pass diff --git a/docutranslate/app.py b/docutranslate/app.py index 0ed3df6..d792cd7 100644 --- a/docutranslate/app.py +++ b/docutranslate/app.py @@ -233,7 +233,7 @@ class GlossaryAgentConfigPayload(BaseModel): model_id: str = Field(..., description="用于术语表生成的Agent的模型ID。", examples=["gpt-4-turbo"]) to_lang: str = Field(..., description="术语表生成的目标语言。", examples=["简体中文", "English"]) temperature: float = Field(default=0.7, description="用于术语表生成的Agent的温度参数。") - max_concurrent: int = Field(default=30, description="Agent的最大并发请求数。") + concurrent: int = Field(default=30, description="Agent的最大并发请求数。") timeout: int = Field(default=2000, description="Agent的API调用超时时间。") thinking: ThinkingMode = Field(default="default", description="Agent的思考模式。") @@ -243,7 +243,7 @@ class BaseWorkflowParams(BaseModel): skip_translate: bool = Field(default=False, description="是否跳过翻译步骤。如果为True,则仅执行文档解析和格式转换。") base_url: Optional[str] = Field(default=None, validation_alias=AliasChoices('base_url', 'baseurl'), description="LLM API的基础URL。当 `skip_translate` 为 `False` 时必填。", examples=["https://api.openai.com/v1"]) - api_key: Optional[str] = Field(default=None, validation_alias=AliasChoices('api_key', 'key'), description="LLM API的密钥。当 `skip_translate` 为 `False` 时必填。", + api_key: Optional[str] = Field(default=None, validation_alias=AliasChoices('api_key', 'key'), description="LLM API的密钥(可选)。", examples=["sk-xxxxxxxxxxxxxxxxxxxxxxxxxxxx"]) model_id: Optional[str] = Field(default=None, description="要使用的LLM模型ID。当 `skip_translate` 为 `False` 时必填。", examples=["gpt-4o"]) @@ -251,6 +251,7 @@ class BaseWorkflowParams(BaseModel): chunk_size: int = Field(default=default_params["chunk_size"], description="文本分割的块大小(字符)。") concurrent: int = Field(default=default_params["concurrent"], description="并发请求数。") temperature: float = Field(default=default_params["temperature"], description="LLM温度参数。") + timeout: int = Field(default=2000, description="API调用超时时间(毫秒)。") thinking: ThinkingMode = Field(default=default_params["thinking"], description="Agent的思考模式。", examples=["default", "enable", "disable"]) custom_prompt: Optional[str] = Field(None, description="用户自定义的翻译Prompt。", alias="custom_prompt") @@ -267,8 +268,6 @@ class BaseWorkflowParams(BaseModel): # Check for standard keys or their aliases if not (values.get('base_url') or values.get('baseurl')): raise ValueError("当 `skip_translate` 为 `False` 时, `base_url` 或 `baseurl` 字段是必须的。") - if not (values.get('api_key') or values.get('key')): - raise ValueError("当 `skip_translate` 为 `False` 时, `api_key` 或 `key` 字段是必须的。") if not values.get('model_id'): raise ValueError("当 `skip_translate` 为 `False` 时, `model_id` 字段是必须的。") # 如果跳过翻译,则不进行任何检查,允许 base_url 等字段为空 @@ -417,6 +416,7 @@ class TranslateServiceRequest(BaseModel): "chunk_size": default_params["chunk_size"], "concurrent": default_params["concurrent"], "temperature": default_params["temperature"], + "timeout": 2000, "thinking": "default", "glossary_generate_enable": False, "convert_engine": "mineru", @@ -438,6 +438,7 @@ class TranslateServiceRequest(BaseModel): "chunk_size": default_params["chunk_size"], "concurrent": default_params["concurrent"], "temperature": default_params["temperature"], + "timeout": 2000, "thinking": "default", "glossary_generate_enable": False, "json_paths": ["$.product.name", "$.product.description", "$.features[*]"], @@ -456,6 +457,7 @@ class TranslateServiceRequest(BaseModel): "chunk_size": default_params["chunk_size"], "concurrent": default_params["concurrent"], "temperature": default_params["temperature"], + "timeout": 2000, "thinking": "default", "glossary_generate_enable": False, "insert_mode": "replace", @@ -483,7 +485,7 @@ class TranslateServiceRequest(BaseModel): "model_id": "gpt-4-turbo", "to_lang": "中文", "temperature": 0.7, - "max_concurrent": 30, + "concurrent": 30, "timeout": 2000, "thinking": "default" } @@ -504,6 +506,7 @@ class TranslateServiceRequest(BaseModel): "chunk_size": default_params["chunk_size"], "concurrent": default_params["concurrent"], "temperature": default_params["temperature"], + "timeout": 2000, "thinking": "default", } }, @@ -522,6 +525,7 @@ class TranslateServiceRequest(BaseModel): "chunk_size": default_params["chunk_size"], "concurrent": default_params["concurrent"], "temperature": default_params["temperature"], + "timeout": 2000, "thinking": "default", } }, @@ -540,6 +544,7 @@ class TranslateServiceRequest(BaseModel): "chunk_size": default_params["chunk_size"], "concurrent": default_params["concurrent"], "temperature": default_params["temperature"], + "timeout": 2000, "thinking": "default", } }, @@ -558,6 +563,7 @@ class TranslateServiceRequest(BaseModel): "chunk_size": default_params["chunk_size"], "concurrent": default_params["concurrent"], "temperature": default_params["temperature"], + "timeout": 2000, "thinking": "default", } } @@ -612,7 +618,7 @@ async def _perform_translation( task_logger.info("构建 MarkdownBasedWorkflow 配置。") translator_args = payload.model_dump(include={ 'skip_translate', 'base_url', 'api_key', 'model_id', 'to_lang', 'custom_prompt', - 'temperature', 'thinking', 'chunk_size', 'concurrent', 'glossary_dict' + 'temperature', 'thinking', 'chunk_size', 'concurrent', 'glossary_dict', 'timeout' }, exclude_none=True) translator_args['glossary_generate_enable'] = payload.glossary_generate_enable translator_args['glossary_agent_config'] = build_glossary_agent_config() @@ -639,7 +645,7 @@ async def _perform_translation( translator_args = payload.model_dump(include={ 'skip_translate', 'base_url', 'api_key', 'model_id', 'to_lang', 'custom_prompt', 'temperature', 'thinking', 'chunk_size', 'concurrent', 'glossary_dict', - 'insert_mode', 'separator' + 'insert_mode', 'separator', 'timeout' }, exclude_none=True) translator_args['glossary_generate_enable'] = payload.glossary_generate_enable translator_args['glossary_agent_config'] = build_glossary_agent_config() @@ -657,7 +663,7 @@ async def _perform_translation( translator_args = payload.model_dump(include={ 'skip_translate', 'base_url', 'api_key', 'model_id', 'to_lang', 'custom_prompt', 'temperature', 'thinking', 'chunk_size', 'concurrent', 'glossary_dict', - 'json_paths' + 'json_paths', 'timeout' }, exclude_none=True) translator_args['glossary_generate_enable'] = payload.glossary_generate_enable translator_args['glossary_agent_config'] = build_glossary_agent_config() @@ -675,7 +681,7 @@ async def _perform_translation( translator_args = payload.model_dump(include={ 'skip_translate', 'base_url', 'api_key', 'model_id', 'to_lang', 'custom_prompt', 'temperature', 'thinking', 'chunk_size', 'concurrent', - 'insert_mode', 'separator', 'translate_regions', 'glossary_dict' + 'insert_mode', 'separator', 'translate_regions', 'glossary_dict', 'timeout' }, exclude_none=True) translator_args['glossary_generate_enable'] = payload.glossary_generate_enable translator_args['glossary_agent_config'] = build_glossary_agent_config() @@ -694,7 +700,7 @@ async def _perform_translation( translator_args = payload.model_dump(include={ 'skip_translate', 'base_url', 'api_key', 'model_id', 'to_lang', 'custom_prompt', 'temperature', 'thinking', 'chunk_size', 'concurrent', - 'insert_mode', 'separator', 'glossary_dict' + 'insert_mode', 'separator', 'glossary_dict', 'timeout' }, exclude_none=True) translator_args['glossary_generate_enable'] = payload.glossary_generate_enable translator_args['glossary_agent_config'] = build_glossary_agent_config() @@ -713,7 +719,7 @@ async def _perform_translation( translator_args = payload.model_dump(include={ 'skip_translate', 'base_url', 'api_key', 'model_id', 'to_lang', 'custom_prompt', 'temperature', 'thinking', 'chunk_size', 'concurrent', - 'insert_mode', 'separator', 'glossary_dict' + 'insert_mode', 'separator', 'glossary_dict', 'timeout' }, exclude_none=True) translator_args['glossary_generate_enable'] = payload.glossary_generate_enable translator_args['glossary_agent_config'] = build_glossary_agent_config() @@ -732,7 +738,7 @@ async def _perform_translation( translator_args = payload.model_dump(include={ 'skip_translate', 'base_url', 'api_key', 'model_id', 'to_lang', 'custom_prompt', 'temperature', 'thinking', 'chunk_size', 'concurrent', - 'insert_mode', 'separator', 'glossary_dict' + 'insert_mode', 'separator', 'glossary_dict', 'timeout' }, exclude_none=True) translator_args['glossary_generate_enable'] = payload.glossary_generate_enable translator_args['glossary_agent_config'] = build_glossary_agent_config() @@ -752,7 +758,7 @@ async def _perform_translation( translator_args = payload.model_dump(include={ 'skip_translate', 'base_url', 'api_key', 'model_id', 'to_lang', 'custom_prompt', 'temperature', 'thinking', 'chunk_size', 'concurrent', - 'insert_mode', 'separator', 'glossary_dict' + 'insert_mode', 'separator', 'glossary_dict', 'timeout' }, exclude_none=True) translator_args['glossary_generate_enable'] = payload.glossary_generate_enable translator_args['glossary_agent_config'] = build_glossary_agent_config() diff --git a/docutranslate/static/index.html b/docutranslate/static/index.html index 909b627..7590fc0 100644 --- a/docutranslate/static/index.html +++ b/docutranslate/static/index.html @@ -1 +1 @@ - DocuTranslate - 交互式文档翻译

DocuTranslate

如果上传的文件本身是.md格式,此项可不选。
mineru VLM是更新的内测模型。

Base URL:

选择一个或多个CSV文件。文件需包含'src'和'dst'两列标题,分别代表原文和译文。

GitHub主页(欢迎star❤):
https://github.com/xunbu/docutranslate

交流QQ群: 1047781902

version:

任务列表

LOGO

当前没有任务,点击“新建任务”开始吧!

预览
原文
译文
\ No newline at end of file + DocuTranslate - 交互式文档翻译

DocuTranslate

如果上传的文件本身是.md格式,此项可不选。
mineru VLM是更新的内测模型。

Base URL:

选择一个或多个CSV文件。文件需包含'src'和'dst'两列标题,分别代表原文和译文。

GitHub主页(欢迎star❤):
https://github.com/xunbu/docutranslate

交流QQ群: 1047781902

version:

任务列表

LOGO

当前没有任务,点击“新建任务”开始吧!

预览
原文
译文
\ No newline at end of file diff --git a/docutranslate/translator/ai_translator/base.py b/docutranslate/translator/ai_translator/base.py index 9d757f2..89f71aa 100644 --- a/docutranslate/translator/ai_translator/base.py +++ b/docutranslate/translator/ai_translator/base.py @@ -4,28 +4,24 @@ from abc import abstractmethod from dataclasses import dataclass, field from typing import TypeVar -from docutranslate.agents.agent import ThinkingMode +from docutranslate.agents.agent import ThinkingMode, AgentConfig from docutranslate.agents.glossary_agent import GlossaryAgentConfig, GlossaryAgent from docutranslate.ir.document import Document from docutranslate.translator.base import Translator, TranslatorConfig @dataclass(kw_only=True) -class AiTranslatorConfig(TranslatorConfig): - base_url: str | None = field(default=None,metadata={"description": "OpenAI兼容地址,当skip_translate为False时为必填项"}) - api_key: str | None = field(default=None,metadata={"description": "当skip_translate为False时为必填项"}) - model_id: str | None = field(default=None,metadata={"description": "当skip_translate为False时为必填项"}) +class AiTranslatorConfig(TranslatorConfig, AgentConfig): + base_url: str | None = field(default=None, + metadata={"description": "OpenAI兼容地址,当skip_translate为False时为必填项"}) + model_id: str | None = field(default=None, metadata={"description": "当skip_translate为False时为必填项"}) to_lang: str = "简体中文" custom_prompt: str | None = None - temperature: float = 0.7 - thinking: ThinkingMode = "default" - timeout: int = 2000 chunk_size: int = 3000 - concurrent: int = 30 glossary_dict: dict[str:str] | None = field(default=None) glossary_generate_enable: bool = False glossary_agent_config: GlossaryAgentConfig | None = None - skip_translate: bool = False + skip_translate: bool = False # 当skip_translate为False时base_url、model_id为必填项 T = TypeVar('T', bound=Document) @@ -55,7 +51,7 @@ class AiTranslator(Translator[T]): model_id=config.model_id, temperature=config.temperature, thinking=config.thinking, - max_concurrent=config.concurrent, + concurrent=config.concurrent, timeout=config.timeout, logger=self.logger, ) diff --git a/docutranslate/translator/ai_translator/docx_translator.py b/docutranslate/translator/ai_translator/docx_translator.py index c48d95c..3eebb88 100644 --- a/docutranslate/translator/ai_translator/docx_translator.py +++ b/docutranslate/translator/ai_translator/docx_translator.py @@ -49,7 +49,7 @@ class DocxTranslator(AiTranslator): model_id=config.model_id, temperature=config.temperature, thinking=config.thinking, - max_concurrent=config.concurrent, + concurrent=config.concurrent, timeout=config.timeout, logger=self.logger, glossary_dict=config.glossary_dict diff --git a/docutranslate/translator/ai_translator/epub_translator.py b/docutranslate/translator/ai_translator/epub_translator.py index 7d85211..ffacf55 100644 --- a/docutranslate/translator/ai_translator/epub_translator.py +++ b/docutranslate/translator/ai_translator/epub_translator.py @@ -40,7 +40,7 @@ class EpubTranslator(AiTranslator): model_id=config.model_id, temperature=config.temperature, thinking=config.thinking, - max_concurrent=config.concurrent, + concurrent=config.concurrent, timeout=config.timeout, logger=self.logger, glossary_dict=config.glossary_dict diff --git a/docutranslate/translator/ai_translator/html_translator.py b/docutranslate/translator/ai_translator/html_translator.py index 9e4b21c..2098020 100644 --- a/docutranslate/translator/ai_translator/html_translator.py +++ b/docutranslate/translator/ai_translator/html_translator.py @@ -97,7 +97,7 @@ class HtmlTranslator(AiTranslator): model_id=config.model_id, temperature=config.temperature, thinking=config.thinking, - max_concurrent=config.concurrent, + concurrent=config.concurrent, timeout=config.timeout, logger=self.logger, glossary_dict=config.glossary_dict diff --git a/docutranslate/translator/ai_translator/json_translator.py b/docutranslate/translator/ai_translator/json_translator.py index 18230d2..014f85e 100644 --- a/docutranslate/translator/ai_translator/json_translator.py +++ b/docutranslate/translator/ai_translator/json_translator.py @@ -30,7 +30,7 @@ class JsonTranslator(AiTranslator): model_id=config.model_id, temperature=config.temperature, thinking=config.thinking, - max_concurrent=config.concurrent, + concurrent=config.concurrent, timeout=config.timeout, logger=self.logger, glossary_dict=config.glossary_dict diff --git a/docutranslate/translator/ai_translator/md_translator.py b/docutranslate/translator/ai_translator/md_translator.py index ac87cb0..20de634 100644 --- a/docutranslate/translator/ai_translator/md_translator.py +++ b/docutranslate/translator/ai_translator/md_translator.py @@ -30,7 +30,7 @@ class MDTranslator(AiTranslator): model_id=config.model_id, temperature=config.temperature, thinking=config.thinking, - max_concurrent=config.concurrent, + concurrent=config.concurrent, timeout=config.timeout, logger=self.logger, glossary_dict=config.glossary_dict) diff --git a/docutranslate/translator/ai_translator/srt_translator.py b/docutranslate/translator/ai_translator/srt_translator.py index 7406e5a..dfd0b41 100644 --- a/docutranslate/translator/ai_translator/srt_translator.py +++ b/docutranslate/translator/ai_translator/srt_translator.py @@ -36,7 +36,7 @@ class SrtTranslator(AiTranslator): model_id=config.model_id, temperature=config.temperature, thinking=config.thinking, - max_concurrent=config.concurrent, + concurrent=config.concurrent, timeout=config.timeout, logger=self.logger, glossary_dict=config.glossary_dict diff --git a/docutranslate/translator/ai_translator/txt_translator.py b/docutranslate/translator/ai_translator/txt_translator.py index 78106b8..bcb2ca3 100644 --- a/docutranslate/translator/ai_translator/txt_translator.py +++ b/docutranslate/translator/ai_translator/txt_translator.py @@ -54,7 +54,7 @@ class TXTTranslator(AiTranslator): model_id=config.model_id, temperature=config.temperature, thinking=config.thinking, - max_concurrent=config.concurrent, + concurrent=config.concurrent, timeout=config.timeout, logger=self.logger, glossary_dict=config.glossary_dict diff --git a/docutranslate/translator/ai_translator/xlsx_translator.py b/docutranslate/translator/ai_translator/xlsx_translator.py index 981c95b..38c5c19 100644 --- a/docutranslate/translator/ai_translator/xlsx_translator.py +++ b/docutranslate/translator/ai_translator/xlsx_translator.py @@ -38,7 +38,7 @@ class XlsxTranslator(AiTranslator): model_id=config.model_id, temperature=config.temperature, thinking=config.thinking, - max_concurrent=config.concurrent, + concurrent=config.concurrent, timeout=config.timeout, logger=self.logger, glossary_dict=config.glossary_dict