AgentConfig的字段和AiTranslatorConfig使用相同写法

This commit is contained in:
xunbu committed 2025-09-04 19:10:18 +08:00
1 parent 95ed4cc361
commit 8bb4fc3d18
15 files changed
+30 -39

No files matched your search

+4 -4
View File
@@ -41,8 +41,8 @@ class PartialAgentResultError(ValueError):
@dataclass(kw_only=True)
class AgentConfig:
logger: logging.Logger
baseurl: str
key: str
base_url: str
api_key: str
model_id: str
temperature: float = 0.7
max_concurrent: int = 30
@@ -110,11 +110,11 @@ class Agent:
def __init__(self, config: AgentConfig):
self.baseurl = config.baseurl.strip()
self.baseurl = config.base_url.strip()
if self.baseurl.endswith("/"):
self.baseurl = self.baseurl[:-1]
self.domain = urlparse(self.baseurl).netloc
self.key = config.key.strip() or "xx"
self.key = config.api_key.strip() or "xx"
self.model_id = config.model_id.strip()
self.system_prompt = ""
self.temperature = config.temperature
+4 -3
View File
@@ -33,8 +33,9 @@ You need to extract person names and location names from these paragraphs and tr
Finally, output a glossary of original terms:translated terms
# Requirements
- The original language is identified based on the context.The target language is {self.to_lang}
- The src in the output glossary must exactly match the original term in original language, while dst is the {self.to_lang} translation of the term
- Do not include special tags or tags formatted as `<ph-xxxxxx>` in the glossary
- The src in the output glossary must exactly match the original term, while dst is the {self.to_lang} translation of the term
- The same src should only appear once in the glossary without repetition
- Do not include common nouns in the glossary.
@@ -42,10 +43,10 @@ Finally, output a glossary of original terms:translated terms
The output format should be plain JSON text in a list format
{[{"src": "<Original Term>", "dst": "<Translated Term>"}]}
# Example
# Example1(Assuming the source language is English and the target language is Chinese in the example)
## Input
{{"0":"Jobs likes apples","1":"Bill Gates is sunbathing in Shanghai."}}
## Output(Assuming the target language is Chinese)
## Output
{r'[{"src": "Jobs", "dst": "乔布斯"}, {"src": "Bill Gates", "dst": "比尔盖茨"}, {"src": "Shanghai", "dst": "上海"}]'}
"""
+1 -2
View File
@@ -40,8 +40,7 @@ Target language: {config.to_lang}
# Output
The translated markdown text as plain text (not in a markdown code block, with no extraneous text).
# Example
## Target language is Chinese
# Example(Assuming the target language is Chinese in the example, {config.to_lang} is the actual target language)
Input:
hello, what's your nam*@e?
![photo title](<ph-abcdde>)
+2 -2
View File
@@ -43,10 +43,10 @@ class SegmentsTranslateAgent(Agent):
- The translated sequence of segments, represented as JSON text (note: not a code block). The keys are the segment IDs, and the values are the translated segments.
- The returned JSON text must be a dictionary of the form {{<segment_id>: <translation>}}.
- The segment IDs in the output must **exactly** match those in the input. And all segment IDs in input must appear in the output.
# Example
# Example(Assuming the target language is Chinese in the example, {config.to_lang} is the actual target language)
## Input
{r'{"10":"hello","11":"apple","12":true,"13":"false","14":null}'}
## Output(Assuming the target language is Chinese)
## Output
{r'{"10":"你好","11":"苹果","12":true,"13":"错误","14":null}'}
> Warning: Never wrap the JSON text in ```.
"""
-9
View File
@@ -273,15 +273,6 @@ class BaseWorkflowParams(BaseModel):
# 如果跳过翻译,则不进行任何检查,允许 base_url 等字段为空
return values
@model_validator(mode='after')
def check_glossary_config(self) -> 'BaseWorkflowParams':
"""
在所有字段验证后,检查术语表相关配置的逻辑一致性。
"""
if self.glossary_generate_enable and not self.glossary_agent_config:
raise ValueError("当 `glossary_generate_enable` 为 `True` 时, `glossary_agent_config` 字段是必须的。")
return self
# 2. 为每个工作流创建独立的参数模型
class MarkdownWorkflowParams(BaseWorkflowParams):
+1 -1
View File
@@ -1 +1 @@
<!DOCTYPE html> <html lang="zh-CN" data-bs-theme="auto"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title data-i18n-title="pageTitle">DocuTranslate - 交互式文档翻译</title> <link rel="icon" href="/static/favicon.ico" type="image/x-icon"> <!-- Bootstrap CSS --> <link href="/static/bootstrap.css" rel="stylesheet" crossorigin="anonymous"> <!-- Bootstrap Icons --> <link rel="stylesheet" href="/static/bootstrap-icons.css"> <style> body { background-color: var(--bs-body-bg); } button:focus { outline: none !important; box-shadow: none !important; } .main-container { display: flex; flex-direction: column; height: 100vh; padding-top: 1rem; padding-bottom: 1rem; } .settings-panel { height: calc(100vh - 2rem); overflow-y: auto; padding-right: 15px; /* for scrollbar */ } .task-area { height: calc(100vh - 2rem); overflow-y: auto; } .task-card { transition: all 0.3s ease-in-out; } .task-id-placeholder { color: var(--bs-secondary-color); font-style: italic; } .log-area { height: 150px; background-color: var(--bs-tertiary-bg); border: 1px solid var(--bs-border-color); border-radius: .375rem; font-family: monospace; font-size: 0.8rem; padding: 10px; overflow-y: auto; white-space: pre-wrap; word-break: break-all; } .file-drop-area { border: 2px dashed var(--bs-secondary-bg); border-radius: .375rem; padding: 2rem; text-align: center; cursor: pointer; transition: all 0.2s ease-in-out; background-color: var(--bs-body-bg); } .file-drop-area.drag-over { border-color: var(--bs-primary); background-color: var(--bs-secondary-bg); } .file-drop-area.file-selected { border-style: solid; border-color: var(--bs-success); background-color: var(--bs-success-bg-subtle); } .file-drop-area.input-error { border-color: var(--bs-danger); } .file-name-display.input-error-text { color: var(--bs-danger); font-weight: bold; } #printFrame, #translatedPreviewFrame { border: none; width: 100%; } #previewOffcanvas { --bs-offcanvas-width: 95vw; max-width: 1600px; } .preview-split-container { display: flex; flex-direction: row; height: 90%; } .preview-pane-wrapper { display: flex; flex-direction: column; overflow: hidden; /* Important for split.js */ } .preview-pane-wrapper h6 { flex-shrink: 0; padding: 0.25rem; } .preview-pane-wrapper .preview-pane { flex-grow: 1; /* Make the inner pane grow */ border: 1px solid var(--bs-border-color); border-radius: .375rem; overflow: auto; } .gutter { background-color: var(--bs-tertiary-bg); background-repeat: no-repeat; background-position: 50%; } .gutter.gutter-horizontal { cursor: col-resize; border-left: 1px solid var(--bs-border-color); border-right: 1px solid var(--bs-border-color); } .gutter.gutter-vertical { cursor: row-resize; border-top: 1px solid var(--bs-border-color); border-bottom: 1px solid var(--bs-border-color); } .preview-pane iframe, .preview-pane pre { width: 100%; height: 95%; border: none; margin: 0; padding: 0; overflow: auto; background-color: var(--bs-body-bg); } .slider-reset-btn { visibility: hidden; } .bottom-left-controls { position: fixed; bottom: 1rem; left: 1rem; z-index: 1050; display: flex; gap: 0.5rem; } .project-info p { letter-spacing: 0.8px; line-height: 1.6; } @media (max-width: 991.98px) { .main-container { height: auto; padding-bottom: 6rem; } .settings-panel, .task-area { height: auto; overflow-y: visible; } .settings-panel { pLine truncated
<!DOCTYPE html> <html lang="zh-CN" data-bs-theme="auto"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title data-i18n-title="pageTitle">DocuTranslate - 交互式文档翻译</title> <link rel="icon" href="/static/favicon.ico" type="image/x-icon"> <!-- Bootstrap CSS --> <link href="/static/bootstrap.css" rel="stylesheet" crossorigin="anonymous"> <!-- Bootstrap Icons --> <link rel="stylesheet" href="/static/bootstrap-icons.css"> <style> body { background-color: var(--bs-body-bg); } button:focus { outline: none !important; box-shadow: none !important; } .main-container { display: flex; flex-direction: column; height: 100vh; padding-top: 1rem; padding-bottom: 1rem; } .settings-panel { height: calc(100vh - 2rem); overflow-y: auto; padding-right: 15px; /* for scrollbar */ } .task-area { height: calc(100vh - 2rem); overflow-y: auto; } .task-card { transition: all 0.3s ease-in-out; } .task-id-placeholder { color: var(--bs-secondary-color); font-style: italic; } .log-area { height: 150px; background-color: var(--bs-tertiary-bg); border: 1px solid var(--bs-border-color); border-radius: .375rem; font-family: monospace; font-size: 0.8rem; padding: 10px; overflow-y: auto; white-space: pre-wrap; word-break: break-all; } .file-drop-area { border: 2px dashed var(--bs-secondary-bg); border-radius: .375rem; padding: 2rem; text-align: center; cursor: pointer; transition: all 0.2s ease-in-out; background-color: var(--bs-body-bg); } .file-drop-area.drag-over { border-color: var(--bs-primary); background-color: var(--bs-secondary-bg); } .file-drop-area.file-selected { border-style: solid; border-color: var(--bs-success); background-color: var(--bs-success-bg-subtle); } .file-drop-area.input-error { border-color: var(--bs-danger); } .file-name-display.input-error-text { color: var(--bs-danger); font-weight: bold; } #printFrame, #translatedPreviewFrame { border: none; width: 100%; } #previewOffcanvas { --bs-offcanvas-width: 95vw; max-width: 1600px; } .preview-split-container { display: flex; flex-direction: row; height: 90%; } .preview-pane-wrapper { display: flex; flex-direction: column; overflow: hidden; /* Important for split.js */ } .preview-pane-wrapper h6 { flex-shrink: 0; padding: 0.25rem; } .preview-pane-wrapper .preview-pane { flex-grow: 1; /* Make the inner pane grow */ border: 1px solid var(--bs-border-color); border-radius: .375rem; overflow: auto; } .gutter { background-color: var(--bs-tertiary-bg); background-repeat: no-repeat; background-position: 50%; } .gutter.gutter-horizontal { cursor: col-resize; border-left: 1px solid var(--bs-border-color); border-right: 1px solid var(--bs-border-color); } .gutter.gutter-vertical { cursor: row-resize; border-top: 1px solid var(--bs-border-color); border-bottom: 1px solid var(--bs-border-color); } .preview-pane iframe, .preview-pane pre { width: 100%; height: 95%; border: none; margin: 0; padding: 0; overflow: auto; background-color: var(--bs-body-bg); } .slider-reset-btn { visibility: hidden; } .bottom-left-controls { position: fixed; bottom: 1rem; left: 1rem; z-index: 1050; display: flex; gap: 0.5rem; } .project-info p { letter-spacing: 0.8px; line-height: 1.6; } @media (max-width: 991.98px) { .main-container { height: auto; padding-bottom: 6rem; } .settings-panel, .task-area { height: auto; overflow-y: visible; } .settings-panel { pLine truncated
@@ -50,8 +50,8 @@ class AiTranslator(Translator[T]):
else:
glossary_agent_config = GlossaryAgentConfig(
to_lang=config.to_lang,
baseurl=config.base_url,
key=config.api_key,
base_url=config.base_url,
api_key=config.api_key,
model_id=config.model_id,
temperature=config.temperature,
thinking=config.thinking,
@@ -44,8 +44,8 @@ class DocxTranslator(AiTranslator):
agent_config = SegmentsTranslateAgentConfig(
custom_prompt=config.custom_prompt,
to_lang=config.to_lang,
baseurl=config.base_url,
key=config.api_key,
base_url=config.base_url,
api_key=config.api_key,
model_id=config.model_id,
temperature=config.temperature,
thinking=config.thinking,
@@ -35,8 +35,8 @@ class EpubTranslator(AiTranslator):
agent_config = SegmentsTranslateAgentConfig(
custom_prompt=config.custom_prompt,
to_lang=config.to_lang,
baseurl=config.base_url,
key=config.api_key,
base_url=config.base_url,
api_key=config.api_key,
model_id=config.model_id,
temperature=config.temperature,
thinking=config.thinking,
@@ -92,8 +92,8 @@ class HtmlTranslator(AiTranslator):
agent_config = SegmentsTranslateAgentConfig(
custom_prompt=config.custom_prompt,
to_lang=config.to_lang,
baseurl=config.base_url,
key=config.api_key,
base_url=config.base_url,
api_key=config.api_key,
model_id=config.model_id,
temperature=config.temperature,
thinking=config.thinking,
@@ -25,8 +25,8 @@ class JsonTranslator(AiTranslator):
agent_config = SegmentsTranslateAgentConfig(
custom_prompt=config.custom_prompt,
to_lang=config.to_lang,
baseurl=config.base_url,
key=config.api_key,
base_url=config.base_url,
api_key=config.api_key,
model_id=config.model_id,
temperature=config.temperature,
thinking=config.thinking,
@@ -25,8 +25,8 @@ class MDTranslator(AiTranslator):
if not self.skip_translate:
agent_config = MDTranslateAgentConfig(custom_prompt=config.custom_prompt,
to_lang=config.to_lang,
baseurl=config.base_url,
key=config.api_key,
base_url=config.base_url,
api_key=config.api_key,
model_id=config.model_id,
temperature=config.temperature,
thinking=config.thinking,
@@ -31,8 +31,8 @@ class SrtTranslator(AiTranslator):
agent_config = SegmentsTranslateAgentConfig(
custom_prompt=config.custom_prompt,
to_lang=config.to_lang,
baseurl=config.base_url,
key=config.api_key,
base_url=config.base_url,
api_key=config.api_key,
model_id=config.model_id,
temperature=config.temperature,
thinking=config.thinking,
@@ -49,8 +49,8 @@ class TXTTranslator(AiTranslator):
agent_config = SegmentsTranslateAgentConfig(
custom_prompt=config.custom_prompt,
to_lang=config.to_lang,
baseurl=config.base_url,
key=config.api_key,
base_url=config.base_url,
api_key=config.api_key,
model_id=config.model_id,
temperature=config.temperature,
thinking=config.thinking,
@@ -33,8 +33,8 @@ class XlsxTranslator(AiTranslator):
agent_config = SegmentsTranslateAgentConfig(
custom_prompt=config.custom_prompt,
to_lang=config.to_lang,
baseurl=config.base_url,
key=config.api_key,
base_url=config.base_url,
api_key=config.api_key,
model_id=config.model_id,
temperature=config.temperature,
thinking=config.thinking,