Просмотр исходного кода

refactor: improve project structure

Talegorithm 3 недель назад
Родитель
Сommit
d662097715
52 измененных файлов с 755 добавлено и 3324 удалено
  1. 2 1
      .claude/settings.local.json
  2. 17 7
      agent/__init__.py
  3. 0 51
      agent/core/README.md
  4. 7 2
      agent/core/__init__.py
  5. 0 26
      agent/core/config.py
  6. 60 0
      agent/core/presets.py
  7. 26 6
      agent/core/runner.py
  8. 0 70
      agent/execution/__init__.py
  9. 0 26
      agent/goal/__init__.py
  10. 0 91
      agent/memory/README.md
  11. 0 0
      agent/memory/skills/core.md
  12. 0 137
      agent/subagents/default.json
  13. 0 94
      agent/tools/README.md
  14. 10 7
      agent/tools/builtin/__init__.py
  15. 18 2
      agent/tools/builtin/browser/baseClass.py
  16. 19 0
      agent/tools/builtin/file/__init__.py
  17. 0 0
      agent/tools/builtin/file/edit.py
  18. 0 0
      agent/tools/builtin/file/glob.py
  19. 0 0
      agent/tools/builtin/file/grep.py
  20. 0 0
      agent/tools/builtin/file/read.py
  21. 0 0
      agent/tools/builtin/file/write.py
  22. 0 75
      agent/tools/builtin/goal.py
  23. 2 2
      agent/tools/builtin/skill.py
  24. 38 0
      agent/trace/__init__.py
  25. 1 1
      agent/trace/api.py
  26. 1 1
      agent/trace/compaction.py
  27. 3 3
      agent/trace/delegate.py
  28. 3 3
      agent/trace/explore.py
  29. 0 0
      agent/trace/goal_models.py
  30. 74 2
      agent/trace/goal_tool.py
  31. 0 0
      agent/trace/models.py
  32. 2 2
      agent/trace/protocols.py
  33. 2 2
      agent/trace/store.py
  34. 0 0
      agent/trace/trace_id.py
  35. 1 1
      agent/trace/tree_dump.py
  36. 1 1
      agent/trace/websocket.py
  37. 3 3
      api_server.py
  38. 418 406
      docs/README.md
  39. 0 306
      docs/REFACTOR_SUMMARY.md
  40. 0 618
      docs/cloud_browser_guide.md
  41. 44 0
      docs/decisions.md
  42. 0 215
      docs/dependencies.md
  43. 0 129
      docs/project-structure.md
  44. 0 0
      docs/ref/context-comparison.md
  45. 0 174
      docs/refactor-plan.md
  46. 0 241
      docs/sub-agents.md
  47. 0 109
      docs/testing.md
  48. 0 232
      docs/tools-adapters.md
  49. 1 1
      examples/feature_extract/run.py
  50. 1 1
      examples/research/run.py
  51. 0 276
      examples/test_plan.py
  52. 1 0
      vendor/browser-use

+ 2 - 1
.claude/settings.local.json

@@ -10,7 +10,8 @@
       "Bash(pip install:*)",
       "Bash(timeout 60 python:*)",
       "Bash(timeout 240 python:*)",
-      "Bash(curl:*)"
+      "Bash(curl:*)",
+      "Bash(tree:*)"
     ],
     "deny": [],
     "ask": []

+ 17 - 7
agent/__init__.py

@@ -4,19 +4,21 @@ Reson Agent - 模块化、可扩展的 Agent 框架
 核心导出:
 - AgentRunner: Agent 执行引擎
 - AgentConfig: Agent 配置
-- Trace, Step: 执行追踪
+- Trace, Message, Goal: 执行追踪
 - Experience, Skill: 记忆模型
 - tool: 工具装饰器
 - TraceStore, MemoryStore: 存储接口
 """
 
 # 核心引擎
-from agent.core.runner import AgentRunner
-from agent.core.config import AgentConfig, CallResult
+from agent.core.runner import AgentRunner, AgentConfig, CallResult
+from agent.core.presets import AgentPreset, AGENT_PRESETS, get_preset
 
 # 执行追踪
-from agent.execution.models import Trace, Step, StepType, StepStatus
-from agent.execution.protocols import TraceStore
+from agent.trace.models import Trace, Message, Step, StepType, StepStatus
+from agent.trace.goal_models import Goal, GoalTree, GoalStatus
+from agent.trace.protocols import TraceStore
+from agent.trace.store import FileSystemTraceStore
 
 # 记忆系统
 from agent.memory.models import Experience, Skill
@@ -27,19 +29,27 @@ from agent.memory.stores import MemoryMemoryStore, MemoryStateStore
 from agent.tools import tool, ToolRegistry, get_tool_registry
 from agent.tools.models import ToolResult, ToolContext
 
-__version__ = "0.2.0"
+__version__ = "0.3.0"
 
 __all__ = [
     # Core
     "AgentRunner",
     "AgentConfig",
     "CallResult",
-    # Execution
+    "AgentPreset",
+    "AGENT_PRESETS",
+    "get_preset",
+    # Trace
     "Trace",
+    "Message",
     "Step",
     "StepType",
     "StepStatus",
+    "Goal",
+    "GoalTree",
+    "GoalStatus",
     "TraceStore",
+    "FileSystemTraceStore",
     # Memory
     "Experience",
     "Skill",

+ 0 - 51
agent/core/README.md

@@ -1,51 +0,0 @@
-# Agent Core - 核心引擎模块
-
-## 职责
-
-核心引擎是框架的"心脏",负责:
-
-1. **Agent 主循环逻辑** (`runner.py`)
-   - 单次调用模式:`call()` - 简单的 LLM 调用
-   - Agent 模式:`run()` - 循环执行 + 记忆 + 工具调用
-
-2. **配置数据类** (`config.py`)
-   - `AgentConfig` - Agent 配置参数
-   - `CallResult` - 单次调用返回结果
-
-3. **事件定义** (`events.py`)
-   - `AgentEvent` - Agent 事件数据结构
-   - `AgentEventType` - 事件类型枚举
-
-## 特点
-
-- **最小依赖**:核心模块只依赖 execution, memory, tools
-- **最稳定**:核心 API 变更频率最低
-- **可扩展**:通过插件化的 tools, execution, memory 扩展功能
-
-## 使用示例
-
-```python
-from agent.core import AgentRunner, AgentConfig
-
-# 创建 Runner
-runner = AgentRunner(
-    llm_call=my_llm_function,
-    config=AgentConfig(max_iterations=10)
-)
-
-# 单次调用
-result = await runner.call(
-    messages=[{"role": "user", "content": "Hello"}]
-)
-
-# Agent 模式
-async for event in runner.run(task="Complete this task"):
-    print(event)
-```
-
-## 文件说明
-
-- `runner.py` - AgentRunner 类,核心执行逻辑
-- `config.py` - 配置类定义
-- `events.py` - 事件系统
-- `__init__.py` - 模块导出

+ 7 - 2
agent/core/__init__.py

@@ -4,14 +4,19 @@ Agent Core - 核心引擎模块
 职责:
 1. Agent 主循环逻辑(call() 和 run())
 2. 配置数据类(AgentConfig, CallResult)
+3. Agent 预设(AgentPreset)
 """
 
-from agent.core.runner import AgentRunner, BUILTIN_TOOLS
-from agent.core.config import AgentConfig, CallResult
+from agent.core.runner import AgentRunner, BUILTIN_TOOLS, AgentConfig, CallResult
+from agent.core.presets import AgentPreset, AGENT_PRESETS, get_preset, register_preset
 
 __all__ = [
     "AgentRunner",
     "BUILTIN_TOOLS",
     "AgentConfig",
     "CallResult",
+    "AgentPreset",
+    "AGENT_PRESETS",
+    "get_preset",
+    "register_preset",
 ]

+ 0 - 26
agent/core/config.py

@@ -1,26 +0,0 @@
-"""
-Agent 配置类
-"""
-
-from dataclasses import dataclass
-from typing import Optional, List, Dict
-
-
-@dataclass
-class AgentConfig:
-    """Agent 配置"""
-    agent_type: str = "default"
-    max_iterations: int = 10
-    enable_memory: bool = True
-    auto_execute_tools: bool = True
-
-
-@dataclass
-class CallResult:
-    """单次调用结果"""
-    reply: str
-    tool_calls: Optional[List[Dict]] = None
-    trace_id: Optional[str] = None
-    step_id: Optional[str] = None
-    tokens: Optional[Dict[str, int]] = None
-    cost: float = 0.0

+ 60 - 0
agent/core/presets.py

@@ -0,0 +1,60 @@
+"""
+Agent Presets - Agent 类型预设配置
+
+定义不同类型 Agent 的工具权限和运行参数。
+用户可通过 .agent/presets.json 覆盖或添加预设。
+"""
+
+from dataclasses import dataclass, field
+from typing import Optional, List
+
+
+@dataclass
+class AgentPreset:
+    """Agent 预设配置"""
+
+    # 工具权限
+    allowed_tools: Optional[List[str]] = None  # None 表示允许全部
+    denied_tools: Optional[List[str]] = None   # 黑名单
+
+    # 运行参数
+    max_iterations: int = 30
+    temperature: Optional[float] = None
+
+    # 描述
+    description: Optional[str] = None
+
+
+# 内置预设
+AGENT_PRESETS = {
+    "default": AgentPreset(
+        allowed_tools=None,
+        max_iterations=30,
+        description="默认 Agent,拥有全部工具权限",
+    ),
+    "explore": AgentPreset(
+        allowed_tools=["read", "glob", "grep", "list_files"],
+        denied_tools=["write", "edit", "bash", "task"],
+        max_iterations=15,
+        description="探索型 Agent,只读权限,用于代码分析",
+    ),
+    "analyst": AgentPreset(
+        allowed_tools=["read", "glob", "grep", "web_search", "webfetch"],
+        denied_tools=["write", "edit", "bash", "task"],
+        temperature=0.3,
+        max_iterations=25,
+        description="分析型 Agent,用于深度分析和研究",
+    ),
+}
+
+
+def get_preset(name: str) -> AgentPreset:
+    """获取预设配置"""
+    if name not in AGENT_PRESETS:
+        raise ValueError(f"Unknown preset: {name}. Available: {list(AGENT_PRESETS.keys())}")
+    return AGENT_PRESETS[name]
+
+
+def register_preset(name: str, preset: AgentPreset) -> None:
+    """注册自定义预设"""
+    AGENT_PRESETS[name] = preset

+ 26 - 6
agent/core/runner.py

@@ -10,14 +10,14 @@ Agent Runner - Agent 执行引擎
 """
 
 import logging
+from dataclasses import dataclass
 from datetime import datetime
 from typing import AsyncIterator, Optional, Dict, Any, List, Callable, Literal, Union
 
-from agent.core.config import AgentConfig, CallResult
-from agent.execution.models import Trace, Message
-from agent.execution.protocols import TraceStore
-from agent.goal.models import GoalTree
-from agent.goal.tool import goal_tool
+from agent.trace.models import Trace, Message
+from agent.trace.protocols import TraceStore
+from agent.trace.goal_models import GoalTree
+from agent.trace.goal_tool import goal_tool
 from agent.memory.models import Experience, Skill
 from agent.memory.protocols import MemoryStore, StateStore
 from agent.memory.skill_loader import load_skills_from_dir
@@ -26,6 +26,26 @@ from agent.tools import ToolRegistry, get_tool_registry
 logger = logging.getLogger(__name__)
 
 
+@dataclass
+class AgentConfig:
+    """Agent 配置"""
+    agent_type: str = "default"
+    max_iterations: int = 10
+    enable_memory: bool = True
+    auto_execute_tools: bool = True
+
+
+@dataclass
+class CallResult:
+    """单次调用结果"""
+    reply: str
+    tool_calls: Optional[List[Dict]] = None
+    trace_id: Optional[str] = None
+    step_id: Optional[str] = None
+    tokens: Optional[Dict[str, int]] = None
+    cost: float = 0.0
+
+
 # 内置工具列表(始终自动加载)
 BUILTIN_TOOLS = [
     # 文件操作工具
@@ -370,7 +390,7 @@ class AgentRunner:
                 goal_tree = await self.trace_store.get_goal_tree(trace_id)
 
                 # 设置 goal_tree 到 goal 工具(供 LLM 调用)
-                from agent.tools.builtin.goal import set_goal_tree
+                from agent.trace.goal_tool import set_goal_tree
                 set_goal_tree(goal_tree)
 
             # 执行循环

+ 0 - 70
agent/execution/__init__.py

@@ -1,70 +0,0 @@
-"""
-Execution - 执行追踪系统
-
-核心职责:
-1. Trace/Message 模型定义(新架构)
-2. 存储接口和实现(文件系统)
-3. GoalTree 集成(计划管理)
-4. RESTful API(可视化查询)
-5. WebSocket 推送(实时更新,支持断线续传)
-"""
-
-# 模型(核心,无依赖)
-from agent.execution.models import Trace, Message
-
-# 向后兼容:保留 Step 导出(已废弃)
-from agent.execution.models import Step, StepType, StepStatus
-
-# 存储接口(核心,无依赖)
-from agent.execution.protocols import TraceStore
-
-# 文件系统存储实现(跨进程 + 持久化)
-from agent.execution.fs_store import FileSystemTraceStore
-
-
-# API 路由(可选,需要 FastAPI)
-def _get_api_router():
-    """延迟导入 API Router(避免强制依赖 FastAPI)"""
-    from agent.execution.api import router
-    return router
-
-
-def _get_ws_router():
-    """延迟导入 WebSocket Router(避免强制依赖 FastAPI)"""
-    from agent.execution.websocket import router
-    return router
-
-
-# WebSocket 广播函数(可选,需要 FastAPI)
-def _get_broadcast_functions():
-    """延迟导入 WebSocket 广播函数"""
-    from agent.execution.websocket import (
-        broadcast_goal_added,
-        broadcast_goal_updated,
-        broadcast_branch_started,
-        broadcast_branch_completed,
-        broadcast_explore_completed,
-        broadcast_trace_completed,
-    )
-    return (
-        broadcast_goal_added,
-        broadcast_goal_updated,
-        broadcast_branch_started,
-        broadcast_branch_completed,
-        broadcast_explore_completed,
-        broadcast_trace_completed,
-    )
-
-
-__all__ = [
-    # 模型
-    "Trace",
-    "Message",
-    # 向后兼容(已废弃)
-    "Step",
-    "StepType",
-    "StepStatus",
-    # 存储
-    "TraceStore",
-    "FileSystemTraceStore",
-]

+ 0 - 26
agent/goal/__init__.py

@@ -1,26 +0,0 @@
-"""
-Goal 模块 - 执行计划管理
-
-提供 Goal 和 GoalTree 数据模型,以及 goal 工具。
-"""
-
-from agent.goal.models import (
-    Goal,
-    GoalTree,
-    GoalStatus,
-    GoalType,
-    GoalStats,
-)
-from agent.goal.tool import goal_tool, create_goal_tool_schema
-
-__all__ = [
-    # Models
-    "Goal",
-    "GoalTree",
-    "GoalStatus",
-    "GoalType",
-    "GoalStats",
-    # Tool
-    "goal_tool",
-    "create_goal_tool_schema",
-]

+ 0 - 91
agent/memory/README.md

@@ -1,91 +0,0 @@
-# Agent Memory - 记忆系统
-
-## 职责
-
-记忆系统管理 Agent 的长期记忆和技能:
-
-1. **数据模型** (`models.py`)
-   - `Experience` - 经验记录(从执行中提取的知识)
-   - `Skill` - 技能定义(领域知识和最佳实践)
-
-2. **存储接口** (`protocols.py`, `stores.py`)
-   - `MemoryStore` - 经验和技能存储接口
-   - `StateStore` - 状态存储接口
-   - `MemoryMemoryStore` - 内存实现
-   - `MemoryStateStore` - 内存实现
-
-3. **技能加载** (`skill_loader.py`)
-   - 从 Markdown 文件加载技能
-   - 支持 YAML frontmatter 和行内元数据
-
-## 模块边界
-
-- **只依赖**:无(纯数据模型和接口)
-- **被依赖**:core.runner(加载和注入记忆)
-- **独立开发**:记忆检索、经验提取算法可独立迭代
-
-## 使用示例
-
-```python
-from agent.memory import (
-    MemoryMemoryStore,
-    Experience,
-    Skill,
-    load_skills_from_dir
-)
-
-# 创建存储
-memory_store = MemoryMemoryStore()
-
-# 添加经验
-exp = Experience.create(
-    scope="coding",
-    context="Python type hints",
-    pattern="Use Optional[T] for nullable types",
-    outcome="success"
-)
-await memory_store.add_experience(exp)
-
-# 加载技能
-skills = load_skills_from_dir("./config/skills")
-for skill in skills:
-    await memory_store.add_skill(skill)
-
-# 检索记忆
-experiences = await memory_store.search_experiences(
-    scope="coding",
-    context="type hints",
-    limit=5
-)
-```
-
-## 技能文件格式
-
-技能文件使用 Markdown + YAML frontmatter:
-
-```markdown
----
-name: browser-automation
-description: Browser automation best practices
-category: web-automation
-scope: agent:*
----
-
-## When to use
-
-- Scraping dynamic web pages
-- Testing web applications
-
-## Guidelines
-
-- Always check if element exists before clicking
-- Use explicit waits instead of sleep()
-```
-
-## 文件说明
-
-- `models.py` - Experience 和 Skill 数据模型
-- `protocols.py` - MemoryStore 和 StateStore 接口
-- `stores.py` - 内存存储实现
-- `skill_loader.py` - 技能加载器
-- `__init__.py` - 模块导出

+ 0 - 0
agent/skills/core.md → agent/memory/skills/core.md


+ 0 - 137
agent/subagents/default.json

@@ -1,137 +0,0 @@
-{
-  "agents": {
-    "code-reviewer": {
-      "description": "代码审查专家,专注于代码质量和最佳实践",
-      "mode": "subagent",
-      "allowed_tools": [
-        "read_file",
-        "search_code",
-        "list_files"
-      ],
-      "denied_tools": [
-        "write_file",
-        "edit_file",
-        "execute_bash",
-        "task"
-      ],
-      "max_iterations": 15,
-      "temperature": 0.2,
-      "system_prompt": "你是一个代码审查专家。专注于:\n\n1. 代码质量\n   - 可读性和可维护性\n   - 命名规范\n   - 注释质量\n\n2. 最佳实践\n   - 设计模式的正确使用\n   - SOLID 原则\n   - DRY 原则\n\n3. 潜在问题\n   - 性能问题\n   - 内存泄漏\n   - 边界条件\n\n输出格式:\n- **文件**: [路径]\n- **问题**: [描述]\n- **严重程度**: [高/中/低]\n- **建议**: [改进建议]\n- **示例**: [可选的代码示例]",
-      "can_spawn_subagent": false
-    },
-
-    "security-scanner": {
-      "description": "安全扫描专家,查找安全漏洞和敏感信息泄露",
-      "mode": "subagent",
-      "allowed_tools": [
-        "read_file",
-        "search_code",
-        "list_files"
-      ],
-      "denied_tools": [
-        "write_file",
-        "edit_file",
-        "execute_bash",
-        "task"
-      ],
-      "max_iterations": 20,
-      "temperature": 0.1,
-      "system_prompt": "你是一个安全扫描专家。专注于:\n\n1. 常见漏洞\n   - SQL 注入\n   - XSS 攻击\n   - CSRF 漏洞\n   - 不安全的反序列化\n\n2. 敏感信息\n   - 硬编码的密钥\n   - API tokens\n   - 数据库凭据\n\n3. 配置安全\n   - 不安全的默认配置\n   - 过于宽松的权限\n\n输出格式:\n- **漏洞类型**: [类型]\n- **位置**: [文件:行号]\n- **严重程度**: [高/中/低]\n- **描述**: [详细说明]\n- **修复建议**: [如何修复]",
-      "can_spawn_subagent": false,
-      "permissions": {
-        "paths": {
-          "/etc": "deny",
-          "~/.ssh": "deny",
-          "/tmp": "allow"
-        }
-      }
-    },
-
-    "doc-writer": {
-      "description": "文档编写专家,生成和改进项目文档",
-      "mode": "subagent",
-      "allowed_tools": [
-        "read_file",
-        "search_code",
-        "list_files",
-        "write_file"
-      ],
-      "denied_tools": [
-        "execute_bash",
-        "task"
-      ],
-      "max_iterations": 15,
-      "temperature": 0.5,
-      "system_prompt": "你是一个文档编写专家。专注于:\n\n1. 文档结构\n   - 清晰的层次\n   - 合理的章节划分\n   - 完整的目录\n\n2. 内容质量\n   - 准确性\n   - 示例代码\n   - 使用场景\n\n3. 文档类型\n   - README\n   - API 文档\n   - 教程\n   - 架构设计文档\n\n输出格式:使用 Markdown",
-      "can_spawn_subagent": false
-    },
-
-    "performance-analyzer": {
-      "description": "性能分析专家,识别性能瓶颈和优化机会",
-      "mode": "subagent",
-      "allowed_tools": [
-        "read_file",
-        "search_code",
-        "list_files",
-        "execute_bash"
-      ],
-      "denied_tools": [
-        "write_file",
-        "edit_file",
-        "task"
-      ],
-      "max_iterations": 25,
-      "temperature": 0.2,
-      "system_prompt": "你是一个性能分析专家。专注于:\n\n1. 性能问题识别\n   - N+1 查询\n   - 不必要的计算\n   - 内存泄漏\n   - 阻塞操作\n\n2. 优化建议\n   - 缓存策略\n   - 数据库索引\n   - 并发处理\n   - 批量操作\n\n3. 基准测试\n   - 关键路径分析\n   - 性能指标\n\n输出格式:\n- **问题**: [描述]\n- **位置**: [文件:函数]\n- **影响**: [响应时间/内存/CPU]\n- **优化建议**: [具体方案]\n- **预期收益**: [性能提升估算]",
-      "can_spawn_subagent": false
-    },
-
-    "test-writer": {
-      "description": "测试编写专家,生成单元测试和集成测试",
-      "mode": "subagent",
-      "allowed_tools": [
-        "read_file",
-        "search_code",
-        "list_files",
-        "write_file"
-      ],
-      "denied_tools": [
-        "execute_bash",
-        "task"
-      ],
-      "max_iterations": 20,
-      "temperature": 0.3,
-      "system_prompt": "你是一个测试编写专家。专注于:\n\n1. 测试覆盖\n   - 核心功能\n   - 边界条件\n   - 错误处理\n\n2. 测试质量\n   - 可读性\n   - 独立性\n   - 可维护性\n\n3. 测试类型\n   - 单元测试\n   - 集成测试\n   - 端到端测试\n\n遵循 AAA 模式:Arrange, Act, Assert",
-      "can_spawn_subagent": false
-    },
-
-    "my-primary-agent": {
-      "description": "自定义主 Agent,具有完整权限",
-      "mode": "primary",
-      "can_spawn_subagent": true,
-      "max_iterations": 30,
-      "temperature": 0.7
-    }
-  },
-
-  "default_agent": "my-primary-agent",
-
-  "permissions": {
-    "global": {
-      "tools": {
-        "execute_bash": "ask",
-        "write_file": "ask"
-      },
-      "paths": {
-        "/etc": "deny",
-        "~/.ssh": "deny",
-        "/tmp": "allow"
-      },
-      "network": {
-        "blocked_domains": [
-          "*.evil.com"
-        ]
-      }
-    }
-  }
-}

+ 0 - 94
agent/tools/README.md

@@ -1,94 +0,0 @@
-# Agent Tools - 工具系统
-
-## 职责
-
-工具系统提供 Agent 可调用的各种能力:
-
-1. **工具注册** (`registry.py`)
-   - 工具装饰器 `@tool`
-   - 全局工具注册表
-   - 工具发现和调用
-
-2. **Schema 生成** (`schema.py`)
-   - 将 Python 函数转换为 OpenAI function calling schema
-   - 支持类型注解和文档字符串
-
-3. **工具模型** (`models.py`)
-   - `ToolResult` - 工具执行结果
-   - `ToolContext` - 工具执行上下文
-
-4. **内置工具** (`builtin/`)
-   - `read_file` - 读取文件
-   - `edit_file` - 编辑文件
-   - `write_file` - 写入文件
-   - `glob_files` - 文件搜索
-   - `grep_content` - 内容搜索
-   - `bash_command` - 执行 Shell 命令
-   - `skill` - 加载技能文档
-
-5. **高级工具** (`advanced/`)
-   - LSP - Language Server Protocol 集成
-   - WebFetch - 网页抓取
-
-6. **适配器** (`adapters/`)
-   - Browser-use - 浏览器自动化
-
-## 工具开发
-
-创建自定义工具:
-
-```python
-from agent.tools import tool, ToolResult
-
-@tool(description="Calculate sum of two numbers")
-async def add(a: int, b: int, uid: str = "") -> ToolResult:
-    """
-    Add two numbers
-
-    Args:
-        a: First number
-        b: Second number
-        uid: User ID (auto-injected)
-
-    Returns:
-        ToolResult with sum
-    """
-    return ToolResult(
-        success=True,
-        data={"sum": a + b}
-    )
-```
-
-## 文件说明
-
-- `registry.py` - 工具注册表和装饰器
-- `schema.py` - OpenAI schema 生成
-- `models.py` - ToolResult 等数据模型
-- `sensitive.py` - 敏感数据处理
-- `url_matcher.py` - URL 模式匹配
-- `builtin/` - 核心工具
-- `advanced/` - 高级工具
-- `adapters/` - 外部集成
-
-## 目录结构
-
-```
-tools/
-├── __init__.py          # 工具装饰器和注册表
-├── registry.py          # 核心注册逻辑
-├── schema.py            # Schema 生成
-├── models.py            # 数据模型
-├── builtin/             # 核心工具(必需)
-│   ├── read.py
-│   ├── edit.py
-│   ├── write.py
-│   ├── glob.py
-│   ├── grep.py
-│   ├── bash.py
-│   └── skill.py
-├── advanced/            # 高级工具(可选)
-│   ├── lsp.py
-│   └── webfetch.py
-└── adapters/            # 外部集成(可选)
-    └── browser_use/
-```

+ 10 - 7
agent/tools/builtin/__init__.py

@@ -7,14 +7,16 @@
 参考版本:opencode main branch (2025-01)
 """
 
