import time
import json
import requests
from typing import List, Dict, Optional
from docx import Document
from docx.shared import Inches, Pt
from docx.enum.text import WD_PARAGRAPH_ALIGNMENT
from docx.oxml.ns import qn

# ===================== 工作流配置(两个不同模型的工作流) =====================
# Agent A:对接 Azure OpenAI GPT5.2 的工作流
AGENT_A_CONFIG = {
    "name": "OpenClaw 支持者 (Azure OpenAI GPT5.2)",
    "stance": "OpenClaw 是下一代智能自动化技术,在复杂场景中具备不可替代的优势,与RPA互补而非替代",
    "core_arguments": [
        "微服务架构适配复杂异构系统",
        "多模态AI处理非结构化数据",
        "长期维护成本更低",
        "适配大型企业复杂场景"
    ],
    "workflow": {
        "api_url": "https://power-api.yingdao.com/oapi/power/v1/rest/flow/4fa38143-da21-4104-b4b2-93d2e5671ec6/execute",  # A的工作流ID
        "headers": {
            "Authorization": "Bearer XXX",  # A的鉴权Token
            "Content-Type": "application/json"
        },
        "timeout": 60  # 请求超时时间
    },
    "debate_params": {
        "temperature": 0.8,
        "max_tokens": 500
    }
}

# Agent B:对接火山引擎豆包 seed1.6 的工作流
AGENT_B_CONFIG = {
    "name": "RPA 支持者 (火山引擎豆包 seed1.6)",
    "stance": "RPA仍是企业自动化主流,成熟生态和低成本优势不可替代,OpenClaw是补充而非替代",
    "core_arguments": [
        "市场成熟度高,生态完善",
        "实施成本低,落地速度快",
        "规则驱动更稳定可控",
        "适配80%标准化流程场景"
    ],
    "workflow": {
        "api_url": "https://power-api.yingdao.com/oapi/power/v1/rest/flow/1ff93694-2476-49e8-91f2-b2a8d7247058/execute",  # B的工作流ID
        "headers": {
            "Authorization": "Bearer xxx",  # B的鉴权Token
            "Content-Type": "application/json"
        },
        "timeout": 60
    },
    "debate_params": {
        "temperature": 0.6,
        "max_tokens": 500
    }
}

# 辩论规则
DEBATE_ROUNDS = 1

