OpenManus代码详解(五):app/tool/planning.py

请添加图片描述

往期推荐:

1. OpenManus架构解析
2. OpenManus代码详解(一):app/agent
3. OpenManus代码详解(二):app/flow
4. OpenManus代码详解(三):app/tool
5. OpenManus代码详解(四):app/schema.py
6. OpenManus代码详解(五):app/tool/planning.py
7. OpenManus代码详解(六):代码调用流程

官方地址:https://github.com/mannaandpoem/OpenManus


1. PlanningTool 类定义

class PlanningTool(BaseTool):
    """计划管理工具"""
    name: str = "planning"
    description: str = "用于创建和管理任务计划"
    plans: Dict[str, Dict] = Field(default_factory=dict)  # 存储所有计划
    
    parameters: dict = {
        "type": "object",
        "properties": {
            "command": {
                "type": "string",
                "enum": ["create", "get", "mark_step", "update"]
            },
            "plan_id": {"type": "string"},
            "title": {"type": "string"},
            "steps": {"type": "array", "items": {"type": "string"}},
            "step_index": {"type": "integer"},
            "step_status": {"type": "string"}
        },
        "required": ["command", "plan_id"]
    }

2. 主要命令实现

2.1 创建计划
async def _create_plan(self, plan_id: str, title: str, steps: List[str]) -> Dict:
    """创建新计划"""
    plan = {
        "id": plan_id,
        "title": title,
        "steps": steps,
        "step_statuses": ["not_started"] * len(steps),
        "created_at": time.time()
    }
    self.plans[plan_id] = plan
    return plan
2.2 获取计划
async def _get_plan(self, plan_id: str) -> Dict:
    """获取计划详情"""
    if plan_id not in self.plans:
        raise ValueError(f"Plan {plan_id} not found")
    return self.plans[plan_id]
2.3 更新步骤状态
async def _mark_step(self, plan_id: str, step_index: int, step_status: str) -> Dict:
    """更新步骤状态"""
    plan = await self._get_plan(plan_id)
    if step_index >= len(plan["steps"]):
        raise ValueError(f"Step index {step_index} out of range")
    plan["step_statuses"][step_index] = step_status
    return plan

3. 执行流程

  1. 初始化流程:
# 创建工具实例
planning_tool = PlanningTool()

# 添加到工具集合
tools = ToolCollection(planning_tool, ...)
  1. 创建计划流程:
# 代理调用工具创建计划
await planning_tool.execute(
    command="create",
    plan_id="plan_123",
    title="示例计划",
    steps=["步骤1", "步骤2", "步骤3"]
)
  1. 执行计划流程:
# 1. 获取计划
plan = await planning_tool.execute(
    command="get",
    plan_id="plan_123"
)

# 2. 更新步骤状态
for step_index in range(len(plan["steps"])):
    # 标记步骤为进行中
    await planning_tool.execute(
        command="mark_step",
        plan_id="plan_123",
        step_index=step_index,
        step_status="in_progress"
    )
    
    # 执行步骤...
    
    # 标记步骤完成
    await planning_tool.execute(
        command="mark_step",
        plan_id="plan_123",
        step_index=step_index,
        step_status="completed"
    )

4. 完整调用示例

async def example_planning_flow():
    # 1. 创建计划工具
    planning_tool = PlanningTool()
    
    # 2. 创建新计划
    plan = await planning_tool.execute(
        command="create",
        plan_id="task_001",
        title="开发新功能",
        steps=[
            "分析需求",
            "设计架构",
            "编写代码",
            "测试验证"
        ]
    )
    
    # 3. 获取计划详情
    current_plan = await planning_tool.execute(
        command="get",
        plan_id="task_001"
    )
    
    # 4. 更新第一个步骤状态
    await planning_tool.execute(
        command="mark_step",
        plan_id="task_001",
        step_index=0,
        step_status="in_progress"
    )
    
    # 5. 完成第一个步骤
    await planning_tool.execute(
        command="mark_step",
        plan_id="task_001",
        step_index=0,
        step_status="completed"
    )

5. 状态流转

计划步骤状态的流转:

not_started -> in_progress -> completed
     ^            |
     |            v
     +---- blocked ----+

6. 错误处理

async def execute(self, **kwargs) -> Any:
    try:
        command = kwargs.get("command")
        plan_id = kwargs.get("plan_id")
        
        if not command or not plan_id:
            raise ValueError("Missing required parameters")
            
        if command == "create":
            return await self._create_plan(
                plan_id=plan_id,
                title=kwargs.get("title", "Untitled Plan"),
                steps=kwargs.get("steps", [])
            )
        elif command == "get":
            return await self._get_plan(plan_id)
        # ... 其他命令处理
            
    except Exception as e:
        logger.error(f"Error in PlanningTool: {str(e)}")
        raise

7. 与其他组件的交互

  1. 与 PlanningFlow 的交互:
class PlanningFlow(BaseFlow):
    planning_tool: PlanningTool = Field(default_factory=PlanningTool)
    
    async def execute(self, input_text: str) -> str:
        # 创建初始计划
        await self.planning_tool.execute(...)
        
        # 执行计划步骤
        while True:
            step_info = await self._get_current_step_info()
            if not step_info:
                break
                
            # 执行步骤
            await self._execute_step(...)
  1. 与 Memory 的集成:
# 记录计划相关的消息
self.memory.add_message(
    Message.tool_message(
        content=f"Created plan: {plan['title']}",
        name="planning",
        tool_call_id="..."
    )
)

工具提供了完整的计划管理功能,包括创建、查询、更新计划,以及跟踪每个步骤的执行状态。它与代理系统紧密集成,支持复杂任务的分解和执行跟踪。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值