Skip to content

.NET: Preserve structured tool arguments in GitHub Copilot AG-UI events - #4

Closed
kzu with Copilot wants to merge 500 commits into
mainfrom
copilot/implement-raw-json-element-support
Closed

kzu with Copilot wants to merge 500 commits into
mainfrom
copilot/implement-raw-json-element-support

Conversation

Copilot AI commented Mar 24, 2026

Copy link
Copy Markdown

Motivation and Context

AG-UI tool call arguments were flattening nested objects/arrays into raw JSON strings. That causes downstream serialization to double-encode structured arguments instead of emitting JSON objects and arrays.

Description

  • Argument preservation

    • Update ConvertJsonElementToArguments in GitHubCopilotAgent to keep JsonValueKind.Object and JsonValueKind.Array as cloned JsonElement values.
    • Map JsonValueKind.Undefined to null rather than falling through to string conversion.
  • Behavioral effect

    • Tool call payloads now retain structured JSON for nested arguments when flowing through FunctionCallContent into AG-UI events.
    • This avoids converting:
      • { "nested": "value" } into the string "{"nested":"value"}"
      • [1,2,3] into the string "[1,2,3]"
  • Regression coverage

    • Update the GitHub Copilot unit test to assert nested object and array arguments are exposed as JsonElement and remain queryable as structured JSON.
arguments[property.Name] = property.Value.ValueKind switch
{
    JsonValueKind.Object => property.Value.Clone(),
    JsonValueKind.Array => property.Value.Clone(),
    JsonValueKind.Undefined => null,
    // existing primitive mappings unchanged
};

Contribution Checklist

  • The code builds clean without any errors or warnings
  • The PR follows the Contribution Guidelines
  • All unit tests pass, and I have added new tests where possible
  • Is this a breaking change? If yes, add "[BREAKING]" prefix to the title of the PR.

