diff --git a/docutranslate/agents/agent.py b/docutranslate/agents/agent.py index 47d7966..c27e625 100644 --- a/docutranslate/agents/agent.py +++ b/docutranslate/agents/agent.py @@ -32,9 +32,10 @@ class AgentResultError(ValueError): class PartialAgentResultError(ValueError): """一个特殊的异常,用于表示结果不完整但包含了部分成功的数据,以便触发重试。该错误不计入总错误数""" - def __init__(self, message, partial_result: dict): + def __init__(self, message, partial_result: dict,append_prompt:str=None): super().__init__(message) self.partial_result = partial_result + self.append_prompt=append_prompt @dataclass(kw_only=True) @@ -327,6 +328,8 @@ class Agent: self.logger.error(f"收到部分返回结果,将尝试重试: {e}") current_partial_result = e.partial_result should_retry = True + if e.append_prompt: + prompt+=e.append_prompt # is_hard_error 保持 False # 捕获硬错误 diff --git a/docutranslate/agents/segments_agent.py b/docutranslate/agents/segments_agent.py index 17c4145..2f0c7c0 100644 --- a/docutranslate/agents/segments_agent.py +++ b/docutranslate/agents/segments_agent.py @@ -79,7 +79,7 @@ class SegmentsTranslateAgentConfig(AgentConfig): to_lang: str custom_prompt: str | None = None glossary_dict: dict[str, str] | None = None - json_format:bool = True + json_format:bool = False class SegmentsTranslateAgent(Agent): @@ -147,8 +147,9 @@ class SegmentsTranslateAgent(Agent): for key in missing_keys: final_chunk[key] = str(original_chunk[key]) + # 抛出自定义异常,将部分结果和错误信息一起传递出去 - raise PartialAgentResultError("键不匹配,触发重试", partial_result=final_chunk) + raise PartialAgentResultError("键不匹配,触发重试", partial_result=final_chunk,append_prompt=f"\nThe following keys must be included:{','.join(sorted(list(missing_keys)))}") # 如果键完全匹配(理想情况),正常返回 for key, value in repaired_result.items(): diff --git a/docutranslate/translator/ai_translator/txt_translator.py b/docutranslate/translator/ai_translator/txt_translator.py index e09ee9e..28497b7 100644 --- a/docutranslate/translator/ai_translator/txt_translator.py +++ b/docutranslate/translator/ai_translator/txt_translator.py @@ -32,7 +32,7 @@ class TXTTranslatorConfig(AiTranslatorConfig): """ insert_mode: Literal["replace", "append", "prepend"] = "replace" separator: str = "\n" - segment_mode: Literal["line", "paragraph"] = "line" + segment_mode: Literal["line", "paragraph", "none"] = "line" class TXTTranslator(AiTranslator): @@ -91,8 +91,10 @@ class TXTTranslator(AiTranslator): if self.segment_mode == "line": return self._segment_by_line(txt_content) - else: # paragraph mode + elif self.segment_mode == "paragraph": # paragraph mode return self._segment_by_paragraph(txt_content) + else: + return [txt_content] def _segment_by_line(self, txt_content: str) -> List[str]: """ @@ -153,8 +155,10 @@ class TXTTranslator(AiTranslator): """ if self.segment_mode == "line": return self._reconstruct_by_line(translated_texts, original_texts) - else: # paragraph mode + elif self.segment_mode == "paragraph": # paragraph mode return self._reconstruct_by_paragraph(translated_texts, original_texts) + else: + return self._reconstruct_none(translated_texts, original_texts) def _reconstruct_by_line(self, translated_texts: List[str], original_lines: List[str]) -> bytes: """ @@ -230,6 +234,36 @@ class TXTTranslator(AiTranslator): return "\n".join(result_lines).encode('utf-8') + def _reconstruct_none(self, translated_texts: List[str], original_texts: List[str]) -> bytes: + """ + 不分段模式重建文档。 + + Args: + translated_texts (List[str]): 翻译后的文本列表(应只包含一个元素) + original_texts (List[str]): 原始文本列表(应只包含一个元素) + + Returns: + bytes: 重建的文档内容 + """ + if not translated_texts or not original_texts: + return b"" + + original_text = original_texts[0] + translated_text = translated_texts[0] + + # 根据插入模式处理 + if self.insert_mode == "replace": + result_text = translated_text + elif self.insert_mode == "append": + result_text = original_text + self.separator + translated_text + elif self.insert_mode == "prepend": + result_text = translated_text + self.separator + original_text + else: + self.logger.error(f"不正确的insert_mode参数: '{self.insert_mode}'") + result_text = translated_text + + return result_text.encode('utf-8') + def translate(self, document: Document) -> Self: """ 同步翻译TXT文档。 @@ -341,4 +375,4 @@ class TXTTranslator(AiTranslator): document.content = await asyncio.to_thread( self._after_translate, final_translated_texts, original_segments ) - return self \ No newline at end of file + return self