Home / Function/ test_middleware_model_swap_provider_to_tool_strategy() — langchain Function Reference

test_middleware_model_swap_provider_to_tool_strategy() — langchain Function Reference

Architecture documentation for the test_middleware_model_swap_provider_to_tool_strategy() function in test_response_format.py from the langchain codebase.

Entity Profile

Dependency Diagram

graph TD
  3a8452d0_bc0b_b762_5ef2_4ace62e82c54["test_middleware_model_swap_provider_to_tool_strategy()"]
  873688ef_76d2_d38f_3fb5_8b8c01c2a0c4["TestDynamicModelWithResponseFormat"]
  3a8452d0_bc0b_b762_5ef2_4ace62e82c54 -->|defined in| 873688ef_76d2_d38f_3fb5_8b8c01c2a0c4
  0874fe8b_e998_4a85_2ac5_c9e21542b1cd["bind_tools()"]
  3a8452d0_bc0b_b762_5ef2_4ace62e82c54 -->|calls| 0874fe8b_e998_4a85_2ac5_c9e21542b1cd
  8bf7d888_c163_f6dc_ebf8_00b118b0434e["wrap_model_call()"]
  3a8452d0_bc0b_b762_5ef2_4ace62e82c54 -->|calls| 8bf7d888_c163_f6dc_ebf8_00b118b0434e
  style 3a8452d0_bc0b_b762_5ef2_4ace62e82c54 fill:#6366f1,stroke:#818cf8,color:#fff

Relationship Graph

Source Code

libs/langchain_v1/tests/unit_tests/agents/test_response_format.py lines 792–871

    def test_middleware_model_swap_provider_to_tool_strategy(self) -> None:
        """Test that strategy resolution is deferred until after middleware modifies the model.

        Verifies that when a raw schema is provided, `_supports_provider_strategy` is called
        on the middleware-modified model (not the original), ensuring the correct strategy is
        selected based on the final model's capabilities.
        """

        # Custom model that we'll use to test whether the tool strategy is applied
        # correctly at runtime.
        class CustomModel(GenericFakeChatModel):
            tool_bindings: list[Any] = Field(default_factory=list)

            def bind_tools(
                self,
                tools: Sequence[dict[str, Any] | type[BaseModel] | Callable[..., Any] | BaseTool],
                **kwargs: Any,
            ) -> Runnable[LanguageModelInput, AIMessage]:
                # Record every tool binding event.
                self.tool_bindings.append(tools)
                return self

        model = CustomModel(
            messages=iter(
                [
                    # Simulate model returning structured output directly
                    # (this is what provider strategy would do)
                    json.dumps(WEATHER_DATA),
                ]
            )
        )

        # Create middleware that swaps the model in the request
        class ModelSwappingMiddleware(AgentMiddleware):
            def wrap_model_call(
                self,
                request: ModelRequest,
                handler: Callable[[ModelRequest], ModelResponse],
            ) -> ModelCallResult:
                # Replace the model with our custom test model
                return handler(request.override(model=model))

        # Track which model is checked for provider strategy support
        calls = []

        def mock_supports_provider_strategy(
            model: str | BaseChatModel, tools: list[Any] | None = None
        ) -> bool:
            """Track which model is checked and return True for ProviderStrategy."""
            calls.append(model)
            return True

        # Use raw Pydantic model (not wrapped in ToolStrategy or ProviderStrategy)
        # This should auto-detect strategy based on model capabilities
        agent = create_agent(
            model=model,
            tools=[],
            # Raw schema - should auto-detect strategy
            response_format=WeatherBaseModel,
            middleware=[ModelSwappingMiddleware()],
        )

        with patch(
            "langchain.agents.factory._supports_provider_strategy",
            side_effect=mock_supports_provider_strategy,
        ):
            response = agent.invoke({"messages": [HumanMessage("What's the weather?")]})

        # Verify strategy resolution was deferred: check was called once during _get_bound_model
        assert len(calls) == 1

        # Verify successful parsing of JSON as structured output via ProviderStrategy
        assert response["structured_response"] == EXPECTED_WEATHER_PYDANTIC
        # Two messages: Human input message and AI response with JSON content
        assert len(response["messages"]) == 2
        ai_message = response["messages"][1]
        assert isinstance(ai_message, AIMessage)
        # ProviderStrategy doesn't use tool calls - it parses content directly
        assert ai_message.tool_calls == []
        assert ai_message.content == json.dumps(WEATHER_DATA)

Domain

Subdomains

Frequently Asked Questions

What does test_middleware_model_swap_provider_to_tool_strategy() do?
test_middleware_model_swap_provider_to_tool_strategy() is a function in the langchain codebase, defined in libs/langchain_v1/tests/unit_tests/agents/test_response_format.py.
Where is test_middleware_model_swap_provider_to_tool_strategy() defined?
test_middleware_model_swap_provider_to_tool_strategy() is defined in libs/langchain_v1/tests/unit_tests/agents/test_response_format.py at line 792.
What does test_middleware_model_swap_provider_to_tool_strategy() call?
test_middleware_model_swap_provider_to_tool_strategy() calls 2 function(s): bind_tools, wrap_model_call.

Analyze Your Own Codebase

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

Try Supermodel Free