dependabot Bot and others added 30 commits February 19, 2026 08:13
Bumps [prek](https://github.com/j178/prek) from 0.3.2 to 0.3.3.
- [Release notes](https://github.com/j178/prek/releases)
- [Changelog](https://github.com/j178/prek/blob/master/CHANGELOG.md)
- [Commits](j178/prek@v0.3.2...v0.3.3)

---
updated-dependencies:
- dependency-name: prek
  dependency-version: 0.3.3
  dependency-type: direct:development
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <[email protected]>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
…osoft#4036)

Bumps [tar](https://github.com/isaacs/node-tar) from 7.5.3 to 7.5.9.
- [Release notes](https://github.com/isaacs/node-tar/releases)
- [Changelog](https://github.com/isaacs/node-tar/blob/main/CHANGELOG.md)
- [Commits](isaacs/node-tar@v7.5.3...v7.5.9)

---
updated-dependencies:
- dependency-name: tar
  dependency-version: 7.5.9
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <[email protected]>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: Mark Wallace <[email protected]>
microsoft#3989)

* Fix FoundryAgents_Step15_ComputerUse sample for Azure Agents API

The Azure Agents API rejects previous_response_id alongside computer_call_output
items, unlike the vanilla OpenAI Responses API. This fix:

- Send all prior response output items (reasoning, computer_call, etc.) as input
  items in follow-up calls so the API has full conversation context
- Create a fresh session per call to avoid ConversationId/previous_response_id
- Use currentCallId instead of initialCallId for computer_call_output
- Clear ContinuationToken after polling to prevent stale tokens
- Remove unused initialCallId tracking variable

Co-authored-by: Copilot <[email protected]>

* Address comments

---------

Co-authored-by: Copilot <[email protected]>
* .NET: Add File Search sample microsoft#3674

* Add FileSearch sample to solution and parent README

- Add FoundryAgents_Step18_FileSearch to agent-framework-dotnet.slnx
- Add FileSearch entry to FoundryAgents samples table in README.md
- Fix README inaccuracy: sample creates one agent, not two

Co-authored-by: Copilot <[email protected]>

* Refactor FileSearch sample: local functions + DefaultAzureCredential

- Refactor agent creation into switchable local functions
- Use DefaultAzureCredential with WARNING comment (matching other samples)
- Update README to reference DefaultAzureCredential

Co-authored-by: Copilot <[email protected]>

* Fix orphaned temp file in FileSearch sample

Use Path.Combine + Path.GetRandomFileName instead of Path.GetTempFileName
to avoid leaving an orphaned temp file on disk.

Co-authored-by: Copilot <[email protected]>

---------

Co-authored-by: Copilot <[email protected]>
…urce not found (microsoft#3856)

* Update packages

* Fix run-request.http format
…#4043)

* Initial plan

* Add load_dotenv() to 303 Python samples for environment variable loading

Co-authored-by: TaoChenOSU <[email protected]>

* Update SAMPLE_GUIDELINES.md to document load_dotenv() requirement

Co-authored-by: TaoChenOSU <[email protected]>

* Update samples README.md to document .env file usage

Co-authored-by: TaoChenOSU <[email protected]>

* Run ruff format on all changed sample files

Co-authored-by: TaoChenOSU <[email protected]>

* Clarify load_dotenv() usage in README - local dev vs production

Co-authored-by: TaoChenOSU <[email protected]>

* Remove deprecated getting_started folder as requested

Co-authored-by: TaoChenOSU <[email protected]>

* Document env_file_path parameter for per-client configuration

Co-authored-by: TaoChenOSU <[email protected]>

* Merge main branch to resolve conflicts

Co-authored-by: TaoChenOSU <[email protected]>

* Fix run_evaluation.py file that was empty in merge commit

Co-authored-by: TaoChenOSU <[email protected]>

* Remove dotnet changes from merge - out of scope for this PR

Co-authored-by: TaoChenOSU <[email protected]>

* Remove package and test changes from merge - only sample changes needed

Co-authored-by: TaoChenOSU <[email protected]>

* Remove test_func_utils.py - only sample changes needed

Co-authored-by: TaoChenOSU <[email protected]>

* Revert sample files not in original changeset - keep only load_dotenv additions

Co-authored-by: TaoChenOSU <[email protected]>

* Move load_dotenv() outside snippet tag in 06_host_your_agent.py

Co-authored-by: TaoChenOSU <[email protected]>

* Fix comment placement - move load_dotenv before code comments

Co-authored-by: TaoChenOSU <[email protected]>

* Fix load_dotenv() placement across all samples - after docstring, before code comments

Co-authored-by: TaoChenOSU <[email protected]>

* Merge latest main branch with load_dotenv changes

Co-authored-by: TaoChenOSU <[email protected]>

* Remove non-sample changes from merge - keep only load_dotenv additions

Co-authored-by: TaoChenOSU <[email protected]>

* Revert non-load_dotenv sample changes from merge

Co-authored-by: TaoChenOSU <[email protected]>

* Fix run_evaluation.py - use main's improved version (file already had load_dotenv)

Co-authored-by: TaoChenOSU <[email protected]>

* Manual update

* Manual update 2

* Fix Role usage and load_dotenv placement per PR review feedback

Co-authored-by: eavanvalkenburg <[email protected]>

* Fix Role usage - use string literals not enum attributes

Co-authored-by: eavanvalkenburg <[email protected]>

* Fix SAMPLE_GUIDELINES.md example - load_dotenv before docstring per guidance

Co-authored-by: eavanvalkenburg <[email protected]>

* Move load_dotenv() before docstrings in all samples per SAMPLE_GUIDELINES ordering

Co-authored-by: eavanvalkenburg <[email protected]>

* Address PR review: rename files, fix placement, add session usage, remove note

Co-authored-by: eavanvalkenburg <[email protected]>

* Update Redis README to reference renamed file redis_history_provider.py

Co-authored-by: eavanvalkenburg <[email protected]>

---------

Co-authored-by: copilot-swe-agent[bot] <[email protected]>
Co-authored-by: TaoChenOSU <[email protected]>
Co-authored-by: Tao Chen <[email protected]>
Co-authored-by: eavanvalkenburg <[email protected]>
Co-authored-by: Eduard van Valkenburg <[email protected]>
* feat: Implement Polymorphic Routing

* feat: Add support for Send/Yield annotations with basic Executor

* Adds annotations to Declarative workflow executors

* fix: Address PR Comments

* Implicit filter in collection loops
* Remove debug / usused / superfluous code
* Fix ProtocolBuilder implicit output registrations
* Fix logic error in ExecuteRouteGeneratorTests.ClassWithManualConfigureProtocol_DoesNotGenerate

* fix: Solidify type checks and send/yield type registrations

* fix: Suppress generation of TurnTokens out of AggregateTurnMessagesExecutor

* Fixes an issue where ConcurrentEndExecutor is not expecting TurnTokens.

* fix: Add ProtocolBuilder support for chained-delegation

* Updates Declarative pacakge to rely on chained-delegation Send/Yield registration
* Renames DeclarativeActionExectuor's new ExecuteAsync to ExecuteActionAsync to avoid colliding with Executor.ExecutoeAsync

* fix: Address PR Comments

* Fixes type mapping in FanInEdgeRunner
* Fixes and expalins send/yield type registration in FunctionExecutor

* fixup: build-break

* fix: Add missing SendsMesage declaration to InvokeAzureAgentExecutor
) (microsoft#3812)

Track the last CheckpointInfo in InProcessRunner so that newly created
checkpoints reference their parent. When resuming from a checkpoint,
the resumed-from checkpoint becomes the parent of the next checkpoint.

Adds tests verifying:
- First checkpoint has null parent
- Subsequent checkpoints chain parents correctly
- Checkpoint after resume references the resumed-from checkpoint
- Rename UserNameProvider → UserMemoryProvider
- Use session state (state dict) instead of instance variables
- Use context.extend_instructions() instead of context.instructions.append()
- Use DEFAULT_SOURCE_ID class attribute
- Fix imports to use public agent_framework API
- Add session state inspection at end of sample

Co-authored-by: Copilot <[email protected]>
* .NET: Add OpenAPI Tools sample microsoft#3674

* Apply format fixes

* Add MEAI and Native SDK creation options for OpenAPI Tools sample

Co-authored-by: Copilot <[email protected]>

* Address PR review: DefaultAzureCredential and CS8321 in NoWarn

Co-authored-by: Copilot <[email protected]>

* Add project to slnx

---------

Co-authored-by: Copilot <[email protected]>
* Updated package versions for RC release

* Update python/packages/redis/pyproject.toml

Co-authored-by: Copilot <[email protected]>

* Small fix

---------

Co-authored-by: Copilot <[email protected]>
…#4088)

Replace ad_token, ad_token_provider, and get_entra_auth_token with a
unified credential parameter across all Azure-related packages.

Core changes:
- Add AzureCredentialTypes (TokenCredential | AsyncTokenCredential) and
  AzureTokenProvider (Callable[[], str | Awaitable[str]]) type aliases
- Add resolve_credential_to_token_provider() using azure.identity's
  get_bearer_token_provider for automatic token caching/refresh
- Update AzureOpenAIChatClient, AzureOpenAIResponsesClient, and
  AzureOpenAIAssistantsClient to accept credential: AzureCredentialTypes |
  AzureTokenProvider
- Remove ad_token, ad_token_provider params and get_entra_auth_token helpers

Package updates:
- azure-ai: Accept AzureCredentialTypes on AzureAIClient,
  AzureAIAgentClient, AzureAIProjectAgentProvider, AzureAIAgentsProvider
- azure-ai-search: Accept AzureCredentialTypes on
  AzureAISearchContextProvider
- purview: Accept AzureCredentialTypes | AzureTokenProvider on
  PurviewClient, PurviewPolicyMiddleware, PurviewChatPolicyMiddleware

Fixes microsoft#3449
Fixes microsoft#3500

Co-authored-by: Copilot <[email protected]>
…crosoft#4037)

* [BREAKING] refactor: Decouple Checkpointing and Execution APIs

With this change, Checkpointing becomes an property of an IWorkflowExecutionEnvironment. This lets environments that are tightly-coupled to their CheckpointManager avoid needing to present APIs that would not work (e.g. taking in an InMemory CheckpointManager for Durable Tasks, for example)

* refactor: Normalize IsCheckpointingEnabled naming
* Updated package versions for RC release

* Resolved comment

* Resolved comments
* Add tweaks to .net agent skills

* Address PR feedback
* [BREAKING] Redesign Python exception hierarchy

Replace the flat ServiceException family with domain-scoped branches:
- AgentException (with InvalidAuth, InvalidRequest, InvalidResponse, ContentFilter)
- ChatClientException (same consistent suberrors)
- IntegrationException (same + InitializationError)
- WorkflowException (Runner, Convergence, Checkpoint, Validation, Action, Declarative)
- ContentError (AdditionItemMismatch)
- ToolException / ToolExecutionException (unchanged)
- MiddlewareException / MiddlewareTermination (unchanged)

Key changes:
- All Service* exceptions removed (ServiceException, ServiceInitializationError, etc.)
- AgentExecutionException split into AgentInvalidRequest/ResponseException
- AgentInvocationError removed, split into AgentInvalidRequest/ResponseException
- Workflow exceptions moved from _workflows/_exceptions.py into main exceptions.py
- _workflows/__init__.py emptied; main __init__.py imports directly from submodules
- Purview exceptions re-parented under IntegrationException hierarchy
- Init validation errors use built-in ValueError/TypeError instead of custom exceptions
- CODING_STANDARD.md updated with hierarchy design and rationale

Fixes microsoft#3410

Co-authored-by: Copilot <[email protected]>

* Clarify ToolException vs ToolExecutionException docstrings

ToolException: base class for all tool-related exceptions (preconditions,
connection/init failures).
ToolExecutionException: runtime call failures (tool call failed, reconnect
failed, MCP errors).

Co-authored-by: Copilot <[email protected]>

* Fix remaining stale imports from agent_framework._workflows

- azurefunctions: _context.py, _app.py, _serialization.py, test_func_utils.py
  used 'from agent_framework._workflows import X' which broke after
  emptying _workflows/__init__.py; changed to direct submodule imports
- azure-ai-search: test still referenced ServiceInitializationError;
  updated to ValueError to match production code

Co-authored-by: Copilot <[email protected]>

---------

Co-authored-by: Copilot <[email protected]>
microsoft#4009)

* Support a message only AIContextProvider as an AIAgent Decorator

* Fix formatting

* Address PR comments.
…ages (microsoft#3811)

* Fix handoff orchestration not passing user message to handoff target agent (microsoft#3161)

Filter out internal handoff function call and tool result messages before
passing conversation history to the target agent's LLM. These messages
confused the model into ignoring the original user question.

* Add handoff tool call filtering behavior and enhance workflow builder

- Introduced HandoffToolCallFilteringBehavior enum to specify filtering behavior for tool call contents in handoff workflows.
- Updated HandoffsWorkflowBuilder to support customizable handoff instructions and tool call filtering behavior.
- Enhanced HandoffAgentExecutor to utilize new filtering options for improved message handling during agent handoffs.

* Enhance handoff message filtering logic and add unit tests for filtering behaviors

* Refactor HandoffMessagesFilter to remove unused handoff function names and enhance filtering logic for non-handoff function calls

* Refactor HandoffMessagesFilter to streamline FilterCandidateState initialization and improve clarity

* Refactor HandoffMessagesFilter to improve filtering logic and add integration tests for handoff workflows

* fix: HandoffAgentExecutor tests
microsoft#4083)

* fix: strip function_call and text_reasoning from cross-agent workflow handoff

When a reasoning model (e.g. gpt-5-mini) runs as Agent 1 in a workflow, its
response includes text_reasoning items (with server-scoped IDs like rs_XXXX)
and function_call items. Forwarding these to Agent 2 in a fresh conversation
caused API errors because the reasoning/call IDs are scoped to the original
stored response context.

Changes:
- Strip 'function_call', 'text_reasoning', 'function_approval_request', and
  'function_approval_response' from handoff messages in _agent_executor.py
- Keep 'function_result' so the actual tool output content is preserved for
  the next agent's context
- Update unit tests to reflect that function_result messages survive handoff
  (messages grow from 2→3: user, tool(result), assistant(summary))
- Fix incorrect test assertions in test_function_invocation_stop_clears_*
  that assumed the client layer updates session.service_session_id
- Also fixed _extract_function_calls to search all messages with call_id
  deduplication, and the error-limit stop path to submit function_call_output
  items before halting (via tool_choice=none cleanup call)

Relates to: microsoft#4047

Co-authored-by: Copilot <[email protected]>

* fix: reasoning model workflow handoff and history serialization

Fixes multiple related issues when using reasoning models (gpt-5-mini,
gpt-5.2) in multi-agent workflows that chain agents via from_response
or replay full conversation history via AgentExecutorRequest.

## Reasoning items always emitted on output_item.added

When a reasoning model produces encrypted or hidden reasoning (no
visible text), the Responses API still fires a reasoning output item
without any reasoning_text.delta events. Previously no text_reasoning
Content was emitted in that case, making it invisible to downstream
logic. Both the non-streaming (_parse_response_from_openai) and
streaming (output_item.added) paths now always emit at least one
text_reasoning Content — with empty text if no content is available —
so co-occurrence detection and serialization guards work reliably.

## Reasoning items only serialized when paired with a function_call

The Responses API only accepts reasoning items in input when they
directly preceded a function_call in the original response. Sending a
reasoning item that preceded a text response (no tool call) causes:
  "reasoning was provided without its required following item"
_prepare_message_for_openai now checks has_function_call per message
and skips text_reasoning serialization when there is no accompanying
function_call.

## summary field is an array, not an object

The reasoning item summary field sent to the Responses API must be an
array of objects ([{"type": "summary_text", "text": ...}]), not a
single object. Fixed _prepare_content_for_openai accordingly.

## service_session_id cleared when explicit history is provided

When a workflow coordinator replays a full conversation (including
function calls from a previous agent run) back to an executor via
AgentExecutorRequest or from_response, the executor's session still
held a service_session_id (previous_response_id) from the prior run.
The API then received the same function-call items twice — once from
previous_response_id (server-stored) and once from the explicit input —
causing: "Duplicate item found with id fc_...".

AgentExecutor.run (when should_respond=True) and from_response now
reset self._session.service_session_id = None before running so that
explicit input is the sole source of conversation context.

Co-authored-by: Copilot <[email protected]>

* small improvements in text reasoning

* refactor: add reset_service_session to AgentExecutorRequest for explicit history replay

Replace the implicit 'always clear service_session_id when should_respond=True'
with an explicit opt-in field on AgentExecutorRequest.

The old approach used should_respond=True as a proxy for 'full history replay',
but that conflates two distinct intents:
- Orchestrations group chat sends should_respond=True with an empty/single-message
  list (not a full replay) — unnecessarily clearing service_session_id.
- HITL / feedback coordinators send the full prior conversation and truly need
  a fresh service session ID to avoid duplicate-item API errors.

Changes:
- Add AgentExecutorRequest.reset_service_session: bool = False
- AgentExecutor.run only clears service_session_id when this flag is True
- AgentExecutor.from_response unchanged (always clears; always full conversation)
- Set reset_service_session=True in all full-history-replay call sites:
  agents_with_HITL.py, azure_chat_agents_tool_calls_with_feedback.py,
  autogen-migration round-robin coordinator, tau2 runner
- Update _FullHistoryReplayCoordinator test helper to pass the flag

Co-authored-by: Copilot <[email protected]>

* comment update

* fixes from feedback

* fix test

* reverted changes to agent executor

* fix: remove reset_service_session from tau2 runner

Co-authored-by: Copilot <[email protected]>

* two other reverts

* fix sample

---------

Co-authored-by: Giles Odigwe <[email protected]>
Co-authored-by: Copilot <[email protected]>
* Add more unit test coverage gates

* Fix missing `files` parameter in `print_coverage_table()` docstring (microsoft#4106)

* Initial plan

* Update print_coverage_table docstring to document files parameter

Co-authored-by: TaoChenOSU <[email protected]>

---------

Co-authored-by: copilot-swe-agent[bot] <[email protected]>
Co-authored-by: TaoChenOSU <[email protected]>

---------

Co-authored-by: Copilot <[email protected]>
Co-authored-by: TaoChenOSU <[email protected]>
* Small fixes in README

* Disabled problematic test

* Disabled problematic test
…soft#4090)

* refactor: Normalize Run/RunStreaming with AIAgent

* refactor: Clarify Session vs. Run -level concepts

* Rename RunId to SessionId to better match Run/Session terminology in AIAgent
* [BREAKING]: Will break existing checkpointed sessions in CosmosDb due to field rename

* refactor: Rename and simplify interface around getting typed data out of ExternalRequest/Response

* Also adds hints around using value types in PortableValue

* refactor: Rename AddFanInEdge to AddFanInBarrierEdge

This will prevent a breaking change later when we introduce a programmable FanIn edge, analogous to the FanOut edge's EdgeSelector.

The goal, in the long run is to support a number of different FanIn scenarios, with naive FanIn (no barrier) by default, similar to FanOut.

* refactor: AsAgent(this Workflow, ...) => AsAIAgent(...)

* misc - part1: SwitchBuilder internal

---------

Co-authored-by: Dmytro Struk <[email protected]>
* Add Azure AI Foundry Memory Context Provider with unit tests

* Add FoundryMemory integration tests and sample application

* Fix ClearStoredMemoriesAsync to handle 404 gracefully and rename to EnsureStoredMemoriesDeletedAsync

* Refactor FoundryMemory: simplify architecture and add memory store creation

- Remove IFoundryMemoryOperations interface (was only for test mocking)
- Remove AIProjectClientMemoryOperations wrapper class
- Provider now directly uses AIProjectClient with internal extension methods
- Extension methods return actual response models instead of extracted values
- Remove WaitForUpdateCompletionAsync from provider (sample uses delay)
- Simplify EnsureMemoryStoreCreatedAsync to return Task instead of Task<bool>
- Add memory store creation with chat_model and embedding_model
- Add UpdateMemoriesResponse with SupersededBy and Error fields
- Simplify unit tests to focus on constructor validation and serialization
- Update sample to use simple delay for memory processing wait

* Add waiting operation for memory store updates

* Fix UTF-8 BOM encoding for FoundryMemory csproj files

* Update copilot instructions for UTF-8 BOM and fix sample API rename

* Fix UTF-8 BOM encoding for TestableAIProjectClient.cs

* Add missing response headers for TS

* Changing default embedding

* Using the SDK Models

* Program update

* Remove debugging code from sample

* Adapt FoundryMemoryProvider to new AIContextProvider API and add UTF-8 BOM instruction

- Override ProvideAIContextAsync/StoreAIContextAsync instead of removed virtual InvokingAsync/InvokedAsync
- Use ProviderSessionState<State> for session-scoped state management (matching Mem0Provider pattern)
- Replace constructor-based scope with stateInitializer delegate
- Remove Serialize method (no longer on base class)
- Add SearchInputMessageFilter, StorageInputMessageFilter, StateKey to options
- Update sample to use AIContextProviders list instead of AIContextProviderFactory
- Update unit and integration tests for new API
- Add UTF-8 BOM encoding and --tl:off instructions to dotnet/AGENTS.md

Co-authored-by: Copilot <[email protected]>

* Use DefaultAzureCredential in Foundry Memory sample

Co-authored-by: Copilot <[email protected]>

* Address PR review comments for FoundryMemoryProvider

- Move memoryStoreName from options to required constructor parameter
- Make FoundryMemoryProviderScope require non-null/whitespace scope in constructor
- Make Scope property read-only (getter only)
- Replace ConcurrentQueue with single last update ID to fix memory leak
- Only clear pending update ID after successful completion
- Add delete success logging
- Mark FoundryMemoryProvider with [Experimental] attribute
- Update unit tests for new API signatures

Co-authored-by: Copilot <[email protected]>

* Use Throw.IfNullOrWhitespace for scope and memoryStoreName validation

Co-authored-by: Copilot <[email protected]>

---------

Co-authored-by: Copilot <[email protected]>
…vider (microsoft#4096)

Extract 11 private const string fields for vector store property names
(Key, Role, MessageId, AuthorName, ApplicationId, AgentId, UserId,
SessionId, Content, CreatedAt, ContentEmbedding) and replace all inline
usages across the collection definition, store dictionary, search result
access, and filter expressions.

Fixes microsoft#3801

Co-authored-by: Copilot <[email protected]>
…icrosoft#4128)

* Initial plan

* Fix failing vision integration tests by using local test files

Co-authored-by: westey-m <[email protected]>

* Fix net472 build error: replace File.ReadAllBytesAsync with compatible helper using AppContext.BaseDirectory

Co-authored-by: westey-m <[email protected]>

* Simplify ReadLocalFile: return byte[] directly instead of Task<byte[]>

Co-authored-by: westey-m <[email protected]>

---------

Co-authored-by: copilot-swe-agent[bot] <[email protected]>
Co-authored-by: westey-m <[email protected]>
Bumps [flask](https://github.com/pallets/flask) from 3.1.2 to 3.1.3.
- [Release notes](https://github.com/pallets/flask/releases)
- [Changelog](https://github.com/pallets/flask/blob/main/CHANGES.rst)
- [Commits](pallets/flask@3.1.2...3.1.3)

---
updated-dependencies:
- dependency-name: flask
  dependency-version: 3.1.3
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <[email protected]>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
* support agent skills

* make the new agent skill provider experimental

* Fix file encoding: add UTF-8 BOM to .cs files

Co-authored-by: Copilot <[email protected]>

* Fix final newline and simplify new expressions

Co-authored-by: Copilot <[email protected]>

* Fix broken links in Agent Skills sample README

Co-authored-by: Copilot <[email protected]>

* Add null check for skillPaths parameter

Co-authored-by: Copilot <[email protected]>

* Normalize references

* normilize skill path

* address comments regarding symlink check

* address comments

* fix failing test + regex improvements

* small optimizations and improvments

* address pr review comments

* Update dotnet/src/Microsoft.Agents.AI/Skills/FileAgentSkillsProvider.cs

Co-authored-by: Roger Barreto <[email protected]>

* address pr review comments

* address pr review comments

---------

Co-authored-by: Copilot <[email protected]>
Co-authored-by: Roger Barreto <[email protected]>
…icrosoft#4135)

* Added new GitHub action for manual integration test run based on PR

* Addressed comments

* Added branch name as input

* Small improvements
…ts and OTel 0.4.14 (microsoft#4161)

* Fix system message content sent as list instead of string

Some OpenAI-compatible endpoints (e.g. NVIDIA NIM) reject system messages
when content is a list of content parts. This change flattens system and
developer message content to a plain string in the Chat Completions client.

Fixes microsoft#1407

Co-authored-by: Copilot <[email protected]>

* Fix compatibility with opentelemetry-semantic-conventions-ai 0.4.14

Version 0.4.14 removed several LLM_* attributes from SpanAttributes
(LLM_SYSTEM, LLM_REQUEST_MODEL, LLM_RESPONSE_MODEL, LLM_REQUEST_MAX_TOKENS,
LLM_REQUEST_TEMPERATURE, LLM_REQUEST_TOP_P, LLM_TOKEN_TYPE).

Move these to the OtelAttr enum with their well-known gen_ai.* string values
and update all references in observability.py and tests.

Fixes microsoft#4160

Co-authored-by: Copilot <[email protected]>

* Flatten text-only message content to string for all roles

Extend the system/developer fix to all message roles. Text-only content
lists are now post-processed into plain strings, while multimodal content
(text + images/audio) remains as a list. This fixes compatibility with
OpenAI-like endpoints that cannot deserialize list content (e.g. Foundry
Local's Neutron backend).

Partially fixes microsoft#4084

Co-authored-by: Copilot <[email protected]>

* Fix streaming text lost when usage data in same chunk

Some providers (e.g. Gemini) include both usage data and text content
in the same streaming chunk. The early return on chunk.usage caused
text and tool call parsing to be skipped entirely. Remove the early
return and process usage alongside text/tool calls.

Fixes microsoft#3434

Co-authored-by: Copilot <[email protected]>

* Fix mypy errors in _chat_client.py

Rename shadowed variable 'args' in system/developer branch to 'sys_args'
and rename loop variable 'content' to 'msg_content' to avoid type conflict.

Co-authored-by: Copilot <[email protected]>

---------

Co-authored-by: Copilot <[email protected]>
eavanvalkenburg and others added 24 commits March 19, 2026 10:45
…microsoft#4757)

* Fix A2AAgent to invoke context providers before and after run

A2AAgent.run() bypassed the context provider lifecycle (before_run/after_run)
that BaseAgent defines as a contract for all agents. This caused A2AAgent to
violate the semantic definition of BaseAgent, resulting in inconsistency with
other agent implementations.

The fix follows the same pattern used by WorkflowAgent:
- Create SessionContext and run before_run on all context providers before
  processing the A2A stream
- Collect response updates and run after_run on all context providers after
  the stream is fully consumed
- Auto-create a session when context providers are configured but no session
  is explicitly passed

Fixes microsoft#4754

Co-authored-by: Copilot <[email protected]>

* Apply pre-commit auto-fixes

* Remove reproduction report from repository

Co-authored-by: Copilot <[email protected]>

* Address PR review feedback for microsoft#4754

- Validate messages when no continuation_token: raise ValueError if
  normalized_messages is empty, preventing IndexError on messages[-1]
- Import BaseContextProvider/SessionContext from public agent_framework
  package instead of internal agent_framework._sessions module
- Add test for ValueError on run(None) without continuation_token

Co-authored-by: Copilot <[email protected]>

* Improve test coverage for empty-messages guard in A2AAgent.run (microsoft#4754)

- Parameterize test to cover both messages=None and messages=[] inputs
- Add test verifying run(None, continuation_token=...) does not raise

Co-authored-by: Copilot <[email protected]>

---------

Co-authored-by: Copilot <[email protected]>
Co-authored-by: Copilot <[email protected]>
* Trim src references and add utility to enforce

* Potential fix for pull request finding

Co-authored-by: Copilot Autofix powered by AI <[email protected]>

---------

Co-authored-by: Copilot Autofix powered by AI <[email protected]>
…sing 'properties' key (microsoft#4771)

* Fix zero-argument MCP tool schema missing 'properties' key (microsoft#4540)

MCP servers for zero-argument tools (e.g. matlab-mcp-core-server's
detect_matlab_toolboxes) declare inputSchema as {"type": "object"}
without a "properties" key. OpenAI's API requires "properties" to
be present on object schemas, causing a 400 invalid_request_error.

Normalize inputSchema at MCP ingestion in load_tools() to inject an
empty "properties": {} when it is missing from object-type schemas.

Co-authored-by: Copilot <[email protected]>

* Address review feedback for microsoft#4540: improve test robustness and add defensive guard

- Look up loaded functions by name instead of index to avoid brittle
  ordering assumptions
- Add negative-path test cases: non-object schema (type: string) and
  empty schema ({}) to verify guard clause skips them correctly
- Assert original inputSchema dicts are not mutated by load_tools()
- Add defensive guard for tool.inputSchema being None

Co-authored-by: Copilot <[email protected]>

* Address review feedback for microsoft#4540: Python: [Bug]: Local stdio MCP works for calculator but fails for official matlab-mcp-core-server on LM Studio /v1/responses

---------

Co-authored-by: Copilot <[email protected]>
Co-authored-by: Copilot <[email protected]>
…microsoft#4756)

* Support detail field in OpenAI image_url payload (microsoft#4616)

Include the optional 'detail' field from Content.additional_properties
when building image_url payloads for the OpenAI Chat API, matching the
existing pattern used for 'filename' in document file payloads.

Co-authored-by: Copilot <[email protected]>

* Apply pre-commit auto-fixes

* Remove reproduction report

Co-authored-by: Copilot <[email protected]>

* Simplify detail extraction from additional_properties (microsoft#4616)

- Remove unnecessary hasattr check; additional_properties is always
  initialized as a dict on Content instances.
- Use 'is not None' instead of truthy check to be more precise.

Co-authored-by: Copilot <[email protected]>

* Apply pre-commit auto-fixes

* Remove detail allowlist in chat client to align with responses client

Replace the strict allowlist check ('low', 'high', 'auto') with an
isinstance(detail, str) check so that any valid string detail value is
passed through to OpenAI. This aligns the chat client behavior with the
responses client, which passes detail through unconditionally.

Also add test coverage for:
- Future/unknown string detail values being passed through
- Data URI images (covering the 'data' branch of the match)

Co-authored-by: Copilot <[email protected]>

---------

Co-authored-by: Copilot <[email protected]>
Co-authored-by: Copilot <[email protected]>
)

* Add script to ping on stale issues/PRs

* Add script to ping on stale issues/PRs

* Fix stale issue/PR ping script review comments

- Rename TEAM_NAME env var to TEAM_SLUG for clarity
- Add actionable error messages for 403/404 team lookup failures
- Add contents:read permission for actions/checkout
- Use github.event.inputs context with fallback for scheduled runs
- Pin PyGithub to 2.6.0 for reproducible builds
- Fetch comments once in should_ping() to reduce API calls
- Make ping() retry loop idempotent (track comment/label state)
- Validate DAYS_THRESHOLD with helpful error for non-numeric input
- Fix timezone bug: use astimezone() instead of replace(tzinfo=)
- Add comprehensive unit tests (29 tests)

Co-authored-by: Copilot <[email protected]>

---------

Co-authored-by: Copilot <[email protected]>
Co-authored-by: Copilot <[email protected]>
…ning (microsoft#4760)

* Python: Emit AG-UI events for MCP tool calls, results, and text reasoning

Fixes microsoft#4213 — `_emit_content()` in the AG-UI layer only handled `text`,
`function_call`, `function_result`, `function_approval_request`, `usage`,
and `oauth_consent_request` content types. Foundry MCP content types
(`mcp_server_tool_call`, `mcp_server_tool_result`) and `text_reasoning`
fell through unhandled, producing no SSE events for AG-UI consumers.

Added three new handler functions wired into `_emit_content()`:

- `_emit_mcp_tool_call`: emits TOOL_CALL_START + TOOL_CALL_ARGS and
  tracks in FlowState for MESSAGES_SNAPSHOT inclusion
- `_emit_mcp_tool_result`: emits TOOL_CALL_END + TOOL_CALL_RESULT with
  full FlowState cleanup mirroring `_emit_tool_result`
- `_emit_text_reasoning`: emits the protocol-defined reasoning event
  sequence (ReasoningStart → MessageStart → MessageContent → MessageEnd
  → ReasoningEnd) with ReasoningEncryptedValueEvent for protected_data

* Add HTTP round-trip tests for MCP tool and reasoning SSE events

Exercises the full POST → SSE bytes → parse → validate pipeline for
mcp_server_tool_call, mcp_server_tool_result, text_reasoning, and
ReasoningEncryptedValueEvent content through FastAPI TestClient.

* Fix _emit_mcp_tool_result missing predictive_handler support (microsoft#4213)

- Add predictive_handler parameter to _emit_mcp_tool_result and mirror
  the apply_pending_updates + StateSnapshotEvent block from _emit_tool_result
- Forward predictive_handler from _emit_content to _emit_mcp_tool_result
- Add assertion for stored arguments in MCP tool call test
- Add test for predictive handler state snapshot after MCP tool result

Co-authored-by: Copilot <[email protected]>

* Apply pre-commit auto-fixes

* Refactor MCP tool emit functions and add missing tests (microsoft#4213)

- Extract _emit_tool_result_common shared helper to eliminate duplication
  between _emit_tool_result and _emit_mcp_tool_result
- Remove server_name prefix from tool_call_name in _emit_mcp_tool_call;
  display_name now equals tool_name directly
- Add test for tool_name fallback to 'mcp_tool' when tool_name is None
- Add test for output=None fallback to empty string in _emit_mcp_tool_result

Co-authored-by: Copilot <[email protected]>

* Address review feedback for microsoft#4213: review comment fixes

---------

Co-authored-by: Copilot <[email protected]>
Co-authored-by: Copilot <[email protected]>
microsoft#4758)

* Emit TOOL_CALL_RESULT events on approval resume (microsoft#4589)

When a tool call is approved via the interrupt/resume flow,
_resolve_approval_responses executes the tool and injects the result
into the messages array, but no TOOL_CALL_RESULT SSE event was yielded
to the client.

Changes:
- _resolve_approval_responses now returns the list of resolved
  function_result Content objects instead of None
- run_agent_stream yields ToolCallResultEvent for each resolved
  approval result after RunStartedEvent is emitted
- Add ToolCallResultEvent to ag_ui.core imports in _agent_run.py

Co-authored-by: Copilot <[email protected]>

* Apply pre-commit auto-fixes

* fix(ag-ui): address PR review feedback for microsoft#4589

1. _resolve_approval_responses now returns only approved results (not
   rejections) so TOOL_CALL_RESULT events are emitted only for executed
   tools. Rejection results are still written into message history.

2. Emit resolved TOOL_CALL_RESULT events in the no-updates fallback
   RUN_STARTED path so approval results are never lost.

3. Rewrite tests to use real FunctionTool with func and
   approval_mode='always_require' via StubAgent default_options,
   verifying actual tool execution output in TOOL_CALL_RESULT content.
   Added test for rejection not emitting TOOL_CALL_RESULT.

Co-authored-by: Copilot <[email protected]>

* Fix microsoft#4589: clean up approval resolution and add missing tests

- Extract duplicated TOOL_CALL_RESULT emission block into
  _make_approval_tool_result_events helper to prevent drift
- Remove dead rejection_results construction in _resolve_approval_responses;
  _replace_approval_contents_with_results already handles rejections inline
- Pass only approved_results (not all_results) to clarify the contract
- Add mixed approve/reject test validating the core splitting logic
- Add zero-updates test covering the no-updates fallback emission path
- Add direct unit test for _resolve_approval_responses return value

Co-authored-by: Copilot <[email protected]>

* Apply pre-commit auto-fixes

* Fix import sorting lint error in test_approval_result_event.py

Add blank line between first-party and third-party import groups
to satisfy ruff I001 rule.

Fixes microsoft#4589

Co-authored-by: Copilot <[email protected]>

---------

Co-authored-by: Copilot <[email protected]>
Co-authored-by: Copilot <[email protected]>
…aw client (microsoft#4746)

* [BREAKING] Refactor middleware layering and raw clients

Reorder chat client layers so function invocation wraps chat middleware, and chat middleware stays outside telemetry while still running for each inner model call. Add middleware pipeline caching, refresh docs and samples, and split Anthropic into raw and public clients to match the standard layering model.

Co-authored-by: Copilot <[email protected]>

* Tighten typing ignores in ancillary modules

Add targeted typing ignores in workflow visualization and lab modules so pyright stays clean alongside the middleware refactor work.

Co-authored-by: Copilot <[email protected]>

* Fix categorize_middleware to unpack tuple/Sequence and use relative MRO assertions

- Broaden isinstance check in categorize_middleware from list to Sequence
  so tuples and other Sequence types are properly unpacked instead of
  being appended as a single item.
- Replace fragile hardcoded MRO index assertions in anthropic test with
  relative ordering via mro.index().
- Add regression tests for categorize_middleware with tuple, list, and
  None inputs.

Co-authored-by: Copilot <[email protected]>

* Fix middleware string decomposition, add middleware param to FunctionInvocationLayer, and add tests (microsoft#4710)

- Guard categorize_middleware Sequence check against str/bytes to prevent
  character-by-character decomposition of accidentally passed strings
- Add explicit middleware parameter to FunctionInvocationLayer.get_response
  and merge it into client_kwargs before categorization, fixing the
  inconsistency where only OpenAIChatClient supported this parameter
- Add assertions that RawAnthropicClient does not inherit convenience layers
- Add chat middleware cache test with non-empty base middleware
- Add tests for single unwrapped middleware item and string input

Co-authored-by: Copilot <[email protected]>

* Apply pre-commit auto-fixes

* Apply pre-commit auto-fixes

* Address review feedback for microsoft#4710: review comment fixes

---------

Co-authored-by: Copilot <[email protected]>
Co-authored-by: Copilot <[email protected]>
…oft#4711)

* Emit tool call events in GitHubCopilotAgent streaming

_stream_updates now yields FunctionCallContent for TOOL_EXECUTION_START
and FunctionResultContent for TOOL_EXECUTION_COMPLETE events from the
Copilot SDK session. This enables DevUI and other consumers to display
tool calls during streaming agent execution. Previously only ASSISTANT_MESSAGE_DELTA, SESSION_IDLE, and SESSION_ERROR
were handled — tool execution events were silently dropped.

Signed-off-by: James Sturtevant <[email protected]>

* Add some tests

Signed-off-by: James Sturtevant <[email protected]>

* Respond to feedback

Signed-off-by: James Sturtevant <[email protected]>

* Fix TOOL_EXECUTION_COMPLETE to use correct SDK types

- Read result text from session_events.Result.content (not ToolResult.text_result_for_llm)
- Read failure state from event.data.success/error (not result_obj.result_type/error)
- Handle ErrorClass.message and plain string errors
- Update tests to use session_events.Result and ErrorClass
- Add tests for string errors, success-with-error, and COMPLETE missing fields

Signed-off-by: James Sturtevant <[email protected]>

---------

Signed-off-by: James Sturtevant <[email protected]>
…e. (microsoft#4807)

* Bump Python version to 1.0.0rc5 and 1.0.0b260319 for a release.

* update missed pkg versions

* Update changelog
…icrosoft#4804)

* Deprecate Azure AI v1 (Persistent Agents API) helper methods

Add DeprecationWarning to v1 classes and functions that have been
superseded by the v2 (Projects/Responses) API:

- AzureAIAgentsProvider -> use AzureAIProjectAgentProvider
- AzureAIAgentClient -> use AzureAIClient
- AzureAIAgentOptions -> use AzureAIProjectAgentOptions
- to_azure_ai_agent_tools() -> use to_azure_ai_tools()
- from_azure_ai_agent_tools() -> use from_azure_ai_tools()
- AzureAIAgentClient static tool factory methods -> use AzureAIClient equivalents

All v1 components still function but emit warnings to guide migration.

Co-authored-by: Copilot <[email protected]>

* Add deprecation warnings to AzureAIAgentsProvider methods

Mark create_agent(), get_agent(), and as_agent() as deprecated
individually, pointing to AzureAIProjectAgentProvider equivalents.

Co-authored-by: Copilot <[email protected]>

---------

Co-authored-by: Copilot <[email protected]>
* Python: avoid duplicate agent response telemetry

* Python: conditionally suppress duplicate agent telemetry

* Simplify telemetry ownership tracking

Co-authored-by: Copilot <[email protected]>

* Aggregate token usage from inner chat spans on invoke_agent span

The invoke_agent span now carries the aggregated input/output token
counts from all inner chat completion spans that occur during an agent
run. Previously, when inner ChatTelemetryLayer spans captured usage,
the outer AgentTelemetryLayer skipped setting usage entirely to avoid
duplication. Now a new INNER_ACCUMULATED_USAGE context variable tracks
cumulative usage across all inner completions, and the agent span
always reports the total.

Co-authored-by: Copilot <[email protected]>

---------

Co-authored-by: Copilot <[email protected]>
)

* update script to ping only on certain waiting for author label

* Update .github/scripts/stale_issue_pr_ping.py

Co-authored-by: Copilot <[email protected]>

* Update .github/scripts/stale_issue_pr_ping.py

Co-authored-by: Copilot <[email protected]>

* Fix docstring

---------

Co-authored-by: Copilot <[email protected]>
….Extensions.AI 10.4.0, and Azure.AI.Projects 2.0.0-beta.2 (microsoft#4613)

* Initial plan

* Update code for Microsoft.Extensions.AI.Abstractions 10.4.0 breaking changes

- Rename FunctionApprovalRequestContent → ToolApprovalRequestContent
- Rename FunctionApprovalResponseContent → ToolApprovalResponseContent
- Rename UserInputRequestContent → ToolApprovalRequestContent
- Rename UserInputResponseContent → ToolApprovalResponseContent
- Update .FunctionCall property → .ToolCall with FunctionCallContent casts where needed
- Update .Id property → .RequestId on the renamed types
- Rename FunctionApprovalRequestEventGenerator → ToolApprovalRequestEventGenerator
- Rename FunctionApprovalResponseEventGenerator → ToolApprovalResponseEventGenerator

Co-authored-by: Copilot <[email protected]>

* Update OpenAI 2.9.1, ME.AI 10.4.0, fix breaking API changes

Co-authored-by: stephentoub <[email protected]>

* Fix remaining ME.AI 10.4.0 breaking changes: MCP approval types, .Output→.Outputs

Co-authored-by: stephentoub <[email protected]>

* Use pattern matching with `when` for ToolApprovalRequestContent/FunctionCallContent

Co-authored-by: stephentoub <[email protected]>

* Update Azure.AI.OpenAI to 2.9.0-beta.1

Co-authored-by: stephentoub <[email protected]>

* Fix remaining GetResponsesClient(model) build failures for Azure.AI.OpenAI 2.9.0-beta.1

Co-authored-by: stephentoub <[email protected]>

* Address review feedback: remove redundant type checks in TestRequestAgent.cs and fix error message in AIAgentHostExecutor.cs

Co-authored-by: stephentoub <[email protected]>

* Update Azure.AI.Projects to 2.0.0-beta.2 with namespace migration

- Azure.AI.Projects 2.0.0-beta.1 → 2.0.0-beta.2
- Azure.AI.Projects.OpenAI → Azure.AI.Extensions.OpenAI (transitive)
- Agent types moved to Azure.AI.Projects.Agents namespace
- AgentRecord.Versions.Latest → AgentRecord.GetLatestVersion()
- OpenAPIFunctionDefinition → OpenApiFunctionDefinition
- BingCustomSearchToolParameters → BingCustomSearchToolOptions
- MemorySearchPreviewTool.UpdateDelay → UpdateDelayInSecs
- Azure.Identity 1.17.1 → 1.19.0
- Microsoft.Identity.Client.Extensions.Msal 4.78.0 → 4.83.1

Co-authored-by: rogerbarreto <[email protected]>

* Fix remaining type renames for Azure.AI.Projects 2.0.0-beta.2

- BrowserAutomationToolParameters → BrowserAutomationToolOptions
- MemoryUpdateOptions.UpdateDelay stays as UpdateDelay (not renamed)
- WaitForMemoriesUpdateAsync parameter order: pollingInterval before options
- AIProjectAgentsOperations → AgentsClient

Co-authored-by: rogerbarreto <[email protected]>

* Fix format errors and OpenTelemetry test for ME.AI 10.4.0

- Remove unused 'using Azure.AI.Extensions.OpenAI' and fix import ordering
  in Agent_With_AzureAIProject/Program.cs
- Update OpenTelemetryAgentTests: gen_ai.tool.definitions is now always
  emitted regardless of EnableSensitiveData per ME.AI 10.4.0 change
  (dotnet/extensions#7346). Tool definitions are not considered sensitive.

Co-authored-by: Copilot <[email protected]>

* Fix GetRepoFolder() to work in git worktrees

Use 'workflow-samples' directory as repo root marker instead of '.git',
which fails in worktrees (.git is a file) and also matches too early
when a '.github' folder exists in subdirectories.

Co-authored-by: Copilot <[email protected]>

* Fix formatting: remove unused usings and fix import ordering

dotnet format applied across 59 impacted projects. Primarily removes
unnecessary 'using Azure.AI.Projects' where Azure.AI.Projects.Agents
provides all needed types, and fixes import ordering per editorconfig.

Co-authored-by: Copilot <[email protected]>

* Disable AzureAIAgentsPersistent integration tests (microsoft#4769)

Azure.AI.Agents.Persistent 1.2.0-beta.9 references McpServerToolApprovalResponseContent
which was removed in ME.AI 10.4.0 (renamed to ToolApprovalResponseContent), causing
TypeLoadException at runtime. Mark all 6 test classes with IntegrationDisabled trait
until Persistent ships a version targeting ME.AI 10.4.0+.

Upstream fix: Azure/azure-sdk-for-net#56929

Co-authored-by: Copilot <[email protected]>

* Add README with compatibility note for AzureAI.Persistent (microsoft#4769)

Documents that Azure.AI.Agents.Persistent 1.2.0-beta.9 is only compatible
with ME.AI ≤10.3.0 and OpenAI ≤2.8.0 due to type renames in ME.AI 10.4.0.

Co-authored-by: Copilot <[email protected]>

* Fix file encoding: restore UTF-8 BOM on Persistent test files

Co-authored-by: Copilot <[email protected]>

* Mark AzureAI.Persistent as IsPackable=false (microsoft#4769)

Prevent shipping until Azure.AI.Agents.Persistent targets ME.AI 10.4.0+.

Co-authored-by: Copilot <[email protected]>

* Moving IsPackable after import

---------

Co-authored-by: copilot-swe-agent[bot] <[email protected]>
Co-authored-by: Copilot <[email protected]>
Co-authored-by: stephentoub <[email protected]>
Co-authored-by: rogerbarreto <[email protected]>
* Add context mode to AgentExecutor

* Fix unit tests

* Address comments

* Address comments

* REvise context mode and add tests

* Add chain config to sequential builder

* Add sample

* Fix pipeline

* Address comments

* Address comments
…ts in increase timeouts (microsoft#4820)

* Reduce timeout flakiness for AzureFunctions Workflows samples run tests

* Add more updates

* Address PR comments

* Address PR comments
…re possible (microsoft#4795)

* Obsolete the V1 helper methods and migrate samples using it where possible

* Address PR comments
* Add ADR-0020: Foundry Evals integration design

Captures the design for integrating Azure AI Foundry Evaluations with
agent-framework. Key decisions:

- EvalItem with conversation (list[Message]) as single source of truth
- query/response derived from configurable conversation split strategies
- Tools as list[FunctionTool] (including auto-extracted MCP tools)
- FoundryEvals provider with auto-detection of evaluator capabilities
- LocalEvaluator with @function_evaluator decorator for local checks
- Consistent Python/C# APIs: evaluate_agent, evaluate_workflow

Co-authored-by: Copilot <[email protected]>

* Mark ADR 0020 Foundry Evals as accepted

Co-authored-by: Copilot <[email protected]>

---------

Co-authored-by: alliscode <[email protected]>
Co-authored-by: Copilot <[email protected]>
* Fix source generator bug that silently drops base class handler registrations for protocol-only partial executors

* Fixed xml comments and variable naming.

* Fix workflow samples broken due to routing change
Added two new case branches and three new converter methods:

 - ToolExecutionStartEvent → FunctionCallContent (the AGUI layer then emits TOOL_CALL_START/ARGS/END to the client)
 - ToolExecutionCompleteEvent → FunctionResultContent → TOOL_CALL_RESULT
 - Arguments are converted from JsonElement using AOT-safe JsonElement.EnumerateObject() — no reflection/dynamic code

Fixes microsoft#4823
Copilot AI assigned Copilot and kzu Mar 24, 2026
@kzu kzu closed this Mar 24, 2026
@kzu
kzu deleted the copilot/implement-raw-json-element-support branch March 24, 2026 16:26
kzu pushed a commit that referenced this pull request Aug 10, 2026
…after_run hooks (microsoft#5013)

* Fix GitHubCopilotAgent not calling context provider hooks (microsoft#3984)

GitHubCopilotAgent accepted context_providers in its constructor but
never called before_run()/after_run() on them in _run_impl() or
_stream_updates(), silently ignoring all context providers.

Add _run_before_providers() helper to create SessionContext and invoke
before_run on each provider. Both _run_impl() and _stream_updates() now
run the full provider lifecycle: before_run before sending the prompt
(with provider instructions prepended) and after_run after receiving the
response. This follows the same pattern used by A2AAgent.

Co-authored-by: Copilot <[email protected]>

* Python: Fix GitHubCopilotAgent to invoke context provider before_run/after_run hooks

Fixes microsoft#3984

* fix(microsoft#3984): address review feedback for context provider integration

- Build prompt from session_context.get_messages(include_input=True) so
  provider-injected context_messages are included in both non-streaming
  and streaming paths (review comments #1, #2)
- Preserve timeout in opts (use get instead of pop) so providers can
  observe it via context.options (review comment #3)
- Eliminate streaming double-buffer: move after_run invocation to a
  ResponseStream result_hook (matching Agent class pattern) instead of
  maintaining a separate updates list in the generator (review comment #4)
- Improve _run_before_providers docstring

Add tests for:
- Context messages included in prompt (non-streaming + streaming)
- Error path: after_run NOT called when send_and_wait/streaming raises
- Multiple providers: forward before_run, reverse after_run ordering
- BaseHistoryProvider with load_messages=False is skipped
- Streaming after_run response contains aggregated updates
- Streaming with no updates still sets empty response
- Timeout preserved in session context options for providers

Note: _run_before_providers remains on GitHubCopilotAgent for now. A
follow-up PR should extract it to BaseAgent so subclasses can reuse it
without duplicating the provider iteration logic.

Co-authored-by: Copilot <[email protected]>

* Address review feedback for microsoft#3984: Python: [Bug]: GitHubCopilotAgent Memory Example

* refactor(microsoft#3984): promote _run_before_providers to BaseAgent

Move _run_before_providers from GitHubCopilotAgent into BaseAgent,
mirroring the existing _run_after_providers helper. Agent's
_prepare_session_and_messages now delegates to the shared base method,
eliminating the near-duplicate provider iteration logic that could
drift as the provider contract evolves.

Co-authored-by: Copilot <[email protected]>

* Address review feedback for microsoft#3984: Python: [Bug]: GitHubCopilotAgent Memory Example

* revert: keep _run_before_providers in GitHubCopilotAgent only

Undo the promotion of _run_before_providers to BaseAgent. The method
stays in GitHubCopilotAgent where it is needed, and _agents.py
retains its original inline provider iteration in RawAgent.

Co-authored-by: Copilot <[email protected]>

* fix: replace deprecated BaseContextProvider/BaseHistoryProvider with ContextProvider/HistoryProvider

Update imports and usages in GitHubCopilotAgent and its tests to use
the new non-deprecated class names from the core package.

Co-authored-by: Copilot <[email protected]>

* fix: address review feedback - reorder providers before session, wrap streaming after_run in try/except, assert after_run on skipped HistoryProvider

- Move _run_before_providers before _get_or_create_session so provider
  contributions can affect session configuration
- Wrap _run_after_providers in try/except in streaming _after_run_hook
  to prevent provider errors from replacing successful responses
- Add after_run assertion to test_history_provider_skip_when_load_messages_false

Co-authored-by: Copilot <[email protected]>

---------

Co-authored-by: Copilot <[email protected]>
Co-authored-by: Copilot <[email protected]>
kzu pushed a commit that referenced this pull request Aug 10, 2026
…rosoft#4941)

* Harden Python checkpoint persistence defaults

Add RestrictedUnpickler to _checkpoint_encoding.py that limits which
types may be instantiated during pickle deserialization.  By default
FileCheckpointStorage now uses the restricted unpickler, allowing only:

- Built-in Python value types (primitives, datetime, uuid, decimal,
  collections, etc.)
- All agent_framework.* internal types
- Additional types specified via the new allowed_checkpoint_types
  parameter on FileCheckpointStorage

This narrows the default type surface area for persisted checkpoints
while keeping framework-owned scenarios working without extra
configuration.  Developers can extend the allowed set by passing
"module:qualname" strings to allowed_checkpoint_types.

The decode_checkpoint_value function retains backward-compatible
unrestricted behavior when called without the new allowed_types kwarg.

Fixes microsoft#4894

Co-authored-by: Copilot <[email protected]>

* fix: resolve mypy no-any-return error in checkpoint encoding

Add explicit type annotation for super().find_class() return value
to satisfy mypy's no-any-return check.

Fixes microsoft#4894

Co-authored-by: Copilot <[email protected]>

* Simplify find_class return in _RestrictedUnpickler (microsoft#4894)

Remove unnecessary intermediate variable and apply # noqa: S301 # nosec
directly on the super().find_class() call, matching the established
pattern used on the pickle.loads() call in the same file.

Co-authored-by: Copilot <[email protected]>

* Address review feedback for microsoft#4894: Python: Harden Python checkpoint persistence defaults

* Restore # noqa: S301 on line 102 of _checkpoint_encoding.py (microsoft#4894)

The review feedback correctly identified that removing the # noqa: S301
suppression from the find_class return statement would cause a ruff S301
lint failure, since the project enables bandit ("S") rules. This
restores consistency with lines 82 and 246 in the same file.

Co-authored-by: Copilot <[email protected]>

* Address review feedback for microsoft#4894: Python: Harden Python checkpoint persistence defaults

* Address PR review comments on checkpoint encoding (microsoft#4894)

- Move module docstring to proper position after __future__ import
- Fix find_class return type annotation to type[Any]
- Add missing # noqa: S301 pragma on find_class return
- Improve error message to reference both allowed_types param and
  FileCheckpointStorage.allowed_checkpoint_types
- Add -> None return annotation to FileCheckpointStorage.__init__
- Replace tempfile.mktemp with TemporaryDirectory in test
- Replace contextlib.suppress with pytest.raises for precise assertion
- Remove unused contextlib import

Co-authored-by: Copilot <[email protected]>

* Address PR microsoft#4941 review comments: fix docstring position and return type

- Move module docstring before 'from __future__' import so it populates
  __doc__ (comment #4)
- Change find_class return annotation from type[Any] to type to avoid
  misleading callers about non-type returns like copyreg._reconstructor
  (comment #2)

Comments #1, #3, #5, microsoft#6, microsoft#7, microsoft#8 were already addressed in the current code.

Co-authored-by: Copilot <[email protected]>

* Address review feedback for microsoft#4894: review comment fixes

* fix: use pickle.UnpicklingError in RestrictedUnpickler and improve docstring (microsoft#4894)

- Change _RestrictedUnpickler.find_class to raise pickle.UnpicklingError
  instead of WorkflowCheckpointException, since it is pickle-level concern
  that gets wrapped by the caller in _base64_to_unpickle.
- Remove now-unnecessary WorkflowCheckpointException re-raise in
  _base64_to_unpickle (pickle.UnpicklingError is caught by the generic
  except Exception handler and wrapped).
- Expand decode_checkpoint_value docstring to show a concrete example of
  the module:qualname format with a user-defined class.
- Add regression test verifying find_class raises pickle.UnpicklingError.

Co-authored-by: Copilot <[email protected]>

* fix: address PR microsoft#4941 review comments for checkpoint encoding

- Comment 1 (line 103): Already resolved in prior commit — _RestrictedUnpickler
  now raises pickle.UnpicklingError instead of WorkflowCheckpointException.

- Comment 2 (line 140): Add concrete usage examples to decode_checkpoint_value
  docstring showing both direct allowed_types usage and FileCheckpointStorage
  allowed_checkpoint_types usage. Rename 'SafeState' to 'MyState' across all
  docstrings for consistency, making it clear this is a user-defined class name.

Co-authored-by: Copilot <[email protected]>

* fix: replace deprecated 'builtin' repo with pre-commit-hooks in pre-commit config

pre-commit 4.x no longer supports 'repo: builtin'. Merge those hooks into
the existing pre-commit-hooks repo entry.

Co-authored-by: Copilot <[email protected]>

* style: apply pyupgrade formatting to docstring example

Co-authored-by: Copilot <[email protected]>

* fix: resolve pre-commit hook paths for monorepo git root

The poe-check and bandit hooks referenced paths relative to python/
but pre-commit runs hooks from the git root (monorepo root). Fix
poe-check entry to cd into python/ first, and update bandit config
path to python/pyproject.toml.

Co-authored-by: Copilot <[email protected]>

* Fix pre-commit config paths for prek --cd python execution

Revert bandit config path from 'python/pyproject.toml' to 'pyproject.toml'
and poe-check entry from explicit 'cd python' wrapper to direct invocation,
since prek --cd python already sets the working directory to python/.

Also apply ruff formatting fixes to cosmos checkpoint storage files.

Fixes microsoft#4894

Co-authored-by: Copilot <[email protected]>

* fix: add builtins:getattr to checkpoint deserialization allowlist

Pickle uses builtins:getattr to reconstruct enum members (e.g.,
WorkflowMessage.type which is a MessageType enum). Without it in the
allowlist, checkpoint roundtrip tests fail with
WorkflowCheckpointException.

Fixes microsoft#4894

Co-authored-by: Copilot <[email protected]>

* Address review feedback for microsoft#4894: review comment fixes

---------

Co-authored-by: Copilot <[email protected]>
Co-authored-by: Copilot <[email protected]>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.