# ===================== 新增Word报告生成类 =====================
class WordReportGenerator:
    """Word报告生成器 - 生成结构化的辩论报告"""
    def __init__(self, filename: str = "辩论报告.docx"):
        self.doc = Document()
        self.filename = filename
        # 设置文档样式
        self._setup_document_style()
    
    def _setup_document_style(self):
        """设置文档基础样式(中文适配)"""
        # 设置默认字体为宋体
        style = self.doc.styles['Normal']
        style.font.name = '宋体'
        style._element.rPr.rFonts.set(qn('w:eastAsia'), '宋体')
        style.font.size = Pt(11)
    
    def add_title(self, title: str):
        """添加文档标题"""
        title_para = self.doc.add_heading(title, level=0)
        title_para.alignment = WD_PARAGRAPH_ALIGNMENT.CENTER
        # 设置标题字体
        for run in title_para.runs:
            run.font.name = '黑体'
            run._element.rPr.rFonts.set(qn('w:eastAsia'), '黑体')
            run.font.size = Pt(16)
    
    def add_debate_metadata(self, agent_a_name: str, agent_b_name: str):
        """添加辩论元信息(参与方、时间)"""
        meta_para = self.doc.add_paragraph()
        meta_para.add_run(f"辩论主题:OpenClaw与RPA的竞争合作关系\n").bold = True
        meta_para.add_run(f"辩论双方:{agent_a_name} VS {agent_b_name}\n")
        meta_para.add_run(f"辩论时间:{time.strftime('%Y年%m月%d日 %H:%M:%S')}\n")
        meta_para.add_run(f"辩论轮次:{DEBATE_ROUNDS + 1}轮(1轮开场 + {DEBATE_ROUNDS}轮交锋)")
        meta_para.space_after = Pt(12)
    
    def add_debate_records(self, records: List[Dict]):
        """添加完整的辩论记录(按轮次结构化)"""
        # 添加辩论记录标题
        self.doc.add_heading("一、完整辩论记录", level=1)
        
        # 分类整理记录(开场 + 交锋)
        opening_round = records[:2]  # 前两条是开场立论
        debate_rounds = records[2:]  # 后面是交锋内容
        
        # 1. 开场立论部分
        self.doc.add_heading("1. 开场立论", level=2)
        for i, record in enumerate(opening_round, 1):
            self._add_speech_record(f"发言人{i}", record)
        
        # 2. 多轮交锋部分
        for round_num in range(1, DEBATE_ROUNDS + 1):
            self.doc.add_heading(f"2. 第{round_num}轮交锋", level=2)
            # 每轮有两条记录(A反驳B,B反驳A)
            start_idx = (round_num - 1) * 2
            end_idx = start_idx + 2
            round_records = debate_rounds[start_idx:end_idx]
            
            for i, record in enumerate(round_records, 1):
                self._add_speech_record(f"交锋{i}", record)
    
    def _add_speech_record(self, label: str, record: Dict):
        """添加单条发言记录"""
        # 发言人信息
        speaker_para = self.doc.add_paragraph()
        speaker_para.add_run(f"{label} - {record['speaker']}:").bold = True
        speaker_para.space_after = Pt(6)
        
        # 发言内容
        content_para = self.doc.add_paragraph(record['content'])
        content_para.space_after = Pt(12)
        content_para.line_spacing = 1.5  # 设置行间距
    
    def add_summary_report(self, summary: str):
        """添加总结报告"""
        self.doc.add_heading("二、辩论总结报告", level=1)
        summary_para = self.doc.add_paragraph(summary)
        summary_para.line_spacing = 1.5
        summary_para.space_after = Pt(12)
    
    def save_document(self):
        """保存Word文档"""
        self.doc.save(self.filename)
        print(f"\n📄 Word报告已保存:{self.filename}")

class WorkflowClient:
    """工作流客户端 - 封装你的API调用逻辑"""
    def __init__(self, workflow_config: Dict):
        self.api_url = workflow_config["api_url"]
        self.headers = workflow_config["headers"]
        self.timeout = workflow_config.get("timeout", 30)
    
    def call_workflow(self, prompt: str) -> str:
        """调用工作流API,返回模型生成的文本"""
        try:
            # 构造你指定的请求格式
            payload = {
                "input": {
                    "input_text_0": prompt  # 工作流要求的输入字段
                }
            }
            
            # 发送请求
            response = requests.post(
                self.api_url,
                headers=self.headers,
                json=payload,
                timeout=self.timeout
            )
            
            # 检查响应状态
            response.raise_for_status()
            result = response.json()
            
            # 解析结果(关键:根据你的工作流返回格式调整)
            # 这里假设工作流返回的结构是 {"output": {"output_text_0": "辩论内容"}}
            # 如果你的返回格式不同,修改下面这行即可
            debate_content = result['data']['result']['output_text_0']
            
            if not debate_content:
                return f"【解析失败】工作流返回格式异常:{json.dumps(result, ensure_ascii=False)[:200]}"
            
            return debate_content.strip()
        
        except requests.exceptions.Timeout:
            return f"【请求超时】调用工作流超时({self.timeout}秒)"
        except requests.exceptions.RequestException as e:
            return f"【请求失败】{str(e)}"
        except Exception as e:
            return f"【解析异常】{str(e)}"

