diff --git a/agent/component/docs_generator.py b/agent/component/docs_generator.py index 297fac9b1..9c89eefbf 100644 --- a/agent/component/docs_generator.py +++ b/agent/component/docs_generator.py @@ -189,7 +189,7 @@ class DocGenerator(Message, ABC): flags=re.DOTALL, ) - return content + return self._strip_thinking(content) def _get_output_directory(self) -> str: os.makedirs(self._default_output_directory, exist_ok=True) diff --git a/agent/component/message.py b/agent/component/message.py index 6b03b5f44..d9077313d 100644 --- a/agent/component/message.py +++ b/agent/component/message.py @@ -365,10 +365,31 @@ class Message(ComponentBase): return None + @staticmethod + def _strip_thinking(content: str) -> str: + """Remove ... reasoning blocks before document export. + + Reasoning models (e.g. DeepSeek-R1, OpenAI o1) embed chain-of-thought + inside ```` tags. These blocks must not leak into exported + Word/PDF/Excel documents. + """ + if not isinstance(content, str) or not content: + return content + # Remove complete think blocks (DOTALL so newlines are matched) + cleaned = re.sub(r".*?", "", content, flags=re.DOTALL) + # Remove any dangling unclosed opening tag + trailing content + cleaned = re.sub(r".*$", "", cleaned, flags=re.DOTALL) + # Remove leftover standalone tags + cleaned = re.sub(r"", "", cleaned) + # Collapse 3+ consecutive newlines left behind by removed blocks + cleaned = re.sub(r"\n{3,}", "\n\n", cleaned) + return cleaned.strip() + def _convert_content(self, content): if not self._param.output_format: return + content = self._strip_thinking(content) import pypandoc doc_id = get_uuid()