Talegorithm hai 21 horas
pai
achega
7a951bd2c4

+ 0 - 67
examples/research/config.py

@@ -1,67 +0,0 @@
-"""
-项目配置
-
-定义项目的运行配置。
-"""
-
-from agent.core.runner import KnowledgeConfig, RunConfig
-
-
-# ===== Agent 运行配置 =====
-
-RUN_CONFIG = RunConfig(
-    # 模型配置
-    model="qwen3.5-plus",
-    temperature=0.3,
-    max_iterations=1000,
-
-    # 启用 thinking 模式
-    extra_llm_params={"extra_body": {"enable_thinking": True}},
-
-    # 主 Agent 预设(对应 presets.json 中的 "main")
-    agent_type="main",
-
-    # 任务名称
-    name="调研",
-
-    # 知识管理配置
-    knowledge=KnowledgeConfig(
-        # 压缩时提取(消息量超阈值触发压缩时,用完整 history 反思)
-        enable_extraction=False,
-        reflect_prompt="",  # 自定义反思 prompt;空则使用默认,见 agent/core/prompts/knowledge.py:REFLECT_PROMPT
-
-        # agent运行完成后提取(不代表任务完成,agent 可能中途退出等待人工评估)
-        enable_completion_extraction=False,
-        completion_reflect_prompt="",  # 自定义复盘 prompt;空则使用默认,见 agent/core/prompts/knowledge.py:COMPLETION_REFLECT_PROMPT
-
-        # 知识注入(agent切换当前工作的goal时,自动注入相关知识)
-        enable_injection=False,
-
-        # 默认字段(保存/搜索时自动注入)
-        owner="sunlit.howard@gmail.com",  # 所有者(空则尝试从 git config user.email 获取,再空则用 agent:{agent_id})
-        default_tags={"project": "research", "domain": "ai_agent"},  # 默认 tags(会与工具调用参数合并)
-        default_scopes=["org:cybertogether"],  # 默认 scopes
-        default_search_types=["strategy"],  # 默认搜索类型过滤
-        default_search_owner="sunlit.howard@gmail.com"  # 默认搜索 owner 过滤(空则不过滤)
-    )
-)
-
-
-# ===== 任务配置 =====
-
-# INPUT_DIR = "examples/research/huahua"       # 输入素材目录
-# OUTPUT_DIR = "examples/research/outputs/huahua_3"                   # 输出目录 ID,输出保存在 examples/plan/outputs/{OUTPUT_DIR}/
-
-
-# ===== 基础设施配置 =====
-
-SKILLS_DIR = "./skills"
-TRACE_STORE_PATH = ".trace"
-DEBUG = True
-LOG_LEVEL = "INFO"
-LOG_FILE = None  # 设置为文件路径可以同时输出到文件
-
-# ===== 浏览器配置 =====
-# 可选值: "cloud" (云浏览器) 或 "local" (本地浏览器) 或 "container" (容器浏览器,支持预配置账户)
-BROWSER_TYPE = "local"
-HEADLESS = False

+ 0 - 14
examples/research/presets.json

@@ -1,14 +0,0 @@
-{
-  "main": {
-    "max_iterations": 1000,
-    "skills": ["planning"],
-    "description": "主 Agent - 调研任务管理与协调"
-  },
-  "research": {
-    "system_prompt_file": "research.prompt",
-    "max_iterations": 200,
-    "temperature": 0.3,
-    "skills": ["planning", "research", "browser"],
-    "description": "调研 Agent - 根据指令搜索策略、工具、方法论等信息"
-  }
-}

+ 0 - 42
examples/research/requirement.prompt

