mirror of
https://github.com/hwchase17/langchain.git
synced 2026-06-09 18:50:33 +00:00
chore(langchain): add end to end test for strict mode in provider strategy (#34289)
This commit is contained in:
Binary file not shown.
BIN
libs/langchain_v1/tests/cassettes/test_strict_mode[True].yaml.gz
Normal file
BIN
libs/langchain_v1/tests/cassettes/test_strict_mode[True].yaml.gz
Normal file
Binary file not shown.
@@ -44,13 +44,15 @@ print("\n\n")
|
|||||||
"""
|
"""
|
||||||
|
|
||||||
import os
|
import os
|
||||||
|
from typing import Any
|
||||||
|
from unittest.mock import patch
|
||||||
|
|
||||||
import pytest
|
import pytest
|
||||||
from langchain_core.messages import HumanMessage
|
from langchain_core.messages import HumanMessage
|
||||||
from pydantic import BaseModel, Field
|
from pydantic import BaseModel, Field
|
||||||
|
|
||||||
from langchain.agents import create_agent
|
from langchain.agents import create_agent
|
||||||
from langchain.agents.structured_output import ToolStrategy
|
from langchain.agents.structured_output import ProviderStrategy, ToolStrategy
|
||||||
|
|
||||||
|
|
||||||
class WeatherBaseModel(BaseModel):
|
class WeatherBaseModel(BaseModel):
|
||||||
@@ -140,3 +142,52 @@ def test_inference_to_tool_output(use_responses_api: bool) -> None:
|
|||||||
"ai", # structured response
|
"ai", # structured response
|
||||||
"tool", # artificial tool message
|
"tool", # artificial tool message
|
||||||
]
|
]
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.mark.requires("langchain_openai")
|
||||||
|
@pytest.mark.vcr
|
||||||
|
@pytest.mark.parametrize("use_responses_api", [False, True])
|
||||||
|
def test_strict_mode(use_responses_api: bool) -> None:
|
||||||
|
from langchain_openai import ChatOpenAI
|
||||||
|
|
||||||
|
model_kwargs = {"model": "gpt-5", "use_responses_api": use_responses_api}
|
||||||
|
|
||||||
|
if "OPENAI_API_KEY" not in os.environ:
|
||||||
|
model_kwargs["api_key"] = "foo"
|
||||||
|
|
||||||
|
model = ChatOpenAI(**model_kwargs)
|
||||||
|
|
||||||
|
# spy on _get_request_payload to check that `strict` is enabled
|
||||||
|
original_method = model._get_request_payload
|
||||||
|
payloads = []
|
||||||
|
|
||||||
|
def capture_payload(*args: Any, **kwargs: Any) -> dict[str, Any]:
|
||||||
|
result = original_method(*args, **kwargs)
|
||||||
|
payloads.append(result)
|
||||||
|
return result
|
||||||
|
|
||||||
|
with patch.object(model, "_get_request_payload", side_effect=capture_payload):
|
||||||
|
agent = create_agent(
|
||||||
|
model,
|
||||||
|
tools=[get_weather],
|
||||||
|
response_format=ProviderStrategy(WeatherBaseModel, strict=True),
|
||||||
|
)
|
||||||
|
response = agent.invoke({"messages": [HumanMessage("What's the weather in Boston?")]})
|
||||||
|
|
||||||
|
assert len(payloads) == 2
|
||||||
|
if use_responses_api:
|
||||||
|
assert payloads[-1]["text"]["format"]["strict"]
|
||||||
|
else:
|
||||||
|
assert payloads[-1]["response_format"]["json_schema"]["strict"]
|
||||||
|
|
||||||
|
assert isinstance(response["structured_response"], WeatherBaseModel)
|
||||||
|
assert response["structured_response"].temperature == 75.0
|
||||||
|
assert response["structured_response"].condition.lower() == "sunny"
|
||||||
|
assert len(response["messages"]) == 4
|
||||||
|
|
||||||
|
assert [m.type for m in response["messages"]] == [
|
||||||
|
"human", # "What's the weather?"
|
||||||
|
"ai", # "What's the weather?"
|
||||||
|
"tool", # "The weather is sunny and 75°F."
|
||||||
|
"ai", # structured response
|
||||||
|
]
|
||||||
|
|||||||
Reference in New Issue
Block a user