更新日志
This commit is contained in:
@@ -1,3 +1,3 @@
|
||||
# SPDX-FileCopyrightText: 2025 QinHan
|
||||
# SPDX-License-Identifier: MPL-2.0
|
||||
__version__="1.4.0"
|
||||
__version__="1.4.1"
|
||||
@@ -46,7 +46,7 @@ class AgentConfig:
|
||||
model_id: str
|
||||
temperature: float = 0.7
|
||||
concurrent: int = 30
|
||||
timeout: int = 2000
|
||||
timeout: int = 1200 # 单位(秒),这个值是httpx.TimeOut中read的值,并非总的超时时间
|
||||
thinking: ThinkingMode = "default"
|
||||
|
||||
|
||||
@@ -119,7 +119,7 @@ class Agent:
|
||||
self.system_prompt = ""
|
||||
self.temperature = config.temperature
|
||||
self.max_concurrent = config.concurrent
|
||||
self.timeout = config.timeout
|
||||
self.timeout = httpx.Timeout(connect=5, read=config.timeout, write=300, pool=10)
|
||||
self.thinking = config.thinking
|
||||
self.logger = config.logger or global_logger
|
||||
self.total_error_counter = TotalErrorCounter(logger=self.logger)
|
||||
@@ -272,7 +272,12 @@ class Agent:
|
||||
|
||||
proxies = get_httpx_proxies() if USE_PROXY else None
|
||||
|
||||
async with httpx.AsyncClient(trust_env=False, proxies=proxies, verify=False) as client:
|
||||
limits = httpx.Limits(
|
||||
max_connections=self.max_concurrent * 2, # 为重试和并发预留空间
|
||||
max_keepalive_connections=self.max_concurrent # 保持活动的连接数
|
||||
)
|
||||
|
||||
async with httpx.AsyncClient(trust_env=False, proxies=proxies, verify=False, limits=limits) as client:
|
||||
async def send_with_semaphore(p_text: str):
|
||||
async with semaphore:
|
||||
result = await self.send_async(
|
||||
@@ -419,9 +424,12 @@ class Agent:
|
||||
pre_send_handlers = itertools.repeat(pre_send_handler, len(prompts))
|
||||
result_handlers = itertools.repeat(result_handler, len(prompts))
|
||||
error_result_handlers = itertools.repeat(error_result_handler, len(prompts))
|
||||
|
||||
limits = httpx.Limits(
|
||||
max_connections=self.max_concurrent * 2, # 允许连接复用
|
||||
max_keepalive_connections=self.max_concurrent # 保持活跃连接
|
||||
)
|
||||
proxies = get_httpx_proxies() if USE_PROXY else None
|
||||
with httpx.Client(trust_env=False, proxies=proxies, verify=False) as client:
|
||||
with httpx.Client(trust_env=False, proxies=proxies, verify=False, limits=limits) as client:
|
||||
clients = itertools.repeat(client, len(prompts))
|
||||
with ThreadPoolExecutor(max_workers=self.max_concurrent) as executor:
|
||||
results_iterator = executor.map(self._send_prompt_count, clients, prompts, system_prompts, counters,
|
||||
|
||||
@@ -228,30 +228,35 @@ app.mount("/static", StaticFiles(directory=STATIC_DIR), name="static")
|
||||
# ===================================================================
|
||||
|
||||
class GlossaryAgentConfigPayload(BaseModel):
|
||||
base_url: str = Field(..., validation_alias=AliasChoices('base_url', 'baseurl'), description="用于术语表生成的Agent的LLM API基础URL。", examples=["https://api.openai.com/v1"])
|
||||
api_key: str = Field(..., validation_alias=AliasChoices('api_key', 'key'), description="用于术语表生成的Agent的LLM API密钥。", examples=["sk-agent-api-key"])
|
||||
base_url: str = Field(..., validation_alias=AliasChoices('base_url', 'baseurl'),
|
||||
description="用于术语表生成的Agent的LLM API基础URL。", examples=["https://api.openai.com/v1"])
|
||||
api_key: str = Field(..., validation_alias=AliasChoices('api_key', 'key'),
|
||||
description="用于术语表生成的Agent的LLM API密钥。", examples=["sk-agent-api-key"])
|
||||
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的温度参数。")
|
||||
concurrent: int = Field(default=30, description="Agent的最大并发请求数。")
|
||||
timeout: int = Field(default=2000, description="Agent的API调用超时时间。")
|
||||
timeout: int = Field(default=default_params["timeout"], description="等待API回复的时间(秒)。")
|
||||
thinking: ThinkingMode = Field(default="default", description="Agent的思考模式。")
|
||||
|
||||
|
||||
# 1. 定义所有工作流共享的基础参数
|
||||
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` 时必填。",
|
||||
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的密钥(可选)。",
|
||||
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` 时必填。",
|
||||
model_id: Optional[str] = Field(default=None,
|
||||
description="要使用的LLM模型ID。当 `skip_translate` 为 `False` 时必填。",
|
||||
examples=["gpt-4o"])
|
||||
to_lang: str = Field(default="中文", description="目标翻译语言。", examples=["简体中文", "English"])
|
||||
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调用超时时间(毫秒)。")
|
||||
timeout: int = Field(default=default_params["timeout"], 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")
|
||||
@@ -416,7 +421,7 @@ class TranslateServiceRequest(BaseModel):
|
||||
"chunk_size": default_params["chunk_size"],
|
||||
"concurrent": default_params["concurrent"],
|
||||
"temperature": default_params["temperature"],
|
||||
"timeout": 2000,
|
||||
"timeout": default_params["timeout"],
|
||||
"thinking": "default",
|
||||
"glossary_generate_enable": False,
|
||||
"convert_engine": "mineru",
|
||||
@@ -438,7 +443,7 @@ class TranslateServiceRequest(BaseModel):
|
||||
"chunk_size": default_params["chunk_size"],
|
||||
"concurrent": default_params["concurrent"],
|
||||
"temperature": default_params["temperature"],
|
||||
"timeout": 2000,
|
||||
"timeout": default_params["timeout"],
|
||||
"thinking": "default",
|
||||
"glossary_generate_enable": False,
|
||||
"json_paths": ["$.product.name", "$.product.description", "$.features[*]"],
|
||||
@@ -457,7 +462,7 @@ class TranslateServiceRequest(BaseModel):
|
||||
"chunk_size": default_params["chunk_size"],
|
||||
"concurrent": default_params["concurrent"],
|
||||
"temperature": default_params["temperature"],
|
||||
"timeout": 2000,
|
||||
"timeout": default_params["timeout"],
|
||||
"thinking": "default",
|
||||
"glossary_generate_enable": False,
|
||||
"insert_mode": "replace",
|
||||
@@ -486,7 +491,7 @@ class TranslateServiceRequest(BaseModel):
|
||||
"to_lang": "中文",
|
||||
"temperature": 0.7,
|
||||
"concurrent": 30,
|
||||
"timeout": 2000,
|
||||
"timeout": default_params["timeout"],
|
||||
"thinking": "default"
|
||||
}
|
||||
}
|
||||
@@ -506,7 +511,7 @@ class TranslateServiceRequest(BaseModel):
|
||||
"chunk_size": default_params["chunk_size"],
|
||||
"concurrent": default_params["concurrent"],
|
||||
"temperature": default_params["temperature"],
|
||||
"timeout": 2000,
|
||||
"timeout": default_params["timeout"],
|
||||
"thinking": "default",
|
||||
}
|
||||
},
|
||||
@@ -525,7 +530,7 @@ class TranslateServiceRequest(BaseModel):
|
||||
"chunk_size": default_params["chunk_size"],
|
||||
"concurrent": default_params["concurrent"],
|
||||
"temperature": default_params["temperature"],
|
||||
"timeout": 2000,
|
||||
"timeout": default_params["timeout"],
|
||||
"thinking": "default",
|
||||
}
|
||||
},
|
||||
@@ -544,7 +549,7 @@ class TranslateServiceRequest(BaseModel):
|
||||
"chunk_size": default_params["chunk_size"],
|
||||
"concurrent": default_params["concurrent"],
|
||||
"temperature": default_params["temperature"],
|
||||
"timeout": 2000,
|
||||
"timeout": default_params["timeout"],
|
||||
"thinking": "default",
|
||||
}
|
||||
},
|
||||
@@ -563,7 +568,7 @@ class TranslateServiceRequest(BaseModel):
|
||||
"chunk_size": default_params["chunk_size"],
|
||||
"concurrent": default_params["concurrent"],
|
||||
"temperature": default_params["temperature"],
|
||||
"timeout": 2000,
|
||||
"timeout": default_params["timeout"],
|
||||
"thinking": "default",
|
||||
}
|
||||
}
|
||||
@@ -1411,7 +1416,7 @@ async def service_content(
|
||||
file_info = task_state.get("downloadable_files", {}).get(file_type)
|
||||
if not file_info or not os.path.exists(file_info.get("path")):
|
||||
raise HTTPException(status_code=404,
|
||||
detail=f"任务 '{task_id}' 不支持获取 '{file_type}' 类型的内容,或文件已丢失。")
|
||||
detail=f"任务 '{task_id}' 不支持获取 '{file_type}' 类型の内容,或文件已丢失。")
|
||||
|
||||
file_path = file_info["path"]
|
||||
filename = file_info["filename"]
|
||||
@@ -1546,7 +1551,7 @@ def run_app(port: int | None = None):
|
||||
port_to_use = find_free_port(initial_port)
|
||||
if port_to_use != initial_port: print(f"端口 {initial_port} 被占用,将使用端口 {port_to_use} 代替")
|
||||
print(f"正在启动 DocuTranslate WebUI 版本号:{__version__}")
|
||||
app.state.port_to_use=port_to_use
|
||||
app.state.port_to_use = port_to_use
|
||||
uvicorn.run(app, host=None, port=port_to_use, workers=1)
|
||||
except Exception as e:
|
||||
print(f"启动失败: {e}")
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
default_params = {
|
||||
"thinking":"default",
|
||||
"thinking": "default",
|
||||
"chunk_size": 3000,
|
||||
"concurrent": 30,
|
||||
"temperature": 0.7,
|
||||
"timeout": 1200,
|
||||
}
|
||||
Reference in New Issue
Block a user