Files
sanguo_vnpy/test/backtest/court_discuss_client.py
T
2026-04-11 21:18:55 +08:00

418 lines
14 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
#!/usr/bin/env python3
"""
朝堂议政引擎 - 手动调用脚本
用于测试和使用朝堂议政功能
"""
import requests
import json
import time
# edict API基础地址
BASE_URL = "http://localhost:7891/api"
# 官员ID列表(可以选择参与议政的官员)
ALL_OFFICIALS = [
'taizi', # 太子
'zhongshu', # 中书省
'menxia', # 门下省
'shangshu', # 尚书省
'libu', # 礼部
'hubu', # 户部
'bingbu', # 兵部
'xingbu', # 刑部
'gongbu', # 工部
'libu_hr', # 吏部
]
def print_separator(title=""):
"""打印分隔线"""
print("\n" + "="*80)
if title:
print(f" {title}")
print("="*80)
def list_officials():
"""列出所有可用官员"""
print_separator("👥 可用官员列表")
try:
response = requests.get(f"{BASE_URL}/court-discuss/officials")
result = response.json()
if result.get('ok'):
officials = result.get('officials', {})
for oid, profile in officials.items():
print(f"\n {profile['emoji']} {profile['name']} ({oid})")
print(f" 角色: {profile['role']}")
print(f" 职责: {profile['duty'][:80]}...")
else:
print(f" ❌ 获取官员列表失败: {result.get('error')}")
except Exception as e:
print(f" ❌ 请求失败: {e}")
def create_session(topic, official_ids, task_id=""):
"""创建朝堂议政会话"""
print_separator("🏛️ 创建议政会话")
print(f" 议题: {topic}")
print(f" 参与官员: {', '.join(official_ids)}")
if task_id:
print(f" 关联任务: {task_id}")
try:
response = requests.post(
f"{BASE_URL}/court-discuss/start",
json={
'topic': topic,
'officials': official_ids,
'taskId': task_id
}
)
result = response.json()
if result.get('ok'):
session_id = result.get('taskId') or result.get('sessionId')
print(f"\n ✅ 议政会话创建成功!")
print(f" 会话ID: {session_id}")
return session_id
else:
print(f"\n ❌ 创建失败: {result.get('error')}")
return None
except Exception as e:
print(f"\n ❌ 请求失败: {e}")
return None
def advance_discussion(session_id, user_message=None, decree=None):
"""推进一轮讨论"""
print_separator("💬 推进讨论")
print(f" 会话ID: {session_id}")
if user_message:
print(f" 皇帝发言: {user_message}")
if decree:
print(f" 天命降临: {decree}")
try:
response = requests.post(
f"{BASE_URL}/court-discuss/advance",
json={
'sessionId': session_id,
'userMessage': user_message,
'decree': decree
}
)
result = response.json()
if result.get('ok'):
print(f"\n ✅ 讨论推进成功!")
print(f"{result.get('round')} 轮讨论")
print(f" 新增 {len(result.get('new_messages', []))} 条消息")
# 打印官员发言
new_messages = result.get('new_messages', [])
if new_messages:
print("\n 📜 官员发言:")
for msg in new_messages:
name = msg.get('name', '?')
content = msg.get('content', '')
emotion = msg.get('emotion', 'neutral')
if len(content) > 100:
print(f"\n {name}: {content[:100]}...")
else:
print(f"\n {name}: {content}")
if emotion != 'neutral':
print(f" (情绪: {emotion})")
scene_note = result.get('scene_note')
if scene_note:
print(f"\n 🎭 场景: {scene_note}")
return True
else:
print(f"\n ❌ 推进失败: {result.get('error')}")
return False
except Exception as e:
print(f"\n ❌ 请求失败: {e}")
return False
def get_session(session_id):
"""获取会话详情"""
print_separator("📋 会话详情")
try:
response = requests.get(f"{BASE_URL}/court-discuss/session/{session_id}")
result = response.json()
if result.get('ok') or result.get('session_id'):
session = result
print(f"\n 会话ID: {session.get('session_id')}")
print(f" 议题: {session.get('topic')}")
print(f" 轮数: {session.get('round')}")
print(f" 状态: {session.get('phase')}")
print(f" 参与官员: {len(session.get('officials', []))}")
print(f" 消息总数: {len(session.get('messages', []))}")
# 打印所有消息
messages = session.get('messages', [])
if messages:
print("\n 📜 完整消息历史:")
for msg in messages:
msg_type = msg.get('type')
timestamp = time.strftime('%H:%M:%S', time.localtime(msg.get('timestamp', 0)))
if msg_type == 'system':
print(f"\n [{timestamp}] 系统: {msg.get('content')}")
elif msg_type == 'emperor':
print(f"\n [{timestamp}] 👑 皇帝: {msg.get('content')}")
elif msg_type == 'decree':
print(f"\n [{timestamp}] ⚡ 天命降临: {msg.get('content')}")
elif msg_type == 'official':
name = msg.get('official_name', '?')
content = msg.get('content', '')
print(f"\n [{timestamp}] {name}: {content}")
elif msg_type == 'scene_note':
print(f"\n [{timestamp}] 🎭 场景: {msg.get('content')}")
return session
else:
print(f"\n ❌ 获取失败: {result.get('error')}")
return None
except Exception as e:
print(f"\n ❌ 请求失败: {e}")
return None
def list_sessions():
"""列出所有活跃会话"""
print_separator("📋 活跃会话列表")
try:
response = requests.get(f"{BASE_URL}/court-discuss/list")
result = response.json()
if result.get('ok'):
sessions = result.get('sessions', [])
if sessions:
for s in sessions:
print(f"\n 会话ID: {s.get('session_id')}")
print(f" 议题: {s.get('topic')}")
print(f" 轮数: {s.get('round')}")
print(f" 状态: {s.get('phase')}")
print(f" 官员数: {s.get('official_count')}")
print(f" 消息数: {s.get('message_count')}")
else:
print(" 暂无活跃会话")
return sessions
else:
print(f" ❌ 获取失败: {result.get('error')}")
return []
except Exception as e:
print(f" ❌ 请求失败: {e}")
return []
def conclude_session(session_id):
"""结束议政会话"""
print_separator("🏁 结束议政")
try:
response = requests.post(
f"{BASE_URL}/court-discuss/conclude",
json={'sessionId': session_id}
)
result = response.json()
if result.get('ok'):
print(f"\n ✅ 议政结束!")
print(f" 总结: {result.get('summary')}")
return True
else:
print(f"\n ❌ 结束失败: {result.get('error')}")
return False
except Exception as e:
print(f"\n ❌ 请求失败: {e}")
return False
def get_fate_event():
"""获取随机命运事件"""
print_separator("🎲 命运骰子")
try:
response = requests.get(f"{BASE_URL}/court-discuss/fate")
result = response.json()
if result.get('ok'):
event = result.get('event')
print(f"\n 🎭 {event}")
return event
else:
print(f" ❌ 获取失败: {result.get('error')}")
return None
except Exception as e:
print(f" ❌ 请求失败: {e}")
return None
def demo_full_flow():
"""演示完整流程"""
print_separator("🚀 朝堂议政完整流程演示")
# 1. 列出官员
list_officials()
# 2. 选择官员参与议政
selected_officials = ['zhongshu', 'menxia', 'shangshu', 'hubu']
print(f"\n\n 选择参与议政的官员: {', '.join(selected_officials)}")
# 3. 创建议政会话
topic = "如何建立一个稳定高效的量化交易系统?"
session_id = create_session(topic, selected_officials)
if not session_id:
return
# 等待一下
time.sleep(2)
# 4. 推进几轮讨论
for i in range(3):
print_separator(f"🔄 第 {i+1} 轮讨论")
advance_discussion(session_id)
time.sleep(3)
# 5. 皇帝发言
print_separator("👑 皇帝发言")
advance_discussion(
session_id,
user_message="诸位爱卿的讨论很有见地,朕想听听关于风险控制方面的具体建议。"
)
time.sleep(3)
# 6. 再来一轮
advance_discussion(session_id)
time.sleep(3)
# 7. 获取会话详情
get_session(session_id)
# 8. 结束议政
conclude_session(session_id)
def interactive_mode():
"""交互式模式"""
print_separator("🎮 朝堂议政 - 交互式模式")
print("\n 欢迎使用朝堂议政引擎!")
print(" 输入 'help' 查看可用命令")
current_session_id = None
while True:
try:
cmd = input("\n > ").strip()
if cmd == 'help' or cmd == '?':
print("\n 可用命令:")
print(" officials - 列出所有官员")
print(" create - 创建议政会话")
print(" advance - 推进讨论")
print(" emperor <msg> - 皇帝发言")
print(" decree <msg> - 天命降临(下旨)")
print(" fate - 命运骰子")
print(" session - 查看当前会话")
print(" list - 列出所有会话")
print(" conclude - 结束议政")
print(" demo - 运行完整演示")
print(" clear - 清屏")
print(" quit / exit - 退出")
elif cmd == 'officials':
list_officials()
elif cmd == 'create':
topic = input(" 请输入议题: ").strip()
if not topic:
print(" ❌ 议题不能为空!")
continue
print("\n 可用官员:")
for i, oid in enumerate(ALL_OFFICIALS, 1):
print(f" {i}. {oid}")
selection = input("\n 请选择参与官员(用逗号分隔,如: 1,2,3,4): ").strip()
try:
indices = [int(x.strip()) - 1 for x in selection.split(',')]
selected = [ALL_OFFICIALS[i] for i in indices if 0 <= i < len(ALL_OFFICIALS)]
except:
print(" ❌ 选择无效!")
continue
if len(selected) < 2:
print(" ❌ 至少需要选择2位官员!")
continue
task_id = input(" 关联任务ID(可选,直接回车跳过): ").strip()
current_session_id = create_session(topic, selected, task_id)
elif cmd == 'advance':
if not current_session_id:
print(" ❌ 没有活跃会话,请先创建!")
continue
advance_discussion(current_session_id)
elif cmd.startswith('emperor '):
if not current_session_id:
print(" ❌ 没有活跃会话,请先创建!")
continue
msg = cmd[len('emperor '):].strip()
advance_discussion(current_session_id, user_message=msg)
elif cmd.startswith('decree '):
if not current_session_id:
print(" ❌ 没有活跃会话,请先创建!")
continue
msg = cmd[len('decree '):].strip()
advance_discussion(current_session_id, decree=msg)
elif cmd == 'fate':
event = get_fate_event()
if event and current_session_id:
if input(" 是否将此事件加入讨论?(y/n): ").strip().lower() == 'y':
advance_discussion(current_session_id, decree=f"【命运骰子】{event}")
elif cmd == 'session':
if not current_session_id:
print(" ❌ 没有活跃会话!")
continue
get_session(current_session_id)
elif cmd == 'list':
sessions = list_sessions()
if sessions and not current_session_id:
choice = input(" 选择会话(输入ID: ").strip()
if choice:
current_session_id = choice
elif cmd == 'conclude':
if not current_session_id:
print(" ❌ 没有活跃会话!")
continue
if conclude_session(current_session_id):
current_session_id = None
elif cmd == 'demo':
demo_full_flow()
elif cmd == 'clear':
import os
os.system('clear' if os.name == 'posix' else 'cls')
elif cmd == 'quit' or cmd == 'exit':
print("\n 👋 再见!")
break
elif cmd:
print(f" ❌ 未知命令: {cmd}")
except KeyboardInterrupt:
print("\n\n 👋 再见!")
break
except Exception as e:
print(f" ❌ 错误: {e}")
if __name__ == '__main__':
import sys
if len(sys.argv) > 1 and sys.argv[1] == 'demo':
demo_full_flow()
else:
interactive_mode()