algorithm-agent / reporting.py
fanjingbo111's picture
Deploy algorithm agent app
ae0a268 verified
Raw
History Blame Contribute Delete
5.31 kB
from __future__ import annotations
import os
import shutil
import subprocess
import textwrap
import time
from pathlib import Path
from typing import Dict, Tuple
OUTPUT_DIR = Path("outputs")
def latex_escape(value: str) -> str:
replacements = {
"\\": r"\textbackslash{}",
"&": r"\&",
"%": r"\%",
"$": r"\$",
"#": r"\#",
"_": r"\_",
"{": r"\{",
"}": r"\}",
"~": r"\textasciitilde{}",
"^": r"\textasciicircum{}",
}
return "".join(replacements.get(ch, ch) for ch in value)
def build_solution_tex(data: Dict[str, str]) -> str:
original = latex_escape(data.get("original_problem", ""))
structured = latex_escape(data.get("structured_problem", ""))
strategy = latex_escape(data.get("strategy", ""))
result = latex_escape(data.get("tool_result", ""))
final_answer = latex_escape(data.get("final_answer", ""))
process = latex_escape(data.get("process_log", ""))
complexity = latex_escape(data.get("complexity_analysis", "本系统在工具层执行真实计算,再由语言模型或规则化报告模块生成解释,从而降低纯文本推理产生错误答案的风险。"))
timestamp = latex_escape(time.strftime("%Y-%m-%d %H:%M:%S"))
return rf"""
\documentclass[11pt,fontset=none]{{ctexart}}
\usepackage[a4paper,margin=2.4cm]{{geometry}}
\usepackage{{booktabs}}
\usepackage{{enumitem}}
\usepackage{{hyperref}}
\usepackage{{xcolor}}
\usepackage{{listings}}
\setCJKmainfont{{Songti SC}}
\setCJKsansfont{{Songti SC}}
\setCJKmonofont{{Songti SC}}
\hypersetup{{colorlinks=true,linkcolor=blue,urlcolor=blue}}
\lstset{{basicstyle=\ttfamily\small,breaklines=true,frame=single}}
\title{{通用问题优化智能体求解报告}}
\author{{Problem Optimization Agent}}
\date{{{timestamp}}}
\begin{{document}}
\maketitle
\section{{原始问题}}
{original}
\section{{优化后的结构化问题}}
\begin{{lstlisting}}
{structured}
\end{{lstlisting}}
\section{{求解策略}}
{strategy}
\section{{工具调用与计算结果}}
\begin{{lstlisting}}
{result}
\end{{lstlisting}}
\section{{智能体求解过程记录}}
\begin{{lstlisting}}
{process}
\end{{lstlisting}}
\section{{最终答案}}
{final_answer}
\section{{复杂度与适用性分析}}
{complexity}
\section{{结论}}
本次求解将自然语言理解、结构化建模和确定性算法工具结合起来。语言模型或规则化模块负责
问题优化、解释和报告化表达,工具层负责关键计算和验证,因此求解过程可以被复查和复现。
\end{{document}}
""".strip()
def _fallback_pdf(text: str, pdf_path: Path) -> None:
from reportlab.lib.pagesizes import A4
from reportlab.lib.styles import getSampleStyleSheet
from reportlab.pdfbase import pdfmetrics
from reportlab.pdfbase.cidfonts import UnicodeCIDFont
from reportlab.platypus import Paragraph, SimpleDocTemplate, Spacer
font_name = "STSong-Light"
pdfmetrics.registerFont(UnicodeCIDFont(font_name))
doc = SimpleDocTemplate(str(pdf_path), pagesize=A4, rightMargin=42, leftMargin=42, topMargin=42, bottomMargin=42)
styles = getSampleStyleSheet()
styles["BodyText"].fontName = font_name
styles["BodyText"].leading = 15
story = []
for para in text.split("\n\n"):
clean = para.replace("&", "&amp;").replace("<", "&lt;").replace(">", "&gt;").replace("\n", "<br/>")
story.append(Paragraph(clean, styles["BodyText"]))
story.append(Spacer(1, 10))
doc.build(story)
def write_solution_report(data: Dict[str, str], stem: str = "solution_report") -> Tuple[str, str]:
OUTPUT_DIR.mkdir(exist_ok=True)
tex_path = OUTPUT_DIR / f"{stem}.tex"
pdf_path = OUTPUT_DIR / f"{stem}.pdf"
tex = build_solution_tex(data)
tex_path.write_text(tex, encoding="utf-8")
engine = shutil.which("xelatex") or shutil.which("pdflatex")
if engine:
try:
subprocess.run(
[engine, "-interaction=nonstopmode", "-halt-on-error", tex_path.name],
cwd=OUTPUT_DIR,
check=True,
stdout=subprocess.PIPE,
stderr=subprocess.PIPE,
timeout=60,
)
except Exception:
fallback_text = "\n\n".join(
[
"通用问题优化智能体求解报告",
data.get("original_problem", ""),
data.get("structured_problem", ""),
data.get("strategy", ""),
data.get("tool_result", ""),
data.get("final_answer", ""),
]
)
_fallback_pdf(fallback_text, pdf_path)
else:
fallback_text = textwrap.dedent(
f"""
通用问题优化智能体求解报告
原始问题:
{data.get('original_problem', '')}
优化后的结构化问题:
{data.get('structured_problem', '')}
求解策略:
{data.get('strategy', '')}
工具调用与结果:
{data.get('tool_result', '')}
最终答案:
{data.get('final_answer', '')}
"""
)
_fallback_pdf(fallback_text, pdf_path)
return str(pdf_path), str(tex_path)