mirror of
https://github.com/hwchase17/langchain.git
synced 2026-06-09 10:17:00 +00:00
chore(openai): fix broken vcr cassette playback and add ci guard (#36502)
Fix broken VCR cassette playback in `langchain-openai` integration tests and add a CI job to prevent regressions. Two independent bugs made all VCR-backed tests fail: `before_record_request` redacts URIs to `**REDACTED**` but `match_on` still included `uri` (so playback never matched), and a typo-fix commit (`c9f51aef85`) changed test input strings without re-recording cassettes (so `json_body` matching also failed).
This commit is contained in:
@@ -27,6 +27,11 @@ test tests:
|
||||
integration_test integration_tests:
|
||||
uv run --group test --group test_integration pytest -n auto $(TEST_FILE)
|
||||
|
||||
# Run VCR cassette-backed integration tests in playback-only mode (no API keys needed).
|
||||
# Catches stale cassettes caused by test input changes without re-recording.
|
||||
test_vcr:
|
||||
uv run --group test pytest --record-mode=none -m vcr --ignore=tests/integration_tests/chat_models/test_azure_standard.py tests/integration_tests/
|
||||
|
||||
test_watch:
|
||||
uv run --group test ptw --snapshot-update --now . -- -vv $(TEST_FILE)
|
||||
|
||||
|
||||
@@ -32,7 +32,9 @@ def vcr_config() -> dict:
|
||||
"""Extend the default configuration coming from langchain_tests."""
|
||||
config = base_vcr_config()
|
||||
config["match_on"] = [
|
||||
m if m != "body" else "json_body" for m in config.get("match_on", [])
|
||||
m if m != "body" else "json_body"
|
||||
for m in config.get("match_on", [])
|
||||
if m != "uri"
|
||||
]
|
||||
config.setdefault("filter_headers", []).extend(_EXTRA_HEADERS)
|
||||
config["before_record_request"] = remove_request_headers
|
||||
|
||||
@@ -182,13 +182,13 @@ def test_function_calling(output_version: Literal["v0", "responses/v1", "v1"]) -
|
||||
|
||||
llm = ChatOpenAI(model=MODEL_NAME, output_version=output_version)
|
||||
bound_llm = llm.bind_tools([multiply, {"type": "web_search_preview"}])
|
||||
ai_msg = cast(AIMessage, bound_llm.invoke("what's 5 * 4"))
|
||||
ai_msg = cast(AIMessage, bound_llm.invoke("whats 5 * 4"))
|
||||
assert len(ai_msg.tool_calls) == 1
|
||||
assert ai_msg.tool_calls[0]["name"] == "multiply"
|
||||
assert set(ai_msg.tool_calls[0]["args"]) == {"x", "y"}
|
||||
|
||||
full: Any = None
|
||||
for chunk in bound_llm.stream("what's 5 * 4"):
|
||||
for chunk in bound_llm.stream("whats 5 * 4"):
|
||||
assert isinstance(chunk, AIMessageChunk)
|
||||
full = chunk if full is None else full + chunk
|
||||
assert len(full.tool_calls) == 1
|
||||
@@ -416,7 +416,7 @@ def test_function_calling_and_structured_output(schema: Any) -> None:
|
||||
assert parsed == response.additional_kwargs["parsed"]
|
||||
|
||||
# Test function calling
|
||||
ai_msg = cast(AIMessage, bound_llm.invoke("what's 5 * 4"))
|
||||
ai_msg = cast(AIMessage, bound_llm.invoke("whats 5 * 4"))
|
||||
assert len(ai_msg.tool_calls) == 1
|
||||
assert ai_msg.tool_calls[0]["name"] == "multiply"
|
||||
assert set(ai_msg.tool_calls[0]["args"]) == {"x", "y"}
|
||||
@@ -555,7 +555,7 @@ def test_stream_reasoning_summary(
|
||||
)
|
||||
message_1 = {
|
||||
"role": "user",
|
||||
"content": "What was the third tallest building in the year 2000?",
|
||||
"content": "What was the third tallest buliding in the year 2000?",
|
||||
}
|
||||
response_1: BaseMessageChunk | None = None
|
||||
for chunk in llm.stream([message_1]):
|
||||
|
||||
Reference in New Issue
Block a user