From 27e4b78bb0679d7be4a33bf16d9a3a9057b522b8 Mon Sep 17 00:00:00 2001 From: cbornet Date: Thu, 1 Jan 2026 14:02:45 +0100 Subject: [PATCH 1/3] test(langchain): activate test_return_direct_spec tests --- .../langchain/agents/structured_output.py | 4 +-- libs/langchain_v1/pyproject.toml | 2 -- .../agents/test_return_direct_spec.py | 27 +++++++++++++------ .../tests/unit_tests/agents/utils.py | 6 ++++- 4 files changed, 26 insertions(+), 13 deletions(-) diff --git a/libs/langchain_v1/langchain/agents/structured_output.py b/libs/langchain_v1/langchain/agents/structured_output.py index ed9751942a41a..d6428c8966ef0 100644 --- a/libs/langchain_v1/langchain/agents/structured_output.py +++ b/libs/langchain_v1/langchain/agents/structured_output.py @@ -182,7 +182,7 @@ def __init__( class ToolStrategy(Generic[SchemaT]): """Use a tool calling strategy for model responses.""" - schema: type[SchemaT] + schema: type[SchemaT] | dict[str, Any] """Schema for the tool calls.""" schema_specs: list[_SchemaSpec[SchemaT]] @@ -208,7 +208,7 @@ class ToolStrategy(Generic[SchemaT]): def __init__( self, - schema: type[SchemaT], + schema: type[SchemaT] | dict[str, Any], *, tool_message_content: str | None = None, handle_errors: bool diff --git a/libs/langchain_v1/pyproject.toml b/libs/langchain_v1/pyproject.toml index 3409d822b6d69..c39f4034aca44 100644 --- a/libs/langchain_v1/pyproject.toml +++ b/libs/langchain_v1/pyproject.toml @@ -118,7 +118,6 @@ ignore = [ # TODO rules "ANN401", # Any in type annotations "BLE", # Blind exceptions - "PLC0415", # Imports should be at the top. Not always desirable ] unfixable = [ "B028", # People should intentionally tune the stacklevel @@ -137,7 +136,6 @@ ignore-var-parameters = true # ignore missing documentation for *args and **kwa "ANN", # Annotations, needs to fix "ARG", # Arguments, needs to fix ] -"tests/unit_tests/agents/test_return_direct_spec.py" = ["F821"] "tests/unit_tests/agents/test_responses_spec.py" = ["F821"] "tests/unit_tests/agents/test_responses.py" = ["F821"] "tests/unit_tests/agents/test_react_agent.py" = ["ALL"] diff --git a/libs/langchain_v1/tests/unit_tests/agents/test_return_direct_spec.py b/libs/langchain_v1/tests/unit_tests/agents/test_return_direct_spec.py index ca1ba39f2a20f..62c12857c5747 100644 --- a/libs/langchain_v1/tests/unit_tests/agents/test_return_direct_spec.py +++ b/libs/langchain_v1/tests/unit_tests/agents/test_return_direct_spec.py @@ -1,16 +1,27 @@ from __future__ import annotations +import os +from typing import ( + Any, +) +from unittest.mock import MagicMock + import pytest +from langchain_core.messages import HumanMessage +from langchain_core.tools import tool -# Skip this test since langgraph.prebuilt.responses is not available -pytest.skip("langgraph.prebuilt.responses not available", allow_module_level=True) +from langchain.agents import create_agent +from langchain.agents.structured_output import ( + ToolStrategy, +) +from tests.unit_tests.agents.utils import BaseSchema, load_spec try: from langchain_openai import ChatOpenAI except ImportError: skip_openai_integration_tests = True else: - skip_openai_integration_tests = False + skip_openai_integration_tests = "OPEN_API_KEY" not in os.environ AGENT_PROMPT = """ You are a strict polling bot. @@ -33,10 +44,10 @@ class TestCase(BaseSchema): TEST_CASES = load_spec("return_direct", as_model=TestCase) -def _make_tool(*, return_direct: bool): +def _make_tool(*, return_direct: bool) -> dict[str, Any]: attempts = 0 - def _side_effect(): + def _side_effect() -> dict[str, Any]: nonlocal attempts attempts += 1 return { @@ -54,7 +65,7 @@ def _side_effect(): ), return_direct=return_direct, ) - def _wrapped(): + def _wrapped() -> Any: return mock() return {"tool": _wrapped, "mock": mock} @@ -74,14 +85,14 @@ def test_return_direct_integration_matrix(case: TestCase) -> None: agent = create_agent( model, tools=[poll_tool["tool"]], - prompt=AGENT_PROMPT, + system_prompt=AGENT_PROMPT, response_format=ToolStrategy(case.response_format), ) else: agent = create_agent( model, tools=[poll_tool["tool"]], - prompt=AGENT_PROMPT, + system_prompt=AGENT_PROMPT, ) result = agent.invoke( diff --git a/libs/langchain_v1/tests/unit_tests/agents/utils.py b/libs/langchain_v1/tests/unit_tests/agents/utils.py index 21a9d438af556..7adccaf368b7b 100644 --- a/libs/langchain_v1/tests/unit_tests/agents/utils.py +++ b/libs/langchain_v1/tests/unit_tests/agents/utils.py @@ -1,5 +1,6 @@ import json from pathlib import Path +from typing import TypeVar from pydantic import BaseModel, ConfigDict from pydantic.alias_generators import to_camel @@ -13,7 +14,10 @@ class BaseSchema(BaseModel): ) -def load_spec(spec_name: str, as_model: type[BaseModel]) -> list[BaseModel]: +_T = TypeVar("_T", bound=BaseModel) + + +def load_spec(spec_name: str, as_model: type[_T]) -> list[_T]: with (Path(__file__).parent / "specifications" / f"{spec_name}.json").open( "r", encoding="utf-8" ) as f: From fbe724b22baaf373bd9a3f7d2f12594b72dd93ec Mon Sep 17 00:00:00 2001 From: Mason Daugherty Date: Fri, 9 Jan 2026 22:00:20 -0500 Subject: [PATCH 2/3] fix typo --- .../tests/unit_tests/agents/test_return_direct_spec.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libs/langchain_v1/tests/unit_tests/agents/test_return_direct_spec.py b/libs/langchain_v1/tests/unit_tests/agents/test_return_direct_spec.py index 62c12857c5747..691106251c727 100644 --- a/libs/langchain_v1/tests/unit_tests/agents/test_return_direct_spec.py +++ b/libs/langchain_v1/tests/unit_tests/agents/test_return_direct_spec.py @@ -21,7 +21,7 @@ except ImportError: skip_openai_integration_tests = True else: - skip_openai_integration_tests = "OPEN_API_KEY" not in os.environ + skip_openai_integration_tests = "OPENAI_API_KEY" not in os.environ AGENT_PROMPT = """ You are a strict polling bot. From b9c04e97e9bf03af01812e6f476c080b77910ca2 Mon Sep 17 00:00:00 2001 From: Mason Daugherty Date: Fri, 9 Jan 2026 22:46:18 -0500 Subject: [PATCH 3/3] remove duplicate key --- libs/langchain_v1/pyproject.toml | 1 - 1 file changed, 1 deletion(-) diff --git a/libs/langchain_v1/pyproject.toml b/libs/langchain_v1/pyproject.toml index 68301a442d9be..0ba0adbf8d19b 100644 --- a/libs/langchain_v1/pyproject.toml +++ b/libs/langchain_v1/pyproject.toml @@ -144,7 +144,6 @@ ignore-var-parameters = true # ignore missing documentation for *args and **kwa ] "tests/unit_tests/agents/test_responses_spec.py" = ["F821"] "tests/unit_tests/agents/test_return_direct_spec.py" = ["F821"] -"tests/unit_tests/agents/test_responses_spec.py" = ["F821"] "tests/unit_tests/agents/test_react_agent.py" = ["ALL"] "tests/*" = [