class WorkflowDebateAgent:
    """基于工作流的独立辩论Agent"""
    def __init__(self, config: Dict):
        self.name = config["name"]
        self.stance = config["stance"]
        self.core_arguments = config["core_arguments"]
        self.workflow_client = WorkflowClient(config["workflow"])
        self.debate_params = config["debate_params"]
        self.private_history = []  # 仅自己可见的辩论历史
    
    def add_to_history(self, speaker: str, content: str):
        """添加辩论记录到私有历史"""
        self.private_history.append({
            "speaker": speaker,
            "content": content,
            "timestamp": time.strftime("%Y-%m-%d %H:%M:%S")
        })
    
    def _build_prompt(self, prompt_template: str, **kwargs) -> str:
        """构建带角色和上下文的prompt"""
        # 拼接历史上下文
        history_text = "\n".join([
            f"【{item['speaker']}】:{item['content']}" 
            for item in self.private_history
        ])
        
        # 填充模板变量
        prompt = prompt_template.format(
            agent_name=self.name,
            stance=self.stance,
            core_arguments="\n- ".join(self.core_arguments),
            history=history_text,
            temperature=self.debate_params["temperature"],
            max_tokens=self.debate_params["max_tokens"],
            **kwargs
        )
        return prompt
    
    def make_opening(self) -> str:
        """生成开场立论(调用工作流)"""
        prompt_template = """
        你是{agent_name},请围绕 OpenClaw 和 RPA 的竞争合作关系发表开场论述,要求:
        1. 核心立场:{stance}
        2. 结合核心论点:
           - {core_arguments}
        3. 内容要求:
           - 明确阐述你支持的技术核心优势
           - 客观提及与另一技术的竞争点
           - 提出可能的合作方向
           - 语言专业但易懂,逻辑清晰,300字左右
           - 只输出辩论内容,不要额外解释或开场白
        4. 生成参数:temperature={temperature},max_tokens={max_tokens}
        """
        # 生成prompt并调用工作流
        prompt = self._build_prompt(prompt_template)
        opening_content = self.workflow_client.call_workflow(prompt)
        self.add_to_history(self.name, opening_content)
        return opening_content
    
    def refute(self, opponent_arg: str, round_num: int) -> str:
        """反驳对方论点(调用工作流)"""
        prompt_template = """
        【辩论背景】
        你是{agent_name},核心立场:{stance}
        已发生的辩论内容:
        {history}
        
        【本轮任务】
        第{round_num}轮辩论,对方最新论点:
        {opponent_arg}
        
        请针对性反驳,要求:
        1. 直击对方核心观点漏洞,不要泛泛而谈
        2. 结合你的核心论点({core_arguments})提出新论据
        3. 理性客观,不情绪化,200-300字
        4. 只输出反驳内容,无其他文字
        5. 生成参数:temperature={temperature},max_tokens={max_tokens}
        """
        # 生成prompt并调用工作流
        prompt = self._build_prompt(prompt_template, round_num=round_num, opponent_arg=opponent_arg)
        refute_content = self.workflow_client.call_workflow(prompt)
        self.add_to_history(self.name, refute_content)
        return refute_content