@@ -1,42 +0,0 @@
----
-model: qwen3.5-plus
-temperature: 0.3
----
-
-$system$
-
-## 角色
-你是有空杯心态的搜索调研专家。
-
-## 工作流程
-
-### 第一步:分析梳理调研需求
-根据制作需求,判断需要调研哪些方向的信息。
-
-### 第二步:循环迭代地向调研agent提问、评估调研结果、更新调研计划
-1. **提问**:向 subagent 提出调研问题
-   - MUST 调用工具 `agent(task="string - 一句话描述调研需求", agent_type="research")`
-   - **严格禁止**在启动调研时在 task 中预设猜想的具体示例
-2. **评估**:subagent 返回后(可能是阶段性结果),读取调研结果并评估:
-   - **相关性**:找到的内容是不是我要的方向?
-   - **可靠性**:找到的信息是否经过交叉验证?是否是可靠信源?是否很可能是广告营销软文?
-   - **时效性**:找到的信息是不是过时了?(AI行业迭代很快,6个月前的信息都大概率过时了)
-   - **信息完整性**:找到的信息是否足够支撑后续选择?(信息够不够)
-3. **追问或结束**:
-   - 结论为"需补充"→ 用 `continue_from` 调用同一个 subagent,**在 task 中明确告知**:
-     - 还缺什么:缺少哪些必需/建议信息,或需要补充哪些方向的调研
-     - 建议搜索方向:给出具体的搜索建议(如"搜索XXX的用户评价")
-   - 结论为"通过"→ 进入下一个问题或结束调研
-4. **基于最新信息思考**:
-   - 最新信息是否带来了新的思路?
-   - 是否需要更新原来的调研需求分析、提出新的调研问题?
-5. **创建或更新调研计划**
-   - 根据最新信息,撰写或更新调研思路(路径:%output_dir%/research_thinking.md")
-循环1-5的步骤,直到你对获取到的信息感到充分和满意。预期每个调研方向会经历 2-3 轮追问。
-
-### 第四步:输出调研报告
-综合所有调研思路和调研结果,确定最终的调研报告。
-
-**输出**:`%output_dir%/research.md`
-
-$user$

+ 0 - 68
examples/research/research.prompt

@@ -1,68 +0,0 @@
----
-model: sonnet-4.6
-temperature: 0.3
----
-
-$system$
-## 角色
-你是一个调研专家,负责根据指令搜索、反思并如实记录调研发现。
-
-## 执行流程
-
-### 第一步:理解调研目标
-
-### 第二步:执行搜索
-
-**搜索优先级**:
-1. **知识库优先**:用 `knowledge_search` 按需求关键词搜索,查看已有策略经验、工具评估、工作流总结
-2. **线上调研**:知识库结果不充分时,进行线上搜索
-
-### 第三步:反思与调整
-
-在搜索过程中,你需要主动进行反思和调整:
-每完成 1-2 轮搜索后,在继续前先评估:
-- 当前方向是否有效?是否偏离需求?
-- 结果质量如何?下一轮应该调整 query 还是换角度?
-- 可选调用 `reflect` 工具辅助判断
-根据反思结果调整后续搜索策略,直到你认为信息充分或遇到明确的阻塞。
-
-### 第四步:结束与输出
-
-**何时结束**:
-- 信息已充分覆盖调研目标
-- 搜索结果开始重复,无新信息
-- 方向不明确,需要用户指导
-
-**如何结束**:
-输出一条纯文本消息(不带 tool_call),概括:发现了什么、还缺什么
-
-
-## 输出格式
-
-**Schema**:
-
-```jsonschema
-{
-  "搜索主题": "string — 本次搜索主题",
-  "搜索轨迹": "string — 搜索过程:尝试了哪些 query、如何调整方向等",
-  "调研发现": [
-    {
-      "名称": "string — 发现项名称",
-      "来源": ["string — 来源(knowledge_id / URL / 帖子链接)", ...],
-      "核心描述": "string — 核心思路或能力描述",
-      "具体信息": {
-        ...(这部分要根据具体调研问题和发现,自行设计汇报格式)
-      },
-      "外部评价": {
-        "专家或KOL推荐": ["string — 来源 + 评价摘要"],
-        "社区反馈": ["string — 来源 + 反馈摘要"],
-        "热度指标": "string — 提及次数、榜单排名、帖子热度等"
-      }
-    }
-  ]
-}
-```
-
-## 注意事项
-- `search_posts` 不好用时改用 `browser-use`
-- 如果调研过程中遇到不确定的问题,要停下来询问用户

+ 0 - 378
examples/research/run.py

@@ -1,378 +0,0 @@
-"""
-示例(简化版 - 使用框架交互功能)
-
-使用 Agent 模式 + Skills + 框架交互控制器
-
-新功能:
-1. 使用框架提供的 InteractiveController
-2. 使用配置文件管理运行参数
-3. 支持命令行随时打断(输入 'p' 暂停,'q' 退出)
-4. 暂停后可插入干预消息
-5. 支持触发经验总结
-6. 查看当前 GoalTree
-7. 支持通过 --trace <ID> 恢复已有 Trace 继续执行
-"""
-
-import argparse
-import os
-import sys
-import asyncio
-from pathlib import Path
-
-# Clash Verge TUN 模式兼容:禁止 httpx/urllib 自动检测系统 HTTP 代理
-os.environ.setdefault("no_proxy", "*")
-
-# 添加项目根目录到 Python 路径
-sys.path.insert(0, str(Path(__file__).parent.parent.parent))
-
-from dotenv import load_dotenv
-load_dotenv()
-
-from agent.llm.prompts import SimplePrompt
-from agent.core.runner import AgentRunner, RunConfig
-from agent.trace import (
-    FileSystemTraceStore,
-    Trace,
-    Message,
-)
-from agent.llm import create_qwen_llm_call
-from agent.cli import InteractiveController
-from agent.utils import setup_logging
-from agent.tools.builtin.browser.baseClass import init_browser_session, kill_browser_session
-
-# 导入自定义工具(触发 @tool 注册)
-from tools.reflect import reflect
-
-# 导入项目配置
-from config import RUN_CONFIG, SKILLS_DIR, TRACE_STORE_PATH, DEBUG, LOG_LEVEL, LOG_FILE, BROWSER_TYPE, HEADLESS, INPUT_DIR, OUTPUT_DIR
-
-
-async def main():
-    # 解析命令行参数
-    parser = argparse.ArgumentParser(description="任务 (Agent 模式 + 交互增强)")
-    parser.add_argument(
-        "--trace", type=str, default=None,
-        help="已有的 Trace ID,用于恢复继续执行(不指定则新建)",
-    )
-    args = parser.parse_args()
-
-    # 路径配置
-    base_dir = Path(__file__).parent
-    project_root = base_dir.parent.parent
-    prompt_path = base_dir / "requirement.prompt"
-    output_dir = project_root / OUTPUT_DIR
-    output_dir.mkdir(parents=True, exist_ok=True)
-
-    # 1. 配置日志
-    setup_logging(level=LOG_LEVEL, file=LOG_FILE)
-
-    # 2. 加载项目级 presets
-    print("2. 加载 presets...")
-    presets_path = base_dir / "presets.json"
-    if presets_path.exists():
-        from agent.core.presets import load_presets_from_json
-        load_presets_from_json(str(presets_path))
-        print(f"   - 已加载项目 presets")
-    else:
-        print(f"   - 未找到 presets.json,跳过")
-
-    # 3. 加载 prompt
-    print("3. 加载 prompt...")
-    prompt = SimplePrompt(prompt_path)
-
-    # 4. 构建任务消息
-    print("4. 构建任务消息...")
-    print(f"   - 输入目录: {INPUT_DIR}")
-    print(f"   - 输出 ID: {OUTPUT_DIR}")
-    messages = prompt.build_messages(input_dir=INPUT_DIR, output_dir=OUTPUT_DIR)
-
-    # 5. 初始化浏览器
-    browser_mode_names = {"cloud": "云浏览器", "local": "本地浏览器", "container": "容器浏览器"}
-    browser_mode_name = browser_mode_names.get(BROWSER_TYPE, BROWSER_TYPE)
-    print(f"5. 正在初始化{browser_mode_name}...")
-    await init_browser_session(
-        browser_type=BROWSER_TYPE,
-        headless=HEADLESS,
-        url="https://www.google.com/",
-        profile_name=""
-    )
-    print(f"   ✅ {browser_mode_name}初始化完成\n")
-
-    # 6. 创建 Agent Runner
-    print("6. 创建 Agent Runner...")
-    print(f"   - Skills 目录: {SKILLS_DIR}")
-
-    # 从 prompt 的 frontmatter 中提取模型配置(优先于 config.py)
-    prompt_model = prompt.config.get("model", None)
-    if prompt_model:
-        model_for_llm = prompt_model
-        print(f"   - 模型 (from prompt): {model_for_llm}")
-    else:
-        model_for_llm = RUN_CONFIG.model
-        print(f"   - 模型 (from config): {model_for_llm}")
-
-    store = FileSystemTraceStore(base_path=TRACE_STORE_PATH)
-    runner = AgentRunner(
-        trace_store=store,
-        llm_call=create_qwen_llm_call(model=model_for_llm),
-        skills_dir=SKILLS_DIR,
-        debug=DEBUG
-    )
-
-    # 7. 创建交互控制器
-    interactive = InteractiveController(
-        runner=runner,
-        store=store,
-        enable_stdin_check=True
-    )
-    # 将 stdin 检查回调注入 runner,供子 agent 执行期间使用
-    runner.stdin_check = interactive.check_stdin
-
-    # 8. 任务信息
-    task_name = RUN_CONFIG.name or base_dir.name
-    print("=" * 60)
-    print(f"{task_name}")
-    print("=" * 60)
-    print("💡 交互提示:")
-    print("   - 执行过程中输入 'p' 或 'pause' 暂停并进入交互模式")
-    print("   - 执行过程中输入 'q' 或 'quit' 停止执行")
-    print("=" * 60)
-    print()
-
-    # 9. 判断是新建还是恢复
-    resume_trace_id = args.trace
-    if resume_trace_id:
-        existing_trace = await store.get_trace(resume_trace_id)
-        if not existing_trace:
-            print(f"\n错误: Trace 不存在: {resume_trace_id}")
-            sys.exit(1)
-        print(f"恢复已有 Trace: {resume_trace_id[:8]}...")
-        print(f"   - 状态: {existing_trace.status}")
-        print(f"   - 消息数: {existing_trace.total_messages}")
-        print(f"\n💡 提示:恢复 Trace 时会先进入交互菜单,您可以选择从指定消息续跑")
-    else:
-        print(f"启动新 Agent...")
-
-    print()
-
-    final_response = ""
-    current_trace_id = resume_trace_id
-    current_sequence = 0
-    should_exit = False
-
-    try:
-        # 配置
-        run_config = RUN_CONFIG
-        if resume_trace_id:
-            initial_messages = None
-            run_config.trace_id = resume_trace_id
-        else:
-            initial_messages = messages
-            run_config.name = f"{task_name}:调研任务"
-
-        while not should_exit:
-            if current_trace_id:
-                run_config.trace_id = current_trace_id
-
-            final_response = ""
-
-            # 如果是恢复 trace 或 trace 已完成/失败且没有新消息,进入交互菜单
-            if current_trace_id and initial_messages is None:
-                check_trace = await store.get_trace(current_trace_id)
-                if check_trace:
-                    # 显示 trace 状态
-                    if check_trace.status == "completed":
-                        print(f"\n[Trace] ✅ 已完成")
-                        print(f"  - Total messages: {check_trace.total_messages}")
-                        print(f"  - Total cost: ${check_trace.total_cost:.4f}")
-                    elif check_trace.status == "failed":
-                        print(f"\n[Trace] ❌ 已失败: {check_trace.error_message}")
-                    elif check_trace.status == "stopped":
-                        print(f"\n[Trace] ⏸️ 已停止")
-                        print(f"  - Total messages: {check_trace.total_messages}")
-                    else:
-                        print(f"\n[Trace] 📊 状态: {check_trace.status}")
-                        print(f"  - Total messages: {check_trace.total_messages}")
-
-                    current_sequence = check_trace.head_sequence
-
-                    menu_result = await interactive.show_menu(current_trace_id, current_sequence)
-
-                    if menu_result["action"] == "stop":
-                        break
-                    elif menu_result["action"] == "continue":
-                        new_messages = menu_result.get("messages", [])
-                        if new_messages:
-                            initial_messages = new_messages
-                            run_config.after_sequence = menu_result.get("after_sequence")
-                        else:
-                            initial_messages = []
-                            run_config.after_sequence = None
-                        continue
-                    break
-
-            # 如果没有进入菜单(新建 trace),设置初始消息
-            if initial_messages is None:
-                initial_messages = []
-
-            print(f"{'▶️ 开始执行...' if not current_trace_id else '▶️ 继续执行...'}")
-
-            # 执行 Agent
-            paused = False
-            try:
-                async for item in runner.run(messages=initial_messages, config=run_config):
-                    # 检查用户中断
-                    cmd = interactive.check_stdin()
-                    if cmd == 'pause':
-                        print("\n⏸️ 正在暂停执行...")
-                        if current_trace_id:
-                            await runner.stop(current_trace_id)
-                        await asyncio.sleep(0.5)
-
-                        menu_result = await interactive.show_menu(current_trace_id, current_sequence)
-
-                        if menu_result["action"] == "stop":
-                            should_exit = True
-                            paused = True
-                            break
-                        elif menu_result["action"] == "continue":
-                            new_messages = menu_result.get("messages", [])
-                            if new_messages:
-                                initial_messages = new_messages
-                                after_seq = menu_result.get("after_sequence")
-                                if after_seq is not None:
-                                    run_config.after_sequence = after_seq
-                                paused = True
-                                break
-                            else:
-                                initial_messages = []
-                                run_config.after_sequence = None
-                                paused = True
-                                break
-
-                    elif cmd == 'quit':
-                        print("\n🛑 用户请求停止...")
-                        if current_trace_id:
-                            await runner.stop(current_trace_id)
-                        should_exit = True
-                        break
-
-                    # 处理 Trace 对象
-                    if isinstance(item, Trace):
-                        current_trace_id = item.trace_id
-                        if item.status == "running":
-                            print(f"[Trace] 开始: {item.trace_id[:8]}...")
-                        elif item.status == "completed":
-                            print(f"\n[Trace] ✅ 完成")
-                            print(f"  - Total messages: {item.total_messages}")
-                            print(f"  - Total cost: ${item.total_cost:.4f}")
-                        elif item.status == "failed":
-                            print(f"\n[Trace] ❌ 失败: {item.error_message}")
-                        elif item.status == "stopped":
-                            print(f"\n[Trace] ⏸️ 已停止")
-
-                    # 处理 Message 对象
-                    elif isinstance(item, Message):
-                        current_sequence = item.sequence
-
-                        if item.role == "assistant":
-                            content = item.content
-                            if isinstance(content, dict):
-                                text = content.get("text", "")
-                                tool_calls = content.get("tool_calls")
-
-                                if text and not tool_calls:
-                                    final_response = text
-                                    print(f"\n[Response] Agent 回复:")
-                                    print(text)
-                                elif text:
-                                    preview = text[:150] + "..." if len(text) > 150 else text
-                                    print(f"[Assistant] {preview}")
-
-                        elif item.role == "tool":
-                            content = item.content
-                            tool_name = "unknown"
-                            if isinstance(content, dict):
-                                tool_name = content.get("tool_name", "unknown")
-
-                            if item.description and item.description != tool_name:
-                                desc = item.description[:80] if len(item.description) > 80 else item.description
-                                print(f"[Tool Result] ✅ {tool_name}: {desc}...")
-                            else:
-                                print(f"[Tool Result] ✅ {tool_name}")
-
-            except Exception as e:
-                print(f"\n执行出错: {e}")
-                import traceback
-                traceback.print_exc()
-
-            if paused:
-                if should_exit:
-                    break
-                continue
-
-            if should_exit:
-                break
-
-            # Runner 退出后显示交互菜单
-            if current_trace_id:
-                menu_result = await interactive.show_menu(current_trace_id, current_sequence)
-
-                if menu_result["action"] == "stop":
-                    break
-                elif menu_result["action"] == "continue":
-                    new_messages = menu_result.get("messages", [])
-                    if new_messages:
-                        initial_messages = new_messages
-                        run_config.after_sequence = menu_result.get("after_sequence")
-                    else:
-                        initial_messages = []
-                        run_config.after_sequence = None
-                    continue
-            break
-
-    except KeyboardInterrupt:
-        print("\n\n用户中断 (Ctrl+C)")
-        if current_trace_id:
-            await runner.stop(current_trace_id)
-    finally:
-        # 清理浏览器会话
-        try:
-            await kill_browser_session()
-        except Exception:
-            pass
-
-    # 7. 输出结果
-    if final_response:
-        print()
-        print("=" * 60)
-        print("Agent 响应:")
-        print("=" * 60)
-        print(final_response)
-        print("=" * 60)
-        print()
-
-        output_file = output_dir / "result.txt"
-        with open(output_file, 'w', encoding='utf-8') as f:
-            f.write(final_response)
-
-        print(f"✓ 结果已保存到: {output_file}")
-        print()
-
-    # 可视化提示
-    if current_trace_id:
-        print("=" * 60)
-        print("可视化 Step Tree:")
-        print("=" * 60)
-        print("1. 启动 API Server:")
-        print("   python3 api_server.py")
-        print()
-        print("2. 浏览器访问:")
-        print("   http://localhost:8000/api/traces")
-        print()
-        print(f"3. Trace ID: {current_trace_id}")
-        print("=" * 60)
-
-
-if __name__ == "__main__":
-    asyncio.run(main())

+ 0 - 139
examples/research/tools/reflect.py

@@ -1,139 +0,0 @@
-"""
-reflect 工具 — 轻量反思
-
-用普通模型快速评估当前搜索结果,输出简短思路和下一步建议。
-继承调用者的完整对话历史作为上下文。
-"""
-
-import logging
-import os
-from typing import Any, Dict, List, Optional
-
-from agent.llm.qwen import qwen_llm_call
-from agent.tools import tool
-from agent.tools.models import ToolContext, ToolResult
-
-
-logger = logging.getLogger(__name__)
-
-# 反思模型配置(普通模式,非 thinking)
-REFLECT_MODEL = os.getenv("REFLECT_MODEL", "qwen-plus")
-
-REFLECT_SYSTEM_PROMPT = """你是调研助手。根据对话历史和当前搜索结果,简要回答:
-1. 本轮搜到了什么有价值的信息?缺了什么?
-2. 下一轮搜什么?给出 1-3 个具体 query 词
-3. 是否需要换搜索渠道或角度?
-
-要求:直接输出思路,不要分析框架,不要长篇大论。3-5 句话即可。"""
-
-REFLECT_USER_TEMPLATE = """需求:{question}
-
-本轮搜索结果:
-{findings}
-
-简要反思,给出下一步 query。"""
-
-
-async def _fetch_caller_history(context: Optional[Dict[str, Any]]) -> List[Dict]:
-    """从 context 中获取调用者的历史消息队列"""
-    if not context:
-        return []
-
-    store = context.get("store")
-    trace_id = context.get("trace_id")
-    if not store or not trace_id:
-        return []
-
-    try:
-        trace = await store.get_trace(trace_id)
-        if not trace:
-            return []
-
-        messages = await store.get_main_path_messages(
-            trace_id, trace.head_sequence
-        )
-
-        # 转为 LLM 消息格式
-        history = []
-        for msg in messages:
-            llm_dict = msg.to_llm_dict()
-            if llm_dict:
-                history.append(llm_dict)
-
-        logger.info(f"reflect: 获取到 {len(history)} 条历史消息")
-        return history
-
-    except Exception as e:
-        logger.warning(f"reflect: 获取历史消息失败: {e}")
-        return []
-
-
-@tool(
-    description="轻量反思:快速评估本轮搜索结果,输出简短思路和下一步 query 建议",
-    hidden_params=["context"],
-)
-async def reflect(
-    question: str,
-    findings: str,
-    context: Optional[ToolContext] = None,
-) -> ToolResult:
-    """
-    对本轮搜索结果进行轻量反思,给出下一步搜索思路。
-
-    Args:
-        question: 原始调研问题/需求描述
-        findings: 本轮搜索结果摘要
-    """
-    # 获取调用者的历史消息
-    # context 可能是 ToolContextImpl(有 .context 属性)或直接是 dict
-    if context is None:
-        caller_context = None
-    elif isinstance(context, dict):
-        caller_context = context
-    else:
-        caller_context = getattr(context, 'context', None)
-    caller_history = await _fetch_caller_history(caller_context)
-
-    # 构建消息:system + 调用者历史 + 反思请求
-    messages = [{"role": "system", "content": REFLECT_SYSTEM_PROMPT}]
-
-    if caller_history:
-        messages.extend(caller_history)
-
-    messages.append({
-        "role": "user",
-        "content": REFLECT_USER_TEMPLATE.format(
-            question=question,
-            findings=findings,
-        ),
-    })
-
-    try:
-        result = await qwen_llm_call(
-            messages=messages,
-            model=REFLECT_MODEL,
-            temperature=0.2,
-        )
-
-        content = result["content"]
-        msg_count = len(caller_history)
-        cost = result.get("cost", 0.0)
-        reasoning_tokens = result.get("reasoning_tokens", 0)
-
-        return ToolResult(
-            title=f"反思完成 (model: {REFLECT_MODEL}, 继承 {msg_count} 条历史)",
-            output=content,
-            tool_usage={
-                "model": REFLECT_MODEL,
-                "prompt_tokens": result.get("prompt_tokens", 0),
-                "completion_tokens": result.get("completion_tokens", 0),
-                "reasoning_tokens": reasoning_tokens,
-                "cost": cost,
-            },
-        )
-
-    except Exception as e:
-        return ToolResult(
-            title="reflect 失败",
-            output=f"调用反思模型出错: {str(e)}",
-        )