Home / Class/ TestAgentMiddlewareHooks Class — langchain Architecture

TestAgentMiddlewareHooks Class — langchain Architecture

Architecture documentation for the TestAgentMiddlewareHooks class in test_framework.py from the langchain codebase.

Entity Profile

Dependency Diagram

graph TD
  9e2d20bd_cff7_3577_a41c_be4a0e929bf8["TestAgentMiddlewareHooks"]
  949c7cf4_56fe_f3b4_cd89_9631a7e9cb1e["AgentMiddleware"]
  9e2d20bd_cff7_3577_a41c_be4a0e929bf8 -->|extends| 949c7cf4_56fe_f3b4_cd89_9631a7e9cb1e
  8310d669_2524_e019_e333_8473b50a4990["test_framework.py"]
  9e2d20bd_cff7_3577_a41c_be4a0e929bf8 -->|defined in| 8310d669_2524_e019_e333_8473b50a4990
  e16a31b9_f39c_c0b9_3ca8_fc42ed96cc32["test_hook_execution()"]
  9e2d20bd_cff7_3577_a41c_be4a0e929bf8 -->|method| e16a31b9_f39c_c0b9_3ca8_fc42ed96cc32
  05e1929f_e974_6405_7ed0_3f3f64215f33["test_hook_with_class_inheritance()"]
  9e2d20bd_cff7_3577_a41c_be4a0e929bf8 -->|method| 05e1929f_e974_6405_7ed0_3f3f64215f33

Relationship Graph

Source Code

libs/langchain_v1/tests/unit_tests/agents/middleware/core/test_framework.py lines 769–875

class TestAgentMiddlewareHooks:
    """Test before_agent and after_agent middleware hooks."""

    @pytest.mark.parametrize("is_async", [False, True])
    @pytest.mark.parametrize("hook_type", ["before", "after"])
    async def test_hook_execution(self, *, is_async: bool, hook_type: str) -> None:
        """Test that agent hooks are called in both sync and async modes."""
        execution_log: list[str] = []

        if is_async:
            if hook_type == "before":

                @before_agent
                async def log_hook(
                    state: AgentState[Any], *_args: Any, **_kwargs: Any
                ) -> dict[str, Any] | None:
                    execution_log.append(f"{hook_type}_agent_called")
                    execution_log.append(f"message_count: {len(state['messages'])}")
                    return None

            else:

                @after_agent
                async def log_hook(
                    state: AgentState[Any], *_args: Any, **_kwargs: Any
                ) -> dict[str, Any] | None:
                    execution_log.append(f"{hook_type}_agent_called")
                    execution_log.append(f"message_count: {len(state['messages'])}")
                    return None

        elif hook_type == "before":

            @before_agent
            def log_hook(
                state: AgentState[Any], *_args: Any, **_kwargs: Any
            ) -> dict[str, Any] | None:
                execution_log.append(f"{hook_type}_agent_called")
                execution_log.append(f"message_count: {len(state['messages'])}")
                return None

        else:

            @after_agent
            def log_hook(
                state: AgentState[Any], *_args: Any, **_kwargs: Any
            ) -> dict[str, Any] | None:
                execution_log.append(f"{hook_type}_agent_called")
                execution_log.append(f"message_count: {len(state['messages'])}")
                return None

        model = GenericFakeChatModel(messages=iter([AIMessage(content="Response")]))
        agent = create_agent(model=model, tools=[], middleware=[log_hook])

        if is_async:
            await agent.ainvoke({"messages": [HumanMessage("Hi")]})
        else:
            agent.invoke({"messages": [HumanMessage("Hi")]})

        assert f"{hook_type}_agent_called" in execution_log
        assert any("message_count:" in log for log in execution_log)

    @pytest.mark.parametrize("is_async", [False, True])
    @pytest.mark.parametrize("hook_type", ["before", "after"])
    async def test_hook_with_class_inheritance(self, *, is_async: bool, hook_type: str) -> None:
        """Test agent hooks using class inheritance in both sync and async modes."""
        execution_log: list[str] = []

        class AsyncCustomMiddleware(AgentMiddleware):
            async def abefore_agent(
                self, state: AgentState[Any], runtime: Runtime
            ) -> dict[str, Any] | None:
                if hook_type == "before":
                    execution_log.append("hook_called")
                return None

            async def aafter_agent(
                self, state: AgentState[Any], runtime: Runtime
            ) -> dict[str, Any] | None:
                if hook_type == "after":
                    execution_log.append("hook_called")
                return None

Extends

Frequently Asked Questions

What is the TestAgentMiddlewareHooks class?
TestAgentMiddlewareHooks is a class in the langchain codebase, defined in libs/langchain_v1/tests/unit_tests/agents/middleware/core/test_framework.py.
Where is TestAgentMiddlewareHooks defined?
TestAgentMiddlewareHooks is defined in libs/langchain_v1/tests/unit_tests/agents/middleware/core/test_framework.py at line 769.
What does TestAgentMiddlewareHooks extend?
TestAgentMiddlewareHooks extends AgentMiddleware.

Analyze Your Own Codebase

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

Try Supermodel Free