class CrossWorkflowDebateManager:
    """跨工作流辩论管理器"""
    def __init__(self, agent_a: WorkflowDebateAgent, agent_b: WorkflowDebateAgent):
        self.agent_a = agent_a
        self.agent_b = agent_b
        self.public_record = []  # 公开的辩论记录
    
    def _log_and_broadcast(self, speaker: str, content: str):
        """记录并广播发言(双方都添加到自己的历史)"""
        self.public_record.append({
            "speaker": speaker,
            "content": content,
            "timestamp": time.strftime("%Y-%m-%d %H:%M:%S")
        })
        # 双方同步这条记录
        self.agent_a.add_to_history(speaker, content)
        self.agent_b.add_to_history(speaker, content)
        
        # 打印输出
        print(f"\n📢 【{speaker}】")
        print(content,"\n")
        # print("-" * 120)
        time.sleep(3)  # 工作流调用可能较慢,增加间隔
    
    def run_debate(self) -> Dict:
        """运行跨工作流的双模型辩论"""
        print(f"=== 跨平台辩论:{self.agent_a.name} vs {self.agent_b.name} ===\n")
        
        # 第一轮:开场立论
        print(f"===== 第1轮 - 开场立论 =====")
        print(f"🤔 {self.agent_a.name} 正在生成开场论述...")
        a_opening = self.agent_a.make_opening()
        self._log_and_broadcast(self.agent_a.name, a_opening)
        
        print(f"🤔 {self.agent_b.name} 正在生成开场论述...")
        b_opening = self.agent_b.make_opening()
        self._log_and_broadcast(self.agent_b.name, b_opening)
        
        # 多轮交锋
        last_a_arg = a_opening
        last_b_arg = b_opening
        
        for round_num in range(1, DEBATE_ROUNDS + 1):
            print(f"\n===== 第{round_num+1}轮 - 交锋 =====")
            
            # A反驳B
            print(f"🤔 {self.agent_a.name} 正在反驳对方论点...")
            a_refute = self.agent_a.refute(last_b_arg, round_num)
            self._log_and_broadcast(self.agent_a.name, a_refute)
            last_a_arg = a_refute
            
            # B反驳A
            print(f"🤔 {self.agent_b.name} 正在反驳对方论点...")
            b_refute = self.agent_b.refute(last_a_arg, round_num)
            self._log_and_broadcast(self.agent_b.name, b_refute)
            last_b_arg = b_refute
        
        # 生成总结报告(可选:调用其中一个工作流或独立模型)
        summary = self._generate_summary()
        print(f"\n===== 辩论总结报告 =====")
        print(summary)
        
        return {
            "debate_record": self.public_record,
            "summary_report": summary,
            "agent_a": self.agent_a.name,
            "agent_b": self.agent_b.name
        }
    
    def _generate_summary(self) -> str:
        """生成总结报告(调用Agent A的工作流)"""
        record_text = "\n".join([
            f"【{item['speaker']}】:{item['content']}" 
            for item in self.public_record
        ])
        
        summary_prompt = f"""
        请作为中立裁判,总结以下辩论的核心内容(OpenClaw vs RPA):
        {record_text}
        
        报告结构:
        1. 核心分歧点(双方的主要争议)
        2. 共识点(双方认可的内容)
        3. 竞争合作建议(基于双方论点的客观建议)
        4. 结论(总结整体关系)
        要求:客观中立,500-600字,仅输出报告内容,无其他文字。
        """
        
        # 调用Agent A的工作流生成总结
        summary = self.agent_a.workflow_client.call_workflow(summary_prompt)
        return summary

# ===================== 运行辩论 =====================
if __name__ == "__main__":
    try:
        # 创建两个基于工作流的Agent
        agent_a = WorkflowDebateAgent(AGENT_A_CONFIG)
        agent_b = WorkflowDebateAgent(AGENT_B_CONFIG)
        
        # 启动辩论
        manager = CrossWorkflowDebateManager(agent_a, agent_b)
        debate_result = manager.run_debate()

        # 生成Word报告
        print("\n📝 正在生成Word报告...")
        word_generator = WordReportGenerator("OpenClaw vs RPA 辩论报告.docx")
        
        # 添加标题和元信息
        word_generator.add_title("OpenClaw与RPA竞争合作关系辩论报告")
        word_generator.add_debate_metadata(
            agent_a_name=debate_result["agent_a"],
            agent_b_name=debate_result["agent_b"]
        )
        
        # 添加完整辩论记录(每一轮的发言)
        word_generator.add_debate_records(debate_result["debate_record"])
        
        # 添加总结报告
        word_generator.add_summary_report(debate_result["summary_report"])
        
        # 保存Word文档
        word_generator.save_document()
        
        # 保存结果到文件
        with open("cross_workflow_debate_report.json", "w", encoding="utf-8") as f:
            json.dump(debate_result, f, ensure_ascii=False, indent=2)
        
        print("\n✅ 跨工作流辩论完成!完整报告已保存到 cross_workflow_debate_report.json")
    
    except Exception as e:
        print(f"\n❌ 辩论执行失败:{str(e)}")

更多推荐