-from agent.tools.builtin.read import read_file
-from agent.tools.builtin.edit import edit_file
-from agent.tools.builtin.write import write_file
-from agent.tools.builtin.glob import glob_files
-from agent.tools.builtin.grep import grep_content
+# 文件操作工具
+from agent.tools.builtin.file.read import read_file
+from agent.tools.builtin.file.edit import edit_file
+from agent.tools.builtin.file.write import write_file
+from agent.tools.builtin.file.glob import glob_files
+from agent.tools.builtin.file.grep import grep_content
+
+# 系统工具
 from agent.tools.builtin.bash import bash_command
 from agent.tools.builtin.skill import skill, list_skills
-from agent.tools.builtin.goal import goal
 from agent.tools.builtin.search import search_posts, get_search_suggestions
 from agent.tools.builtin.sandbox import (sandbox_create_environment, sandbox_run_shell,
                                          sandbox_rebuild_with_ports,sandbox_destroy_environment)
@@ -23,15 +25,16 @@ from agent.tools.builtin.sandbox import (sandbox_create_environment, sandbox_run
 import agent.tools.builtin.browser  # noqa: F401
 
 __all__ = [
+    # 文件操作
     "read_file",
     "edit_file",
     "write_file",
     "glob_files",
     "grep_content",
+    # 系统工具
     "bash_command",
     "skill",
     "list_skills",
-    "goal",
     "search_posts",
     "get_search_suggestions",
     "sandbox_create_environment",

+ 18 - 2
agent/tools/builtin/browser/baseClass.py

@@ -1250,8 +1250,24 @@ async def browser_get_selector_map() -> ToolResult:
     try:
         browser, tools = await get_browser_session()
 
-        # 获取选择器映射
-        selector_map = await browser.get_selector_map()
+        # 关键修复:先触发 BrowserStateRequestEvent 来更新 DOM 状态
+        # 这会触发 DOM watchdog 重新构建 DOM 树并更新 selector_map
+        from browser_use.browser.events import BrowserStateRequestEvent
+
+        # 触发事件并等待结果
+        event = browser.event_bus.dispatch(
+            BrowserStateRequestEvent(
+                include_dom=True,
+                include_screenshot=False,  # 不需要截图,节省时间
+                include_recent_events=False
+            )
+        )
+
+        # 等待 DOM 更新完成
+        browser_state = await event.event_result(raise_if_none=True, raise_if_any=True)
+
+        # 从更新后的状态中获取 selector_map
+        selector_map = browser_state.dom_state.selector_map if browser_state.dom_state else {}
 
         # 构建输出信息
         elements_info = []

+ 19 - 0
agent/tools/builtin/file/__init__.py

@@ -0,0 +1,19 @@
+"""
+File tools - 文件操作工具
+
+包含:read, write, edit, glob, grep
+"""
+
+from .read import read_file
+from .write import write_file
+from .edit import edit_file
+from .glob import glob_files
+from .grep import grep_content
+
+__all__ = [
+    "read_file",
+    "write_file",
+    "edit_file",
+    "glob_files",
+    "grep_content",
+]

+ 0 - 0
agent/tools/builtin/edit.py → agent/tools/builtin/file/edit.py


+ 0 - 0
agent/tools/builtin/glob.py → agent/tools/builtin/file/glob.py


+ 0 - 0
agent/tools/builtin/grep.py → agent/tools/builtin/file/grep.py


+ 0 - 0
agent/tools/builtin/read.py → agent/tools/builtin/file/read.py


+ 0 - 0
agent/tools/builtin/write.py → agent/tools/builtin/file/write.py


+ 0 - 75
agent/tools/builtin/goal.py

@@ -1,75 +0,0 @@
-"""
-Goal 工具 - 执行计划管理
-
-提供 LLM 可调用的 goal 工具,用于管理执行计划(GoalTree)。
-"""
-
-from typing import Optional
-from agent.tools import tool
-
-
-# 全局 GoalTree 引用(由 AgentRunner 注入)
-_current_goal_tree = None
-
-
-def set_goal_tree(tree):
-    """设置当前 GoalTree(由 AgentRunner 调用)"""
-    global _current_goal_tree
-    _current_goal_tree = tree
-
-
-def get_goal_tree():
-    """获取当前 GoalTree"""
-    return _current_goal_tree
-
-
-@tool(description="管理执行计划,添加/完成/放弃目标,切换焦点")
-async def goal(
-    add: Optional[str] = None,
-    reason: Optional[str] = None,
-    done: Optional[str] = None,
-    abandon: Optional[str] = None,
-    focus: Optional[str] = None,
-    context: Optional[dict] = None
-) -> str:
-    """
-    管理执行计划,添加/完成/放弃目标,切换焦点。
-
-    Args:
-        add: 添加目标(逗号分隔多个)。添加到当前 focus 的 goal 下作为子目标。
-        reason: 创建理由(逗号分隔多个,与 add 一一对应)。说明为什么要做这些目标。
-        done: 完成当前目标,值为 summary
-        abandon: 放弃当前目标,值为原因(会触发 context 压缩)
-        focus: 切换焦点到指定 ID(如 "1", "2.1", "2.2")
-        context: 工具执行上下文(包含 store 和 trace_id)
-
-    Examples:
-        goal(add="分析代码, 实现功能, 测试", reason="了解现有结构, 完成需求, 确保质量")
-        goal(focus="2", add="设计接口, 实现代码", reason="明确API规范, 编写核心逻辑")
-        goal(done="发现用户模型在 models/user.py")
-        goal(done="已完成调研", focus="2")
-        goal(abandon="方案A需要Redis,环境没有", add="实现方案B", reason="使用现有技术栈")
-
-    Returns:
-        str: 更新后的计划状态文本
-    """
-    from agent.goal.tool import goal_tool
-
-    tree = get_goal_tree()
-    if tree is None:
-        return "错误:GoalTree 未初始化"
-
-    # 从 context 获取 store 和 trace_id
-    store = context.get("store") if context else None
-    trace_id = context.get("trace_id") if context else None
-
-    return await goal_tool(
-        tree=tree,
-        store=store,
-        trace_id=trace_id,
-        add=add,
-        reason=reason,
-        done=done,
-        abandon=abandon,
-        focus=focus
-    )

+ 2 - 2
agent/tools/builtin/skill.py

@@ -15,7 +15,7 @@ from agent.memory.skill_loader import SkillLoader
 # 默认 skills 目录(优先级:项目 skills > 框架 skills)
 DEFAULT_SKILLS_DIRS = [
     os.getenv("SKILLS_DIR", "./skills"),      # 项目特定 skills(优先)
-    "./agent/skills"                           # 框架内置 skills
+    "./agent/memory/skills"                    # 框架内置 skills
 ]
 
 # 默认单一目录(用于 list_skills)
@@ -36,7 +36,7 @@ def _check_skill_setup(skill_name: str) -> Optional[str]:
     if skill_name in ["browser-use", "browser_use"]:
         try:
             # 动态导入 browser-use skill 的 setup 模块
-            from agent.skills.browser_use.setup import (
+            from agent.memory.skills.browser_use.setup import (
                 _check_browser_use_cli,
                 _check_chromium_installed
             )

+ 38 - 0
agent/trace/__init__.py

@@ -0,0 +1,38 @@
+"""
+Trace module - 执行追踪与计划管理
+
+包含:
+- Trace, Goal, Message 数据模型
+- TraceStore 存储接口和实现
+- goal 工具(计划管理)
+- Context 压缩
+- REST/WebSocket API
+"""
+
+from .models import Trace, Message
+from .goal_models import Goal, GoalTree, GoalStatus, GoalType, GoalStats
+from .protocols import TraceStore
+from .store import FileSystemTraceStore
+from .trace_id import generate_trace_id, generate_sub_trace_id, parse_parent_trace_id
+from .goal_tool import set_goal_tree, get_goal_tree
+
+__all__ = [
+    # Models
+    "Trace",
+    "Message",
+    "Goal",
+    "GoalTree",
+    "GoalStatus",
+    "GoalType",
+    "GoalStats",
+    # Store
+    "TraceStore",
+    "FileSystemTraceStore",
+    # Utils
+    "generate_trace_id",
+    "generate_sub_trace_id",
+    "parse_parent_trace_id",
+    # Goal tool
+    "set_goal_tree",
+    "get_goal_tree",
+]

+ 1 - 1
agent/execution/api.py → agent/trace/api.py

@@ -8,7 +8,7 @@ from typing import List, Optional, Dict, Any
 from fastapi import APIRouter, HTTPException, Query
 from pydantic import BaseModel
 
-from agent.execution.protocols import TraceStore
+from .protocols import TraceStore
 
 
 router = APIRouter(prefix="/api/traces", tags=["traces"])

+ 1 - 1
agent/goal/compaction.py → agent/trace/compaction.py

@@ -6,7 +6,7 @@ Context 压缩
 """
 
 from typing import List, Dict, Any, Optional
-from agent.goal.models import GoalTree, Goal
+from .goal_models import GoalTree, Goal
 
 
 def compress_messages_for_goal(

+ 3 - 3
agent/goal/delegate.py → agent/trace/delegate.py

@@ -7,9 +7,9 @@ Delegate 工具 - 委托任务给子 Agent
 from typing import Optional, Dict, Any
 from datetime import datetime
 
-from agent.execution.models import Trace, Message
-from agent.execution.trace_id import generate_sub_trace_id
-from agent.goal.models import Goal
+from .models import Trace, Message
+from .trace_id import generate_sub_trace_id
+from .goal_models import Goal
 
 
 async def delegate_tool(

+ 3 - 3
agent/goal/explore.py → agent/trace/explore.py

@@ -8,9 +8,9 @@ import asyncio
 from typing import List, Optional, Dict, Any
 from datetime import datetime
 
-from agent.execution.models import Trace, Message
-from agent.execution.trace_id import generate_sub_trace_id
-from agent.goal.models import Goal
+from .models import Trace, Message
+from .trace_id import generate_sub_trace_id
+from .goal_models import Goal
 
 
 async def explore_tool(

+ 0 - 0
agent/goal/models.py → agent/trace/goal_models.py


+ 74 - 2
agent/goal/tool.py → agent/trace/goal_tool.py

@@ -6,9 +6,81 @@ Goal 工具 - 计划管理
 
 from typing import Optional, List, TYPE_CHECKING
 
+from agent.tools import tool
+
 if TYPE_CHECKING:
-    from agent.goal.models import GoalTree
-    from agent.execution.protocols import TraceStore
+    from .goal_models import GoalTree
+    from .protocols import TraceStore
+
+
+# ===== 全局 GoalTree 状态管理 =====
+
+_current_goal_tree = None
+
+
+def set_goal_tree(tree):
+    """设置当前 GoalTree(由 AgentRunner 调用)"""
+    global _current_goal_tree
+    _current_goal_tree = tree
+
+
+def get_goal_tree():
+    """获取当前 GoalTree"""
+    return _current_goal_tree
+
+
+# ===== LLM 可调用的 goal 工具 =====
+
+@tool(description="管理执行计划,添加/完成/放弃目标,切换焦点")
+async def goal(
+    add: Optional[str] = None,
+    reason: Optional[str] = None,
+    after: Optional[str] = None,
+    under: Optional[str] = None,
+    done: Optional[str] = None,
+    abandon: Optional[str] = None,
+    focus: Optional[str] = None,
+    context: Optional[dict] = None
+) -> str:
+    """
+    管理执行计划,添加/完成/放弃目标,切换焦点。
+
+    Args:
+        add: 添加目标(逗号分隔多个)
+        reason: 创建理由(逗号分隔多个,与 add 一一对应)
+        after: 在指定目标后面添加(同层级)
+        under: 为指定目标添加子目标
+        done: 完成当前目标,值为 summary
+        abandon: 放弃当前目标,值为原因
+        focus: 切换焦点到指定 ID
+        context: 工具执行上下文(包含 store 和 trace_id)
+
+    Returns:
+        str: 更新后的计划状态文本
+    """
+    tree = get_goal_tree()
+    if tree is None:
+        return "错误:GoalTree 未初始化"
+
+    # 从 context 获取 store 和 trace_id
+    store = context.get("store") if context else None
+    trace_id = context.get("trace_id") if context else None
+
+    return await goal_tool(
+        tree=tree,
+        store=store,
+        trace_id=trace_id,
+        add=add,
+        reason=reason,
+        after=after,
+        under=under,
+        done=done,
+        abandon=abandon,
+        focus=focus
+    )
+
+
+# ===== 核心逻辑函数 =====
 
 
 async def goal_tool(

+ 0 - 0
agent/execution/models.py → agent/trace/models.py


+ 2 - 2
agent/execution/protocols.py → agent/trace/protocols.py

@@ -6,8 +6,8 @@ Trace Storage Protocol - Trace 存储接口定义
 
 from typing import Protocol, List, Optional, Dict, Any, runtime_checkable
 
-from agent.execution.models import Trace, Message
-from agent.goal.models import GoalTree, Goal
+from .models import Trace, Message
+from .goal_models import GoalTree, Goal
 
 
 @runtime_checkable

+ 2 - 2
agent/execution/fs_store.py → agent/trace/store.py

@@ -26,8 +26,8 @@ from pathlib import Path
 from typing import Dict, List, Optional, Any
 from datetime import datetime
 
-from agent.execution.models import Trace, Message
-from agent.goal.models import GoalTree, Goal, GoalStats
+from .models import Trace, Message
+from .goal_models import GoalTree, Goal, GoalStats
 
 
 class FileSystemTraceStore:

+ 0 - 0
agent/execution/trace_id.py → agent/trace/trace_id.py


+ 1 - 1
agent/execution/tree_dump.py → agent/trace/tree_dump.py

@@ -11,7 +11,7 @@ Step 树 Debug 输出
        code .trace/tree.txt
 
     3. 代码中使用:
-       from agent.execution import dump_tree
+       from agent.trace import dump_tree
        dump_tree(trace, steps)
 """
 

+ 1 - 1
agent/execution/websocket.py → agent/trace/websocket.py

@@ -8,7 +8,7 @@ from typing import Dict, Set, Any
 from datetime import datetime
 from fastapi import APIRouter, WebSocket, WebSocketDisconnect, Query
 
-from agent.execution.protocols import TraceStore
+from .protocols import TraceStore
 
 
 router = APIRouter(prefix="/api/traces", tags=["websocket"])

+ 3 - 3
api_server.py

@@ -9,9 +9,9 @@ from fastapi import FastAPI
 from fastapi.middleware.cors import CORSMiddleware
 import uvicorn
 
-from agent.execution import FileSystemTraceStore
-from agent.execution.api import router as api_router, set_trace_store as set_api_trace_store
-from agent.execution.websocket import router as ws_router, set_trace_store as set_ws_trace_store
+from agent.trace import FileSystemTraceStore
+from agent.trace.api import router as api_router, set_trace_store as set_api_trace_store
+from agent.trace.websocket import router as ws_router, set_trace_store as set_ws_trace_store
 
 
 # ===== 日志配置 =====

+ 418 - 406
docs/README.md

@@ -1,47 +1,94 @@
 # Agent 功能需求与架构设计文档
 
-> **可执行规格书**:本文档是系统的核心设计。代码修改必须同步更新此文档。
-> 如文档与代码冲突,以代码为准,并立即修复文档。
-
----
 
 ## 文档维护规范
 
-**维护原则**:
-1. **谁改代码谁更新文档** - 功能变更后,相关文档必须同步修改
-2. **保持结构稳定** - 只增删内容,不随意调整层级结构
-3. **流程优先** - 新功能先写入核心流程,再补充模块详情
-4. **链接代码** - 关键实现标注文件路径,格式:`module/file.py:function_name`
-5. **简洁原则** - 只记录最重要的、与代码准确对应的或者明确的已完成的设计的信息,避免推测、建议,或大量代码
-6. **文档分层** - 每层文档是不同层次的overview,在上层文档对应位置引用下层详细文档
+0. **先改文档,再动代码** - 新功能或重大修改需先完成文档更新、并完成审阅后,再进行代码实现;除非改动较小、不被文档涵盖
+1. **文档分层,链接代码** - 重要或复杂设计可以另有详细文档;关键实现需标注代码文件路径;格式:`module/file.py:function_name`
+2. **简洁快照,日志分离** - 只记录最重要的、与代码准确对应的或者明确的已完成的设计的信息,避免推测、建议,或大量代码;决策依据或修改日志若有必要,可在`docs/decisions.md`另行记录
 
 ---
 
 ## 系统概览
 
-**单次调用是 Agent 的特例**:
+**核心理念:所有 Agent 都是 Trace**
 
-| 特性 | 单次调用 | Agent 模式 | Sub-Agent 模式 |
-|------|---------|-----------|--------------|
-| 循环次数 | 1 | N (可配置) | N (可配置,受限) |
-| 工具调用 | 可选 | 常用 | 受限工具集 |
-| 状态管理 | 无 | 有 (Trace) | 有 (独立 Trace + 父子关系) |
-| 记忆检索 | 无 | 有 (Experience/Skill) | 有 (继承主 Agent) |
-| 执行图 | 1 条 Message | N 条 Messages 的 DAG | 嵌套 DAG(多个 Trace) |
-| 触发方式 | 直接调用 | 直接调用 | 通过 Task 工具 |
-| 权限范围 | 完整 | 完整 | 受限(可配置) |
+| 类型 | 创建方式 | 父子关系 | 状态 |
+|------|---------|---------|------|
+| 主 Agent | 直接调用 `runner.run()` | 无 parent | 正常执行 |
+| 子 Agent | 通过 `task` 工具 | `parent_trace_id` 指向父 | 正常执行 |
+| 人类协助 | 通过 `ask_human` 工具 | `parent_trace_id` 指向父 | 阻塞等待 |
 
 ---
 
 ## 核心架构
 
+### 模块结构
+
+```
+agent/
+├── core/                  # 核心引擎
+│   ├── runner.py          # AgentRunner + 运行时配置
+│   └── presets.py         # Agent 预设(explore、analyst 等)
+│
+├── trace/                 # 执行追踪(含计划管理)
+│   ├── models.py          # Trace, Message
+│   ├── goal_models.py     # Goal, GoalTree, GoalStats
+│   ├── protocols.py       # TraceStore 接口
+│   ├── store.py           # FileSystemTraceStore 实现
+│   ├── goal_tool.py       # goal 工具(计划管理)
+│   ├── explore.py         # 探索式子任务
+│   ├── delegate.py        # 委派式子任务
+│   ├── compaction.py      # Context 压缩
+│   ├── api.py             # REST API
+│   ├── websocket.py       # WebSocket API
+│   └── trace_id.py        # Trace ID 生成工具
+│
+├── tools/                 # 外部交互工具
+│   ├── registry.py        # 工具注册表
+│   ├── schema.py          # Schema 生成器
+│   ├── models.py          # ToolResult, ToolContext
+│   └── builtin/
+│       ├── file/          # 文件操作(read, write, edit, glob, grep)
+│       ├── browser/       # 浏览器自动化
+│       ├── bash.py        # 命令执行
+│       ├── sandbox.py     # 沙箱环境
+│       ├── search.py      # 网络搜索
+│       ├── webfetch.py    # 网页抓取
+│       ├── skill.py       # 技能加载
+│       └── ask_human.py   # 人类协助
+│
+├── memory/                # 跨会话记忆
+│   ├── models.py          # Experience, Skill
+│   ├── protocols.py       # MemoryStore 接口
+│   ├── stores.py          # 存储实现
+│   ├── skill_loader.py    # Skill 加载器
+│   └── skills/            # 内置 Skills
+│       └── core.md        # Core Skill(自动加载)
+│
+├── llm/                   # LLM 集成
+│   ├── gemini.py          # Gemini Provider
+│   ├── openrouter.py      # OpenRouter Provider
+│   └── prompts/           # Prompt 工具
+```
+
+### 职责划分
+
+| 模块 | 职责 |
+|-----|------|
+| **core/** | Agent 执行引擎 + 预设配置 |
+| **trace/** | 执行追踪 + 计划管理 + 子任务(goal, explore, delegate) |
+| **tools/** | 与外部世界交互(文件、命令、网络、浏览器) |
+| **memory/** | 跨会话知识(Skills、Experiences) |
+| **llm/** | LLM Provider 适配 |
+
 ### 三层记忆模型
 
 ```
 ┌─────────────────────────────────────────────────────────────┐
 │ Layer 3: Skills(技能库)                                     │
-│ - Markdown 文件,存储详细的能力描述                            │
-│ - 通过 skill 工具按需加载                                     │
+│ - Markdown 文件,存储领域知识和能力描述
+│ - 通过 skill 工具按需加载到对话历史
 └─────────────────────────────────────────────────────────────┘
                               │ 归纳
@@ -53,43 +100,39 @@
                               │ 提取
 ┌─────────────────────────────────────────────────────────────┐
-│ Layer 1: Task State(任务状态)
+│ Layer 1: Trace(任务状态)     
 │ - 当前任务的工作记忆                                          │
 │ - Trace + Messages 记录执行过程                               │
-│ - GoalTree 管理执行计划
+│ - Goals 管理执行计划   
 └─────────────────────────────────────────────────────────────┘
 ```
 
-**注入方式**:
-- **Skills**:通过 `skill` 工具动态加载到对话历史
-- **Experiences**:检索后注入到 system prompt
-
 ---
 
 ## 核心流程:Agent Loop
 
 ```python
-async def run(task: str, max_steps: int = 50) -> AsyncIterator[Union[Trace, Message]]:
+async def run(task: str, agent_type: str = "default") -> AsyncIterator[Union[Trace, Message]]:
     # 1. 创建 Trace
-    trace = Trace.create(mode="agent", task=task, status="in_progress")
-    await trace_store.create_trace(trace)
-    yield trace  # 返回 Trace(表示开始)
+    trace = Trace.create(
+        mode="agent",
+        task=task,
+        agent_type=agent_type,
+        model=config.model
+    )
+    await store.create_trace(trace)
+    yield trace
 
-    # 2. 加载 Skills(内置 + 自定义)
+    # 2. 加载 Skills,构建 system prompt
     skills = load_skills_from_dir(skills_dir)
-    skills_text = format_skills(skills)
-
-    # 3. 检索 Experiences,构建 system prompt
-    experiences = await search_experiences(task)
-    system_prompt = build_system_prompt(experiences, skills_text)
+    system_prompt = build_system_prompt(skills)
 
-    # 4. 初始化消息和 GoalTree
+    # 3. 初始化
     messages = [{"role": "user", "content": task}]
-    goal_tree = GoalTree(mission=task)
 
-    # 5. ReAct 循环
-    for step in range(max_steps):
-        # 注入当前计划到 system prompt
+    # 4. ReAct 循环
+    for step in range(max_iterations):
+        # 注入当前计划
         plan_text = goal_tree.to_prompt()
 
         # 调用 LLM
@@ -100,67 +143,35 @@ async def run(task: str, max_steps: int = 50) -> AsyncIterator[Union[Trace, Mess
         )
 
         # 记录 assistant Message
-        assistant_msg = Message.create(
+        await store.add_message(Message.create(
             trace_id=trace.trace_id,
             role="assistant",
-            goal_id=goal_tree.current_id,
-            content=response.content,  # text + tool_calls
-        )
-        await trace_store.add_message(assistant_msg)
+            sequence=next_seq,
+            content=response
+        ))
         yield assistant_msg
 
         # 没有工具调用,完成
         if not response.tool_calls:
             break
 
-        # 执行工具
+        # 执行工具,记录 tool Message
         for tool_call in response.tool_calls:
             result = await execute_tool(tool_call)
-
-            # 记录 tool Message
-            tool_msg = Message.create(
+            await store.add_message(Message.create(
                 trace_id=trace.trace_id,
                 role="tool",
-                goal_id=goal_tree.current_id,
-                tool_call_id=tool_call.id,
-                content=result,
-            )
-            await trace_store.add_message(tool_msg)
+                sequence=next_seq,
+                content=result
+            ))
             yield tool_msg
 
-            # 添加到消息历史
-            messages.append({"role": "assistant", "tool_calls": [tool_call]})
-            messages.append({"role": "tool", "tool_call_id": tool_call.id, "content": result})
-
-    # 6. 完成
+    # 5. 完成
     trace.status = "completed"
-    await trace_store.update_trace(trace.trace_id, status="completed")
     yield trace
 ```
 
-**关键机制**:
-- **统一返回类型**:`AsyncIterator[Union[Trace, Message]]` - 实时返回执行状态
-- **GoalTree 注入**:每次 LLM 调用前注入当前计划(过滤废弃目标,连续编号)
-- **Message 关联 Goal**:每条 Message 通过 `goal_id` 关联所属 Goal
-- **Doom Loop 检测**:跟踪最近 3 次工具调用,如果都是同一个工具且参数相同,中断循环
-
-### Sub-Agent 执行流程
-
-主 Agent 通过 `task` 工具启动 Sub-Agent。
-
-**层级关系**:
-```
-Main Trace (primary agent)
-  └─▶ Sub Trace (parent_trace_id 指向主 Trace)
-        └─▶ Steps...
-```
-
-**关键字段**:
-- `Trace.parent_trace_id` - 指向父 Trace
-- `Trace.agent_definition` - Sub-Agent 类型(如 "explore")
-- Sub-Agent 有独立的工具权限配置
-
-**实现位置**:`agent/tools/builtin/task.py`(待实现)
+**实现**:`agent/core/runner.py:AgentRunner`
 
 ---
 
@@ -168,270 +179,360 @@ Main Trace (primary agent)
 
 ### Trace(任务执行)
 
+一次完整的 Agent 执行。所有 Agent(主、子、人类协助)都是 Trace。
+
 ```python
 @dataclass
 class Trace:
     trace_id: str
-    mode: Literal["call", "agent"]
+    mode: Literal["call", "agent"]           # 单次调用 or Agent 模式
+
+    # Prompt 标识
+    prompt_name: Optional[str] = None
+
+    # Agent 模式特有
     task: Optional[str] = None
     agent_type: Optional[str] = None
-    status: Literal["running", "completed", "failed"] = "running"
 
-    # Sub-Agent 支持
-    parent_trace_id: Optional[str] = None      # 父 Trace ID
-    agent_definition: Optional[str] = None     # Agent 类型名称
-    spawned_by_tool: Optional[str] = None      # 启动此 Sub-Agent 的 Message ID
+    # 父子关系(Sub-Trace 特有)
+    parent_trace_id: Optional[str] = None    # 父 Trace ID
+    parent_goal_id: Optional[str] = None     # 哪个 Goal 启动的
+
+    # 状态
+    status: Literal["running", "completed", "failed"] = "running"
 
     # 统计
     total_messages: int = 0
-    total_tokens: int = 0
+    total_tokens: int = 0                    # 总 tokens(prompt + completion)
+    total_prompt_tokens: int = 0
+    total_completion_tokens: int = 0
     total_cost: float = 0.0
+    total_duration_ms: int = 0
 
-    # 上下文
+    # 进度追踪
+    last_sequence: int = 0                   # 最新 message 的 sequence
+    last_event_id: int = 0                   # 最新事件 ID(用于 WS 续传)
+
+    # 配置
     uid: Optional[str] = None
-    context: Dict[str, Any] = field(default_factory=dict)
-    current_goal_id: Optional[str] = None      # 当前焦点 goal
+    model: Optional[str] = None              # 默认模型
+    tools: Optional[List[Dict]] = None       # 工具定义(OpenAI 格式)
+    llm_params: Dict[str, Any] = {}          # LLM 参数(temperature 等)
+    context: Dict[str, Any] = {}             # 其他元数据
+
+    # 当前焦点
+    current_goal_id: Optional[str] = None
+
+    # 结果
+    result_summary: Optional[str] = None
+    error_message: Optional[str] = None
+
+    # 时间
+    created_at: datetime
+    completed_at: Optional[datetime] = None
+```
+
+**实现**:`agent/trace/models.py`
+
+### Goal(目标节点)
+
+计划中的一个目标,支持层级结构。单独存储于 `goal.json`。
+
+```python
+@dataclass
+class Goal:
+    id: str                                  # 内部 ID("1", "2"...)
+    description: str
+    reason: str = ""                         # 创建理由
+    parent_id: Optional[str] = None          # 父 Goal ID
+    type: GoalType = "normal"                # normal | agent_call
+    status: GoalStatus = "pending"           # pending | in_progress | completed | abandoned
+    summary: Optional[str] = None            # 完成/放弃时的总结
+
+    # agent_call 特有(启动 Sub-Trace)
+    sub_trace_ids: Optional[List[str]] = None
+    agent_call_mode: Optional[str] = None    # explore | delegate | sequential
+    sub_trace_metadata: Optional[Dict] = None
+
+    # 统计
+    self_stats: GoalStats                    # 自身 Messages 统计
+    cumulative_stats: GoalStats              # 包含子孙的累计统计
+
+    created_at: datetime
 ```
 
-**实现**:`agent/execution/models.py:Trace`
+**Goal 操作**(通过 goal 工具):
+- `add` - 添加顶层目标
+- `under` - 在指定目标下添加子目标
+- `after` - 在指定目标后添加兄弟目标
+- `focus` - 切换焦点到指定目标
+- `done` - 完成当前目标(附带 summary)
+- `abandon` - 放弃当前目标(附带原因)
+
+**实现**:`agent/trace/goal_models.py`, `agent/trace/goal_tool.py`
 
 ### Message(执行消息)
 
-对应 LLM API 的消息,加上元数据。不再有 parent_id 树结构。
+对应 LLM API 的消息,每条 Message 关联一个 Goal
 
 ```python
 @dataclass
 class Message:
-    message_id: str
+    message_id: str                          # 格式:{trace_id}-{sequence:04d}
     trace_id: str
-    role: Literal["assistant", "tool"]   # 和 LLM API 一致
-    sequence: int                        # 全局顺序
-    goal_id: str                         # 关联的 Goal 内部 ID
-    tool_call_id: Optional[str] = None   # tool 消息关联对应的 tool_call
-    content: Any = None                  # 消息内容(和 LLM API 格式一致)
-    description: str = ""                # 系统自动提取的摘要
-
-    # 元数据
-    tokens: Optional[int] = None
+    role: Literal["system", "user", "assistant", "tool"]
+    sequence: int                            # 全局顺序
+    goal_id: Optional[str] = None            # 关联的 Goal ID
+    description: str = ""                    # 系统自动生成的摘要
+    tool_call_id: Optional[str] = None
+    content: Any = None
+
+    # 统计
+    prompt_tokens: Optional[int] = None
+    completion_tokens: Optional[int] = None
     cost: Optional[float] = None
+    duration_ms: Optional[int] = None
+
+    # LLM 响应信息(仅 role="assistant")
+    finish_reason: Optional[str] = None
+
+    created_at: datetime
+```
+
+**实现**:`agent/trace/models.py`
+
+---
+
+## Agent 预设
+
+不同类型 Agent 的配置模板,控制工具权限和参数。
+
+```python
+@dataclass
+class AgentPreset:
+    allowed_tools: Optional[List[str]] = None  # None 表示允许全部
+    denied_tools: Optional[List[str]] = None   # 黑名单
+    max_iterations: int = 30
+    temperature: Optional[float] = None
+    description: Optional[str] = None
+
+
+AGENT_PRESETS = {
+    "default": AgentPreset(
+        allowed_tools=None,
+        max_iterations=30,
+        description="默认 Agent,拥有全部工具权限",
+    ),
+    "explore": AgentPreset(
+        allowed_tools=["read", "glob", "grep", "list_files"],
+        denied_tools=["write", "edit", "bash", "task"],
+        max_iterations=15,
+        description="探索型 Agent,只读权限,用于代码分析",
+    ),
+    "analyst": AgentPreset(
+        allowed_tools=["read", "glob", "grep", "web_search", "webfetch"],
+        denied_tools=["write", "edit", "bash", "task"],
+        temperature=0.3,
+        max_iterations=25,
+        description="分析型 Agent,用于深度分析和研究",
+    ),
+}
 ```
 
-**实现**:`agent/execution/models.py:Message`
+**实现**:`agent/core/presets.py`
 
-**Message 类型**:
-- `role="assistant"`:模型的一次返回(可能同时包含文本和多个 tool_calls)
-- `role="tool"`:一个工具的执行结果(通过 `tool_call_id` 关联)
+**用户自定义**:项目级配置 `.agent/presets.json` 可覆盖或添加预设。
 
 ---
 
-## 模块详情
-
-详细的模块文档请参阅:
-
-### [项目结构](./project-structure.md)
-- 框架与应用分层设计
-- 框架内置预设(agent/presets/, agent/skills/)
-- 项目层配置(./skills/, ./subagents/, ./tools/)
-- 加载优先级和覆盖机制
-
-### [Sub-Agent 机制](./sub-agents.md)
-- 数据模型:AgentDefinition、Trace 扩展
-- 内置 Sub-Agent:general、explore、analyst
-- Task Tool 实现
-- Agent Registry 和权限控制
-- 配置文件格式
-
-**使用示例**:`examples/subagent_example.py`
-
-### [Context 管理与可视化](./context-management.md)
-- GoalTree:层级目标管理(嵌套 JSON,注入 LLM)
-- Goal ID 设计:内部 ID(稳定)vs 显示序号(连续,给 LLM)
-- goal 工具:计划管理(add, after, under, done, abandon, focus)
-- 位置控制:after(同层级追加)、under(子任务拆解)
-- Plan 注入策略:完整展示当前目标及其父链
-- explore 工具:并行探索-合并,收集每个 Sub-Trace 的最后消息作为元数据
-- 回溯机制:未执行直接修改 / 已执行标记废弃+新分支
-- DAG 可视化:节点=结果,边=动作,边可展开/折叠
-- 数据结构:GoalTree + Messages(扁平列表,goal_id 关联)
-- Sub-Trace 元数据:last_message, summary, stats(用于辅助决策和可视化)
-
-### [工具系统](./tools.md)
-- 工具定义和注册
-- 双层记忆管理
-- 域名过滤、敏感数据处理
-- 最佳实践
-
-**工具接入规范**:
-- **高频&简单工具**:Python 原生实现 → `agent/tools/builtin/`
-- **复杂&低频工具**:第三方仓库 → `vendor/` + 适配器 → `agent/tools/advanced/`
-- **CLI 命令行工具**:pip 安装 → `bash_command` 调用(如 browser-use)
-
-**内置工具**(`builtin/`):
-- `read_file`, `edit_file`, `write_file` - 文件操作
-- `bash_command` - 命令执行
-- `glob_files`, `grep_content` - 文件搜索
-- `skill`, `list_skills` - 技能库管理
-
-**高级工具**(`advanced/`):
-- `webfetch` - 网页抓取(调用 opencode)
-- `lsp_diagnostics` - LSP 诊断(调用 opencode)
-
-**Skills**(`agent/skills/`):
-- `browser_use` - 浏览器自动化(包含环境配置工具)
-
-**详细设计**:参考 [`docs/tools-adapters.md`](./tools-adapters.md)
-
-**核心特性**:
+## 子 Trace 机制
+
+### explore 模式
+
+并行探索多个分支,汇总结果返回。
+
 ```python
-from reson_agent import tool, ToolResult, ToolContext
+# 创建多个探索分支
+child_traces = await create_explore_traces(
+    parent_trace_id=ctx.trace_id,
+    prompts=["分析 A 方案", "分析 B 方案", "分析 C 方案"]
+)
+# 并行执行
+results = await asyncio.gather(*[run_trace(t) for t in child_traces])
+```
+
+**实现**:`agent/trace/explore.py`
+
+### delegate 模式
 
-@tool(
-    url_patterns=["*.google.com"],
-    requires_confirmation=True
+委派子任务给专门的 Agent 执行。
+
+```python
+child_trace = await create_delegate_trace(
+    parent_trace_id=ctx.trace_id,
+    task=prompt,
+    agent_type="analyst"  # 使用 analyst 预设
 )
-async def my_tool(arg: str, ctx: ToolContext) -> ToolResult:
-    return ToolResult(
-        title="Success",
-        output="Result content",
-        long_term_memory="Short summary"
-    )
+result = await run_trace(child_trace)
 ```
 
-### [多模态支持](./multimodal.md)
-- Prompt 层多模态消息构建
-- OpenAI 格式消息规范
-- Gemini Provider 适配
-- 图片资源处理
+**实现**:`agent/trace/delegate.py`
 
-**实现**:
-- `agent/llm/prompts/wrapper.py:SimplePrompt` - Prompt 包装器
-- `agent/llm/gemini.py:_convert_messages_to_gemini` - 格式转换
+### ask_human 工具
 
-**使用示例**:`examples/feature_extract/run.py`
+创建阻塞式 Trace,等待人类通过 IM/邮件等渠道回复。
 
-### Prompt Loader(提示加载器)
+```python
+@tool(name="ask_human")
+async def ask_human_tool(question: str, channel: str, ctx: ToolContext) -> ToolResult:
+    human_trace = await ctx.store.create_trace(
+        task=question,
+        parent_trace_id=ctx.trace_id,
+        blocked=True,
+        blocked_reason=f"等待人类通过 {channel} 回复"
+    )
+    await send_to_channel(channel, question)
+    response = await wait_for_human_response(human_trace.id)
+    return ToolResult(output=response)
+```
 
-**职责**:加载和处理 `.prompt` 文件,支持多模态消息构建
+**实现**:`agent/tools/builtin/ask_human.py`
 
-**文件格式**:
-```yaml
----
-model: gemini-2.5-flash
-temperature: 0.3
 ---
 
-$system$
-系统提示...
+## 工具系统
 
-$user$
-用户提示:%variable%
+### 核心概念
+
+```python
+@tool()
+async def my_tool(arg: str, ctx: ToolContext) -> ToolResult:
+    return ToolResult(
+        title="Success",
+        output="Result content",
+        long_term_memory="Short summary"  # 可选:压缩后保留的摘要
+    )
 ```
 
-**核心功能**:
-- YAML frontmatter 解析(配置)
-- `$section$` 分节语法
-- `%variable%` 参数替换
-- 多模态消息支持(图片等)
+| 类型 | 作用 |
+|------|------|
+| `@tool` | 装饰器,自动注册工具并生成 Schema |
+| `ToolResult` | 工具执行结果,支持双层记忆 |
+| `ToolContext` | 工具执行上下文,依赖注入 |
 
-**实现**:
-- `agent/llm/prompts/loader.py:load_prompt()` - 文件解析
-- `agent/llm/prompts/loader.py:get_message()` - 参数替换
-- `agent/llm/prompts/wrapper.py:SimplePrompt` - Prompt 包装器
+### 工具分类
+
+| 目录 | 工具 | 说明 |
+|-----|------|------|
+| `trace/` | goal | Agent 内部计划管理 |
+| `trace/` | explore, delegate | 子 Trace 创建 |
+| `builtin/file/` | read, write, edit, glob, grep | 文件操作 |
+| `builtin/browser/` | browser actions | 浏览器自动化 |
+| `builtin/` | bash, sandbox, search, webfetch, skill, ask_human | 其他工具 |
+
+### 双层记忆管理
+
+大输出(如网页抓取)只传给 LLM 一次,之后用摘要替代:
 
-**使用**:
 ```python
-prompt = SimplePrompt("task.prompt")
-messages = prompt.build_messages(text="...", images="img.png")
+ToolResult(
+    output="<10K tokens 的完整内容>",
+    long_term_memory="Extracted 10000 chars from amazon.com",
+    include_output_only_once=True
+)
 ```
 
-### Skills(技能库)
+**详细文档**:[工具系统](./tools.md)
+
+---
+
+## Skills 系统
 
-**分类**:
+### 分类
 
 | 类型 | 加载位置 | 加载时机 |
 |------|---------|---------|
-| **Core Skill** | System Prompt | Agent 启动时自动 |
+| **Core Skill** | System Prompt | Agent 启动时自动加载 |
 | **普通 Skill** | 对话消息 | 模型调用 `skill` 工具时 |
 
-**目录结构**:
+### 目录结构
 
 ```
-./agent/skills/
-├── core.md                   # Core Skill(自动加载到 System Prompt)
-└── browser_use/              # 普通 Skill(按需加载到对话消息)
-    ├── browser-use.md
-    ├── setup.py
-    └── __init__.py
-```
-
-**Core Skill**(`agent/skills/core.md`):
-- 核心系统功能:Step 管理、进度追踪
-- 框架自动注入到 System Prompt
-
-**普通 Skill**:通过 `skill` 工具动态加载
+agent/memory/skills/
+├── core.md              # Core Skill(自动加载到 System Prompt)
+└── browser_use/         # 普通 Skill(按需加载)
 
-```python
-# Agent 运行时调用
-await tools.execute("skill", {"skill_name": "browser-use"})
-# 内容注入到对话历史
+./skills/                # 项目自定义 Skills(按需加载)
 ```
 
-**实现**:
-- `agent/memory/skill_loader.py:SkillLoader` - Markdown 解析器
-- `agent/memory/skill_loader.py:load_skills_from_dir()` - Skills 自动加载(内置 + 自定义)
-- `agent/tools/builtin/skill.py:skill()` - skill 工具实现
-- `agent/tools/builtin/skill.py:list_skills()` - 列出可用 skills
-
-**详细文档**:参考 [`docs/skills.md`](./skills.md)
+**实现**:`agent/memory/skill_loader.py`
 
-### Experiences(经验库)
+**详细文档**:[Skills 使用指南](./skills.md)
 
-**存储**:PostgreSQL + pgvector
+---
 
-```sql
-CREATE TABLE experiences (
-    exp_id TEXT PRIMARY KEY,
-    scope TEXT,           -- "agent:executor" 或 "user:123"
-    condition TEXT,       -- "当遇到数据库连接超时"
-    rule TEXT,            -- "增加重试次数到5次"
-    evidence JSONB,       -- 证据(step_ids)
+## Experiences 系统
 
-    source TEXT,          -- "execution", "feedback", "manual"
-    confidence FLOAT,
-    usage_count INT,
-    success_rate FLOAT,
+从执行历史中提取的经验规则,用于指导未来任务。
 
-    embedding vector(1536),  -- 向量检索
+### 数据结构
 
-    created_at TIMESTAMP,
-    updated_at TIMESTAMP
-);
+```python
+@dataclass
+class Experience:
+    id: str
+    scope: str           # "agent:executor" 或 "user:123"
+    condition: str       # "当遇到数据库连接超时"
+    rule: str            # "增加重试次数到5次"
+    evidence: Dict       # 证据(trace_ids)
+    confidence: float
+    usage_count: int
+    success_rate: float
+    embedding: List[float]  # 向量,用于检索
 ```
 
-**检索和注入**:
+### 检索和注入
 
 ```python
 # 1. 检索相关 Experiences
 experiences = await db.query(
-    """
-    SELECT condition, rule, success_rate
-    FROM experiences
-    WHERE scope = $1
-    ORDER BY embedding <-> $2
-    LIMIT 10
-    """,
-    f"agent:{agent_type}",
-    embed(task)
+    "SELECT * FROM experiences WHERE scope = $1 ORDER BY embedding <-> $2 LIMIT 10",
+    f"agent:{agent_type}", embed(task)
 )
 
 # 2. 注入到 system prompt
-system_prompt = base_prompt + "\n\n# Learned Experiences\n" + "\n".join([
-    f"- When {e.condition}, then {e.rule} (success rate: {e.success_rate:.1%})"
-    for e in experiences
-])
+system_prompt += "\n# Learned Experiences\n" + format_experiences(experiences)
 ```
 
-**实现**:`agent/memory/stores.py:ExperienceStore`(待实现 PostgreSQL 版本)
+**存储**:PostgreSQL + pgvector
+
+**实现**:`agent/memory/stores.py:ExperienceStore`
+
+---
+
+## Context 压缩
+
+### 压缩时机
+
+Goal 完成(done)或放弃(abandon)时,将详细 Messages 替换为 Summary Message。
+
+### 压缩策略
+
+```
+Goal 状态变化
+    ↓
+收集该 Goal 下的所有 Messages
+    ↓
+生成 Summary(由 LLM 提供)
+    ↓
+替换原始 Messages 为单条 Summary Message
+    ↓
+更新统计信息
+```
+
+**实现**:`agent/trace/compaction.py`
+
+**详细文档**:[Context 管理](./context-management.md)
 
 ---
 
@@ -439,81 +540,47 @@ system_prompt = base_prompt + "\n\n# Learned Experiences\n" + "\n".join([
 
 ```python
 class TraceStore(Protocol):
-    async def save(self, trace: Trace) -> None: ...
-    async def get(self, trace_id: str) -> Trace: ...
+    async def create_trace(self, trace: Trace) -> None: ...
+    async def get_trace(self, trace_id: str) -> Trace: ...
+    async def update_trace(self, trace_id: str, **updates) -> None: ...
     async def add_message(self, message: Message) -> None: ...
     async def get_messages(self, trace_id: str) -> List[Message]: ...
     async def get_messages_by_goal(self, trace_id: str, goal_id: str) -> List[Message]: ...
-
-class ExperienceStore(Protocol):
-    async def search(self, scope: str, query: str, limit: int) -> List[Dict]: ...
-    async def add(self, exp: Dict) -> None: ...
-    async def update_stats(self, exp_id: str, success: bool) -> None: ...
-
-class SkillLoader(Protocol):
-    async def scan(self) -> List[str]:  # 返回 skill names
-        """扫描并返回所有可用的 skill 名称"""
-
-    async def load(self, name: str) -> str:  # 返回内容
-        """加载指定 skill 的 Markdown 内容"""
 ```
 
 **实现**:
-- Trace/Message 协议:`agent/execution/protocols.py`
-- Memory 协议:`agent/memory/protocols.py`
-
-**实现策略**:
-- Trace/Message: 文件系统(JSON)
-  - `FileSystemTraceStore` - 文件持久化(支持跨进程)
-- Experience: PostgreSQL + pgvector
-- Skill: 文件系统(Markdown)
+- 协议定义:`agent/trace/protocols.py`
+- 文件存储:`agent/trace/store.py:FileSystemTraceStore`
 
----
-
-## 模块结构(v0.2.2)
+### 存储结构
 
 ```
-agent/
-├── __init__.py            # 公开 API
-│
-├── core/                  # 核心引擎
-│   ├── runner.py          # AgentRunner
-│   └── config.py          # AgentConfig, CallResult
-│
-├── execution/             # 执行追踪
-│   ├── models.py          # Trace, Message
-│   ├── protocols.py       # TraceStore
-│   ├── fs_store.py        # FileSystemTraceStore
-│   ├── api.py             # RESTful API(DAG 视图)
-│   └── websocket.py       # WebSocket
-│
-├── memory/                # 记忆系统
-│   ├── models.py          # Experience, Skill
-│   ├── protocols.py       # MemoryStore, StateStore
-│   ├── stores.py          # 存储实现
-│   └── skill_loader.py    # Skill 加载器(自动加载内置 skills)
-│
-├── tools/                 # 工具系统
-│   ├── registry.py        # ToolRegistry
-│   ├── models.py          # ToolResult, ToolContext
-│   ├── schema.py          # SchemaGenerator
-│   ├── url_matcher.py     # URL 模式匹配
-│   ├── sensitive.py       # 敏感数据处理
-│   ├── builtin/           # 核心工具
-│   ├── advanced/          # 高级工具
-│   └── adapters/          # 外部集成
-│
-├── llm/                   # LLM 相关
-│   ├── gemini.py
-│   ├── openrouter.py
-│   └── prompts/
-│       ├── loader.py
-│       └── wrapper.py
+.trace/
+├── {trace_id}/
+│   ├── meta.json        # Trace 元数据(含 tools 定义)
+│   ├── goal.json        # GoalTree(mission + goals 列表)
+│   └── messages/        # Messages
+│       ├── 0001.json
+│       └── ...
-├── skills/                # 内置 Skills(自动加载)
-│   └── core.md            # 核心 skill,每次运行自动加载
-│
-└── subagents/             # Sub-agent
+└── {trace_id}@explore-{timestamp}-001/  # 子 Trace
+    └── ...
+```
+
+**meta.json 示例**:
+```json
+{
+  "trace_id": "0415dc38-...",
+  "mode": "agent",
+  "task": "分析代码结构",
+  "agent_type": "default",
+  "status": "running",
+  "model": "google/gemini-2.5-flash",
+  "tools": [...],
+  "llm_params": {"temperature": 0.3},
+  "context": {},
+  "current_goal_id": "3"
+}
 ```
 
 ---
@@ -524,78 +591,23 @@ agent/
 
 **核心决策**:
 
-1. **Skills 通过工具加载**(vs 预先注入)
-   - 按需加载,Agent 自主选择
-   - 参考 OpenCode 和 Claude API 文档
+1. **所有 Agent 都是 Trace** - 主 Agent、子 Agent、人类协助统一为 Trace,通过 `parent_trace_id` 和 `spawn_tool` 区分
 
-2. **Skills 用文件系统**(vs 数据库)
-   - 易于编辑(Markdown)
-   - 版本控制(Git)
-   - 零依赖
+2. **trace/ 模块统一管理执行状态** - 合并原 execution/ 和 goal/,包含计划管理和 Agent 内部控制工具
 
-3. **Experiences 用数据库**(vs 文件)
-   - 需要向量检索
-   - 需要统计分析
-   - 数量大,动态更新
+3. **tools/ 专注外部交互** - 文件、命令、网络、浏览器等与外部世界的交互
 
-4. **Context 管理:GoalTree + Message + DAG 可视化**
-   - GoalTree 嵌套 JSON 注入 LLM,Messages 扁平存储
-   - DAG 可视化从 GoalTree + Messages 派生
-   - 详见 [`docs/context-management.md`](./context-management.md)
+4. **Agent 预设替代 Sub-Agent 配置** - 通过 `core/presets.py` 定义不同类型 Agent 的工具权限和参数
 
 ---
 
-## Debug 工具
-
-开发调试时可通过 API 查看 DAG 可视化:
-
-```bash
-# 启动 API Server
-python api_server.py
-
-# 查看 DAG
-curl http://localhost:8000/api/traces/{trace_id}/dag
-```
-
-**实现**:`agent/execution/api.py`
-
----
-
-## 测试
-
-详见 [测试指南](./testing.md)
-
-**测试分层**:
-- **单元测试**:Agent 定义、工具系统、Trace 模型
-- **集成测试**:Sub-Agent、Trace 存储、多模块协作
-- **E2E 测试**:真实 LLM 调用(需要 API Key)
-
-**运行测试**:
-```bash
-# 单元测试
-pytest tests/ -v -m "not e2e"
-
-# 覆盖率
-pytest --cov=agent tests/ -m "not e2e"
-
-# E2E 测试(可选)
-GEMINI_API_KEY=xxx pytest tests/e2e/ -v -m e2e
-```
-
----
+## 相关文档
 
-## 核心概念速查
-
-| 概念 | 定义 | 存储 | 实现 |
-|------|------|------|------|
-| **Trace** | 一次任务执行 | 文件系统(JSON) | `execution/models.py` |
-| **Message** | 执行消息(对应 LLM 消息) | 文件系统(JSON) | `execution/models.py` |
-| **GoalTree** | 层级执行计划 | goal.json | `goal/models.py` |
-| **Goal** | 计划中的目标节点 | 嵌套在 GoalTree 中 | `goal/models.py` |
-| **Sub-Agent** | 专门化的子代理 | 独立 Trace | `tools/builtin/task.py` |
-| **AgentDefinition** | Agent 类型定义 | 配置文件/代码 | `subagents/` |
-| **Skill** | 能力描述(Markdown) | 文件系统 | `memory/skill_loader.py` |
-| **Experience** | 经验规则(条件+规则) | 数据库 + 向量 | `memory/stores.py` |
-| **Tool** | 可调用的函数 | 内存(注册表) | `tools/registry.py` |
-| **Agent Loop** | ReAct 循环 | - | `core/runner.py` |
-| **Doom Loop** | 无限循环检测 | - | `core/runner.py` |
+| 文档 | 内容 |
+|-----|------|
+| [Context 管理](./context-management.md) | Goals、压缩、Plan 注入策略 |
+| [工具系统](./tools.md) | 工具定义、注册、双层记忆 |
+| [Skills 指南](./skills.md) | Skill 分类、编写、加载 |
+| [多模态支持](./multimodal.md) | 图片、PDF 处理 |
+| [设计决策](./decisions.md) | 架构决策记录 |
+| [测试指南](./testing.md) | 测试策略和命令 |

+ 0 - 306
docs/REFACTOR_SUMMARY.md

@@ -1,306 +0,0 @@
-# 重构总结:移除 Branch 概念,统一 Trace 模型
-
-> 完成时间:2026-02-04
->
-> 本次重构移除了旧的 branch 概念,采用统一的 Trace 模型,每个 Sub-Agent 都是完全独立的 Trace。
-
----
-
-## 重构目标
-
-将基于 branch 的设计重构为基于独立 Trace 的设计:
-- ❌ 旧设计:`.trace/{trace_id}/branches/{branch_id}/`
-- ✅ 新设计:`.trace/{parent_id}@{mode}-{timestamp}-{seq}/`
-
----
-
-## 已完成工作
-
-### ✅ Phase 1: 核心数据结构调整
-
-#### 1.1 Trace ID 生成器
-- ✅ 创建 `agent/execution/trace_id.py`
-  - `generate_trace_id()` - 生成主 Trace UUID
-  - `generate_sub_trace_id(parent_id, mode)` - 生成 Sub-Trace ID
-  - `parse_parent_trace_id(trace_id)` - 解析父 Trace ID
-  - `is_sub_trace(trace_id)` - 判断是否为 Sub-Trace
-  - `extract_mode(trace_id)` - 提取运行模式
-  - 线程安全的序号计数器
-- ✅ 创建单元测试 `tests/test_trace_id.py`
-- ✅ 所有测试通过
-
-#### 1.2 Trace 模型更新 (`agent/execution/models.py`)
-- ✅ 添加 `parent_trace_id: Optional[str]` 字段
-- ✅ 添加 `parent_goal_id: Optional[str]` 字段
-- ✅ 更新 `to_dict()` 方法
-- ✅ 确认 `context: Dict[str, Any]` 字段存在
-
-#### 1.3 Message 模型更新 (`agent/execution/models.py`)
-- ✅ **移除** `branch_id` 字段
-- ✅ 更新 `create()` 方法签名
-- ✅ 更新 `to_dict()` 方法
-- ✅ 文档字符串更新
-
-#### 1.4 Goal 模型更新 (`agent/goal/models.py`)
-- ✅ **移除** `branch_id` 字段
-- ✅ **移除** `branch_ids` 字段
-- ✅ 将 `GoalType` 从 `"explore_start" | "explore_merge"` 改为 `"normal" | "agent_call"`
-- ✅ 添加 `sub_trace_ids: Optional[List[str]]` 字段
-- ✅ 添加 `agent_call_mode: Optional[str]` 字段
-- ✅ **移除** `explore_start_id`, `merge_summary`, `selected_branch` 字段
-- ✅ 更新 `to_dict()` 和 `from_dict()` 方法
-
-#### 1.5 移除 BranchContext
-- ✅ 从 `agent/goal/models.py` 删除 `BranchContext` 类
-- ✅ 从 `agent/goal/__init__.py` 移除导出
-- ✅ **移除** `BranchStatus` 类型定义
-
-### ✅ Phase 2: 存储层重构
-
-#### 2.1 FileSystem Store 更新 (`agent/execution/fs_store.py`)
-
-**移除的方法(11 个)**:
-- ✅ `_get_branches_dir()`
-- ✅ `_get_branch_dir()`
-- ✅ `_get_branch_meta_file()`
-- ✅ `_get_branch_goal_file()`
-- ✅ `_get_branch_messages_dir()`
-- ✅ `create_branch()`
-- ✅ `get_branch()`
-- ✅ `get_branch_goal_tree()`
-- ✅ `update_branch_goal_tree()`
-- ✅ `update_branch()`
-- ✅ `list_branches()`
-
-**更新的方法**:
-- ✅ `create_trace()` - 不再创建 `branches/` 目录
-- ✅ `add_message()` - 移除 `branch_id` 逻辑
-- ✅ `_update_goal_stats()` - 移除 `branch_id` 逻辑
-- ✅ `_get_affected_goals()` - 移除 `branch_id` 逻辑
-- ✅ `get_trace_messages()` - 移除 `branch_id` 参数
-- ✅ `get_messages_by_goal()` - 移除 `branch_id` 参数
-- ✅ `update_message()` - 移除 `branch_id` 逻辑
-- ✅ `get_message()` - 不再扫描 `branches/` 目录
-
-**更新的导入**:
-- ✅ 从 `from agent.goal.models import GoalTree, Goal, BranchContext, GoalStats`
-  改为 `from agent.goal.models import GoalTree, Goal, GoalStats`
-
-#### 2.2 TraceStore 协议更新 (`agent/execution/protocols.py`)
-
-**移除的方法签名(6 个)**:
-- ✅ `create_branch()`
-- ✅ `get_branch()`
-- ✅ `get_branch_goal_tree()`
-- ✅ `update_branch_goal_tree()`
-- ✅ `update_branch()`
-- ✅ `list_branches()`
-
-**更新的方法签名**:
-- ✅ `get_trace_messages()` - 移除 `branch_id` 参数
-- ✅ `get_messages_by_goal()` - 移除 `branch_id` 参数
-
-**更新的导入**:
-- ✅ 从 `from agent.goal.models import GoalTree, Goal, BranchContext`
-  改为 `from agent.goal.models import GoalTree, Goal`
-
----
-
-## 新的 Trace ID 方案
-
-### 主 Trace
-```
-2f8d3a1c-4b6e-4f9a-8c2d-1e5b7a9f3c4d
-```
-- 标准 UUID 格式
-- 36 字符长度
-
-### Sub-Trace
-```
-2f8d3a1c-4b6e-4f9a-8c2d-1e5b7a9f3c4d@explore-20260204220012-001
-```
-- 格式:`{parent_id}@{mode}-{timestamp}-{seq}`
-- 使用**完整 UUID**作为前缀(不截断)
-- 避免 ID 冲突风险
-- 约 65-70 字符长度
-
-### 优势
-
-✅ **零碰撞风险**:使用完整 UUID
-✅ **可精确追溯**:从 Sub-Trace ID 直接看到完整父 ID
-✅ **无需冲突检测**:实现简单,不依赖外部状态
-✅ **信息完整**:一眼看出触发者、模式、时间
-✅ **线程安全**:序号生成器使用锁保护
-
----
-
-## 新的存储结构
-
-### 旧结构(已废弃)
-```
-.trace/
-├── abc123/
-│   ├── meta.json
-│   ├── goal.json
-│   ├── messages/
-│   ├── branches/        ❌ 已移除
-│   │   ├── A/
-│   │   └── B/
-│   └── events.jsonl
-```
-
-### 新结构(当前)
-```
-.trace/
-├── 2f8d3a1c-4b6e-4f9a-8c2d-1e5b7a9f3c4d/           # 主 Trace
-│   ├── meta.json                                   # parent_trace_id: null
-│   ├── goal.json
-│   ├── messages/
-│   └── events.jsonl
-│
-├── 2f8d3a1c...@explore-20260204220012-001/        # Sub-Trace A
-│   ├── meta.json                                   # parent_trace_id: "2f8d3a1c..."
-│   ├── goal.json                                   # 独立的 GoalTree
-│   ├── messages/
-│   └── events.jsonl
-│
-└── 2f8d3a1c...@explore-20260204220012-002/        # Sub-Trace B
-    └── ...
-```
-
----
-
-## 测试验证
-
-### ✅ 导入测试
-```bash
-python3 -c "from agent.execution.fs_store import FileSystemTraceStore"
-# ✅ 成功
-```
-
-### ✅ 功能测试
-- ✅ Trace 模型创建(主 + 子)
-- ✅ Sub-Trace ID 生成
-- ✅ Message 创建(无 branch_id)
-- ✅ Goal 创建(有 sub_trace_ids)
-- ✅ 父子关系设置
-
----
-
-## 待完成工作
-
-### 🔄 Phase 3: 添加 Goal 事件推送
-- [ ] 在 `fs_store.py` 中添加 `goal_added` 事件
-- [ ] 在 `fs_store.py` 中添加 `goal_updated` 事件
-- [ ] 在 `fs_store.py` 中添加 `goal_completed` 事件
-
-### ✅ Phase 4: 工具实现
-- ✅ 实现 `agent/goal/explore.py` - explore 工具
-- ✅ 实现 `agent/goal/delegate.py` - delegate 工具
-- ✅ 两个工具都会推送 `sub_trace_started` 和 `sub_trace_completed` 事件
-
-### ✅ Phase 5: API 层更新
-- ✅ 更新 `agent/execution/api.py` REST 端点
-  - 移除 `BranchDetailResponse` 模型
-  - 更新 `TraceDetailResponse` 使用 `sub_traces`
-  - 更新 `get_trace()` 端点查询 Sub-Traces
-  - 移除 `branch_id` 参数
-  - 移除 `/branches/{branch_id}` 端点
-- ✅ 更新 `agent/execution/websocket.py` 事件格式
-  - 更新事件类型文档(移除 branch 事件,添加 Sub-Trace 事件)
-  - 更新 `connected` 事件:查询 Sub-Traces 而非 branches
-  - 移除 `broadcast_branch_started()`、`broadcast_branch_goal_added()`、`broadcast_branch_completed()`、`broadcast_explore_completed()` 函数
-  - 添加 `broadcast_sub_trace_started()` 和 `broadcast_sub_trace_completed()` 函数
-
-### ✅ Phase 7: 清理和文档
-- ✅ 更新 `docs/trace-api.md` - 完整重写,移除所有 branch 引用
-- ✅ 更新 `docs/decisions.md` - 更新 explore 工具描述
-- ✅ 更新 `docs/context-comparison.md` - 更新执行流程描述
-- ✅ 更新 `frontend/API.md` - 更新 Trace ID 格式,移除 branch_id 字段
-- ✅ 清理 `agent/execution/protocols.py` - 移除注释中的 branch 引用
-- ✅ 代码中的 branch 引用已全部清理(explore.py 中的 branches 是合理的参数名)
-
-### ⏭️ 跳过的工作
-- **Phase 6**: 数据迁移(按用户要求跳过)
-
----
-
-## 文件变更汇总
-
-### 新增文件(4 个)
-- ✅ `agent/execution/trace_id.py` - Trace ID 生成工具
-- ✅ `tests/test_trace_id.py` - 单元测试
-- ✅ `agent/goal/explore.py` - explore 工具实现
-- ✅ `agent/goal/delegate.py` - delegate 工具实现
-
-### 更新文件(9 个)
-- ✅ `agent/execution/models.py` - Trace 和 Message 模型
-- ✅ `agent/goal/models.py` - Goal 模型
-- ✅ `agent/goal/__init__.py` - 导出列表
-- ✅ `agent/execution/fs_store.py` - 存储实现
-- ✅ `agent/execution/protocols.py` - 协议定义
-- ✅ `agent/execution/api.py` - REST API 端点
-- ✅ `agent/execution/websocket.py` - WebSocket 事件
-- ✅ `docs/context-management.md` - 设计文档
-- ✅ `docs/refactor-plan.md` - 重构计划
-
-### 删除的类/方法汇总
-- ❌ `BranchContext` 类
-- ❌ `BranchStatus` 类型
-- ❌ 11 个 branch 相关的存储方法
-- ❌ 6 个 branch 相关的协议方法
-- ❌ `Message.branch_id` 字段
-- ❌ `Goal.branch_id` 字段
-- ❌ `Goal.branch_ids` 字段
-- ❌ `Goal.explore_start_id` 字段
-- ❌ `Goal.merge_summary` 字段
-- ❌ `Goal.selected_branch` 字段
-
----
-
-## 影响范围
-
-### ✅ 已处理
-- ✅ 核心数据模型
-- ✅ 存储层接口和实现
-- ✅ Trace ID 生成工具
-- ✅ Goal 事件推送系统
-- ✅ explore 和 delegate 工具
-- ✅ REST API 端点
-- ✅ WebSocket 事件系统
-- ✅ 基本功能测试
-
-### ⚠️ 需要注意
-- 现有的 `.trace/` 目录中的旧数据(包含 `branches/`)如需使用,需要手动处理
-- 任何外部代码引用 `BranchContext` 或 `branch_id` 的地方需要更新
-- WebSocket 客户端需要更新以使用新的事件格式(`sub_trace_started`/`sub_trace_completed` 替代旧的 branch 事件)
-
----
-
-## 总结
-
-本次重构已全面完成从 branch 概念到统一 Trace 模型的迁移:
-
-1. ✅ **概念统一**:主 Agent 和 Sub-Agent 使用相同的 Trace 结构
-2. ✅ **ID 简洁**:每个 Trace 内部独立编号(1, 2, 3...)
-3. ✅ **完全隔离**:每个 Trace 有独立的 GoalTree、Message List
-4. ✅ **零冲突**:使用完整 UUID 避免 ID 冲突
-5. ✅ **易于分布式**:每个 Trace 可以独立运行、存储
-6. ✅ **事件系统**:Goal 变更自动推送 WebSocket 事件,支持级联完成
-7. ✅ **工具完整**:explore 和 delegate 工具已实现并正常工作
-8. ✅ **API 完善**:REST 和 WebSocket API 均已更新为新格式
-
-### 已完成的 Phase(1-5)
-
-- ✅ **Phase 1**: 核心数据结构调整
-- ✅ **Phase 2**: 存储层重构
-- ✅ **Phase 3**: Goal 事件推送
-- ✅ **Phase 4**: 工具实现(explore & delegate)
-- ✅ **Phase 5**: API 层更新(REST & WebSocket)
-
-### 跳过的 Phase(按用户要求)
-
-- ⏭️ **Phase 6**: 数据迁移(用户要求跳过)
-- ⏭️ **Phase 7**: 文档清理(可选)
-
-重构已全部完成,系统已经可以正常使用新的统一 Trace 模型。

+ 0 - 618
docs/cloud_browser_guide.md

@@ -1,618 +0,0 @@
-# Browser-Use 云浏览器模式使用指南
-
-## 目录
-
-- [简介](#简介)
-- [云浏览器 vs 本地浏览器](#云浏览器-vs-本地浏览器)
-- [环境配置](#环境配置)
-- [快速开始](#快速开始)
-- [核心概念](#核心概念)
-- [示例代码](#示例代码)
-- [高级用法](#高级用法)
-- [常见问题](#常见问题)
-- [最佳实践](#最佳实践)
-
----
-
-## 简介
-
-Browser-Use 云浏览器模式允许你在云端运行浏览器自动化任务,无需在本地安装 Chrome/Chromium。这对于以下场景特别有用:
-
-- 🚀 **无头服务器部署** - 在没有图形界面的服务器上运行
-- 🌍 **分布式爬虫** - 轻松扩展到多个云浏览器实例
-- 💻 **跨平台一致性** - 避免本地环境差异
-- 🔒 **安全隔离** - 浏览器运行在隔离的云环境中
-- 📊 **资源优化** - 不占用本地计算资源
-
----
-
-## 云浏览器 vs 本地浏览器
-
-| 特性         | 云浏览器               | 本地浏览器               |
-| ------------ | ---------------------- | ------------------------ |
-| **安装要求** | 无需安装 Chrome        | 需要安装 Chrome/Chromium |
-| **运行环境** | 云端                   | 本地机器                 |
-| **资源占用** | 不占用本地资源         | 占用本地 CPU/内存        |
-| **网络延迟** | 可能有轻微延迟         | 无网络延迟               |
-| **成本**     | 需要 API 配额          | 免费                     |
-| **调试**     | 提供 Live URL 实时查看 | 可以直接看到浏览器窗口   |
-| **适用场景** | 服务器部署、分布式任务 | 本地开发、调试           |
-
----
-
-## 环境配置
-
-### 1. 安装依赖
-
-```bash
-# 安装 browser-use
-pip install browser-use
-
-# 安装云浏览器所需的额外依赖
-pip install python-socks
-```
-
-### 2. 获取 API Key
-
-1. 访问 [Browser-Use 官网](https://browser-use.com)
-2. 注册账号并获取 API Key
-3. 将 API Key 添加到 `.env` 文件
-
-### 3. 配置环境变量
-
-在项目根目录的 `.env` 文件中添加:
-
-```bash
-# Browser-Use 云浏览器 API Key
-BROWSER_USE_API_KEY=your_api_key_here
-
-# 可选:如果需要使用 LLM 功能
-GOOGLE_API_KEY=your_google_api_key
-GEMINI_API_KEY=your_gemini_api_key
-```
-
----
-
-## 快速开始
-
-### 最简单的云浏览器示例
-
-```python
-import asyncio
-import os
-from dotenv import load_dotenv
-from agent.tools.builtin.browser.baseClass import (
-    init_browser_session,
-    cleanup_browser_session,
-    navigate_to_url,
-)
-
-# 加载环境变量
-load_dotenv()
-
-async def main():
-    # 初始化云浏览器(关键:use_cloud=True)
-    browser, tools = await init_browser_session(
-        headless=True,
-        use_cloud=True,  # 启用云浏览器
-    )
-
-    print("✅ 云浏览器已启动")
-
-    # 访问网页
-    result = await navigate_to_url("https://www.baidu.com")
-    print(f"导航结果: {result.title}")
-
-    # 清理
-    await cleanup_browser_session()
-    print("🧹 浏览器已关闭")
-
-if __name__ == "__main__":
-    asyncio.run(main())
-```
-
-### 运行示例
-
-```bash
-# 运行默认示例(示例 1)
-python examples/cloud_browser_example.py
-
-# 运行指定示例
-python examples/cloud_browser_example.py --example 2
-
-# 运行所有示例
-python examples/cloud_browser_example.py --all
-```
-
----
-
-## 核心概念
-
-### 1. 初始化云浏览器会话
-
-```python
-from agent.tools.builtin.browser.baseClass import init_browser_session
-
-# 云浏览器模式
-browser, tools = await init_browser_session(
-    headless=True,      # 云浏览器通常使用无头模式
-    use_cloud=True,     # 关键参数:启用云浏览器
-)
-```
-
-**参数说明:**
-
-- `headless`: 是否使用无头模式(云浏览器推荐 True)
-- `use_cloud`: 是否使用云浏览器(True=云浏览器,False=本地浏览器)
-- `browser_profile`: 可选,预设 cookies、localStorage 等
-- `**kwargs`: 其他 BrowserSession 参数
-
-### 2. 使用 BrowserProfile 预设配置
-
-```python
-from browser_use import BrowserProfile
-
-# 创建配置文件
-profile = BrowserProfile(
-    # 预设 cookies
-    cookies=[
-        {
-            "name": "session_id",
-            "value": "abc123",
-            "domain": ".example.com",
-            "path": "/",
-        }
-    ],
-    # 预设 localStorage
-    local_storage={
-        "example.com": {
-            "token": "your_token",
-            "user_id": "12345",
-        }
-    },
-    # 自定义 User-Agent
-    user_agent="Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7)",
-)
-
-# 使用配置初始化浏览器
-browser, tools = await init_browser_session(
-    use_cloud=True,
-    browser_profile=profile,
-)
-```
-
-### 3. 可用的工具函数
-
-项目提供了丰富的浏览器操作工具,所有工具都支持云浏览器:
-
-#### 导航类工具
-
-```python
-# 导航到 URL
-await navigate_to_url("https://example.com")
-
-# 在新标签页打开
-await navigate_to_url("https://example.com", new_tab=True)
-
-# 搜索
-await search_web("Python async", engine="google")
-
-# 返回上一页
-await go_back()
-
-# 等待
-await wait(seconds=3)
-```
-
-#### 元素交互工具
-
-```python
-# 点击元素(需要先获取元素索引)
-await click_element(index=5)
-
-# 输入文本
-await input_text(index=0, text="Hello World", clear=True)
-
-# 发送按键
-await send_keys("Enter")
-await send_keys("Control+A")
-
-# 上传文件
-await upload_file(index=7, path="/path/to/file.pdf")
-```
-
-#### 页面操作工具
-
-```python
-# 滚动页面
-await scroll_page(down=True, pages=2.0)
-
-# 查找文本
-await find_text("Privacy Policy")
-
-# 截图
-await screenshot()
-
-# 获取页面 HTML
-html_result = await get_page_html()
-
-# 获取可交互元素
-selector_result = await get_selector_map()
-
-# 执行 JavaScript
-result = await evaluate("document.title")
-```
-
-#### 标签页管理
-
-```python
-# 切换标签页
-await switch_tab(tab_id="a3f2")
-
-# 关闭标签页
-await close_tab(tab_id="a3f2")
-```
-
-#### 文件操作
-
-```python
-# 写入文件
-await write_file("output.txt", "Hello World")
-
-# 读取文件
-content = await read_file("input.txt")
-
-# 替换文件内容
-await replace_file("config.txt", "old_value", "new_value")
-```
-
----
-
-## 示例代码
-
-### 示例 1: 基础导航操作
-
-```python
-async def example_basic_navigation():
-    """访问网页并获取页面信息"""
-    browser, tools = await init_browser_session(use_cloud=True)
-
-    # 导航到百度
-    await navigate_to_url("https://www.baidu.com")
-    await wait(2)
-
-    # 获取页面标题
-    title_result = await evaluate("document.title")
-    print(f"页面标题: {title_result.output}")
-
-    # 截图
-    await screenshot()
-
-    await cleanup_browser_session()
-```
-
-### 示例 2: 搜索和内容提取
-
-```python
-async def example_search():
-    """使用搜索引擎并提取内容"""
-    browser, tools = await init_browser_session(use_cloud=True)
-
-    # 搜索
-    await search_web("Python async programming", engine="google")
-    await wait(3)
-
-    # 获取页面 HTML
-    html_result = await get_page_html()
-    print(f"HTML 长度: {len(html_result.metadata.get('html', ''))} 字符")
-
-    # 获取可交互元素
-    selector_result = await get_selector_map()
-    print(selector_result.output)
-
-    await cleanup_browser_session()
-```
-
-### 示例 3: 使用 BrowserProfile
-
-```python
-async def example_with_profile():
-    """使用预设配置"""
-    from browser_use import BrowserProfile
-
-    # 创建配置
-    profile = BrowserProfile(
-        cookies=[{
-            "name": "test_cookie",
-            "value": "test_value",
-            "domain": ".example.com",
-            "path": "/",
-        }],
-        user_agent="Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7)",
-    )
-
-    # 使用配置初始化
-    browser, tools = await init_browser_session(
-        use_cloud=True,
-        browser_profile=profile,
-    )
-
-    # 访问网页
-    await navigate_to_url("https://httpbin.org/headers")
-    await wait(2)
-
-    # 检查 User-Agent
-    ua_result = await evaluate("navigator.userAgent")
-    print(f"User-Agent: {ua_result.output}")
-
-    await cleanup_browser_session()
-```
-
-### 示例 4: 表单交互
-
-```python
-async def example_form_interaction():
-    """填写表单"""
-    browser, tools = await init_browser_session(use_cloud=True)
-
-    # 访问表单页面
-    await navigate_to_url("https://httpbin.org/forms/post")
-    await wait(2)
-
-    # 获取页面元素
-    selector_result = await get_selector_map()
-    print(f"找到 {selector_result.long_term_memory}")
-
-    # 根据实际页面结构填写表单
-    # await input_text(index=0, text="用户名")
-    # await input_text(index=1, text="密码")
-    # await click_element(index=2)  # 提交按钮
-
-    await cleanup_browser_session()
-```
-
-### 示例 5: 多标签页操作
-
-```python
-async def example_multi_tab():
-    """管理多个标签页"""
-    browser, tools = await init_browser_session(use_cloud=True)
-
-    # 第一个标签页
-    await navigate_to_url("https://www.baidu.com")
-    await wait(2)
-
-    # 新标签页
-    await navigate_to_url("https://www.google.com", new_tab=True)
-    await wait(2)
-
-    # 获取当前页面信息
-    title_result = await evaluate("document.title")
-    print(f"当前标题: {title_result.output}")
-
-    await cleanup_browser_session()
-```
-
----
-
-## 高级用法
-
-### 1. 实时查看云浏览器
-
-云浏览器启动时会输出一个 Live URL,你可以在浏览器中打开这个 URL 实时查看云浏览器的操作:
-
-```
-INFO [cloud] 🔗 Live URL: https://live.browser-use.com?wss=https%3A%2F%2F...
-```
-
-复制这个 URL 到浏览器中打开,即可实时查看云浏览器的操作。
-
-### 2. 错误处理
-
-```python
-async def example_with_error_handling():
-    browser = None
-    try:
-        browser, tools = await init_browser_session(use_cloud=True)
-
-        result = await navigate_to_url("https://example.com")
-        if result.error:
-            print(f"导航失败: {result.error}")
-            return
-
-        # 其他操作...
-
-    except Exception as e:
-        print(f"发生错误: {str(e)}")
-    finally:
-        if browser:
-            await cleanup_browser_session()
-```
-
-### 3. 会话复用
-
-```python
-# 全局会话会自动复用
-# 第一次调用会创建新会话
-browser1, tools1 = await init_browser_session(use_cloud=True)
-
-# 后续调用会返回同一个会话
-browser2, tools2 = await init_browser_session(use_cloud=True)
-
-# browser1 和 browser2 是同一个对象
-assert browser1 is browser2
-```
-
-### 4. 强制终止浏览器
-
-```python
-from agent.tools.builtin.browser.baseClass import kill_browser_session
-
-# 优雅关闭(推荐)
-await cleanup_browser_session()
-
-# 强制终止(用于异常情况)
-await kill_browser_session()
-```
-
----
-
-## 常见问题
-
-### Q1: 云浏览器启动失败
-
-**问题:** `python-socks is required to use a SOCKS proxy`
-
-**解决:**
-
-```bash
-pip install python-socks
-```
-
-### Q2: API Key 无效
-
-**问题:** `未找到 BROWSER_USE_API_KEY`
-
-**解决:**
-
-1. 确保 `.env` 文件在项目根目录
-2. 确保 API Key 格式正确
-3. 确保代码中调用了 `load_dotenv()`
-
-### Q3: 云浏览器连接超时
-
-**问题:** 云浏览器启动后无法连接
-
-**解决:**
-
-1. 检查网络连接
-2. 检查防火墙设置
-3. 尝试使用代理
-
-### Q4: 如何切换回本地浏览器
-
-**解决:**
-
-```python
-# 使用本地浏览器
-browser, tools = await init_browser_session(
-    use_cloud=False,  # 或者不传这个参数,默认是 False
-)
-```
-
-### Q5: 云浏览器的配额限制
-
-**问题:** API 配额用完了怎么办
-
-**解决:**
-
-1. 查看 Browser-Use 官网的定价计划
-2. 升级到更高的配额
-3. 优化代码,减少不必要的浏览器操作
-
----
-
-## 最佳实践
-
-### 1. 合理使用 wait
-
-```python
-# ❌ 不好:固定等待时间太长
-await wait(10)
-
-# ✅ 好:根据实际需要调整等待时间
-await wait(2)  # 页面加载
-await wait(1)  # 动画完成
-```
-
-### 2. 及时清理会话
-
-```python
-# ✅ 使用 try-finally 确保清理
-try:
-    browser, tools = await init_browser_session(use_cloud=True)
-    # 操作...
-finally:
-    await cleanup_browser_session()
-```
-
-### 3. 使用 BrowserProfile 避免重复登录
-
-```python
-# ✅ 预设 cookies,避免每次都登录
-profile = BrowserProfile(
-    cookies=[
-        # 从之前的会话中保存的 cookies
-    ]
-)
-browser, tools = await init_browser_session(
-    use_cloud=True,
-    browser_profile=profile,
-)
-```
-
-### 4. 批量操作时复用会话
-
-```python
-# ✅ 一次会话处理多个任务
-browser, tools = await init_browser_session(use_cloud=True)
-
-for url in urls:
-    await navigate_to_url(url)
-    # 处理页面...
-
-await cleanup_browser_session()
-```
-
-### 5. 使用 Live URL 调试
-
-```python
-# 开发时启用 Live URL 查看
-# 云浏览器启动时会自动输出 Live URL
-# 复制到浏览器中打开即可实时查看
-```
-
----
-
-## 性能优化建议
-
-1. **减少不必要的等待**
-   - 使用最小必要的等待时间
-   - 避免固定的长时间等待
-
-2. **批量处理**
-   - 在一个会话中处理多个任务
-   - 避免频繁创建/销毁会话
-
-3. **合理使用截图**
-   - 只在必要时截图
-   - 截图会增加网络传输时间
-
-4. **优化元素定位**
-   - 使用 `get_selector_map` 一次性获取所有元素
-   - 避免重复查询相同元素
-
----
-
-## 技术支持
-
-- **Browser-Use 官方文档**: https://docs.browser-use.com
-- **GitHub Issues**: https://github.com/browser-use/browser-use
-- **项目内部文档**: 查看 `agent/tools/builtin/baseClass.py` 的注释
-
----
-
-## 更新日志
-
-### v1.0.0 (2026-01-30)
-
-- ✅ 初始版本
-- ✅ 支持云浏览器模式
-- ✅ 提供 5 个完整示例
-- ✅ 完整的使用文档
-
----
-
-## 许可证
-
-本项目遵循项目主许可证。

+ 44 - 0
docs/decisions.md

@@ -590,3 +590,47 @@ execution trace v2.0 引入了 Blob 存储系统用于处理大输出和图片
    - 不需要拆分成 preview + ref
 
 ---
+
+## 13. 架构重组:统一 Trace 模型
+
+**日期**: 2026-02-08
+
+### 问题
+
+原有架构存在以下问题:
+1. `execution/` 和 `goal/` 目录职责边界模糊
+2. `Trace.context` 命名与 `ToolContext` 等概念混淆
+3. `subagents/` 目录与 Agent 预设概念重复
+4. 文档散乱,多个重构相关文档过时
+
+### 决策
+
+**目录重组**:
+- `execution/` + `goal/` → `trace/`(统一执行追踪和计划管理)
+- 删除 `subagents/` 目录,逻辑整合到 `trace/task_tool.py`
+- 删除 `core/config.py`,合并到 `runner.py` 和 `presets.py`
+
+**命名调整**:
+- `Trace.context` → `Trace.meta`(TraceMeta 数据类)
+
+**统一 Agent 模型**:
+- 所有 Agent(主、子、人类协助)都是 Trace
+- 子 Agent = 通过 `task` 工具创建的子 Trace
+- 人类协助 = 通过 `ask_human` 工具创建的阻塞式 Trace
+
+**Agent 预设替代 Sub-Agent 配置**:
+- `core/presets.py` 定义 Agent 类型(default, explore, analyst 等)
+- 项目级 `.agent/presets.json` 可覆盖
+
+**工具目录简化**:
+- 仅对 `file/` 和 `browser/` 做子目录分类
+- 其他工具直接放 `builtin/`
+- `goal` 和 `task` 工具放 `trace/`(Agent 内部控制)
+
+### 理由
+
+1. **概念更清晰**:trace/ 统一管理"执行状态",tools/ 专注"外部交互"
+2. **减少冗余**:删除 subagents/ 目录,用统一的 Trace 机制
+3. **命名准确**:meta 比 context 更准确表达"静态元信息"
+
+---

+ 0 - 215
docs/dependencies.md

@@ -1,215 +0,0 @@
-# Agent Framework 依赖管理
-
-## 📦 核心依赖
-
-### 必需依赖
-
-| 包名 | 版本 | 用途 |
-|------|------|------|
-| `httpx[socks]` | >=0.28.0 | HTTP 客户端,用于调用 Gemini REST API,支持 SOCKS 代理 |
-| `python-dotenv` | >=1.0.0 | 环境变量管理,用于加载 `.env` 配置文件 |
-
-### 可选依赖
-
-| 包名 | 版本 | 用途 | 安装建议 |
-|------|------|------|----------|
-| `docstring-parser` | >=0.15 | 工具文档解析,提供更好的类型提示和描述解析 | 推荐安装 |
-| `google-generativeai` | >=0.8.0 | Google Gemini SDK(不推荐使用) | ❌ 不推荐,使用 HTTP API 代替 |
-
-## 🚀 安装方式
-
-### 方式一:使用 requirements.txt(推荐)
-
-```bash
-pip install -r requirements.txt
-```
-
-### 方式二:手动安装
-
-```bash
-# 安装核心依赖
-pip install httpx[socks]>=0.28.0 python-dotenv>=1.0.0
-
-# 可选:安装 docstring-parser
-pip install docstring-parser>=0.15
-```
-
-### 方式三:使用 pip 直接安装
-
-```bash
-pip install httpx[socks] python-dotenv
-```
-
-## 📝 依赖说明
-
-### httpx[socks]
-- **用途**:异步 HTTP 客户端,用于调用 Gemini REST API
-- **为什么需要 `[socks]`**:支持 SOCKS 代理(很多用户需要代理访问 Google API)
-- **如果不需要代理**:可以只安装 `httpx`,但推荐安装完整版
-
-### python-dotenv
-- **用途**:从 `.env` 文件加载环境变量
-- **配置示例**:
-  ```bash
-  # .env
-  GEMINI_API_KEY=your_api_key_here
-  ```
-
-### docstring-parser(可选)
-- **用途**:解析工具函数的 docstring,提取参数类型和描述
-- **如果没安装**:框架会使用 fallback 解析器,功能稍弱但可用
-- **推荐理由**:提供更准确的工具 schema 生成
-
-### google-generativeai(不推荐)
-- **为什么不推荐**:
-  - SDK 对 JSON Schema 格式要求严格,与 OpenAI 工具格式不完全兼容
-  - 难以调试和自定义
-  - HTTP API 提供更好的控制和灵活性
-- **何时使用**:仅用于学习或简单场景
-
-## 🔧 开发依赖
-
-如果你要开发或测试框架,还需要:
-
-```bash
-# 测试框架
-pip install pytest pytest-asyncio
-
-# 代码质量
-pip install black flake8 mypy
-
-# 文档生成
-pip install mkdocs mkdocs-material
-```
-
-## 🌐 Python 版本要求
-
-- **最低版本**:Python 3.9
-- **推荐版本**:Python 3.11+
-- **兼容性**:
-  - ✅ Python 3.9+
-  - ✅ Python 3.10
-  - ✅ Python 3.11
-  - ✅ Python 3.12
-
-## 📋 依赖检查
-
-运行以下命令检查依赖是否正确安装:
-
-```bash
-python3 -c "
-import httpx
-import dotenv
-print('✅ 核心依赖安装成功')
-
-try:
-    import docstring_parser
-    print('✅ docstring-parser 已安装')
-except ImportError:
-    print('⚠️  docstring-parser 未安装(可选)')
-"
-```
-
-## 🐛 常见问题
-
-### Q1: 安装 httpx 时报错 "No module named 'socksio'"
-
-**解决方案**:
-```bash
-pip install 'httpx[socks]'
-```
-
-### Q2: ImportError: cannot import name 'AsyncClient' from 'httpx'
-
-**解决方案**:升级 httpx 到最新版本
-```bash
-pip install --upgrade httpx
-```
-
-### Q3: 代理设置
-
-如果你使用代理,在 `.env` 中配置:
-```bash
-HTTP_PROXY=socks5://127.0.0.1:7890
-HTTPS_PROXY=socks5://127.0.0.1:7890
-```
-
-或者在代码中设置:
-```python
-import httpx
-
-client = httpx.AsyncClient(
-    proxies={
-        "http://": "socks5://127.0.0.1:7890",
-        "https://": "socks5://127.0.0.1:7890"
-    }
-)
-```
-
-## 📦 生成 requirements.txt
-
-如果你修改了依赖,可以重新生成:
-
-```bash
-# 导出当前环境所有包(不推荐)
-pip freeze > requirements-full.txt
-
-# 手动维护 requirements.txt(推荐)
-# 只包含项目直接依赖,不包括子依赖
-```
-
-## 🔄 更新依赖
-
-```bash
-# 更新所有依赖到最新版本
-pip install --upgrade -r requirements.txt
-
-# 更新特定包
-pip install --upgrade httpx
-```
-
-## 🎯 最小化依赖原则
-
-本框架遵循最小化依赖原则:
-- ✅ 只依赖必需的包
-- ✅ 避免大型框架(如 Django, FastAPI)
-- ✅ 使用标准库优先(asyncio, json, logging)
-- ✅ 可选依赖明确标注
-
-## 📊 依赖关系图
-
-```
-agent/
-├── httpx (必需)
-│   ├── httpcore
-│   ├── certifi
-│   ├── idna
-│   └── socksio (SOCKS 代理支持)
-│
-├── python-dotenv (必需)
-│
-└── docstring-parser (可选)
-```
-
-## 🌟 生产环境建议
-
-生产环境推荐固定版本:
-
-```txt
-# requirements-prod.txt
-httpx[socks]==0.28.1
-python-dotenv==1.2.1
-docstring-parser==0.16
-```
-
-使用:
-```bash
-pip install -r requirements-prod.txt
-```
-
-## 📚 相关文档
-
-- [httpx 文档](https://www.python-httpx.org/)
-- [python-dotenv 文档](https://github.com/theskumar/python-dotenv)
-- [docstring-parser 文档](https://github.com/rr-/docstring_parser)
-- [Gemini API 文档](https://ai.google.dev/api/rest)

+ 0 - 129
docs/project-structure.md

@@ -1,129 +0,0 @@
-# Agent Framework 目录结构
-
-> 框架与应用分层设计
-
----
-
-## 核心架构
-
-**框架层** (`agent/`): 核心代码、内置预设,可作为独立包发布
-
-**应用层** (项目根目录): 项目特定配置,覆盖或扩展框架
-
----
-
-## 框架层(`agent/`)
-
-```
-agent/
-├── core/                       # 核心引擎
-│   ├── runner.py               # AgentRunner
-│   └── config.py               # AgentConfig, CallResult
-├── execution/                  # 执行追踪
-│   ├── models.py               # Trace, Step
-│   ├── protocols.py            # TraceStore
-│   ├── fs_store.py             # FileSystemTraceStore
-│   └── tree_dump.py            # 可视化
-├── memory/                     # 记忆系统
-│   ├── models.py               # Experience, Skill
-│   ├── protocols.py            # MemoryStore, StateStore
-│   ├── stores.py               # 存储实现
-│   └── skill_loader.py         # Skill 加载器(自动加载内置 skills)
-├── tools/                      # 工具系统
-│   ├── builtin/                # 内置基础工具
-│   ├── advanced/               # 高级工具(第三方适配)
-│   └── adapters/               # 外部集成
-├── llm/                        # LLM 相关
-│   ├── gemini.py
-│   ├── openrouter.py
-│   └── prompts/                # Prompt 工具
-├── skills/                     # 框架内置 Skills(自动加载)
-│   ├── core.md                 # 核心 skill,每次运行自动加载
-│   └── browser_use/            # 浏览器自动化 skill
-└── subagents/                  # 内置 Sub-Agent 定义
-```
-
-**实现**:
-- 核心引擎:`agent/core/runner.py`
-- 执行追踪:`agent/execution/`
-- 记忆系统:`agent/memory/`(Skills 自动加载)
-- 工具系统:`agent/tools/`
-- LLM 集成:`agent/llm/`
-- Skills:`agent/skills/core.md`(自动加载)+ `agent/skills/browser_use/`(按需加载)
-- Sub-Agent 预设:`agent/subagents/`
-
----
-
-## 应用层(项目根目录)
-
-项目特定配置(可选):
-
-```
-your-project/
-├── skills/                     # 项目特定 Skills
-├── subagents/                  # 项目特定 Sub-Agents
-└── tools/                      # 项目特定工具
-```
-
----
-
-## 加载优先级
-
-| 资源 | 框架预设 | 项目配置 | 优先级 |
-|------|---------|---------|--------|
-| Skills | `agent/skills/` | `./skills/` | 项目优先(`agent/skills/core.md` 总是自动加载) |
-| Sub-Agents | `agent/subagents/` | `./subagents/` | 项目覆盖 |
-| Tools | `agent/tools/builtin/` | `./tools/` | 手动注册 |
-
-**实现**:
-- Skills 自动加载:`agent/memory/skill_loader.py:load_skills_from_dir()`
-  - 总是自动加载 `agent/skills/` 中的所有 skills(包括 `core.md`)
-  - 可选加载 `skills_dir` 参数指定的额外自定义 skills
-- Skills 工具动态加载:`agent/tools/builtin/skill.py` - 搜索路径 `./skills/` → `./agent/skills/`
-- Sub-Agents 加载:按顺序加载配置,后加载的覆盖先加载的
-
----
-
-## 使用方式
-
-### 加载框架预设
-
-```python
-from agent import AgentRunner
-from agent.llm import create_gemini_llm_call
-
-# Skills 自动加载
-# - agent/skills/core.md 总是自动加载
-# - agent/skills/ 中的其他 skills 也会自动加载
-runner = AgentRunner(
-    llm_call=create_gemini_llm_call(),
-    # skills_dir 可选:加载额外的自定义 skills
-)
-```
-
-### 扩展框架(可选)
-
-```python
-# 加载项目特定的自定义 skills
-runner = AgentRunner(
-    llm_call=create_gemini_llm_call(),
-    skills_dir="./skills",  # 额外加载项目自定义 skills
-)
-
-# 结果:agent/skills/ + ./skills/ 中的所有 skills 都会被加载
-```
-
-**Skills 加载机制**:
-- **自动加载**:`agent/skills/` 中的所有 skills(包括 `core.md`)总是自动加载
-- **可选加载**:通过 `skills_dir` 参数额外加载项目自定义 skills
-- **动态加载**:通过 `skill` 工具运行时按需加载特定 skill
-
-详见 [`SKILLS_SYSTEM.md`](../SKILLS_SYSTEM.md)
-
----
-
-## 相关文档
-
-- [Sub-Agent 配置](./sub-agents.md) - Sub-Agent 定义格式
-- [Skills](./skills.md) - Skill 使用和编写
-- [工具系统](./tools.md) - 工具注册和使用

+ 0 - 0
docs/context-comparison.md → docs/ref/context-comparison.md


+ 0 - 174
docs/refactor-plan.md

@@ -1,174 +0,0 @@
-# 重构计划:统一 Trace 模型
-
-> 基于更新后的 context-management.md 设计,移除 branch 概念,采用独立 Trace 架构
-
-## 目标
-
-将当前基于 branch 的实现重构为统一的 Trace 模型,每个 Sub-Agent 都是独立的 Trace。
-
-## Phase 1: 核心数据结构调整
-
-### 1.1 Trace ID 生成器
-- [ ] 实现 `agent/execution/trace_id.py`
-  - [ ] `generate_sub_trace_id(parent_id, mode)` 函数
-  - [ ] `parse_parent_trace_id(trace_id)` 函数
-  - [ ] 线程安全的序号计数器
-  - [ ] 单元测试
-
-### 1.2 Trace 模型更新
-- [ ] 更新 `agent/execution/models.py:Trace`
-  - [ ] 添加 `parent_trace_id: Optional[str]` 字段
-  - [ ] 添加 `parent_goal_id: Optional[str]` 字段
-  - [ ] 确保 `context: Dict[str, Any]` 字段存在
-  - [ ] 更新 `to_dict()` 和 `from_dict()` 方法
-  - [ ] 移除任何 branch 相关字段(如果有)
-
-### 1.3 Message 模型更新
-- [ ] 更新 `agent/execution/models.py:Message`
-  - [ ] **移除** `branch_id` 字段
-  - [ ] 确保 `duration_ms` 字段存在
-  - [ ] 更新 `to_dict()` 方法
-  - [ ] 更新 `create()` 方法
-
-### 1.4 Goal 模型更新
-- [ ] 更新 `agent/goal/models.py:Goal`
-  - [ ] **移除** `branch_id` 字段
-  - [ ] **移除** `branch_ids` 字段
-  - [ ] 确保 `sub_trace_ids` 字段存在
-  - [ ] 更新 `to_dict()` 和 `from_dict()` 方法
-
-### 1.5 移除 BranchContext
-- [ ] 删除 `agent/goal/models.py:BranchContext` 类
-  - [ ] 检查所有引用
-  - [ ] 移除相关导入
-
-## Phase 2: 存储层重构
-
-### 2.1 FileSystem Store 更新
-- [ ] 重构 `agent/execution/fs_store.py`
-  - [ ] **移除** `_get_branches_dir()` 方法
-  - [ ] **移除** `_get_branch_dir()` 方法
-  - [ ] **移除** `_get_branch_meta_file()` 方法
-  - [ ] **移除** `_get_branch_goal_file()` 方法
-  - [ ] **移除** `_get_branch_messages_dir()` 方法
-  - [ ] **移除** `create_branch()` 方法
-  - [ ] **移除** `get_branch()` 方法
-  - [ ] **移除** `get_branch_goal_tree()` 方法
-  - [ ] **移除** `update_branch_goal_tree()` 方法
-  - [ ] **移除** `update_branch()` 方法
-  - [ ] **移除** `list_branches()` 方法
-  - [ ] 更新 `create_trace()` - 不再创建 branches/ 目录
-  - [ ] 更新 `add_message()` - 移除 branch_id 逻辑
-  - [ ] 更新 `get_trace_messages()` - 移除 branch_id 参数
-  - [ ] 更新 `get_messages_by_goal()` - 移除 branch_id 参数
-  - [ ] 更新 `_update_goal_stats()` - 移除 branch_id 逻辑
-  - [ ] 更新 `_get_affected_goals()` - 移除 branch_id 逻辑
-
-### 2.2 TraceStore 协议更新
-- [ ] 更新 `agent/execution/protocols.py:TraceStore`
-  - [ ] **移除** branch 相关方法签名
-  - [ ] 更新方法签名(移除 branch_id 参数)
-  - [ ] 添加查询 Sub-Trace 的方法(如果需要)
-
-### 2.3 数据迁移脚本
-- [ ] 创建 `scripts/migrate_traces.py`
-  - [ ] 读取旧的 `.trace/*/branches/` 结构
-  - [ ] 为每个 branch 生成新的 trace_id
-  - [ ] 创建独立的 Trace 目录
-  - [ ] 更新 Goal 的 sub_trace_ids
-  - [ ] 移除 branch_id 字段
-  - [ ] 备份原始数据
-
-## Phase 3: 工具实现
-
-### 3.1 explore 工具
-- [ ] 实现 `agent/goal/explore.py`
-  - [ ] `explore_tool(branches, background)` 函数
-  - [ ] 使用 `generate_sub_trace_id()` 生成 Sub-Trace ID
-  - [ ] 创建独立的 Trace 实例
-  - [ ] 并行执行 Sub-Traces
-  - [ ] 汇总结果
-  - [ ] 单元测试
-
-### 3.2 delegate 工具
-- [ ] 实现 `agent/goal/delegate.py`
-  - [ ] `delegate_tool(task)` 函数
-  - [ ] 使用 `generate_sub_trace_id()` 生成 Sub-Trace ID
-  - [ ] 创建独立的 Trace 实例
-  - [ ] 执行并返回结果
-  - [ ] 单元测试
-
-### 3.3 goal 工具更新
-- [ ] 更新 `agent/goal/tool.py`
-  - [ ] 移除任何 branch 相关逻辑
-  - [ ] 确保与新的 Goal 模型兼容
-
-## Phase 4: API 层更新
-
-### 4.1 REST API
-- [ ] 更新 `agent/execution/api.py`
-  - [ ] `GET /api/traces/{trace_id}` - 支持新的 trace_id 格式
-  - [ ] 添加查询 Sub-Traces 的端点
-  - [ ] 移除 branch 相关端点
-  - [ ] 更新响应格式(包含 sub_traces)
-
-### 4.2 WebSocket
-- [ ] 更新 `agent/execution/websocket.py`
-  - [ ] 移除 branch 相关事件
-  - [ ] 添加 `sub_trace_started` 事件
-  - [ ] 添加 `sub_trace_completed` 事件
-  - [ ] 更新事件格式
-
-## Phase 5: 清理和测试
-
-### 5.1 清理
-- [ ] 搜索代码库中所有 "branch" 引用
-  - [ ] 移除或更新相关代码
-- [ ] 删除 `.trace/*/branches/` 目录(旧数据)
-- [ ] 更新所有文档引用
-
-### 5.2 测试
-- [ ] 单元测试
-  - [ ] Trace ID 生成器
-  - [ ] explore 工具
-  - [ ] delegate 工具
-  - [ ] FileSystem Store
-- [ ] 集成测试
-  - [ ] 创建主 Trace
-  - [ ] 启动 Sub-Trace
-  - [ ] 查询跨 Trace 数据
-- [ ] 端到端测试
-  - [ ] 完整的 explore 流程
-  - [ ] 完整的 delegate 流程
-
-## Phase 6: 文档更新
-
-- [ ] 更新 README
-- [ ] 更新 API 文档
-- [ ] 添加迁移指南
-- [ ] 更新示例代码
-
-## 实施顺序建议
-
-1. **Phase 1** (数据结构) - 最重要,先打好基础
-2. **Phase 2.1-2.2** (存储层) - 核心存储逻辑
-3. **Phase 3** (工具实现) - 业务功能
-4. **Phase 4** (API 层) - 对外接口
-5. **Phase 2.3** (数据迁移) - 处理历史数据
-6. **Phase 5** (清理测试) - 确保质量
-7. **Phase 6** (文档) - 最后完善
-
-## 风险和注意事项
-
-1. **兼容性**:旧的 traces 数据需要迁移
-2. **并发安全**:`generate_sub_trace_id` 的序号生成器需要线程安全
-3. **性能**:独立 Trace 可能增加文件系统操作,需要监控
-4. **调试**:新的 trace_id 格式较长,需要确保日志和 UI 能正确显示
-
-## 完成标准
-
-- [ ] 所有测试通过
-- [ ] 文档更新完成
-- [ ] 示例代码可运行
-- [ ] 没有 branch 相关代码残留
-- [ ] 旧数据可以迁移

+ 0 - 241
docs/sub-agents.md

@@ -1,241 +0,0 @@
-# Sub-Agent 实现指南
-
-> **可执行规格书**:Sub-Agent 实现细节。代码修改必须同步更新此文档。
-
----
-
-## 数据模型
-
-### AgentDefinition
-
-```python
-# agent/subagents/agent.py
-
-@dataclass
-class AgentDefinition:
-    name: str
-    description: Optional[str] = None
-    mode: Literal["primary", "subagent", "all"] = "all"
-
-    # 权限配置
-    allowed_tools: Optional[List[str]] = None  # 白名单
-    denied_tools: Optional[List[str]] = None   # 黑名单
-    permissions: Dict[str, Any] = field(default_factory=dict)
-
-    # 模型配置
-    model: Optional[str] = None
-    temperature: Optional[float] = None
-    max_iterations: Optional[int] = None
-    system_prompt: Optional[str] = None
-
-    # 是否可以调用其他 Sub-Agent
-    can_spawn_subagent: bool = False
-```
-
-**实现位置**:`agent/subagents/agent.py:AgentDefinition`(待实现)
-
-### Trace 扩展
-
-```python
-# agent/execution/models.py (扩展现有模型)
-
-@dataclass
-class Trace:
-    # ... 原有字段
-
-    # Sub-Agent 支持(新增)
-    parent_trace_id: Optional[str] = None    # 父 Trace ID
-    agent_definition: Optional[str] = None   # Agent 类型名称
-    spawned_by_tool: Optional[str] = None    # 启动此 Sub-Agent 的 Step ID
-```
-
-**实现位置**:`agent/execution/models.py:Trace`
-
----
-
-## 内置 Sub-Agent
-
-### 1. general - 通用型
-
-```python
-GENERAL_AGENT = AgentDefinition(
-    name="general",
-    description="通用型 Sub-Agent,执行复杂的多步骤任务",
-    mode="subagent",
-    denied_tools=["task"],
-    max_iterations=20,
-)
-```
-
-**用途**:多步骤任务、数据收集、复杂分析
-
-### 2. explore - 探索型
-
-```python
-EXPLORE_AGENT = AgentDefinition(
-    name="explore",
-    description="探索型 Sub-Agent,快速查找文件和代码",
-    mode="subagent",
-    allowed_tools=["read_file", "list_files", "search_code", "search_files"],
-    denied_tools=["write_file", "edit_file", "execute_bash", "task"],
-    max_iterations=15,
-)
-```
-
-**用途**:代码库探索、文件查找、结构分析
-
-### 3. analyst - 分析型
-
-```python
-ANALYST_AGENT = AgentDefinition(
-    name="analyst",
-    description="分析型 Sub-Agent,深度分析和报告生成",
-    mode="subagent",
-    allowed_tools=["read_file", "list_files", "search_code", "web_search", "fetch_url"],
-    denied_tools=["task", "write_file", "edit_file"],
-    max_iterations=25,
-    temperature=0.3,
-)
-```
-
-**用途**:技术栈分析、性能分析、安全审计
-
-**实现位置**:`agent/builtin_agents.py`(待实现)
-
----
-
-## 核心 API
-
-### Task Tool
-
-```python
-# agent/tools/builtin/task.py
-
-@tool(name="task")
-async def task_tool(
-    subagent_type: str,      # Sub-Agent 类型
-    description: str,         # 任务简短描述(3-5词)
-    prompt: str,              # 详细任务描述
-    ctx: ToolContext
-) -> ToolResult:
-    """启动 Sub-Agent 处理子任务"""
-```
-
-**实现位置**:`agent/tools/builtin/task.py:task_tool`(待实现)
-
-### Agent Registry
-
-```python
-# agent/agent_registry.py
-
-class AgentRegistry:
-    def register(self, agent: AgentDefinition) -> None:
-        """注册 Agent"""
-
-    def get(self, name: str) -> Optional[AgentDefinition]:
-        """获取 Agent 定义"""
-
-    def list_subagents(self) -> List[AgentDefinition]:
-        """列出所有可用的 Sub-Agent"""
-
-    def load_from_config(self, config_path: str) -> None:
-        """从配置文件加载"""
-
-# 全局注册表
-def get_agent_registry() -> AgentRegistry:
-    """获取全局 Agent 注册表"""
-```
-
-**实现位置**:`agent/agent_registry.py:AgentRegistry`(待实现)
-
----
-
-## 配置文件
-
-### 格式
-
-```json
-{
-  "agents": {
-    "code-reviewer": {
-      "description": "代码审查专家",
-      "mode": "subagent",
-      "allowed_tools": ["read_file", "search_code", "list_files"],
-      "max_iterations": 15,
-      "temperature": 0.2,
-      "system_prompt": "你是代码审查专家...",
-      "can_spawn_subagent": false
-    }
-  }
-}
-```
-
-**框架预设**:`agent/subagents/default.json`
-
-**项目配置**(可选):`./subagents/custom.json`
-
-### 加载
-
-```python
-from agent.agent_registry import get_agent_registry
-
-# 加载框架预设
-registry = get_agent_registry()
-registry.load_from_config("agent/subagents/default.json")
-
-# 加载项目自定义配置(可选,覆盖框架预设)
-from pathlib import Path
-if Path("./subagents/custom.json").exists():
-    registry.load_from_config("./subagents/custom.json")
-```
-
----
-
-## 使用示例
-
-### 基本使用
-
-```python
-from agent import AgentRunner, AgentConfig
-
-runner = AgentRunner(
-    llm_call=your_llm,
-    config=AgentConfig(max_iterations=20),
-)
-
-# 主 Agent 会自动使用 task 工具启动 Sub-Agent
-async for event in runner.run(
-    task="使用 explore sub-agent 查找所有配置文件"
-):
-    if event.type == "conclusion":
-        print(event.data["content"])
-```
-
-### 自定义 Sub-Agent
-
-```python
-from agent.models.agent import AgentDefinition
-from agent.agent_registry import get_agent_registry
-
-# 定义
-custom = AgentDefinition(
-    name="security-scanner",
-    description="安全扫描专家",
-    mode="subagent",
-    allowed_tools=["read_file", "search_code"],
-)
-
-# 注册
-get_agent_registry().register(custom)
-```
-
-**完整示例**:`examples/subagent_example.py`
-
----
-
-## 注意事项
-
-1. **防止递归**:默认禁止 Sub-Agent 调用 task 工具
-2. **权限隔离**:Sub-Agent 只能访问允许的工具
-3. **Trace 完整性**:每个 Sub-Agent 有独立的 Trace
-4. **成本控制**:跟踪每个 Sub-Agent 的 token 消耗

+ 0 - 109
docs/testing.md

@@ -1,109 +0,0 @@
-# 测试指南
-
-> 项目测试策略和运行方法
-
----
-
-## 测试分层
-
-```
-E2E 测试 - 真实 LLM 调用(需要 API Key)
-    ↑
-集成测试 - 多模块协作(Mock LLM)
-    ↑
-单元测试 - 单个函数/类
-```
-
----
-
-## 运行测试
-
-### 本地运行
-
-```bash
-# 单元测试 + 集成测试
-pytest tests/ -v -m "not e2e"
-
-# 指定模块
-pytest tests/test_agent_definition.py -v
-
-# 生成覆盖率报告
-pytest --cov=agent --cov-report=html tests/ -m "not e2e"
-
-# E2E 测试(可选,需要 API Key)
-GEMINI_API_KEY=xxx pytest tests/e2e/ -v -m e2e
-```
-
-### CI 运行
-
-```bash
-# 单元测试 + 集成测试(PR 时运行)
-pytest tests/ -v -m "not e2e" --cov=agent
-
-# E2E 测试(仅 main 分支)
-pytest tests/e2e/ -v -m e2e
-```
-
----
-
-## 覆盖率要求
-
-| 模块 | 目标覆盖率 |
-|------|-----------|
-| agent/core/ | 90%+ |
-| agent/execution/ | 90%+ |
-| agent/memory/ | 80%+ |
-| agent/tools/ | 85%+ |
-| agent/llm/ | 70%+ |
-
----
-
-## 测试标记
-
-```python
-# 单元测试(默认)
-def test_something():
-    pass
-
-# E2E 测试(需要 API Key)
-@pytest.mark.e2e
-def test_real_llm():
-    pass
-```
-
----
-
-## CI 配置
-
-```yaml
-# .github/workflows/test.yml
-
-jobs:
-  test:
-    - name: Run tests
-      run: pytest tests/ -v -m "not e2e" --cov=agent
-
-  e2e:
-    if: github.ref == 'refs/heads/main'
-    - name: Run E2E tests
-      env:
-        GEMINI_API_KEY: ${{ secrets.GEMINI_API_KEY }}
-      run: pytest tests/e2e/ -v -m e2e
-```
-
----
-
-## 测试文件结构
-
-```
-tests/
-├── conftest.py              # Fixtures
-├── test_agent_definition.py
-├── test_trace.py
-├── test_tools.py
-├── integration/
-│   ├── test_subagent.py
-│   └── test_trace_store.py
-└── e2e/
-    └── test_subagent_e2e.py
-```

+ 0 - 232
docs/tools-adapters.md

@@ -1,232 +0,0 @@
-# 工具适配器
-
-> 参考 opencode 实现的基础工具,移植到 Python 并集成到框架
-
----
-
-## ⚠️ 第三方工具接入规范
-
-**工具分类原则**:
-
-| 类型 | 实现方式 | 目录结构 | 示例 |
-|------|---------|---------|------|
-| **高频&简单工具** | Python 原生实现 | `agent/tools/builtin/` | read_file, edit_file, bash_command |
-| **复杂&低频工具** | 第三方仓库 + 适配器 | `vendor/` + `agent/tools/adapters/` + `agent/tools/advanced/` | webfetch, lsp_diagnostics |
-| **CLI 命令行工具** | pip 安装到虚拟环境 | `requirements.txt` + `bash_command` 调用 | browser-use |
-
-**接入流程**:
-
-1. **简单工具**:直接在 `builtin/` 实现
-   - 参考第三方设计(如 opencode)
-   - Python 完整实现
-   - 通过 `@tool` 装饰器注册
-
-2. **复杂工具**:通过适配器调用
-   - 第三方仓库 → `vendor/`(Git Submodule,只读)
-   - 适配器/桥接 → `agent/tools/adapters/`
-   - 工具注册 → `agent/tools/advanced/`
-
-3. **CLI 工具**:通过 bash_command 调用
-   - 添加到 `requirements.txt`
-   - pip 安装到项目虚拟环境
-   - 通过 `bash_command` 工具调用 CLI
-   - 在 `skills/` 中提供使用指导
-
-**设计目标**:
-- 参考 opencode 的成熟工具设计(Git Submodule: `vendor/opencode/`)
-- Python 实现:基础工具(builtin/)完整复刻,高级工具(advanced/)通过 Bun 调用
-- 保持解耦,便于独立维护和更新
-
----
-
-## 架构设计
-
-```
-vendor/opencode/                       # Git submodule(只读参考)
-  └── packages/opencode/src/tool/      # TypeScript 实现
-
-agent/tools/
-  ├── builtin/                         # 基础工具(Python 完整实现)
-  │   ├── read.py, edit.py, write.py  # 文件操作
-  │   ├── bash.py                      # 命令执行
-  │   └── glob.py, grep.py             # 文件搜索
-  │
-  ├── advanced/                        # 高级工具(Bun 适配器)
-  │   ├── webfetch.py                  # 网页抓取
-  │   └── lsp.py                       # LSP 诊断
-  │
-  └── adapters/
-      ├── base.py                      # 适配器基类
-      ├── opencode_bun_adapter.py      # Bun 调用适配器
-      └── opencode-wrapper.ts          # TypeScript 桥接
-```
-
-**实现策略**:
-- 基础工具(高频):Python 完整实现(~1-5ms,零依赖)
-- 高级工具(低频复杂):通过 Bun 调用 opencode(~50-100ms,功能完整)
-
----
-
-## 工具清单
-
-### 基础工具(Python 实现)
-
-| 工具 | 实现 | 功能 |
-|------|------|------|
-| `read_file` | `builtin/read.py` | 读取文件(文本/图片/PDF),分页支持 |
-| `edit_file` | `builtin/edit.py` | 文件编辑,9 种智能匹配策略 |
-| `write_file` | `builtin/write.py` | 文件写入,自动创建目录 |
-| `bash_command` | `builtin/bash.py` | 命令执行,超时控制 |
-| `glob_files` | `builtin/glob.py` | 文件模式匹配 |
-| `grep_content` | `builtin/grep.py` | 内容搜索(ripgrep 优先) |
-| `skill` | `builtin/skill.py` | 加载技能文档 |
-| `list_skills` | `builtin/skill.py` | 列出可用技能 |
-
-**参考源**:`vendor/opencode/packages/opencode/src/tool/*.ts`
-
-**关键实现**:
-- `edit_file` 的 9 种策略:包含 Levenshtein 算法的 BlockAnchorReplacer
-- `bash_command` 的环境变量支持
-- `grep_content` 的 ripgrep fallback
-
-### 高级工具(Bun 适配器)
-
-| 工具 | 实现 | 调用方式 |
-|------|------|----------|
-| `webfetch` | `advanced/webfetch.py` | Bun → opencode(HTML 转 MD)|
-| `lsp_diagnostics` | `advanced/lsp.py` | Bun → opencode(LSP 集成)|
-
-**依赖**:需要 [Bun](https://bun.sh/) 运行时
-
-**桥接**:`adapters/opencode-wrapper.ts` 通过子进程调用 opencode 工具
-
-### CLI 工具(pip 安装)
-
-| 工具 | 安装方式 | 调用方式 |
-|------|---------|----------|
-| `browser-use` | `pip install browser-use` | `bash_command` 调用 CLI |
-
-**依赖检查**:自动检测并提示缺失的依赖
-
-```python
-# 1. 加载 skill 时自动检查(会提示缺失的依赖)
-await skill(skill_name="browser-use")
-# 输出包含:⚠️ Setup Required - pip install browser-use / uvx browser-use install
-
-# 2. 手动检查依赖(使用 skill 自带的配置工具)
-from agent.skills.browser_use import check_browser_use
-await check_browser_use()
-# 返回详细的依赖状态
-
-# 3. 自动安装 Chromium(可选,需要下载 200-300MB)
-from agent.skills.browser_use import install_browser_use_chromium
-await install_browser_use_chromium()
-```
-
-**使用示例**:
-```python
-# Agent 加载使用指南
-await skill(skill_name="browser-use")
-
-# 通过 bash_command 调用 CLI
-await bash_command(command="browser-use open https://example.com")
-await bash_command(command="browser-use state")
-await bash_command(command="browser-use click 5")
-```
-
-**Skill 文档**:`agent/skills/browser_use/browser-use.md` 提供完整的 CLI 使用指南
-
----
-
-## 适配器接口
-
-**实现**:`agent/tools/adapters/base.py:ToolAdapter`
-
-核心方法:
-- `adapt_execute()` - 执行工具并转换结果为 `ToolResult`
-- `adapt_schema()` - 转换工具 Schema
-- `extract_memory()` - 提取长期记忆摘要
-
-**Bun 适配器**:`adapters/opencode_bun_adapter.py:OpenCodeBunAdapter`
-- 通过子进程调用 `bun run opencode-wrapper.ts <tool> <args>`
-- 30 秒超时
-- JSON 结果解析
-
----
-
-## 更新 opencode 参考
-
-### 检查更新
-
-```bash
-# 查看 submodule 状态
-git submodule status
-
-# 更新 submodule
-cd vendor/opencode
-git pull origin main
-cd ../..
-
-# 提交更新
-git add vendor/opencode
-git commit -m "chore: update opencode reference"
-```
-
-### 同步改进
-
-1. **查看 opencode 变更**:
-   ```bash
-   cd vendor/opencode
-   git log --oneline --since="1 month ago" -- packages/opencode/src/tool/
-   ```
-
-2. **对比实现差异**:
-   - 查看 opencode 的具体改动
-   - 评估是否需要同步到 Python 实现
-
-3. **更新 Python 实现**:
-   - 在 `agent/tools/builtin/` 中更新对应工具
-   - 更新代码注释中的参考位置
-
-4. **测试验证**:
-   ```bash
-   pytest tests/tools/builtin/ -v
-   ```
-
----
-
-## 使用示例
-
-```python
-from agent.tools.builtin import read_file, edit_file, bash_command
-from agent.tools.advanced import webfetch
-
-# 基础工具
-result = await read_file(file_path="config.py", limit=100)
-result = await edit_file(file_path="config.py", old_string="DEBUG = True", new_string="DEBUG = False")
-result = await bash_command(command="git status", timeout=30)
-
-# 高级工具(需要 Bun)
-result = await webfetch(url="https://docs.python.org/3/")
-```
-
-工具通过 `@tool` 装饰器自动注册到 `ToolRegistry`。
-
-**完整示例**:`examples/tools_complete_demo.py`
-
----
-
-## 关键设计
-
-**Git Submodule 原则**:
-- `vendor/opencode/` 只读,绝不修改
-- 作为参考源,可随时更新:`cd vendor/opencode && git pull`
-- 基础工具手动同步重要改进,高级工具自动获得更新
-
-**高内聚原则**:
-- `opencode-wrapper.ts` 与 `opencode_bun_adapter.py` 在同一目录(`adapters/`)
-- Wrapper 是适配器的一部分,不是独立脚本
-
-**性能权衡**:
-- 基础工具(高频):Python 实现避免子进程开销
-- 高级工具(低频):Bun 适配器避免重复实现复杂逻辑

+ 1 - 1
examples/feature_extract/run.py

@@ -17,7 +17,7 @@ load_dotenv()
 
 from agent.llm.prompts import SimplePrompt
 from agent.core.runner import AgentRunner
-from agent.execution import (
+from agent.trace import (
     FileSystemTraceStore,
     Trace,
     Message,

+ 1 - 1
examples/research/run.py

@@ -17,7 +17,7 @@ load_dotenv()
 
 from agent.llm.prompts import SimplePrompt
 from agent.core.runner import AgentRunner
-from agent.execution import (
+from agent.trace import (
     FileSystemTraceStore,
     Trace,
     Message,

+ 0 - 276
examples/test_plan.py

@@ -1,276 +0,0 @@
-"""
-测试新的 Plan 系统
-
-测试 GoalTree、Message、TraceStore 的基本功能
-"""
-
-import asyncio
-import sys
-from pathlib import Path
-
-# 添加项目根目录到 Python 路径
-sys.path.insert(0, str(Path(__file__).parent.parent.parent))
-
-from agent.goal.models import GoalTree, Goal, GoalStats
-from agent.execution.models import Trace, Message
-from agent.execution.fs_store import FileSystemTraceStore
-from agent.goal.tool import goal_tool
-
-
-async def test_basic_plan():
-    """测试基本的计划功能"""
-    print("=" * 60)
-    print("测试 1: 基本计划功能")
-    print("=" * 60)
-    print()
-
-    # 1. 创建 GoalTree
-    tree = GoalTree(mission="实现用户认证功能")
-    print("1. 创建 GoalTree")
-    print(f"   Mission: {tree.mission}")
-    print()
-
-    # 2. 添加顶层目标
-    print("2. 添加顶层目标")
-    result = goal_tool(tree, add="分析代码, 实现功能, 测试")
-    print(result)
-    print()
-
-    # 3. Focus 到目标 2
-    print("3. Focus 到目标 2")
-    result = goal_tool(tree, focus="2")
-    print(result)
-    print()
-
-    # 4. 添加子目标
-    print("4. 在目标 2 下添加子目标")
-    result = goal_tool(tree, add="设计接口, 实现代码, 单元测试")
-    print(result)
-    print()
-
-    # 5. Focus 到子目标并完成
-    print("5. Focus 到 2.1 并完成")
-    result = goal_tool(tree, focus="3")  # 内部 ID 是 3("2.1" 的内部 ID)
-    print(result)
-    print()
-
-    # 通过显示 ID 完成
-    print("6. 完成目标(使用内部 ID)")
-    result = goal_tool(tree, done="API 接口设计完成,定义了登录和注册端点")
-    print(result)
-    print()
-
-    # 7. 测试 abandon
-    print("7. Focus 到 4(2.2)并放弃")
-    result = goal_tool(tree, focus="4")
-    print(result)
-    print()
-
-    result = goal_tool(tree, abandon="发现需求变更,需要改用 OAuth")
-    print(result)
-    print()
-
-    # 8. 添加新方案
-    print("8. 添加新的实现方案")
-    result = goal_tool(tree, add="实现 OAuth 认证")
-    print(result)
-    print()
-
-    # 9. 查看最终状态
-    print("9. 查看完整计划(包含废弃目标)")
-    print(tree.to_prompt(include_abandoned=True))
-    print()
-
-    # 10. 查看过滤后的计划(默认不显示废弃目标)
-    print("10. 查看过滤后的计划(默认)")
-    print(tree.to_prompt())
-    print()
-
-
-async def test_trace_store():
-    """测试 TraceStore 的 GoalTree 和 Message 存储"""
-    print("=" * 60)
-    print("测试 2: TraceStore 存储功能")
-    print("=" * 60)
-    print()
-
-    # 创建 TraceStore
-    store = FileSystemTraceStore(base_path=".trace_test")
-
-    # 1. 创建 Trace
-    print("1. 创建 Trace")
-    trace = Trace.create(
-        mode="agent",
-        task="测试任务"
-    )
-    await store.create_trace(trace)
-    print(f"   Trace ID: {trace.trace_id[:8]}...")
-    print()
-
-    # 2. 创建并保存 GoalTree
-    print("2. 创建并保存 GoalTree")
-    tree = GoalTree(mission="测试任务")
-    tree.add_goals(["分析", "实现", "测试"])
-    await store.update_goal_tree(trace.trace_id, tree)
-    print(f"   添加了 {len(tree.goals)} 个目标")
-    print()
-
-    # 3. 添加 Messages
-    print("3. 添加 Messages")
-
-    # Focus 到第一个目标
-    tree.focus("1")
-    await store.update_goal_tree(trace.trace_id, tree)
-
-    # 添加 assistant message
-    msg1 = Message.create(
-        trace_id=trace.trace_id,
-        role="assistant",
-        sequence=1,
-        goal_id="1",
-        content={"text": "开始分析代码", "tool_calls": [
-            {
-                "id": "call_1",
-                "function": {
-                    "name": "read_file",
-                    "arguments": '{"path": "src/main.py"}'
-                }
-            }
-        ]},
-        tokens=100,
-        cost=0.002
-    )
-    await store.add_message(msg1)
-    print(f"   Message 1: {msg1.description}")
-
-    # 添加 tool message
-    msg2 = Message.create(
-        trace_id=trace.trace_id,
-        role="tool",
-        sequence=2,
-        goal_id="1",
-        tool_call_id="call_1",
-        content={"tool_name": "read_file", "result": "文件内容..."},
-        tokens=50,
-        cost=0.001
-    )
-    await store.add_message(msg2)
-    print(f"   Message 2: {msg2.description}")
-    print()
-
-    # 4. 查看更新后的 GoalTree(stats 应该自动更新)
-    print("4. 查看更新后的 GoalTree(含 stats)")
-    updated_tree = await store.get_goal_tree(trace.trace_id)
-    goal1 = updated_tree.find("1")
-    print(f"   Goal 1 stats:")
-    print(f"     - message_count: {goal1.self_stats.message_count}")
-    print(f"     - total_tokens: {goal1.self_stats.total_tokens}")
-    print(f"     - total_cost: ${goal1.self_stats.total_cost:.4f}")
-    print()
-
-    # 5. 添加子目标和 Message
-    print("5. 添加子目标和 Message")
-    updated_tree.add_goals(["读取配置", "解析代码"], parent_id="1")
-    updated_tree.focus("4")  # Focus 到第一个子目标
-    await store.update_goal_tree(trace.trace_id, updated_tree)
-
-    msg3 = Message.create(
-        trace_id=trace.trace_id,
-        role="assistant",
-        sequence=3,
-        goal_id="4",
-        content={"text": "读取配置文件"},
-        tokens=80,
-        cost=0.0015
-    )
-    await store.add_message(msg3)
-    print(f"   添加子目标 Message: {msg3.description}")
-    print()
-
-    # 6. 查看累计 stats(父节点应该包含子节点的统计)
-    print("6. 查看累计 stats")
-    updated_tree = await store.get_goal_tree(trace.trace_id)
-    goal1 = updated_tree.find("1")
-    print(f"   Goal 1 cumulative stats:")
-    print(f"     - message_count: {goal1.cumulative_stats.message_count}")
-    print(f"     - total_tokens: {goal1.cumulative_stats.total_tokens}")
-    print(f"     - total_cost: ${goal1.cumulative_stats.total_cost:.4f}")
-    print()
-
-    # 7. 查看 Messages
-    print("7. 查询 Messages")
-    all_messages = await store.get_trace_messages(trace.trace_id)
-    print(f"   总共 {len(all_messages)} 条 Messages")
-
-    goal1_messages = await store.get_messages_by_goal(trace.trace_id, "1")
-    print(f"   Goal 1 的 Messages: {len(goal1_messages)} 条")
-    print()
-
-    # 8. 显示完整 GoalTree
-    print("8. 完整 GoalTree")
-    print(updated_tree.to_prompt())
-    print()
-
-    # 9. 测试级联完成
-    print("9. 测试级联完成")
-    updated_tree.focus("4")
-    updated_tree.complete("4", "配置读取完成")
-    updated_tree.focus("5")
-    updated_tree.complete("5", "代码解析完成")
-
-    # 检查父节点是否自动完成
-    goal1 = updated_tree.find("1")
-    print(f"   Goal 1 status: {goal1.status}")
-    print(f"   Goal 1 summary: {goal1.summary}")
-    print()
-
-    print("✅ TraceStore 测试完成!")
-    print(f"   数据保存在: .trace_test/{trace.trace_id[:8]}...")
-    print()
-
-
-async def test_display_ids():
-    """测试显示 ID 的生成"""
-    print("=" * 60)
-    print("测试 3: 显示 ID 生成")
-    print("=" * 60)
-    print()
-
-    tree = GoalTree(mission="测试显示 ID")
-
-    # 添加多层嵌套目标
-    tree.add_goals(["A", "B", "C"])
-    tree.focus("2")
-    tree.add_goals(["B1", "B2"])
-    tree.focus("4")
-    tree.add_goals(["B1-1", "B1-2"])
-
-    print("完整结构:")
-    print(tree.to_prompt())
-    print()
-
-    # 测试 abandon 后的重新编号
-    print("放弃 B1-1 后:")
-    tree.focus("6")
-    tree.abandon("6", "测试废弃")
-    print(tree.to_prompt())
-    print()
-
-    print("包含废弃目标的完整视图:")
-    print(tree.to_prompt(include_abandoned=True))
-    print()
-
-
-async def main():
-    """运行所有测试"""
-    await test_basic_plan()
-    await test_trace_store()
-    await test_display_ids()
-
-    print("=" * 60)
-    print("所有测试完成!")
-    print("=" * 60)
-
-
-if __name__ == "__main__":
-    asyncio.run(main())

+ 1 - 0
vendor/browser-use

@@ -0,0 +1 @@
+Subproject commit c011d07e7e9e41c06b5c72036c6e3efa5b9f287d