Skip to content

Create PlannerComponent for Step-by-Step Plan Generation

Summary

Create a PlannerComponent that enables AI agents to generate detailed step-by-step plans for achieving user goals, with specialized state update capabilities for plan management.

Description

This issue implements part of the design document from gitlab-com/content-sites/handbook!14034 (merged) and follows the componentization architecture established in #1216 (closed). The PlannerComponent should be similar to AgentComponent but with enhanced capabilities for plan creation and management.

Current State:

  • Planning functionality exists in duo_workflow_service/tools/planner.py with specialized tools
  • ToolsExecutor at duo_workflow_service/agents/tools_executor.py handles planner tools differently
  • No dedicated component exists for plan generation workflows

Key Differences from AgentComponent:

  1. State Update Capability: ToolsNode must be capable of writing updates to the state context:<component_name>.plan
  2. Plan Output: Must write to context:<component_name>.plan
  3. Specialized Tools: Uses planner-specific tools that modify workflow state directly

Requirements

Core Functionality:

  • Create PlannerComponent class extending BaseComponent
  • Implement plan generation with step-by-step task breakdown
  • Support output to context:<component_name>.plan format
  • Enable detailed planning workflows for complex user goals

Technical Implementation:

  • Extend AgentComponent architecture with plan-specific modifications
  • Implement specialized PlannerToolsNode that handles plan specific tools, be aware of #1189 which outlines problems with injection of state into tools execution
  • Support planner tools from duo_workflow_service/tools/planner.py:
    • CreatePlan - Create initial plan with tasks
    • AddNewTask - Add tasks to existing plan
    • RemoveTask - Remove tasks from plan
    • UpdateTaskDescription - Modify task descriptions
    • SetTaskStatus - Update task completion status
    • GetPlan - Retrieve current plan state

State Management:

  • Verify if LangGraphCommand responses for state updates can be used, alternatively create dedicated node that will return correct state updates directly
  • Manage plan state through specialized tools
  • Support plan reset and incremental updates
  • Integrate with existing Plan and Task entities

Integration Points:

  • Leverage existing planner tools
  • Maintain compatibility with BaseComponent interface
  • Support prompt registry integration for planning prompts

Output Specification:

  • Write plan output to context:<component_name>.plan
  • Support structured plan format with tasks and status
  • Enable plan persistence across workflow steps

Technical Notes

Reference Implementation:

  • Study duo_workflow_service/tools/planner.py for tool behavior
  • Understand LangGraphCommand usage in planner tools for state updates

Key Differences in Tool Handling:

# Standard tools return strings/ToolMessage
def standard_tool_run(self, args) -> str:
    return "Tool result"

# Planner tools return LangGraphCommand for state updates  
def planner_tool_run(self, args) -> LangGraphCommand:
    return LangGraphCommand(
        update={
            "conversation_history": {...},
            "context": { "plan": Plan(steps=steps, reset=reset) },
        }
    )

Acceptance Criteria

  1. PlannerComponent generates detailed step-by-step plans
  2. Component outputs to context:<component_name>.plan format
  3. Planner tools work correctly with state updat
  4. Plan state is properly managed and persisted
  5. Integration with existing planning tools is seamless
  6. Component follows BaseComponent interface patterns

Examples

Expected Usage:

planner = PlannerComponent(
    name="task_planner",
    flow_id="workflow_123",
    flow_type=CategoryEnum.DUO_WORKFLOW,
    inputs=[IOKey(target="user_request")],
    prompt_id="planner_prompt",
    prompt_version="v1.0",
    toolset=planner_toolset,
)

Expected Output:

# In workflow state after execution
state["context"]["task_planner"]["plan"] = {
    "steps": [
        {"id": "task-0", "description": "Analyze requirements", "status": "not_started"},
        {"id": "task-1", "description": "Design solution", "status": "not_started"},
        {"id": "task-2", "description": "Implement changes", "status": "not_started"}
    ],
    "reset": False
}

Related Issues

Definition of Done

  • PlannerComponent implementation complete
  • Specialized PlannerToolsNode handles state updates
  • Plan output correctly written to context
  • Integration tests with planner tools passing
  • Documentation and examples provided
Edited by Mikołaj Wawrzyniak