Home / Function/ test_human_in_the_loop_middleware_preserves_tool_call_order() — langchain Function Reference

test_human_in_the_loop_middleware_preserves_tool_call_order() — langchain Function Reference

Architecture documentation for the test_human_in_the_loop_middleware_preserves_tool_call_order() function in test_human_in_the_loop.py from the langchain codebase.

Entity Profile

Dependency Diagram

graph TD
  786b2539_4b34_08fc_7343_1cabbb84823e["test_human_in_the_loop_middleware_preserves_tool_call_order()"]
  b9ab5ab1_a37b_d0e1_974a_34ca8a76a788["test_human_in_the_loop.py"]
  786b2539_4b34_08fc_7343_1cabbb84823e -->|defined in| b9ab5ab1_a37b_d0e1_974a_34ca8a76a788
  style 786b2539_4b34_08fc_7343_1cabbb84823e fill:#6366f1,stroke:#818cf8,color:#fff

Relationship Graph

Source Code

libs/langchain_v1/tests/unit_tests/agents/middleware/implementations/test_human_in_the_loop.py lines 596–647

def test_human_in_the_loop_middleware_preserves_tool_call_order() -> None:
    """Test that middleware preserves the original order of tool calls.

    This test verifies that when mixing auto-approved and interrupt tools,
    the final tool call order matches the original order from the AI message.
    """
    middleware = HumanInTheLoopMiddleware(
        interrupt_on={
            "tool_b": {"allowed_decisions": ["approve", "edit", "reject"]},
            "tool_d": {"allowed_decisions": ["approve", "edit", "reject"]},
        }
    )

    # Create AI message with interleaved auto-approved and interrupt tools
    # Order: auto (A) -> interrupt (B) -> auto (C) -> interrupt (D) -> auto (E)
    ai_message = AIMessage(
        content="Processing multiple tools",
        tool_calls=[
            {"name": "tool_a", "args": {"val": 1}, "id": "id_a"},
            {"name": "tool_b", "args": {"val": 2}, "id": "id_b"},
            {"name": "tool_c", "args": {"val": 3}, "id": "id_c"},
            {"name": "tool_d", "args": {"val": 4}, "id": "id_d"},
            {"name": "tool_e", "args": {"val": 5}, "id": "id_e"},
        ],
    )
    state = AgentState[Any](messages=[HumanMessage(content="Hello"), ai_message])

    def mock_approve_all(_: Any) -> dict[str, Any]:
        # Approve both interrupt tools (B and D)
        return {"decisions": [{"type": "approve"}, {"type": "approve"}]}

    with patch(
        "langchain.agents.middleware.human_in_the_loop.interrupt", side_effect=mock_approve_all
    ):
        result = middleware.after_model(state, Runtime())
        assert result is not None
        assert "messages" in result

        updated_ai_message = result["messages"][0]
        assert len(updated_ai_message.tool_calls) == 5

        # Verify original order is preserved: A -> B -> C -> D -> E
        assert updated_ai_message.tool_calls[0]["name"] == "tool_a"
        assert updated_ai_message.tool_calls[0]["id"] == "id_a"
        assert updated_ai_message.tool_calls[1]["name"] == "tool_b"
        assert updated_ai_message.tool_calls[1]["id"] == "id_b"
        assert updated_ai_message.tool_calls[2]["name"] == "tool_c"
        assert updated_ai_message.tool_calls[2]["id"] == "id_c"
        assert updated_ai_message.tool_calls[3]["name"] == "tool_d"
        assert updated_ai_message.tool_calls[3]["id"] == "id_d"
        assert updated_ai_message.tool_calls[4]["name"] == "tool_e"
        assert updated_ai_message.tool_calls[4]["id"] == "id_e"

Domain

Subdomains

Frequently Asked Questions

What does test_human_in_the_loop_middleware_preserves_tool_call_order() do?
test_human_in_the_loop_middleware_preserves_tool_call_order() is a function in the langchain codebase, defined in libs/langchain_v1/tests/unit_tests/agents/middleware/implementations/test_human_in_the_loop.py.
Where is test_human_in_the_loop_middleware_preserves_tool_call_order() defined?
test_human_in_the_loop_middleware_preserves_tool_call_order() is defined in libs/langchain_v1/tests/unit_tests/agents/middleware/implementations/test_human_in_the_loop.py at line 596.

Analyze Your Own Codebase

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

Try Supermodel Free