mirror of
https://github.com/microsoft/agent-framework.git
synced 2026-06-16 21:04:09 +08:00
main
32 Commits
-
Python: Fix Python OTel usage detail attributes (#6493)
* fix python otel usage detail attributes Map cached/read/reasoning usage detail fields to standard OTel GenAI attributes while preserving provider-specific legacy keys. Add focused coverage for direct response spans, aggregated agent spans, and provider usage parsing. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * address usage detail review feedback Omit missing OpenAI Responses usage detail counts while preserving zero-valued counts. Record zero-valued token usage in OTel histograms and add regression coverage. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> --------- Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Eduard van Valkenburg ·
2026-06-15 07:10:14 +00:00 -
Python: fix: use getattr for non-OpenAI provider response compatibility (#6270)
* 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. * 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. * 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. * 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]. * fix: use hasattr guard instead of getattr for response.output Fixes #6235 Using hasattr(response, 'output') and then accessing response.output directly gives pyright enough type information to verify the match statement exhaustiveness. This avoids the cast(list[Any]) approach which pyright still flagged as partially unknown. * fix: use ternary operator for response_outputs assignment Replace if-else block with ternary expression to satisfy ruff SIM108 lint rule. This fixes the Package Checks (3.11) CI failure. * fix: use ternary with cast for ruff SIM108 and pyright type safety Replace if-else block with ternary expression using cast(list[Any], ...) to satisfy: - ruff SIM108 (use ternary instead of if-else) - ruff E501 (line length < 120) - pyright type narrowing (cast preserves type info lost in ternary) All local checks pass: ruff check, ruff format, pyright, 298 tests. * fix: replace hasattr+cast with try/except to preserve pyright types --------- Co-authored-by: Tao Chen <taochen@microsoft.com>
Willow Lopez ·
2026-06-09 15:17:39 +00:00 -
Python: Add
timeoutparameter toFoundryAgentto fixConnectTimeouton multi-turn conversations (#6263)* Python: fix ConnectTimeout on multi-turn FoundryAgent conversations (#6241) Expose a `timeout` parameter on `RawFoundryAgentChatClient`, `_FoundryAgentChatClient`, `RawFoundryAgent`, `FoundryAgent`, and `RawOpenAIChatClient` so callers can override the HTTP timeout used by the underlying AsyncOpenAI client. Root cause: `RawFoundryAgentChatClient.__init__` called `project_client.get_openai_client()` without configuring any timeout, inheriting the OpenAI SDK default of `httpx.Timeout(connect=5.0)`. When connections are recycled between turns under load, the 5 s connect timeout fires and surfaces as `openai.APITimeoutError`. Fix: - `load_openai_service_settings` (`_shared.py`): accept `timeout` and include it in `client_args` for all three `AsyncOpenAI`/ `AsyncAzureOpenAI` construction paths. - `RawOpenAIChatClient.__init__` (`_chat_client.py`): accept `timeout` and forward to `load_openai_service_settings`. - `RawFoundryAgentChatClient.__init__` (`_agent.py`): accept `timeout` and set `openai_client.timeout = timeout` on the client returned by `get_openai_client()` before passing it to the base class. - `_FoundryAgentChatClient`, `RawFoundryAgent`, `FoundryAgent`: accept and propagate `timeout` through the construction chain. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * Add timeout parameter to FoundryAgent and RawOpenAIChatClient Expose a timeout parameter on RawFoundryAgentChatClient, _FoundryAgentChatClient, RawFoundryAgent, FoundryAgent, and RawOpenAIChatClient. When provided, the value is applied to the underlying AsyncOpenAI client so that connect timeouts under load or after connection recycling can be tuned by callers. Previously, get_openai_client() was called without any timeout override, so the SDK default of httpx.Timeout(connect=5.0) was inherited and could fire on multi-turn conversations where the underlying connection is recycled between turns. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * Python: Add `timeout` parameter to `FoundryAgent` to fix `ConnectTimeout` on multi-turn conversations Fixes #6241 * fix(foundry): use with_options to avoid mutating shared OpenAI client timeout (#6241) Replace direct assignment with in RawFoundryAgentChatClient.__init__. The Azure AI Projects SDK caches and returns a shared AsyncOpenAI client per AIProjectClient. Mutating its .timeout attribute leaked the override to all other code paths sharing that client (other agents, user code). with_options() returns a new client instance with the override applied, leaving the original shared client untouched. Update tests to assert with_options is called with the correct timeout and that the original shared client's timeout attribute is not mutated. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * test(foundry): assert with_options return value flows to instance.client (#6241) The four timeout propagation tests verified that with_options was called but did not confirm that the returned (timeout-configured) client was actually stored on the instance. A silent discard of the return value would have left the tests green while the timeout had no effect. Each test now captures the constructed instance and asserts: assert <instance>.client is openai_client_mock.with_options.return_value Affected tests: - test_raw_foundry_agent_chat_client_init_applies_timeout_to_openai_client - test_raw_foundry_agent_chat_client_init_applies_timeout_with_preview_enabled - test_foundry_agent_chat_client_init_propagates_timeout - test_foundry_agent_init_propagates_timeout_to_openai_client Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> --------- Co-authored-by: Copilot <copilot@github.com> Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Evan Mattson ·
2026-06-04 18:25:18 +00:00 -
Yufeng He ·
2026-06-04 18:11:24 +00:00 -
Python: read headers defensively to support stream wrappers without
.headers(#6028) (#6029)`OpenAIChatClient._inner_get_response()` reads `.headers` on the raw streaming response returned by `client.responses.with_raw_response.create(stream=True)` (and its three sibling call sites - retrieve-streaming, non-streaming create and background retrieve) to surface the `x-ms-served-model` Azure header, introduced in #5910. When `azure-ai-projects>=2.1.0` experimental GenAI tracing is enabled (`AZURE_EXPERIMENTAL_ENABLE_GENAI_TRACING=true`), the instrumentor wraps the raw streaming response in an inline `AsyncStreamWrapper` that exposes `.response` but not `.headers`. Reading `raw_create_response.headers` then raises `AttributeError: 'AsyncStreamWrapper' object has no attribute 'headers'`, which `FoundryChatClient` rethrows as a `ChatClientException` and breaks every streaming call (workflows and free chat). Fix: read the header dict via `getattr(raw_response, "headers", None)` at all four call sites. `_extract_served_model()` already short-circuits on `None`, so the served-model surfacing degrades gracefully (model stays the deployment alias) instead of crashing when the response is wrapped by an instrumentor that does not proxy `.headers`. Regression test added: `test_streaming_response_without_headers_attribute_does_not_crash` simulates a stream wrapper that raises `AttributeError` on `.headers` and asserts the stream still completes with the deployment alias as `update.model`. Fixes #6028 Co-authored-by: Emilien Mottet <emilien.mottet@michelin.com>
Emilien Mottet ·
2026-05-28 08:37:38 +00:00 -
Python: fix: keep citation get_url metadata (#6037)
* fix: keep citation get_url metadata * fix: satisfy citation metadata mypy check
Yufeng He ·
2026-05-27 20:09:02 +00:00 -
Python: fix(openai): guard against null delta in streaming chunks from non-co… (#5734)
* fix(openai): guard against null delta in streaming chunks from non-compliant providers (#5732) * chore: resolve nit and align with project style --------- Co-authored-by: Sergey Borisov <sergey.borisov@dataimpact.io> Co-authored-by: Giles Odigwe <79032838+giles17@users.noreply.github.com>
S3rj ·
2026-05-27 07:42:46 +00:00 -
Python: Record actual served model from Azure OpenAI (#5910)
* Record actual served model as response model for Azure OpenAI * Formatting * Fix tests * Fix pipeline error * Comments * Address review: surface served model via ChatResponse.model Apply blocking review feedback from PR #5910: - Use ChatResponse.model / ChatResponseUpdate.model as the source of truth for the Azure x-ms-served-model header value, instead of stashing it in additional_properties and overriding it again in observability. Observability already reads response.model; the chat client now overwrites it post-parse when the served-model header is present. Empirically the Azure Responses API returns the deployment alias in body.model and the actual snapshot (e.g. gpt-5-nano-2025-08-07) in this header. - Move the AZURE_OPENAI_SERVED_MODEL_HEADER constant out of observability.py and into RawOpenAIChatClient (as the SERVED_MODEL_HEADER ClassVar). The header is Azure-OpenAI-Responses-API-specific so observability does not need to know about it. - Revert the streaming text_format path to client.responses.stream(...) and drop the _pydantic_model_to_text_format_param helper. That helper imported from openai.lib._parsing._responses (a private SDK path) and the swap to responses.create(stream=True) dropped client-side output_parsed for structured-output streaming. The streaming-with-text_format path is the only one that does not surface the served-model header - documented inline. - Wrap the raw streaming responses in async with so the underlying socket closes deterministically (continuation_token retrieve + create paths). - Fix the empty-string / whitespace-only header at the source by stripping in _extract_served_model and returning None when nothing remains. - Revert unrelated formatting-only churn in _skills.py and test_mcp.py. - Update unit tests to assert against chat_response.model / update.model and add an aggregated streaming assertion plus a pin that the streaming-with-text_format path does not get the header. Verified end-to-end against Azure OpenAI Responses API: deployment alias gpt-5-nano now reports gpt-5-nano-2025-08-07 as ChatResponse.model in both the non-streaming and streaming paths. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * fix: preserve streaming structured output finalization Agent-Logs-Url: https://github.com/microsoft/agent-framework/sessions/f62076ef-558d-49e8-8fe2-f38d527c9639 Co-authored-by: eavanvalkenburg <13749212+eavanvalkenburg@users.noreply.github.com> * refactor: name streaming response finalizer Agent-Logs-Url: https://github.com/microsoft/agent-framework/sessions/f62076ef-558d-49e8-8fe2-f38d527c9639 Co-authored-by: eavanvalkenburg <13749212+eavanvalkenburg@users.noreply.github.com> * fix: capture streaming response format after prepare Agent-Logs-Url: https://github.com/microsoft/agent-framework/sessions/f62076ef-558d-49e8-8fe2-f38d527c9639 Co-authored-by: eavanvalkenburg <13749212+eavanvalkenburg@users.noreply.github.com> * refactor: clarify streaming response format capture Agent-Logs-Url: https://github.com/microsoft/agent-framework/sessions/f62076ef-558d-49e8-8fe2-f38d527c9639 Co-authored-by: eavanvalkenburg <13749212+eavanvalkenburg@users.noreply.github.com> * test: use public API for streaming structured output Agent-Logs-Url: https://github.com/microsoft/agent-framework/sessions/f62076ef-558d-49e8-8fe2-f38d527c9639 Co-authored-by: eavanvalkenburg <13749212+eavanvalkenburg@users.noreply.github.com> * Inline the served-model header override at its two call sites The `_apply_served_model_header` helper was a 1-line wrapper around `_extract_served_model`. Inlining the `if served_model is not None: ...` matches the pattern already used in the streaming paths and folds the explanatory docstring onto `_extract_served_model` (which is now the single place that knows about the header). Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> --------- Co-authored-by: Eduard van Valkenburg <eavanvalkenburg@users.noreply.github.com> Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com> Co-authored-by: eavanvalkenburg <13749212+eavanvalkenburg@users.noreply.github.com>
Tao Chen ·
2026-05-19 06:38:53 +00:00 -
Python: Strip server-issued response item IDs under storage (#3295) (#5690)
Fixes microsoft/agent-framework#3295. When the OpenAI Responses chat client sends a request that carries previous_response_id / conversation_id / conversation, the server already has the prior turn's response items and rejects duplicates with "Duplicate item found with id fc_xxx". The chat client was re-sending them inline whenever the input messages still carried the items in additional_properties (workflow replay, history providers, etc.), which broke any tool-using agent with persistent history. Decisions: - Single chokepoint: _prepare_message_for_openai. When the resulting request uses service-side storage, drop function_call, reasoning, approval-request/response, and local-shell-call items from the wire input. Keep function_result with its call_id; the server pairs it to the prior function_call via that key. - function_result is preserved unconditionally except for the local-shell variant, which carries its own server-issued item id. - No public API change. Wire format change is subtractive and only on requests that would otherwise 400. - Re-pointed the strict-xfail in test_full_conversation.py from #4047 to #3295. Kept xfail because the test asserts executor-level session-id clearing, which is the defense-in-depth half tracked by 3295-03; this slice closes the wire-level half. Files: - python/packages/openai/agent_framework_openai/_chat_client.py: strip rule applied alongside the existing reasoning-item branch. - python/packages/openai/tests/openai/test_openai_chat_client.py: four new tests pin the contract (function_call, approval, local-shell-call stripped under storage; everything kept without storage). Updated pre-existing tests that exercised the storage-on path to either pass request_uses_service_side_storage=False explicitly or assert the new strip behavior. - python/packages/foundry/tests/foundry/test_foundry_chat_client.py: same explicit storage-off opt-in for the inherited test. - python/packages/core/tests/workflow/test_full_conversation.py: re-pointed xfail reason to #3295 and the executor-level follow-up. Notes for next iteration: - 3295-01 (HITL wire-format validation against live OpenAI/Foundry) was not run; it requires the user's API credentials. The PRD design is locked but the empirical confirmation is still pending. If script 3 fails on either provider, this slice may need to be revisited. - 3295-03 (clear service_session_id in AgentExecutor on full-history replay) remains open. After it lands the xfail in test_full_conversation.py can be removed. - pytest was not run in this iteration because uv-based pytest commands required interactive approval. Validation rests on careful reading; next iteration should run the openai + core test suites.
Evan Mattson ·
2026-05-13 22:09:04 +00:00 -
fix(openai): drop completed continuation_token from shared options in tool loop (#5462)
Fixes #5394. When `background=True` is combined with local function tools, `FunctionInvocationLayer` calls `_inner_get_response(options=mutable_options)` repeatedly with the same dict reference across loop iterations. Once the first poll retrieves a completed background response, `continuation_token` stays in `mutable_options`, so every subsequent iteration takes the `continuation_token is not None` branch and `GET`s the same completed response instead of `POST`ing the tool results. The loop exits after `max_iterations` with empty text and the model never sees any tool output. After the retrieve, if the returned `ChatResponse.continuation_token` is `None` (the background response is no longer in progress), pop `continuation_token` and `background` from the shared options dict in place. The next loop iteration then falls through to the normal `responses.create`/`parse` path and posts tool results. The diagnosis and a verified runtime monkeypatch are in the issue; this is the same fix moved in-tree. Co-authored-by: Yufeng He <40085740+universeplayer@users.noreply.github.com>
Yufeng He ·
2026-05-04 21:22:56 +00:00 -
Python: Support GPT-5 verbosity option and restore Foundry agent_reference (#5619)
* Python: Support GPT-5 verbosity option and restore Foundry agent_reference Adds verbosity as a typed Literal["low","medium","high"] field on OpenAIChatOptions (Responses API) and OpenAIChatCompletionOptions (Chat Completions API), set in the same way as the existing reasoning options. For the Responses API, top-level verbosity is translated to the nested text.verbosity shape the OpenAI service expects. The same field flows through to FoundryChatClient via the existing FoundryChatOptions alias. Also fixes #5582: PR #5447 removed the agent_reference injection from RawFoundryAgentChatClient._prepare_options, so first-turn calls against a Foundry Prompt Agent went out without model and without agent_reference and were rejected by the Responses API with "Missing required parameter: 'model'". Restores the injection on the non-preview path (allow_preview=False) and adds a guard test that asserts the preview path does not inject agent_reference, since the preview SDK injects it via project_client.get_openai_client(agent_name=...). Closes #5516 Closes #5582 * Python: Address Copilot review on PR #5619 - Foundry verbosity sample docstring: replace the misleading "set deployment name on model=" instruction with the actual env-var pattern the sample relies on (FOUNDRY_PROJECT_ENDPOINT and FOUNDRY_MODEL). - _build_agent_reference docstring: clarify the helper is used for both Prompt Agents and HostedAgents on the non-preview path. - Add a Responses API test that locks in the documented precedence rule: when both top-level verbosity and text["verbosity"] are supplied, the top-level value wins. * Python: Drop redundant Foundry verbosity sample and list OpenAI sample in README - Remove samples/02-agents/providers/foundry/foundry_chat_client_verbosity.py per review feedback. The verbosity functionality is identical across the OpenAI and Foundry clients (FoundryChatOptions is an alias of OpenAIChatOptions), so a single sample on the OpenAI side is sufficient. - Add the new client_verbosity.py entry to the OpenAI samples README.
Evan Mattson ·
2026-05-04 21:21:40 +00:00 -
Python: Fix hosted MCP replay producing orphan function_call_output (#5581)
* Python: Fix hosted MCP replay producing orphan function_call_output Resolves part of #5546. After a turn ran a hosted MCP / Foundry-toolbox-MCP tool, the next turn's replayed input array carried a function_call_output with an mcp_* call_id and no matching function_call, and the Responses API returned a 400. Two layers covered here: * Chat-client serialize layer (packages/openai): adds mcp_server_tool_call and mcp_server_tool_result cases to _prepare_message_for_openai and _prepare_content_for_openai. Pairs are coalesced via a post-pass into a single mcp_call input item carrying both arguments and output. Orphan results are dropped (debug-logged) rather than serialized as orphan function_call_output, which is what the Responses API rejected. * Host read layer (packages/foundry_hosting): _item_to_message and _output_item_to_message now route custom_tool_call_output whose call_id.startswith("mcp_") to Content.from_mcp_server_tool_result. Non-mcp_ call_ids continue to produce Content.from_function_result. Symmetric with the host write-side choice for hosted-MCP results. Two further fixes (agentserver SDK additions, host write-side single-item emission) remain tracked on the issue and depend on an SDK release. * Python: Fix pyright unknown-type in _stringify_mcp_output cast(Sequence[Any], output) after the isinstance check so pyright stops flagging the loop variable as unknown. Also normalizes a couple of em-dashes in docstrings I introduced in the prior commit. * Python: Harden _stringify_mcp_output for dict-shaped MCP outputs Address Copilot review on PR #5581. Today the helper falls back to str() for any non-string, non-text-attribute entry, which produces Python repr (single-quoted dicts) for the canonical MCP raw-JSON text-content shape `{"type": "text", "text": "..."}` and any other dict-shaped output. Three small changes: * List-entry path: prefer plain string entries, then `.text` attribute (Content objects), then `entry["text"]` for Mapping entries in the canonical MCP shape, then JSON-encode anything else. * Final fallback: `json.dumps(output, default=str)` so Mappings and scalars produce valid JSON rather than Python repr. * Two new unit tests covering the dict-with-text shape and the non-text-dict JSON fallback. * Python: Suppress mypy redundant-cast on _stringify_mcp_output narrowing The cast is needed by pyright (reportUnknownVariableType) but mypy considers it redundant after the preceding isinstance narrowing. Pyright's behavior is correct for the strict-mode reporting we run, so keep the cast and silence mypy on the line.
Evan Mattson ·
2026-04-30 21:01:52 +00:00 -
Python: Support OpenAI and Gemini
allowed_toolstool choice (#5322)* Support OpenAI allowed_tools in ToolMode (#5309) Add allowed_tools field to ToolMode TypedDict, enabling users to restrict which tools the model may call via the OpenAI allowed_tools tool_choice type. This preserves prompt caching by keeping all tools in the tools list while limiting which ones the model can invoke. - Add allowed_tools: list[str] to ToolMode TypedDict - Add validation in validate_tool_mode() (only valid when mode == "auto") - Convert to OpenAI API format in _prepare_options() - Add tests for validation and API payload generation Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * Python: Support OpenAI `allowed_tools` tool choice in Python SDK Fixes #5309 * Fix #5309: Validate allowed_tools shape and add Chat Completions client support - validate_tool_mode now checks allowed_tools is a non-string sequence of strings and normalizes to list[str], raising ContentError for invalid types - Add missing allowed_tools branch in _chat_completion_client._prepare_options so allowed_tools is emitted as the OpenAI allowed_tools wire format instead of being silently dropped - Add tests for invalid allowed_tools types (string, int, mixed), empty list, tuple normalization, and Chat Completions client payload generation Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * fix: support allowed_tools with mode 'required' in addition to 'auto' OpenAI's allowed_tools tool_choice type supports both mode 'auto' and 'required'. Update validation, client conversion, and tests to allow both modes instead of restricting to 'auto' only. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * fix: use Gemini VALIDATED mode for allowed_tools, warn in unsupported providers - Use FunctionCallingConfigMode.VALIDATED instead of ANY when allowed_tools is set with auto mode in Gemini, preserving optional tool-call semantics. - Handle allowed_tools in required mode with required_function_name precedence. - Fix allowed_names guard to use identity check (is not None) so empty lists are preserved. - Bump google-genai minimum to >=1.32.0 (VALIDATED added in that version). - Add warnings in Anthropic and Bedrock when allowed_tools is set but not supported. - Add Gemini unit tests for allowed_tools with auto, required, empty list, and required_function_name precedence scenarios. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * fix: Chat Completions API does not support allowed_tools, add integration tests - Chat Completions API (_chat_completion_client.py) now warns and falls back to plain mode when allowed_tools is set, since the /chat/completions endpoint does not support the allowed_tools type. - Add allowed_tools integration test param to both OpenAIChatClient (Responses API) and OpenAIChatCompletionClient parametrized option tests. - Update Chat Completions unit tests to reflect the warn-and-fallback behavior. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * fix: remove unused walrus operator variable in chat completion client Remove assigned-but-never-used variable 'allowed' flagged by ruff F841. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> --------- Co-authored-by: Copilot <copilot@github.com> Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Giles Odigwe ·
2026-04-29 17:43:47 +00:00 -
Python: Fix file_search citations breaking assistant history roundtrip (#5557)
* Python: Fix file_search citations breaking assistant history roundtrip The Responses API rejects 'input_file' inside an assistant message, but the SDK was emitting it whenever an assistant Message contained a hosted_file content (which is what file_search citations become). Three coordinated fixes: 1. _prepare_content_for_openai now skips hosted_file for the assistant role instead of mapping to input_file (which the API rejects there). 2. The streaming response.output_text.annotation.added handler attaches file_citation, container_file_citation, and file_path as annotations on text content, matching the non-streaming path. Previously streaming produced standalone HostedFileContent items that always tripped (1). 3. output_text serialization preserves Annotation objects on roundtrip via a new _annotations_to_output_text helper instead of hardcoding 'annotations' to []. file_search citations now survive multi-agent forwarding. Closes #5556. * Address PR review - _annotations_to_output_text: fan out one entry per annotated_region for url_citation/container_file_citation (Annotation.annotated_regions is a Sequence; the API form carries one start/end per entry). - Validate region span bounds are ints before emitting; skip otherwise. - Add test for the file_path branch (annotation with file_id only). - Add test verifying streamed citation events coalesce onto surrounding text via _finalize_response so span indices reference the merged text, not the empty-text streaming carrier.
Evan Mattson ·
2026-04-29 07:38:19 +00:00 -
Python: Fix OpenAI Responses streaming to propagate
created_atfrom finalresponse.completedevent (#5382)* Fix streaming response losing created_at from response.completed event (#5347) The streaming path in _parse_chunk_from_openai did not extract created_at from the response.completed event, unlike the non-streaming path in _parse_responses_response. This caused durabletask persistence warnings when created_at was None. Extract created_at in the response.completed case and pass it to the returned ChatResponseUpdate. Also fix pre-existing pyright errors for optional orjson import in sample files. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * Fix orjson import suppression to use pyright instead of mypy (#5347) Replace `# type: ignore[import-not-found]` with `# pyright: ignore[reportMissingImports]` on optional orjson imports in conversation sample files, matching the repo's Pyright strict configuration. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> --------- Co-authored-by: Copilot <copilot@github.com> Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Evan Mattson ·
2026-04-22 06:19:31 +00:00 -
Python: fix: exclude null file_id from input_image payload to prevent 400 sch… (#5125)
* fix: exclude null file_id from input_image payload to prevent 400 schema error (#5120) * test: add case for additional_properties present without file_id key --------- Co-authored-by: Sergey Borisov <sergey.borisov@dataimpact.io>
S3rj ·
2026-04-21 22:29:00 +00:00 -
Python: Fix OpenAIEmbeddingClient to use AsyncOpenAI for /openai/v1 endpoints (#5137)
* Fix OpenAIEmbeddingClient with /openai/v1 endpoint (#5068) When base_url ends with /openai/v1/ and a credential is provided, load_openai_service_settings was creating an AsyncAzureOpenAI client. The Azure SDK rewrites deployment-based endpoints (including /embeddings) by inserting /deployments/{model}/ into the URL, producing 404s on the OpenAI-compatible /openai/v1 endpoint. Use AsyncOpenAI instead of AsyncAzureOpenAI when the resolved base_url targets /openai/v1, converting the Azure token provider to an async api_key callable. The responses_mode path is unaffected because the Responses API (/responses) is not in the SDK's rewrite list. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * Python: Fix OpenAIEmbeddingClient to use AsyncOpenAI for /openai/v1 endpoints Fixes #5068 * Address review feedback: improve test coverage and remove unrelated changes - Revert unrelated formatting change in test_a2a_agent.py - Fix test_init_with_openai_v1_base_url_and_api_key_uses_openai_client to exercise the Azure settings path (via AZURE_OPENAI_BASE_URL env var) instead of the plain OpenAI path, covering the elif api_key branch - Add _ensure_async_token_provider unit tests for both sync and async token providers Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * Address review feedback for #5068: Python: [Bug]: `OpenAIEmbeddingClient` does not work with `/openai/v1` endpoint --------- Co-authored-by: MAF Dashboard Bot <maf-dashboard-bot@users.noreply.github.com> Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Co-authored-by: Evan Mattson <35585003+moonbox3@users.noreply.github.com>
chetantoshniwal ·
2026-04-21 19:44:25 +00:00 -
Python: Add search tool content for OpenAI responses (#5302)
* Add OpenAI search tool content parsing Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * fix typing * simplified oai image test * same for azure * skip az responses api test --------- Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Eduard van Valkenburg ·
2026-04-20 13:35:30 +00:00 -
Python: Handle url_citation annotations in
FoundryChatClientstreaming responses (#5071)* Fix url_citation annotations dropped in streaming (#5029) Add url_citation branch to the streaming annotation handler in _parse_chunk_from_openai, mirroring the existing non-streaming path. The handler creates an Annotation with type='citation', title, url, and annotated_regions (TextSpanRegion), wrapped in Content.from_text. Update test_streaming_annotation_added_with_unknown_type to use a truly unknown type, and add new tests for url_citation (with and without url). Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * Address review feedback for #5029: Python: [Bug]: url_citation annotations silently dropped in Foundry streaming (SharePoint grounding citations lost) --------- Co-authored-by: Copilot <copilot@github.com> Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Co-authored-by: Evan Mattson <35585003+moonbox3@users.noreply.github.com>
Giles Odigwe ·
2026-04-16 09:33:04 +00:00 -
Python: Fix reasoning replay when store=False (#5250)
* fix reasoning content when store=False * Remove accidental worktree entries Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * remove local session sample * removed left over files * Add attribution override regression test Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> --------- Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Eduard van Valkenburg ·
2026-04-15 17:30:12 +00:00 -
Python: Stop emitting duplicate reasoning content from OpenAI
response.reasoning_text.doneandresponse.reasoning_summary_text.doneevents (#5162)* Fix reasoning text done events duplicating streamed delta content (#5157) The OpenAI Responses API sends both reasoning_text.delta (incremental chunks) and reasoning_text.done (full accumulated text) events. The chat client was emitting Content for both, causing ag-ui to append the full done text onto already-accumulated delta text, producing duplicated reasoning output. Stop emitting Content for reasoning_text.done and reasoning_summary_text.done events, matching how output_text.done is already handled (not emitted). The deltas contain all the content; the done event is redundant. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * fix(openai): emit reasoning done content as fallback when no deltas observed (#5157) Address PR review feedback: - Track item_ids that received reasoning deltas via seen_reasoning_delta_item_ids set - Emit content from done events only when no deltas were received for the item_id, preventing silent content loss on stream resumption - Add comment documenting code_interpreter done event asymmetry - Replace redundant ag-ui test with deduplication-focused test - Add integration test for delta+done sequence in OpenAI chat client tests - Add fallback path tests for done events without preceding deltas Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * Address review feedback for #5157: Python: [Bug]: "type": "response.reasoning_text.delta" and "response.reasoning_text.done" both get exposed as "text_reasoning" * Fix AG-UI reasoning streaming to use proper Start/End pattern (#5157) _emit_text_reasoning now follows the same streaming pattern as _emit_text: - Emits ReasoningStartEvent/ReasoningMessageStartEvent only on the first delta for a given message_id - Emits only ReasoningMessageContentEvent for subsequent deltas - Defers ReasoningMessageEndEvent/ReasoningEndEvent until _close_reasoning_block is called (on content type switch or end-of-run) This produces the correct protocol pattern: ReasoningStartEvent ReasoningMessageStartEvent ReasoningMessageContentEvent(delta1) ReasoningMessageContentEvent(delta2) ReasoningMessageEndEvent ReasoningEndEvent Instead of wrapping every delta in a full Start→End sequence. Backward compatibility is preserved: calling _emit_text_reasoning without a flow argument still produces the full sequence per call. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * Fix import ordering lint error in AG-UI test file (#5157) Move inline import of TextMessageContentEvent to the top-level import block and ensure alphabetical ordering to satisfy ruff I001 rule. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * Fix mypy error: rename loop variable to avoid type conflict with WorkflowEvent The 'event' variable was already typed as WorkflowEvent[Any] from the async for loop at line 590. Reusing it in the _close_reasoning_block loop (which returns list[BaseEvent]) caused an incompatible assignment error. Renamed to 'reasoning_evt' to avoid the conflict. Fixes #5162 Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * Address review feedback for #5157: review comment fixes * narrow test result reporting to explicit pytest JUnit XML * Fix test args * Fix pytest-results-action in merge workflow and remove committed test artifacts Apply the same JUnit XML fix from python-tests.yml to python-merge-tests.yml: add --junitxml=pytest.xml to all test commands and narrow the results action path from ./python/**.xml to ./python/pytest.xml. Also remove accidentally committed pytest.xml and python-coverage.xml and add them to .gitignore. --------- Co-authored-by: Copilot <copilot@github.com> Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Evan Mattson ·
2026-04-09 22:44:59 +00:00 -
Python: Raise clear handler registration error for unresolved TypeVar annotations (#4944)
* Raise clear handler registration error for unresolved TypeVar (#4943) Detect unresolved TypeVar in message parameter annotations during handler registration in both _validate_handler_signature (Executor) and _validate_function_signature (FunctionExecutor). Raises a ValueError with an actionable message recommending @handler(input=..., output=...) or @executor(input=..., output=...) instead of letting TypeVar leak through to a confusing TypeCompatibilityError during workflow edge validation. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * Address review feedback for #4943: reorder checks and harden function executor - Move TypeVar check before validate_workflow_context_annotation in _executor.py so users see the more actionable error first - Wrap get_type_hints in try/except in _function_executor.py matching the defensive pattern in _executor.py - Repurpose duplicate test to cover bounded TypeVar rejection - Add test_function_executor_allows_concrete_types for test symmetry Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * Narrow get_type_hints except clause and add missing tests (#4943) - Narrow `except Exception` to `except (NameError, AttributeError, RecursionError)` in both _executor.py and _function_executor.py so unexpected failures in get_type_hints are not silently swallowed. - Add test_handler_unresolvable_annotation_raises to test_function_executor_future.py exercising the except branch of get_type_hints in the function executor path. - Add test_function_executor_rejects_bounded_typevar_in_message_annotation to test_function_executor.py for parity with the Executor bounded TypeVar test. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * Add error ordering test for TypeVar vs WorkflowContext priority (#4943) Add test_handler_typevar_error_takes_priority_over_context_error to verify that when a handler has both a TypeVar message and an unannotated ctx, the TypeVar error is raised first (the more actionable issue). Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * Python: Fix image content serialization sending null file_id to Foundry API Omit file_id from input_image dict when not present instead of including it as null, which Azure AI Foundry's stricter schema validation rejects. * Python: Fix Foundry API rejecting rich content in function_call_output Azure AI Foundry does not support list-format output in function_call_output items. Add SUPPORTS_RICH_FUNCTION_OUTPUT flag (default True) to RawOpenAIChatClient, set to False in RawFoundryChatClient so Foundry falls back to string output for tool results with images/files. Also omit file_id from input_image dicts when not set, since Foundry rejects explicit nulls. * Python: Surface rich tool content as user message when Foundry lacks support When SUPPORTS_RICH_FUNCTION_OUTPUT is False, image/file items from tool results are injected as a follow-up user message so the model can still process the visual content via Foundry's supported user message format. * Xfail Foundry image integration test for the meantime --------- Co-authored-by: Copilot <copilot@github.com> Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Evan Mattson ·
2026-04-07 16:59:17 +00:00 -
Python: [BREAKING] Python: move Azure AI embeddings to Foundry (#5056)
* renamed AzureAIINferenceEmbeddings and lazy load azure-cosmos and env var rename * updated coverage * fix readme
Eduard van Valkenburg ·
2026-04-02 11:26:35 +00:00 -
Python: updated declarative samples and handling of non-pydantic response formats (#5022)
* updated declarative samples and handling of non-pydantic response formats * fixed from comments * update docstring
Eduard van Valkenburg ·
2026-04-01 19:16:00 +00:00 -
Python: [BREAKING] Standardize model selection on model (#4999)
* Refactor Anthropic model option and provider clients Rename the Anthropic client model option from model_id to model, add provider-specific Anthropic wrappers for Foundry, Bedrock, and Vertex, and expose them through the Anthropic, Foundry, Amazon, and Google namespaces. Update core option handling, docs, samples, and tests accordingly. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * Fix Anthropic skills sample typing Cast the Anthropic beta client to Any in the skills sample so the pre-commit sample pyright check no longer fails on beta skills and files endpoints that are not exposed by the current SDK stubs. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * undo sample mypy * Retry CI after transient external failures Retrigger PR validation after an unrelated Copilot review workflow SAML failure and a transient external tau2 git fetch failure in the Windows Python test setup. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * Address review feedback on model option merging Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * Address Anthropic compatibility review feedback Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * moved all to `model` * fixes for azure ai search * Python: standardize remaining sample env var names Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * Python: fix foundry-local pyright compatibility Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * updated env vars in cicd --------- Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Eduard van Valkenburg ·
2026-04-01 19:00:18 +00:00 -
Python: [BREAKING] Remove deprecated Python OpenAI/Azure AI surfaces (#4990)
* [BREAKING] Remove deprecated Python OpenAI/Azure AI surfaces Also clean up follow-on docs, environment guidance, package metadata, and lab test stability. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * Fix deleted semantic-kernel sample links Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * Address PR review feedback Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * improve foundry language * Fix A2A Foundry sample regression Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> --------- Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Eduard van Valkenburg ·
2026-03-31 20:36:21 +00:00 -
Python: [BREAKING] Remove deprecated kwargs compatibility paths (#4858)
* [BREAKING] Remove deprecated kwargs compatibility paths Remove the deprecated kwargs compatibility shims across core agents, clients, tools, middleware, and telemetry. Keep workflow kwargs behavior intact in this branch and follow up separately in #4850. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * Fix PR CI fallout for kwargs removal Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * Address PR review feedback Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * updates * Fix Azure AI CI fallout Remove the stale _get_current_conversation_id override from the Azure AI client after the OpenAI base helper was deleted. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * fixed new classes * Fix Assistants deprecated import gating Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * Fix integration replay regressions Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * Switch multi-agent hosting samples to Azure chat completions Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * Simplify Azure multi-agent sample config Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> --------- Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Eduard van Valkenburg ·
2026-03-27 21:00:12 +00:00 -
Python: Fix broken samples for GitHub Copilot, declarative, and Responses API (#4915)
* Python: Fix broken samples for GitHub Copilot, declarative, and Responses API - Add missing on_permission_request handler to github_copilot_basic and github_copilot_with_session samples (required by copilot SDK) - Increase timeout for remote MCP query in github_copilot_with_mcp sample - Soften session isolation claim in github_copilot_with_session sample - Fix inline_yaml sample: pass project_endpoint via client_kwargs instead of relying on YAML connection block (AzureAIClient expects project_endpoint, not endpoint) - Handle raw JSON schemas in Responses client _convert_response_format so declarative outputSchema works with the Responses API Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * Improve raw JSON schema detection heuristic and add tests - Broaden raw schema detection to handle anyOf, oneOf, allOf, $ref, $defs keywords and JSON Schema primitive types, not just 'properties' - Apply same raw schema handling to azure-ai _shared.py for consistency - Add unit tests for both openai and azure-ai response_format conversion Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> --------- Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Giles Odigwe ·
2026-03-27 16:27:19 +00:00 -
[BREAKING] Python: fix OpenAI Azure routing and provider samples (#4925)
* Python: fix OpenAI Azure routing and provider samples Prefer OpenAI when OPENAI_API_KEY is present unless Azure is explicitly requested. Clarify constructor docs, keep deprecated Azure wrappers compatible with stricter settings validation, and refresh the provider samples and tests to use the current client patterns. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * fix bandit * Python: align OpenAI embedding Azure routing Extend the shared OpenAI-vs-Azure routing and credential behavior to the embedding client, add Azure embedding regression coverage, and refresh the embedding samples to use the generic client path. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * Python: fix embedding client pyright check Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * Python: thin OpenAI embedding wrapper Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * Python: document embedding overload routing Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * Python: fix callable OpenAI key routing Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * Python: fix Azure credential routing tests Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * Python: address OpenAI review feedback Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * Python: narrow Azure routing markers Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * Python: refine OpenAI model fallback order Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * Python: narrow Azure deployment docs Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * Python: remove embedding routing wording Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * Python: run embedding Azure integration tests Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * changed variable name * Python: expand OpenAI package README Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * clarified readme * Python: fix Azure OpenAI integration setup Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * Python: correct Azure integration env mapping Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * updated code to fix int tests * test updates * test fix * fix test setup * updates to tests and setup * remove openai assistants int tests * improvements in int tests * fix env var * fix env vars * fix azure responses test * trigger actions --------- Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Eduard van Valkenburg ·
2026-03-27 13:33:39 +00:00 -
Python: Support structuredContent in MCP tool results and fix sampling options type (#4763)
* Support MCP sampling tools capability (#4625) Forward systemPrompt, tools, and toolChoice from MCP sampling requests to the chat client's get_response() call. Also advertise the sampling.tools capability to MCP servers when a client is configured. - Pass SamplingCapability with tools support to ClientSession - Convert systemPrompt to instructions in options - Convert MCP Tool objects to FunctionTool instances for options - Map MCP ToolChoice.mode to tool_choice in options - Add tests for all new behaviors and update existing sampling tests Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * Fix #4625: Support MCP sampling tool with proper typing and structured content - Fix mypy error by typing sampling callback options as ChatOptions[None] instead of dict[str, Any], and importing ChatOptions from _types - Handle structuredContent from CallToolResult in _parse_tool_result_from_mcp, serializing it as JSON text Content when present - Add tests for structuredContent parsing (with and without regular content) Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * Fix lint: add author to TODO comment Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * Address review feedback for #4625: remove default=str, add edge-case tests - Remove default=str from json.dumps for structuredContent to fail fast on non-JSON-serializable values instead of silently converting - Add test for non-JSON-serializable structuredContent (TypeError) - Add tests for empty systemPrompt ('') and empty tools list ([]) edge cases in sampling callback - Expand TODO comment noting list[Content] return type constraint for future result_type support Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * Sanitize sampling callback error to avoid leaking internals (#4625) Log exception details at DEBUG level instead of including them in the ErrorData message returned to the MCP server, which may be untrusted. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * Address review feedback for #4625: move params to options, restore error info - Remove stale TODO comment about response_format (ChatOptions already has it) - Restore {ex} in sampling callback error message for useful debugging info - Set structuredContent as additional_property on Content for structured access - Move temperature, max_tokens, stop into options dict (not top-level kwargs) - Only set temperature when provided (not all models support it) - Add tests for generation params in options and temperature omission Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * Fix MCP sampling callback and structured content error handling (#4625) - Guard max_tokens like temperature: only set when not None, so options can properly evaluate to None when all params are absent - Wrap json.dumps of structuredContent in try/except to fall back to str() for non-serializable values instead of propagating TypeError - Extract test_connect_sampling_capabilities_with_client into its own test function so pytest can discover it independently - Add test for max_tokens=None omission from options - Update structured content non-serializable test to expect fallback Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * Address review feedback for #4625: review comment fixes * Fix MCP and Azure validation regressions Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> --------- Co-authored-by: Copilot <copilot@github.com> Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Eduard van Valkenburg ·
2026-03-26 07:33:19 +00:00 -
Python: Fix streaming path to emit mcp_server_tool_result on output_item.done instead of output_item.added (#4821)
* Fix streaming path to deliver mcp_server_tool_result content (#4814) Remove premature mcp_server_tool_result emission from the response.output_item.added/mcp_call handler — at that point the MCP server has not yet responded and output is always None. Add a handler for response.mcp_call.completed that emits mcp_server_tool_result with the actual tool output, matching the non-streaming path behavior. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * Fix streaming path to deliver mcp_server_tool_result content (#4814) Stop eagerly emitting mcp_server_tool_result on response.output_item.added (when output is always None). Instead, handle response.output_item.done for mcp_call items, which carries the full McpCall with populated output. This matches the non-streaming path which guards with 'if item.output is not None' before emitting the result. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * Fix test docstring to match actual implementation event name Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * Address review: call_id fallback and raw_representation consistency (#4814) - Add call_id fallback in response.output_item.done mcp_call handler to match the output_item.added handler pattern - Use done_item instead of event for raw_representation to keep consistent with other output_item branches and non-streaming path - Add test for call_id fallback when id attribute is missing - Add raw_representation assertions to existing done handler tests Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * Address review: call_id fallback for non-streaming path and test coverage (#4814) - Apply defensive call_id fallback (getattr with id/call_id/empty) to non-streaming mcp_call path for consistency with streaming path - Add raw_representation assertion to call_id fallback test - Add test for empty-string fallback when neither id nor call_id exist Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> --------- Co-authored-by: Copilot <copilot@github.com> Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Giles Odigwe ·
2026-03-26 02:09:22 +00:00 -
Python: [BREAKING] Python: Provider-leading client design & OpenAI package extraction (#4818)
* Python: Provider-leading client design & OpenAI package extraction Major refactoring of the Python Agent Framework client architecture: - Extract OpenAI clients into new `agent-framework-openai` package - Core package no longer depends on openai, azure-identity, azure-ai-projects - Rename clients for discoverability: OpenAIResponsesClient → OpenAIChatClient, OpenAIChatClient → OpenAIChatCompletionClient - Unify `model_id`/`deployment_name`/`model_deployment_name` → `model` param - New FoundryChatClient for Azure AI Foundry Responses API - New FoundryAgent/FoundryAgentClient for connecting to pre-configured Foundry agents - Remove OpenAIBase/OpenAIConfigMixin from non-deprecated client MRO - Deprecate AzureOpenAI* clients, AzureAIClient, OpenAIAssistantsClient - Reorganize samples: azure_openai+azure_ai+azure_ai_agent → azure/ - ADR-0020: Provider-Leading Client Design Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * fix: missing Agent imports in samples, .model_id → .model in foundry_local sample Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * fix: CI failures — mypy errors, coverage targets, sample imports - azure-ai mypy: add type ignores for TypedDict total=, model arg, forward ref - Coverage: replace core.azure/openai targets with openai package target - project_provider: add type annotation for opts dict Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * fix: populate openai .pyi stub, fix broken README links, coverage targets Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * fixes * updated observabilitty * reset azure init.pyi * fix errors * updated adr number * fix foundry local * fixed not renamed docstrings and comments, and added deprecated markers to old classes * fix tests and pyprojects * fix test vars * updated function tests * update durable * updated test setup for functions * Fix Foundry auth in workflow samples Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * Stabilize Python integration workflows Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * Update hosting samples for Foundry Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * Trigger full CI rerun Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * Trigger CI rerun again Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * trigger rerun * trigger rerun * fix for litellm * undo durabletask changes * Move Foundry APIs into foundry namespace Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * Fix Foundry pyproject formatting Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * Split provider samples by Foundry surface Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * Restore hosting sample requirements Also fix the Foundry Local sample link after the provider sample move. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * updated tests * udpated foundry integration tests * removed dist from azurefunctions tests * Use separate Foundry clients for concurrent agents Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * fix client setup in azfunc and durable * disabled two tests * updated setup for some function and durable tests * improved azure openai setup with new clients * ignore deprecated * fixes * skip 11 * remove openai assistants int tests --------- Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Eduard van Valkenburg ·
2026-03-25 09:56:29 +00:00