Parcourir la source

refactor: improve project structure

Talegorithm il y a 4 semaines
Parent
commit
d662097715
52 fichiers modifiés avec 755 ajouts et 3324 suppressions
  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(pip install:*)",
       "Bash(timeout 60 python:*)",
       "Bash(timeout 60 python:*)",
       "Bash(timeout 240 python:*)",
       "Bash(timeout 240 python:*)",
-      "Bash(curl:*)"
+      "Bash(curl:*)",
+      "Bash(tree:*)"
     ],
     ],
     "deny": [],
     "deny": [],
     "ask": []
     "ask": []

+ 17 - 7
agent/__init__.py

@@ -4,19 +4,21 @@ Reson Agent - 模块化、可扩展的 Agent 框架
 核心导出:
 核心导出:
 - AgentRunner: Agent 执行引擎
 - AgentRunner: Agent 执行引擎
 - AgentConfig: Agent 配置
 - AgentConfig: Agent 配置
-- Trace, Step: 执行追踪
+- Trace, Message, Goal: 执行追踪
 - Experience, Skill: 记忆模型
 - Experience, Skill: 记忆模型
 - tool: 工具装饰器
 - tool: 工具装饰器
 - TraceStore, MemoryStore: 存储接口
 - 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
 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 import tool, ToolRegistry, get_tool_registry
 from agent.tools.models import ToolResult, ToolContext
 from agent.tools.models import ToolResult, ToolContext
 
 
