From b35707cee5e416829bb7dbf1a3f29dc929632d6a Mon Sep 17 00:00:00 2001 From: Oxygen56 <1391083091@qq.com> Date: Tue, 2 Jun 2026 23:59:15 +0800 Subject: [PATCH 1/4] fix: use getattr for non-OpenAI provider response compatibility Fixes #6234 Fixes #6235 Use getattr with None fallback for system_fingerprint and output attributes to prevent AttributeError when non-OpenAI providers return response objects without these fields. --- python/packages/openai/agent_framework_openai/_chat_client.py | 2 +- .../openai/agent_framework_openai/_chat_completion_client.py | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/python/packages/openai/agent_framework_openai/_chat_client.py b/python/packages/openai/agent_framework_openai/_chat_client.py index 261554fba3..23497c9019 100644 --- a/python/packages/openai/agent_framework_openai/_chat_client.py +++ b/python/packages/openai/agent_framework_openai/_chat_client.py @@ -1971,7 +1971,7 @@ def _parse_response_from_openai( metadata: dict[str, Any] = response.metadata or {} contents: list[Content] = [] local_shell_tool_name = self._get_local_shell_tool_name(options.get("tools")) - for item in response.output: # type: ignore[reportUnknownMemberType] + for item in getattr(response, "output", []): # type: ignore[reportUnknownMemberType] match item.type: # types: # ParsedResponseOutputMessage[Unknown] | diff --git a/python/packages/openai/agent_framework_openai/_chat_completion_client.py b/python/packages/openai/agent_framework_openai/_chat_completion_client.py index a6878c9f2d..0fd14aa2ef 100644 --- a/python/packages/openai/agent_framework_openai/_chat_completion_client.py +++ b/python/packages/openai/agent_framework_openai/_chat_completion_client.py @@ -788,13 +788,13 @@ def _parse_text_from_openai(self, choice: Choice | ChunkChoice) -> Content | Non def _get_metadata_from_chat_response(self, response: ChatCompletion) -> dict[str, Any]: """Get metadata from a chat response.""" return { - "system_fingerprint": response.system_fingerprint, + "system_fingerprint": getattr(response, "system_fingerprint", None), } def _get_metadata_from_streaming_chat_response(self, response: ChatCompletionChunk) -> dict[str, Any]: """Get metadata from a streaming chat response.""" return { - "system_fingerprint": response.system_fingerprint, + "system_fingerprint": getattr(response, "system_fingerprint", None), } def _get_metadata_from_chat_choice(self, choice: Choice | ChunkChoice) -> dict[str, Any]: From e631d30a2bb3c9c53458a9f5dbb19e4fab227ef6 Mon Sep 17 00:00:00 2001 From: Oxygen56 <1391083091@qq.com> Date: Wed, 3 Jun 2026 09:16:13 +0800 Subject: [PATCH 2/4] fix: use typed variable for response output to satisfy pyright Fixes #6235 Use getattr with None fallback for the output attribute, and assign to a typed list variable before the match statement to help pyright narrow the response item types correctly. --- python/packages/openai/agent_framework_openai/_chat_client.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/python/packages/openai/agent_framework_openai/_chat_client.py b/python/packages/openai/agent_framework_openai/_chat_client.py index 23497c9019..abd6059496 100644 --- a/python/packages/openai/agent_framework_openai/_chat_client.py +++ b/python/packages/openai/agent_framework_openai/_chat_client.py @@ -1971,7 +1971,8 @@ def _parse_response_from_openai( metadata: dict[str, Any] = response.metadata or {} contents: list[Content] = [] local_shell_tool_name = self._get_local_shell_tool_name(options.get("tools")) - for item in getattr(response, "output", []): # type: ignore[reportUnknownMemberType] + outputs: list = getattr(response, "output", None) or [] + for item in outputs: match item.type: # types: # ParsedResponseOutputMessage[Unknown] | From 0b870b87d45d803b0c555009a5366653fd55e756 Mon Sep 17 00:00:00 2001 From: Willow Lopez <100782273+Oxygen56@users.noreply.github.com> Date: Wed, 3 Jun 2026 20:29:44 +0800 Subject: [PATCH 3/4] fix: rename response_outputs to avoid name collision with case-block variable Fixes #6235 Rename outputs to response_outputs on line 1974 to avoid mypy error about conflicting variable names in the match statement's case blocks. Also use list[Any] for explicit generic type annotation. --- python/packages/openai/agent_framework_openai/_chat_client.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/python/packages/openai/agent_framework_openai/_chat_client.py b/python/packages/openai/agent_framework_openai/_chat_client.py index abd6059496..e7b32b876b 100644 --- a/python/packages/openai/agent_framework_openai/_chat_client.py +++ b/python/packages/openai/agent_framework_openai/_chat_client.py @@ -1971,8 +1971,8 @@ def _parse_response_from_openai( metadata: dict[str, Any] = response.metadata or {} contents: list[Content] = [] local_shell_tool_name = self._get_local_shell_tool_name(options.get("tools")) - outputs: list = getattr(response, "output", None) or [] - for item in outputs: + response_outputs: list[Any] = getattr(response, "output", None) or [] + for item in response_outputs: match item.type: # types: # ParsedResponseOutputMessage[Unknown] | From 22363c7dc42e2c61c2aecdbd4c34d3d17340147c Mon Sep 17 00:00:00 2001 From: Willow Lopez <100782273+Oxygen56@users.noreply.github.com> Date: Wed, 3 Jun 2026 22:47:41 +0800 Subject: [PATCH 4/4] fix: use cast(list[Any]) for response output to satisfy pyright Fixes #6235 The getattr() call returns Unknown type which pyright cannot narrow in the match statement. Use an explicit cast to list[Any]. --- python/packages/openai/agent_framework_openai/_chat_client.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/python/packages/openai/agent_framework_openai/_chat_client.py b/python/packages/openai/agent_framework_openai/_chat_client.py index e7b32b876b..0837221482 100644 --- a/python/packages/openai/agent_framework_openai/_chat_client.py +++ b/python/packages/openai/agent_framework_openai/_chat_client.py @@ -1971,7 +1971,7 @@ def _parse_response_from_openai( metadata: dict[str, Any] = response.metadata or {} contents: list[Content] = [] local_shell_tool_name = self._get_local_shell_tool_name(options.get("tools")) - response_outputs: list[Any] = getattr(response, "output", None) or [] + response_outputs = cast(list[Any], getattr(response, "output", None) or []) for item in response_outputs: match item.type: # types: