Home / Class/ TodoListMiddleware Class — langchain Architecture

TodoListMiddleware Class — langchain Architecture

Architecture documentation for the TodoListMiddleware class in todo.py from the langchain codebase.

Entity Profile

Dependency Diagram

graph TD
  60552546_6c10_6b0f_fd5d_93ed6530c806["TodoListMiddleware"]
  de5a7878_b3fe_95d7_2575_7f534546dc1e["AIMessage"]
  60552546_6c10_6b0f_fd5d_93ed6530c806 -->|extends| de5a7878_b3fe_95d7_2575_7f534546dc1e
  446b9f1c_796b_e509_22cc_36bc6d734792["todo.py"]
  60552546_6c10_6b0f_fd5d_93ed6530c806 -->|defined in| 446b9f1c_796b_e509_22cc_36bc6d734792
  d98ccf82_4d6c_11e1_1817_de4c6a3ada8b["__init__()"]
  60552546_6c10_6b0f_fd5d_93ed6530c806 -->|method| d98ccf82_4d6c_11e1_1817_de4c6a3ada8b
  599153ad_dee9_927c_45d6_fb594a726e10["wrap_model_call()"]
  60552546_6c10_6b0f_fd5d_93ed6530c806 -->|method| 599153ad_dee9_927c_45d6_fb594a726e10
  a0cc0972_2027_cf0e_3988_c5620bb2f307["awrap_model_call()"]
  60552546_6c10_6b0f_fd5d_93ed6530c806 -->|method| a0cc0972_2027_cf0e_3988_c5620bb2f307
  73f986fb_c908_2f34_a4a9_57bb8e22cdaa["after_model()"]
  60552546_6c10_6b0f_fd5d_93ed6530c806 -->|method| 73f986fb_c908_2f34_a4a9_57bb8e22cdaa
  76ba8848_1b95_5006_0db6_dc2692e6deda["aafter_model()"]
  60552546_6c10_6b0f_fd5d_93ed6530c806 -->|method| 76ba8848_1b95_5006_0db6_dc2692e6deda

Relationship Graph

Source Code

libs/langchain_v1/langchain/agents/middleware/todo.py lines 138–327

class TodoListMiddleware(AgentMiddleware[PlanningState[ResponseT], ContextT, ResponseT]):
    """Middleware that provides todo list management capabilities to agents.

    This middleware adds a `write_todos` tool that allows agents to create and manage
    structured task lists for complex multi-step operations. It's designed to help
    agents track progress, organize complex tasks, and provide users with visibility
    into task completion status.

    The middleware automatically injects system prompts that guide the agent on when
    and how to use the todo functionality effectively. It also enforces that the
    `write_todos` tool is called at most once per model turn, since the tool replaces
    the entire todo list and parallel calls would create ambiguity about precedence.

    Example:
        ```python
        from langchain.agents.middleware.todo import TodoListMiddleware
        from langchain.agents import create_agent

        agent = create_agent("openai:gpt-4o", middleware=[TodoListMiddleware()])

        # Agent now has access to write_todos tool and todo state tracking
        result = await agent.invoke({"messages": [HumanMessage("Help me refactor my codebase")]})

        print(result["todos"])  # Array of todo items with status tracking
        ```
    """

    state_schema = PlanningState  # type: ignore[assignment]

    def __init__(
        self,
        *,
        system_prompt: str = WRITE_TODOS_SYSTEM_PROMPT,
        tool_description: str = WRITE_TODOS_TOOL_DESCRIPTION,
    ) -> None:
        """Initialize the `TodoListMiddleware` with optional custom prompts.

        Args:
            system_prompt: Custom system prompt to guide the agent on using the todo
                tool.
            tool_description: Custom description for the `write_todos` tool.
        """
        super().__init__()
        self.system_prompt = system_prompt
        self.tool_description = tool_description

        # Dynamically create the write_todos tool with the custom description
        @tool(description=self.tool_description)
        def write_todos(
            todos: list[Todo], tool_call_id: Annotated[str, InjectedToolCallId]
        ) -> Command[Any]:
            """Create and manage a structured task list for your current work session."""
            return Command(
                update={
                    "todos": todos,
                    "messages": [
                        ToolMessage(f"Updated todo list to {todos}", tool_call_id=tool_call_id)
                    ],
                }
            )

        self.tools = [write_todos]

    def wrap_model_call(
        self,
        request: ModelRequest[ContextT],
        handler: Callable[[ModelRequest[ContextT]], ModelResponse[ResponseT]],
    ) -> ModelResponse[ResponseT] | AIMessage:
        """Update the system message to include the todo system prompt.

        Args:
            request: Model request to execute (includes state and runtime).
            handler: Async callback that executes the model request and returns
                `ModelResponse`.

        Returns:
            The model call result.
        """
        if request.system_message is not None:
            new_system_content = [
                *request.system_message.content_blocks,

Extends

Frequently Asked Questions

What is the TodoListMiddleware class?
TodoListMiddleware is a class in the langchain codebase, defined in libs/langchain_v1/langchain/agents/middleware/todo.py.
Where is TodoListMiddleware defined?
TodoListMiddleware is defined in libs/langchain_v1/langchain/agents/middleware/todo.py at line 138.
What does TodoListMiddleware extend?
TodoListMiddleware extends AIMessage.

Analyze Your Own Codebase

Get architecture documentation, dependency graphs, and domain analysis for your codebase in minutes.

Try Supermodel Free