Commit Graph

1779 Commits

  • Python: Fix doubled tool_call arguments in MESSAGES_SNAPSHOT when streaming (#4200)
    * fix: prevent doubled tool_call arguments in MESSAGES_SNAPSHOT
    
    When streaming with client-side tools, some providers send a full-
    arguments replay after the streaming deltas complete. The `_emit_tool_call`
    function unconditionally appends every arguments delta to the internal
    `flow.tool_calls_by_id` tracking dictionary via `+=`. When the replay
    contains the exact same complete arguments string that was already
    accumulated from prior deltas, the arguments get doubled (e.g.,
    `{"todoText":"buy groceries"}{"todoText":"buy groceries"}`).
    
    This causes `MESSAGES_SNAPSHOT` events to contain invalid doubled JSON in
    `tool_calls[].function.arguments`, breaking any client or middleware that
    relies on snapshots for state reconstruction.
    
    The fix adds a guard (mirroring the existing duplicate guard in
    `_emit_text`) that detects when the incoming delta exactly equals the
    already-accumulated arguments string, indicating a full-arguments replay
    rather than an incremental delta. In this case the append is skipped,
    preventing the doubling.
    
    The `ToolCallArgsEvent` deltas are still emitted correctly for real-time
    streaming — only the internal snapshot accumulator is guarded.
    
    Fixes #4194
    
    * fix: move duplicate check before event emission + add test
    
    Address Copilot review feedback:
    1. Move duplicate full-arguments replay detection BEFORE emitting
       ToolCallArgsEvent, for consistency with _emit_text() which returns
       early without emitting any events on replay detection.
    2. Add test_emit_tool_call_skips_duplicate_full_arguments_replay() to
       verify the duplicate detection behavior for tool call arguments,
       matching the existing test pattern for text content.
  • Python: updated integration tests and guidance (#4181)
    * updated integration tests and guidance
    
    * fixed merge test
    
    * updated integration tests
    
    * fix: remove duplicate --dist loadfile flag from pytest-xdist config
    
    Only one --dist mode can be active at a time; the second value silently
    overrides the first. Keep --dist worksteal (dynamic load balancing) and
    remove the redundant --dist loadfile from all workflow files and
    pyproject.toml configs.
    
    Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
    
    * docs: add keep-in-sync notes for merge and integration test workflows
    
    Both python-merge-tests.yml and python-integration-tests.yml share the
    same parallel job structure. Added sync reminders in workflow file
    comments, the python-testing SKILL.md, and CODING_STANDARD.md.
    
    Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
    
    * refactor: remove RUN_INTEGRATION_TESTS flag
    
    Integration test gating now uses two mechanisms:
    - `@pytest.mark.integration` for test selection via `-m` filtering
    - `skip_if_*_disabled` for credential/service availability checks
    
    The RUN_INTEGRATION_TESTS env var was redundant since the marker handles
    selection and the skip decorators already check for actual credentials.
    
    Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
    
    * fix: sync missing env vars from merge-tests to integration-tests
    
    Add OPENAI_EMBEDDINGS_MODEL_ID and AZURE_OPENAI_EMBEDDING_DEPLOYMENT_NAME
    to python-integration-tests.yml to match python-merge-tests.yml.
    
    Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
    
    * fix: remove remaining RUN_INTEGRATION_TESTS from embedding tests and docs
    
    Missed test_openai_embedding_client.py and vector-stores README in the
    earlier cleanup.
    
    Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
    
    * set functions tests to 3.10
    
    ---------
    
    Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
  • Python: feat(python): Add embedding abstractions and OpenAI implementation (Phase 1) (#4153)
    * feat(python): Add embedding abstractions and OpenAI implementation (Phase 1)
    
    This PR contains two parts:
    
    1. **Overall migration plan** for porting vector stores and embeddings from
       Semantic Kernel to Agent Framework (docs/features/vector-stores-and-embeddings/README.md)
       covering all 10 phases from core abstractions through connectors and TextSearch.
    
    2. **Phase 1 implementation** — core embedding abstractions and OpenAI/Azure OpenAI
       embedding clients:
    
       Core types (_types.py):
       - EmbeddingGenerationOptions TypedDict (total=False)
       - Embedding[EmbeddingT] generic class with model_id, dimensions, created_at
       - GeneratedEmbeddings[EmbeddingT, EmbeddingOptionsT] list container with options, usage
       - EmbeddingInputT (default str) and EmbeddingT (default list[float]) TypeVars
    
       Protocol + base class (_clients.py):
       - SupportsGetEmbeddings protocol — Generic[EmbeddingInputT, EmbeddingT, OptionsContraT]
       - BaseEmbeddingClient ABC — Generic[EmbeddingInputT, EmbeddingT, OptionsCoT]
    
       Telemetry (observability.py):
       - EmbeddingTelemetryLayer with gen_ai.operation.name = "embeddings"
    
       OpenAI implementation (openai/_embedding_client.py):
       - RawOpenAIEmbeddingClient, OpenAIEmbeddingClient, OpenAIEmbeddingOptions
       - Uses _ensure_client() factory pattern
    
       Azure OpenAI implementation (azure/_embedding_client.py):
       - AzureOpenAIEmbeddingClient following AzureOpenAIChatClient pattern
       - Supports API key, Entra ID credentials, env var configuration
    
       Tests:
       - 47 unit tests for types, protocol, base class, OpenAI, and Azure clients
       - 6 integration tests (gated behind RUN_INTEGRATION_TESTS + credentials)
    
       Samples:
       - samples/02-agents/embeddings/openai_embeddings.py
       - samples/02-agents/embeddings/azure_openai_embeddings.py
    
    Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
    
    * fix: Add AzureOpenAIEmbeddingClient to azure __init__.pyi stub
    
    Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
    
    * ci: Add embedding env vars to Python integration tests
    
    Map OPENAI_EMBEDDING_MODEL_ID and AZURE_OPENAI_EMBEDDING_DEPLOYMENT_NAME
    from GitHub vars to the integration test environment.
    
    Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
    
    * fix: Handle base64 encoding_format in OpenAI embedding client
    
    When encoding_format='base64' is used, the OpenAI API returns base64-encoded
    floats instead of a JSON array. Decode these automatically to list[float]
    so the return type stays consistent regardless of encoding format.
    
    Also adds a unit test for base64 decoding and fixes minor docstring/import issues.
    
    Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
    
    * fix: Only record INPUT_TOKENS for embedding telemetry
    
    Embeddings have no output/completion tokens. Remove OUTPUT_TOKENS recording
    which was double-counting prompt_tokens via the total_tokens fallback.
    
    Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
    
    * fix: Resolve mypy variance error and lint warning
    
    Use contravariant/covariant TypeVars for SupportsGetEmbeddings Protocol.
    Combine nested if into single statement in telemetry layer.
    
    Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
    
    * fix: Make EmbeddingCoT invariant for mypy compatibility
    
    GeneratedEmbeddings is invariant in its type param, so the Protocol
    TypeVar cannot be covariant.
    
    Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
    
    * fix: Address PR review - empty values guard, service_url for telemetry
    
    - Add early return for empty values in get_embeddings to avoid unnecessary API calls
    - Add service_url() method to RawOpenAIEmbeddingClient for proper telemetry endpoint reporting
    - Add test for empty values behavior
    
    Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
    
    * Python: Fix OpenAI chat client compatibility with third-party endpoints and OTel 0.4.14 (#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 https://github.com/microsoft/agent-framework/issues/1407
    
    Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
    
    * 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 https://github.com/microsoft/agent-framework/issues/4160
    
    Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
    
    * 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 https://github.com/microsoft/agent-framework/issues/4084
    
    Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
    
    * 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 https://github.com/microsoft/agent-framework/issues/3434
    
    Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
    
    * 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 <223556219+Copilot@users.noreply.github.com>
    
    ---------
    
    Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
    
    * reorder imports
    
    * fix: Use OtelAttr.REQUEST_MODEL instead of removed SpanAttributes.LLM_REQUEST_MODEL
    
    Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
    
    * docs: Add score_threshold to vector store plan
    
    Reference SK .NET PR #13501 for score threshold filtering semantics.
    Include score_threshold in SearchOptions from Phase 3.
    
    Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
    
    * docs: Add reference to roji's SK .NET MEVD work for SQL connectors
    
    Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
    
    * fix: Clear env vars in construction tests to avoid CI leakage
    
    Tests for missing API key / model ID now use monkeypatch.delenv to ensure
    env vars from the integration test environment don't prevent the expected
    ValueError from being raised.
    
    Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
    
    ---------
    
    Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
  • Python: Add Foundry Memory Context Provider (#3943)
    * Initial plan
    
    * Add FoundryMemoryProvider and tests
    
    Co-authored-by: eavanvalkenburg <13749212+eavanvalkenburg@users.noreply.github.com>
    
    * Add sample and documentation for FoundryMemoryProvider
    
    Co-authored-by: eavanvalkenburg <13749212+eavanvalkenburg@users.noreply.github.com>
    
    * Address code review feedback for FoundryMemoryProvider
    
    Co-authored-by: eavanvalkenburg <13749212+eavanvalkenburg@users.noreply.github.com>
    
    * Address PR review comments: Add DEFAULT_SOURCE_ID, use logging.getLogger, move state to session.state
    
    Co-authored-by: eavanvalkenburg <13749212+eavanvalkenburg@users.noreply.github.com>
    
    * Fix Foundry memory ItemParam usage and exports
    
    Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
    
    * Refactor provider hook state and standardize source IDs
    
    Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
    
    * Support endpoint-based Foundry memory init
    
    Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
    
    * updated implementation and sample
    
    * updated code and samples
    
    * Fix foundry memory provider tests: mock structure and field names
    
    - Use Mock objects with memory_item.content for memory mocks
    - Assert 'content' instead of 'text' on SDK message items
    - Update exception types from ServiceInitializationError to ValueError
    - Remove unused ServiceInitializationError import
    
    Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
    
    * Fix mypy errors in foundry memory provider
    
    Add type: ignore[arg-type] for scope (str | None vs str) and items
    (list variance) passed to Azure SDK methods.
    
    Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
    
    * fix import
    
    ---------
    
    Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>
    Co-authored-by: eavanvalkenburg <13749212+eavanvalkenburg@users.noreply.github.com>
    Co-authored-by: eavanvalkenburg <github@vanvalkenburg.eu>
    Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
  • Python: Add CreateConversationExecutor, fix input routing, remove unused handler layer (#4159)
    * Fixed declarative deep research sample
    
    * Small fix
    
    * Resolved comment
    
    * Add CreateConversationExecutor, fix input routing, remove unused handler layer
    
    * Address Copilot feedback
    
    * Fix System.ConversationId
    
    ---------
    
    Co-authored-by: Dmytro Struk <13853051+dmytrostruk@users.noreply.github.com>
  • Python: Enhance Azure AI Search Citations with Document URLs in Foundry V2 (#4028)
    * Python: Enhance Azure AI Search citations with document URLs in Foundry V2 (Responses API)
    
    Override _parse_response_from_openai and _parse_chunk_from_openai in
    RawAzureAIClient to extract get_urls from azure_ai_search_call_output
    items and enrich url_citation annotations with document-specific URLs.
    
    - Non-streaming: first pass collects get_urls, post-processes annotations
    - Streaming: captures search output state, enriches url_citation events
      (also handles url_citation annotation type not handled by base class)
    - Updated V2 sample to demonstrate citation URL extraction
    - Added 14 unit tests covering extraction, enrichment, and edge cases
    
    Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
    
    * refactor: rework search citation enrichment to override _inner_get_response
    
    - Remove all direct openai/pydantic imports from _client.py
    - Override _inner_get_response instead of _parse_response_from_openai/_parse_chunk_from_openai
    - Use closure-local state for streaming instead of instance-level _streaming_search_get_urls
    - Add _build_url_citation_content helper for streaming url_citation handling
    - Fix mypy errors by using str(value or '') for Annotation TypedDict fields
    - Fix docstring to say 'citation' instead of 'url_citation'
    - Update tests to match new approach
    
    Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
    
    * fix: handle streaming search citations from output_item.done events
    
    The azure_ai_search_call_output item only has populated output data
    (including get_urls) in the response.output_item.done event, not in
    the response.output_item.added event. Also removed the search_get_urls
    guard on url_citation handling so annotations are always produced even
    if get_urls haven't been captured yet.
    
    Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
    
    * addressed comments
    
    * refactor: address PR review - eliminate type: ignore[assignment] pattern
    
    Call super()._inner_get_response() independently in each branch instead
    of once at the top with union type reassignment. Non-streaming uses
    two-arg super() in the closure; streaming uses cast() for type narrowing.
    
    Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
    
    * refactor: remove defensive patterns per PR review
    
    - Replace all getattr() with direct attribute access
    - Remove cast() for streaming branch, use type: ignore[assignment]
    - Simplify _build_url_citation_content to use dict access directly
    - Simplify _extract_azure_search_urls to use item.type/item.output
    - Handle empty list output from streaming 'added' events
    - Update tests to match actual runtime types (objects, not dicts)
    
    Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
    
    * mypy fix
    
    * small fixes
    
    ---------
    
    Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
  • Python: Automate sample validation (#4193)
    * Automate sample validation: part 1
    
    * Automate sample validation: part 2
    
    * Create GH workflow
    
    * comments
    
    * Fix mypy
  • Python: Add max_function_calls to FunctionInvocationConfiguration (#2329) (#4175)
    * Add max_function_calls to FunctionInvocationConfiguration (#2329)
    
    Add a new per-request max_function_calls setting to FunctionInvocationConfiguration
    that limits the total number of individual function invocations across all iterations
    within a single get_response call. This complements max_iterations (which limits LLM
    roundtrips) by providing a hard cap on actual tool executions regardless of parallelism.
    
    - Add max_function_calls field to FunctionInvocationConfiguration (default: None/unlimited)
    - Track cumulative function call count in both streaming and non-streaming tool loops
    - Force tool_choice='none' when the limit is reached
    - Add validation in normalize_function_invocation_configuration
    - Improve docstrings for FunctionInvocationConfiguration, FunctionTool, and @tool
      to clarify semantics of max_iterations vs max_function_calls vs max_invocations
    - Add tests for parallel calls, single calls, unlimited mode, and config validation
    
    Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
    
    * Add sample for controlling total tool executions
    
    Showcases all three mechanisms for limiting tool executions:
    1. max_iterations — caps LLM roundtrips
    2. max_function_calls — caps total individual function invocations per request
    3. max_invocations — lifetime cap on a specific tool instance
    Plus a combined scenario demonstrating defense in depth.
    
    Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
    
    * Suppress ruff E305/fmt in hosting sample to preserve XML doc tags
    
    The XML snippet tags (# <create_agent> / # </create_agent>) are used for
    docs extraction and must stay adjacent to the code they wrap. Both ruff
    check (E305) and ruff format add blank lines after the function definition,
    pushing the closing tag away. Suppress with ruff: noqa: E305 and fmt: off.
    
    Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
    
    * Add per-agent tool wrapping scenario to control_total_tool_executions sample
    
    Show that wrapping the same callable with @tool multiple times creates
    independent FunctionTool instances with separate invocation counters,
    enabling per-agent max_invocations budgets for shared functions.
    
    Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
    
    * Clarify max_function_calls is a best-effort limit
    
    The limit is checked after each batch of parallel calls completes, so the
    current batch always runs to completion even if it overshoots the limit.
    
    Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
    
    * Address PR review: fix docstring reference, clarify best-effort in sample
    
    - Fix malformed Sphinx :attr: role in FunctionTool docstring — use plain
      backtick reference instead
    - Update sample to say 'best-effort cap' instead of 'hard cap' for
      max_function_calls, noting it's checked between iterations
    - Parametrize pattern is correct (fixture override, matching existing tests)
    
    Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
    
    * clarify max_invocations limits
    
    ---------
    
    Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
  • Python: Fix structured_output propagation in ClaudeAgent (#4137)
    * Fix structured_output propagation in ClaudeAgent
    
    Capture structured_output from ResultMessage in _get_stream() and
    propagate it to AgentResponse.value via a custom finalizer. Previously
    structured_output was silently discarded, making output_format unusable.
    
    Fixes #4095
    
    * Address review feedback: use value parameter instead of private properties
    
    - Extend AgentResponse.from_updates() to accept optional value parameter
    - Remove structured_output yield from _get_stream()
    - Update _finalize_response() to pass value via public API
    - Update streaming test to use get_final_response()
    
    * Fix mypy errors: add value parameter to from_updates overloads
    
    Add value parameter to both @overload signatures of
    AgentResponse.from_updates() so mypy recognizes the argument.
    
    ---------
    
    Co-authored-by: Amit Mukherjee <amimukherjee@microsoft.com>
    Co-authored-by: Dmytro Struk <13853051+dmytrostruk@users.noreply.github.com>
  • .NET: Fix case-sensitive property mismatch in CosmosChatHistoryProvider queries (#3485)
    * Initial plan
    
    * Fix case-sensitivity bug in Cosmos queries and add tests
    
    Co-authored-by: markwallace-microsoft <127216156+markwallace-microsoft@users.noreply.github.com>
    
    * Fix style issues and update tests for new API
    
    Co-authored-by: westey-m <164392973+westey-m@users.noreply.github.com>
    
    ---------
    
    Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>
    Co-authored-by: markwallace-microsoft <127216156+markwallace-microsoft@users.noreply.github.com>
    Co-authored-by: westey <164392973+westey-m@users.noreply.github.com>
  • .NET: Add Foundry Agents Tool Sample - Web Search (#4040)
    * .NET: Add Web Search sample #3674
    
    * .NET: Fix WebSearch sample to use Responses API built-in web search
    
    Remove incorrect Bing Grounding connection ID requirement from the
    WebSearch sample. The web search tool uses the OpenAI Responses API
    built-in capability and does not need a connection ID.
    
    - Remove AZURE_FOUNDRY_BING_CONNECTION_ID env var requirement
    - Use HostedWebSearchTool() without connectionId properties
    - Refactor creation options into local functions (MEAI + NativeSDK)
    - Switch from AzureCliCredential to DefaultAzureCredential
    - Update README to reflect correct prerequisites
    
    Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
    
    * Fix README to align DefaultAzureCredential docs with code
    
    Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
    
    * Address review: add project to solution, README, simplify response text
    
    - Add FoundryAgents_Step25_WebSearch to agent-framework-dotnet.slnx
    - Add web search sample entry to parent FoundryAgents README.md
    - Simplify text response extraction to use response.Text directly
    
    Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
    
    * Fix merge conflict in slnx solution file
    
    Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
    
    ---------
    
    Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
  • Make Cosmos DB tests read COSMOSDB_ENDPOINT and COSMOSDB_KEY from environment variables (#4156)
    * Initial plan
    
    * Make Cosmos DB tests read COSMOSDB_ENDPOINT and COSMOSDB_KEY from environment variables
    
    Co-authored-by: crickman <66376200+crickman@users.noreply.github.com>
    
    * Rename EmulatorEndpoint/EmulatorKey static fields to use s_ prefix convention
    
    Co-authored-by: crickman <66376200+crickman@users.noreply.github.com>
    
    ---------
    
    Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>
    Co-authored-by: crickman <66376200+crickman@users.noreply.github.com>
  • .NET: Fix FunctionInvocationDelegatingAgent to preserve all AgentRunOptions properties (#4179)
    When converting base AgentRunOptions to ChatClientAgentRunOptions, the middleware
    now preserves AllowBackgroundResponses, ContinuationToken, and AdditionalProperties
    in addition to ResponseFormat.
    
    Added unit test verifying all properties are preserved during the conversion.
    
    Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
  • Updated GitHub action for manual integration tests (#4147)
    * Updated merge test permissions
    
    * Removed repo check
    
    * Added fetch from main for comparison
    
    * Updated path detection logic
    
    * Small updates
    
    * Reverted file rename
    
    * Created dedicated workflows for integration tests
    
    * Small fix for Python
    
    * Small fixes
    
    * Small update
    
    * Small update
    
    * Added tests check for Python
  • .NET: [BREAKING] Add ChatClient decorator for calling AIContextProviders (#4097)
    * Add ChatClient decorator for calling AIContextProviders
    
    * Format new files
    
    * Address PR comments
    
    * Revert problematic change
    
    * Rename Use to UseAIContextProvider
  • .NET: Add Foundry Agents Tool Sample - Memory Search (#3700)
    * .NET: Add Memory Search sample #3674
    
    * Apply format fixes
    
    * Add MemorySearch sample to solution, FoundryAgents and AgentWithMemory READMEs
    
    - Add FoundryAgents_Step26_MemorySearch.csproj to agent-framework-dotnet.slnx
    - Add Memory Search entry to FoundryAgents/README.md samples table
    - Add cross-reference from AgentWithMemory/README.md to MemorySearch sample
    
    Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
    
    ---------
    
    Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
  • .NET: Simplify store=false scenario for responses (#4124)
    * Simplify store=false scenario for responses
    
    * Mark AsIChatClientWithStoredOutputDisabled as Experimental
  • Python: (ag-ui): Add Workflow Support, Harden Streaming Semantics, and add Dynamic Handoff Demo (#3911)
    * fix Workflow.as_agent() streaming regression in ag-ui
    
    * Address PR feedback
    
    * workflows wip
    
    * wip
    
    * wip
    
    * Workflow AG-UI demo
    
    * Fixes for handoff workflow demo
    
    * Fixes to workflows support in AG-UI
    
    * Fixes
    
    * Add headers to some demo files
    
    * Fix comment
    
    * Fixes for store
    
    * Make _input_schema lazy-loaded
    
    * fix mypy
    
    * revert session change to handoff only for now
    
    ---------
    
    Co-authored-by: Eduard van Valkenburg <eavanvalkenburg@users.noreply.github.com>
  • Python: Fix OpenAI chat client compatibility with third-party endpoints and OTel 0.4.14 (#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 https://github.com/microsoft/agent-framework/issues/1407
    
    Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
    
    * 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 https://github.com/microsoft/agent-framework/issues/4160
    
    Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
    
    * 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 https://github.com/microsoft/agent-framework/issues/4084
    
    Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
    
    * 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 https://github.com/microsoft/agent-framework/issues/3434
    
    Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
    
    * 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 <223556219+Copilot@users.noreply.github.com>
    
    ---------
    
    Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
  • Added new GitHub action for manual integration test run based on PR (#4135)
    * Added new GitHub action for manual integration test run based on PR
    
    * Addressed comments
    
    * Added branch name as input
    
    * Small improvements
  • .NET: Support Agent Skills (#4122)
    * support agent skills
    
    * make the new agent skill provider experimental
    
    * Fix file encoding: add UTF-8 BOM to .cs files
    
    Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
    
    * Fix final newline and simplify new expressions
    
    Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
    
    * Fix broken links in Agent Skills sample README
    
    Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
    
    * Add null check for skillPaths parameter
    
    Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
    
    * 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 <19890735+rogerbarreto@users.noreply.github.com>
    
    * address pr review comments
    
    * address pr review comments
    
    ---------
    
    Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
    Co-authored-by: Roger Barreto <19890735+rogerbarreto@users.noreply.github.com>
  • Bump flask from 3.1.2 to 3.1.3 in /python (#4126)
    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](https://github.com/pallets/flask/compare/3.1.2...3.1.3)
    
    ---
    updated-dependencies:
    - dependency-name: flask
      dependency-version: 3.1.3
      dependency-type: indirect
    ...
    
    Signed-off-by: dependabot[bot] <support@github.com>
    Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
  • .NET: Fix failing vision integration tests by using local test files (#4128)
    * Initial plan
    
    * Fix failing vision integration tests by using local test files
    
    Co-authored-by: westey-m <164392973+westey-m@users.noreply.github.com>
    
    * Fix net472 build error: replace File.ReadAllBytesAsync with compatible helper using AppContext.BaseDirectory
    
    Co-authored-by: westey-m <164392973+westey-m@users.noreply.github.com>
    
    * Simplify ReadLocalFile: return byte[] directly instead of Task<byte[]>
    
    Co-authored-by: westey-m <164392973+westey-m@users.noreply.github.com>
    
    ---------
    
    Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>
    Co-authored-by: westey-m <164392973+westey-m@users.noreply.github.com>
  • Replace inline string literals with constants in ChatHistoryMemoryProvider (#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 #3801
    
    Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
  • .NET: Add Foundry Memory Context Provider (#3522)
    * 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 <223556219+Copilot@users.noreply.github.com>
    
    * Use DefaultAzureCredential in Foundry Memory sample
    
    Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
    
    * 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 <223556219+Copilot@users.noreply.github.com>
    
    * Use Throw.IfNullOrWhitespace for scope and memoryStoreName validation
    
    Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
    
    ---------
    
    Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
  • .NET: [BREAKING] Workflows API Review Naming Changes (Part 1?) (#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 <13853051+dmytrostruk@users.noreply.github.com>
  • .NET: Small fixes in README (#4099)
    * Small fixes in README
    
    * Disabled problematic test
    
    * Disabled problematic test
  • Python: Add more unit test coverage gates (#4104)
    * Add more unit test coverage gates
    
    * Fix missing `files` parameter in `print_coverage_table()` docstring (#4106)
    
    * Initial plan
    
    * Update print_coverage_table docstring to document files parameter
    
    Co-authored-by: TaoChenOSU <12570346+TaoChenOSU@users.noreply.github.com>
    
    ---------
    
    Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>
    Co-authored-by: TaoChenOSU <12570346+TaoChenOSU@users.noreply.github.com>
    
    ---------
    
    Co-authored-by: Copilot <198982749+Copilot@users.noreply.github.com>
    Co-authored-by: TaoChenOSU <12570346+TaoChenOSU@users.noreply.github.com>
  • Python: fix reasoning model workflow handoff and history serialization (#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: https://github.com/microsoft/agent-framework/issues/4047
    
    Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
    
    * 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 <223556219+Copilot@users.noreply.github.com>
    
    * 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 <223556219+Copilot@users.noreply.github.com>
    
    * comment update
    
    * fixes from feedback
    
    * fix test
    
    * reverted changes to agent executor
    
    * fix: remove reset_service_session from tau2 runner
    
    Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
    
    * two other reverts
    
    * fix sample
    
    ---------
    
    Co-authored-by: Giles Odigwe <79032838+giles17@users.noreply.github.com>
    Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
  • .NET: Remove FunctionCalls and Tool Messages from Handoff passed messages (#3811)
    * Fix handoff orchestration not passing user message to handoff target agent (#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
  • .NET: Support a message only AIContextProvider as an AIAgent Decorator (#4009)
    * Support a message only AIContextProvider as an AIAgent Decorator
    
    * Fix formatting
    
    * Address PR comments.
  • Python: [BREAKING] Redesign Python exception hierarchy (#4082)
    * [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/agent-framework#3410
    
    Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
    
    * 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 <223556219+Copilot@users.noreply.github.com>
    
    * 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 <223556219+Copilot@users.noreply.github.com>
    
    ---------
    
    Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
  • .NET: Add tweaks to .net agent skills (#4081)
    * Add tweaks to .net agent skills
    
    * Address PR feedback
  • .NET: Updated package versions for RC release (#4067)
    * Updated package versions for RC release
    
    * Resolved comment
    
    * Resolved comments
  • [BREAKING] .NET: Decouple Checkpointing from Run/StreamAsync APIs (#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
  • Unify Azure credential handling across all Python packages (#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 #3449
    Fixes #3500
    
    Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
  • Python: Updated package versions for RC release (#4068)
    * Updated package versions for RC release
    
    * Update python/packages/redis/pyproject.toml
    
    Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
    
    * Small fix
    
    ---------
    
    Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
  • .NET: Add Foundry Agents Tool Sample - OpenAPI Tools (#3702)
    * .NET: Add OpenAPI Tools sample #3674
    
    * Apply format fixes
    
    * Add MEAI and Native SDK creation options for OpenAPI Tools sample
    
    Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
    
    * Address PR review: DefaultAzureCredential and CS8321 in NoWarn
    
    Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
    
    * Add project to slnx
    
    ---------
    
    Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
  • Simplify memory sample to use session state (#4085)
    - 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 <223556219+Copilot@users.noreply.github.com>
  • Fix CheckpointInfo.Parent always null in InProcessRunner (#3796) (#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
  • .NET: [BREAKING] Implement Polymorphic Routing (#3792)
    * 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
  • Python: Add load_dotenv() to samples for .env file support (#4043)
    * Initial plan
    
    * Add load_dotenv() to 303 Python samples for environment variable loading
    
    Co-authored-by: TaoChenOSU <12570346+TaoChenOSU@users.noreply.github.com>
    
    * Update SAMPLE_GUIDELINES.md to document load_dotenv() requirement
    
    Co-authored-by: TaoChenOSU <12570346+TaoChenOSU@users.noreply.github.com>
    
    * Update samples README.md to document .env file usage
    
    Co-authored-by: TaoChenOSU <12570346+TaoChenOSU@users.noreply.github.com>
    
    * Run ruff format on all changed sample files
    
    Co-authored-by: TaoChenOSU <12570346+TaoChenOSU@users.noreply.github.com>
    
    * Clarify load_dotenv() usage in README - local dev vs production
    
    Co-authored-by: TaoChenOSU <12570346+TaoChenOSU@users.noreply.github.com>
    
    * Remove deprecated getting_started folder as requested
    
    Co-authored-by: TaoChenOSU <12570346+TaoChenOSU@users.noreply.github.com>
    
    * Document env_file_path parameter for per-client configuration
    
    Co-authored-by: TaoChenOSU <12570346+TaoChenOSU@users.noreply.github.com>
    
    * Merge main branch to resolve conflicts
    
    Co-authored-by: TaoChenOSU <12570346+TaoChenOSU@users.noreply.github.com>
    
    * Fix run_evaluation.py file that was empty in merge commit
    
    Co-authored-by: TaoChenOSU <12570346+TaoChenOSU@users.noreply.github.com>
    
    * Remove dotnet changes from merge - out of scope for this PR
    
    Co-authored-by: TaoChenOSU <12570346+TaoChenOSU@users.noreply.github.com>
    
    * Remove package and test changes from merge - only sample changes needed
    
    Co-authored-by: TaoChenOSU <12570346+TaoChenOSU@users.noreply.github.com>
    
    * Remove test_func_utils.py - only sample changes needed
    
    Co-authored-by: TaoChenOSU <12570346+TaoChenOSU@users.noreply.github.com>
    
    * Revert sample files not in original changeset - keep only load_dotenv additions
    
    Co-authored-by: TaoChenOSU <12570346+TaoChenOSU@users.noreply.github.com>
    
    * Move load_dotenv() outside snippet tag in 06_host_your_agent.py
    
    Co-authored-by: TaoChenOSU <12570346+TaoChenOSU@users.noreply.github.com>
    
    * Fix comment placement - move load_dotenv before code comments
    
    Co-authored-by: TaoChenOSU <12570346+TaoChenOSU@users.noreply.github.com>
    
    * Fix load_dotenv() placement across all samples - after docstring, before code comments
    
    Co-authored-by: TaoChenOSU <12570346+TaoChenOSU@users.noreply.github.com>
    
    * Merge latest main branch with load_dotenv changes
    
    Co-authored-by: TaoChenOSU <12570346+TaoChenOSU@users.noreply.github.com>
    
    * Remove non-sample changes from merge - keep only load_dotenv additions
    
    Co-authored-by: TaoChenOSU <12570346+TaoChenOSU@users.noreply.github.com>
    
    * Revert non-load_dotenv sample changes from merge
    
    Co-authored-by: TaoChenOSU <12570346+TaoChenOSU@users.noreply.github.com>
    
    * Fix run_evaluation.py - use main's improved version (file already had load_dotenv)
    
    Co-authored-by: TaoChenOSU <12570346+TaoChenOSU@users.noreply.github.com>
    
    * Manual update
    
    * Manual update 2
    
    * Fix Role usage and load_dotenv placement per PR review feedback
    
    Co-authored-by: eavanvalkenburg <13749212+eavanvalkenburg@users.noreply.github.com>
    
    * Fix Role usage - use string literals not enum attributes
    
    Co-authored-by: eavanvalkenburg <13749212+eavanvalkenburg@users.noreply.github.com>
    
    * Fix SAMPLE_GUIDELINES.md example - load_dotenv before docstring per guidance
    
    Co-authored-by: eavanvalkenburg <13749212+eavanvalkenburg@users.noreply.github.com>
    
    * Move load_dotenv() before docstrings in all samples per SAMPLE_GUIDELINES ordering
    
    Co-authored-by: eavanvalkenburg <13749212+eavanvalkenburg@users.noreply.github.com>
    
    * Address PR review: rename files, fix placement, add session usage, remove note
    
    Co-authored-by: eavanvalkenburg <13749212+eavanvalkenburg@users.noreply.github.com>
    
    * Update Redis README to reference renamed file redis_history_provider.py
    
    Co-authored-by: eavanvalkenburg <13749212+eavanvalkenburg@users.noreply.github.com>
    
    ---------
    
    Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>
    Co-authored-by: TaoChenOSU <12570346+TaoChenOSU@users.noreply.github.com>
    Co-authored-by: Tao Chen <taochen@microsoft.com>
    Co-authored-by: eavanvalkenburg <13749212+eavanvalkenburg@users.noreply.github.com>
    Co-authored-by: Eduard van Valkenburg <eavanvalkenburg@users.noreply.github.com>
  • .NET: Add File Search Sample for Foundry Agents. (#3990)
    * .NET: Add File Search sample #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 <223556219+Copilot@users.noreply.github.com>
    
    * 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 <223556219+Copilot@users.noreply.github.com>
    
    * 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 <223556219+Copilot@users.noreply.github.com>
    
    ---------
    
    Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
  • .NET: Fix FoundryAgents_Step15_ComputerUse sample for Azure Agents API (#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 <223556219+Copilot@users.noreply.github.com>
    
    * Address comments
    
    ---------
    
    Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
  • Bump tar from 7.5.3 to 7.5.9 in /python/packages/devui/frontend (#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](https://github.com/isaacs/node-tar/compare/v7.5.3...v7.5.9)
    
    ---
    updated-dependencies:
    - dependency-name: tar
      dependency-version: 7.5.9
      dependency-type: indirect
    ...
    
    Signed-off-by: dependabot[bot] <support@github.com>
    Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
    Co-authored-by: Mark Wallace <127216156+markwallace-microsoft@users.noreply.github.com>
  • Bump prek from 0.3.2 to 0.3.3 in /python (#3964)
    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](https://github.com/j178/prek/compare/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] <support@github.com>
    Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
  • Bump ruff from 0.15.0 to 0.15.1 in /python (#3963)
    Bumps [ruff](https://github.com/astral-sh/ruff) from 0.15.0 to 0.15.1.
    - [Release notes](https://github.com/astral-sh/ruff/releases)
    - [Changelog](https://github.com/astral-sh/ruff/blob/main/CHANGELOG.md)
    - [Commits](https://github.com/astral-sh/ruff/compare/0.15.0...0.15.1)
    
    ---
    updated-dependencies:
    - dependency-name: ruff
      dependency-version: 0.15.1
      dependency-type: direct:development
      update-type: version-update:semver-patch
    ...
    
    Signed-off-by: dependabot[bot] <support@github.com>
    Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
  • Python: Quick Redis sample fix (#4066)
    * REDIS URL fix
    
    * copilot fix