-__version__ = "0.2.0"
+__version__ = "0.3.0"
 
 
 __all__ = [
 __all__ = [
     # Core
     # Core
     "AgentRunner",
     "AgentRunner",
     "AgentConfig",
     "AgentConfig",
     "CallResult",
     "CallResult",
-    # Execution
+    "AgentPreset",
+    "AGENT_PRESETS",
+    "get_preset",
+    # Trace
     "Trace",
     "Trace",
+    "Message",
     "Step",
     "Step",
     "StepType",
     "StepType",
     "StepStatus",
     "StepStatus",
+    "Goal",
+    "GoalTree",
+    "GoalStatus",
     "TraceStore",
     "TraceStore",
+    "FileSystemTraceStore",
     # Memory
     # Memory
     "Experience",
     "Experience",
     "Skill",
     "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())
 1. Agent 主循环逻辑(call() 和 run())
 2. 配置数据类(AgentConfig, CallResult)
 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__ = [
 __all__ = [
     "AgentRunner",
     "AgentRunner",
     "BUILTIN_TOOLS",
     "BUILTIN_TOOLS",
     "AgentConfig",
     "AgentConfig",
     "CallResult",
     "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
 import logging
+from dataclasses import dataclass
 from datetime import datetime
 from datetime import datetime
 from typing import AsyncIterator, Optional, Dict, Any, List, Callable, Literal, Union
 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.models import Experience, Skill
 from agent.memory.protocols import MemoryStore, StateStore
 from agent.memory.protocols import MemoryStore, StateStore
 from agent.memory.skill_loader import load_skills_from_dir
 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__)
 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 = [
 BUILTIN_TOOLS = [
     # 文件操作工具
     # 文件操作工具
@@ -370,7 +390,7 @@ class AgentRunner:
                 goal_tree = await self.trace_store.get_goal_tree(trace_id)
                 goal_tree = await self.trace_store.get_goal_tree(trace_id)
 
 
                 # 设置 goal_tree 到 goal 工具(供 LLM 调用)
                 # 设置 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)
                 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)
 参考版本: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.bash import bash_command
 from agent.tools.builtin.skill import skill, list_skills
 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.search import search_posts, get_search_suggestions
 from agent.tools.builtin.sandbox import (sandbox_create_environment, sandbox_run_shell,
 from agent.tools.builtin.sandbox import (sandbox_create_environment, sandbox_run_shell,
                                          sandbox_rebuild_with_ports,sandbox_destroy_environment)
                                          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
 import agent.tools.builtin.browser  # noqa: F401
 
 
 __all__ = [
 __all__ = [
+    # 文件操作
     "read_file",
     "read_file",
     "edit_file",
     "edit_file",
     "write_file",
     "write_file",
     "glob_files",
     "glob_files",
     "grep_content",
     "grep_content",
+    # 系统工具
     "bash_command",
     "bash_command",
     "skill",
     "skill",
     "list_skills",
     "list_skills",
-    "goal",
     "search_posts",
     "search_posts",
     "get_search_suggestions",
     "get_search_suggestions",
     "sandbox_create_environment",
     "sandbox_create_environment",

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

@@ -1250,8 +1250,24 @@ async def browser_get_selector_map() -> ToolResult:
     try:
     try:
         browser, tools = await get_browser_session()
         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 = []
         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)
 # 默认 skills 目录(优先级:项目 skills > 框架 skills)
 DEFAULT_SKILLS_DIRS = [
 DEFAULT_SKILLS_DIRS = [
     os.getenv("SKILLS_DIR", "./skills"),      # 项目特定 skills(优先)
     os.getenv("SKILLS_DIR", "./skills"),      # 项目特定 skills(优先)
-    "./agent/skills"                           # 框架内置 skills
+    "./agent/memory/skills"                    # 框架内置 skills
 ]
 ]
 
 
 # 默认单一目录(用于 list_skills)
 # 默认单一目录(用于 list_skills)
@@ -36,7 +36,7 @@ def _check_skill_setup(skill_name: str) -> Optional[str]:
     if skill_name in ["browser-use", "browser_use"]:
     if skill_name in ["browser-use", "browser_use"]:
         try:
         try:
             # 动态导入 browser-use skill 的 setup 模块
             # 动态导入 browser-use skill 的 setup 模块
-            from agent.skills.browser_use.setup import (
+            from agent.memory.skills.browser_use.setup import (
                 _check_browser_use_cli,
                 _check_browser_use_cli,
                 _check_chromium_installed
                 _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 fastapi import APIRouter, HTTPException, Query
 from pydantic import BaseModel
 from pydantic import BaseModel
 
 
-from agent.execution.protocols import TraceStore
+from .protocols import TraceStore
 
 
 
 
 router = APIRouter(prefix="/api/traces", tags=["traces"])
 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 typing import List, Dict, Any, Optional
-from agent.goal.models import GoalTree, Goal
+from .goal_models import GoalTree, Goal
 
 
 
 
 def compress_messages_for_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 typing import Optional, Dict, Any
 from datetime import datetime
 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(
 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 typing import List, Optional, Dict, Any
 from datetime import datetime
 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(
 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 typing import Optional, List, TYPE_CHECKING
 
 
+from agent.tools import tool
+
 if TYPE_CHECKING:
 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(
 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 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
 @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 typing import Dict, List, Optional, Any
 from datetime import datetime
 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:
 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
        code .trace/tree.txt
 
 
     3. 代码中使用:
     3. 代码中使用:
-       from agent.execution import dump_tree
+       from agent.trace import dump_tree
        dump_tree(trace, steps)
        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 datetime import datetime
 from fastapi import APIRouter, WebSocket, WebSocketDisconnect, Query
 from fastapi import APIRouter, WebSocket, WebSocketDisconnect, Query
 
 
-from agent.execution.protocols import TraceStore
+from .protocols import TraceStore
 
 
 
 
 router = APIRouter(prefix="/api/traces", tags=["websocket"])
 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
 from fastapi.middleware.cors import CORSMiddleware
 import uvicorn
 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 功能需求与架构设计文档
 # 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(技能库)                                     │
 │ Layer 3: Skills(技能库)                                     │
-│ - Markdown 文件,存储详细的能力描述                            │
-│ - 通过 skill 工具按需加载                                     │
+│ - Markdown 文件,存储领域知识和能力描述
+│ - 通过 skill 工具按需加载到对话历史
 └─────────────────────────────────────────────────────────────┘
 └─────────────────────────────────────────────────────────────┘
                               │ 归纳
                               │ 归纳
@@ -53,43 +100,39 @@
                               │ 提取
                               │ 提取
 ┌─────────────────────────────────────────────────────────────┐
 ┌─────────────────────────────────────────────────────────────┐
-│ Layer 1: Task State(任务状态)
+│ Layer 1: Trace(任务状态)     
 │ - 当前任务的工作记忆                                          │
 │ - 当前任务的工作记忆                                          │
 │ - Trace + Messages 记录执行过程                               │
 │ - Trace + Messages 记录执行过程                               │
-│ - GoalTree 管理执行计划
+│ - Goals 管理执行计划   
 └─────────────────────────────────────────────────────────────┘
 └─────────────────────────────────────────────────────────────┘
 ```
 ```
 
 
-**注入方式**:
-- **Skills**:通过 `skill` 工具动态加载到对话历史
-- **Experiences**:检索后注入到 system prompt
-
 ---
 ---
 
 
 ## 核心流程:Agent Loop
 ## 核心流程:Agent Loop
 
 
 ```python
 ```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
     # 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 = 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}]
     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()
         plan_text = goal_tree.to_prompt()
 
 
         # 调用 LLM
         # 调用 LLM
@@ -100,67 +143,35 @@ async def run(task: str, max_steps: int = 50) -> AsyncIterator[Union[Trace, Mess
         )
         )
 
 
         # 记录 assistant Message
         # 记录 assistant Message
-        assistant_msg = Message.create(
+        await store.add_message(Message.create(
             trace_id=trace.trace_id,
             trace_id=trace.trace_id,
             role="assistant",
             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
         yield assistant_msg
 
 
         # 没有工具调用,完成
         # 没有工具调用,完成
         if not response.tool_calls:
         if not response.tool_calls:
             break
             break
 
 
-        # 执行工具
+        # 执行工具,记录 tool Message
         for tool_call in response.tool_calls:
         for tool_call in response.tool_calls:
             result = await execute_tool(tool_call)
             result = await execute_tool(tool_call)
-
-            # 记录 tool Message
-            tool_msg = Message.create(
+            await store.add_message(Message.create(
                 trace_id=trace.trace_id,
                 trace_id=trace.trace_id,
                 role="tool",
                 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
             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"
     trace.status = "completed"
-    await trace_store.update_trace(trace.trace_id, status="completed")
     yield trace
     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(任务执行)
 ### Trace(任务执行)
 
 
+一次完整的 Agent 执行。所有 Agent(主、子、人类协助)都是 Trace。
+
 ```python
 ```python
 @dataclass
 @dataclass
 class Trace:
 class Trace:
     trace_id: str
     trace_id: str
-    mode: Literal["call", "agent"]
+    mode: Literal["call", "agent"]           # 单次调用 or Agent 模式
+
+    # Prompt 标识
+    prompt_name: Optional[str] = None
+
+    # Agent 模式特有
     task: Optional[str] = None
     task: Optional[str] = None
     agent_type: 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_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_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
     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(执行消息)
 ### Message(执行消息)
 
 
-对应 LLM API 的消息,加上元数据。不再有 parent_id 树结构。
+对应 LLM API 的消息,每条 Message 关联一个 Goal
 
 
 ```python
 ```python
 @dataclass
 @dataclass
 class Message:
 class Message:
-    message_id: str
+    message_id: str                          # 格式:{trace_id}-{sequence:04d}
     trace_id: str
     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
     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
 ```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
 ```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` 工具时 |
 | **普通 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
 ```python
 # 1. 检索相关 Experiences
 # 1. 检索相关 Experiences
 experiences = await db.query(
 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
 # 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
 ```python
 class TraceStore(Protocol):
 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 add_message(self, message: Message) -> None: ...
     async def get_messages(self, trace_id: str) -> List[Message]: ...
     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]: ...
     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
    - 不需要拆分成 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.llm.prompts import SimplePrompt
 from agent.core.runner import AgentRunner
 from agent.core.runner import AgentRunner
-from agent.execution import (
+from agent.trace import (
     FileSystemTraceStore,
     FileSystemTraceStore,
     Trace,
     Trace,
     Message,
     Message,

+ 1 - 1
examples/research/run.py

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