diff --git a/libs/partners/openai/langchain_openai/chat_models/base.py b/libs/partners/openai/langchain_openai/chat_models/base.py index a694d68e35a..c343bf50f25 100644 --- a/libs/partners/openai/langchain_openai/chat_models/base.py +++ b/libs/partners/openai/langchain_openai/chat_models/base.py @@ -4351,7 +4351,7 @@ def _convert_responses_chunk_to_generation_chunk( elif chunk.type == "response.created": id = chunk.response.id response_metadata["id"] = chunk.response.id # Backwards compatibility - elif chunk.type == "response.completed": + elif chunk.type in ("response.completed", "response.incomplete"): msg = cast( AIMessage, ( diff --git a/libs/partners/openai/tests/cassettes/test_incomplete_response.yaml.gz b/libs/partners/openai/tests/cassettes/test_incomplete_response.yaml.gz new file mode 100644 index 00000000000..f9ac5b9da95 Binary files /dev/null and b/libs/partners/openai/tests/cassettes/test_incomplete_response.yaml.gz differ diff --git a/libs/partners/openai/tests/integration_tests/chat_models/test_responses_api.py b/libs/partners/openai/tests/integration_tests/chat_models/test_responses_api.py index 6ef779a2953..db18dcf046f 100644 --- a/libs/partners/openai/tests/integration_tests/chat_models/test_responses_api.py +++ b/libs/partners/openai/tests/integration_tests/chat_models/test_responses_api.py @@ -58,6 +58,26 @@ def _check_response(response: BaseMessage | None) -> None: assert response.response_metadata["service_tier"] # type: ignore[typeddict-item] +@pytest.mark.vcr +def test_incomplete_response() -> None: + model = ChatOpenAI( + model=MODEL_NAME, use_responses_api=True, max_completion_tokens=16 + ) + response = model.invoke("Tell me a 100 word story about a bear.") + assert response.response_metadata["incomplete_details"] + assert response.response_metadata["incomplete_details"]["reason"] + assert response.response_metadata["status"] == "incomplete" + + full: AIMessageChunk | None = None + for chunk in model.stream("Tell me a 100 word story about a bear."): + assert isinstance(chunk, AIMessageChunk) + full = chunk if full is None else full + chunk + assert isinstance(full, AIMessageChunk) + assert full.response_metadata["incomplete_details"] + assert full.response_metadata["incomplete_details"]["reason"] + assert full.response_metadata["status"] == "incomplete" + + @pytest.mark.default_cassette("test_web_search.yaml.gz") @pytest.mark.vcr @pytest.mark.parametrize("output_version", ["responses/v1", "v1"])