Commit Graph

350 Commits

  • Python: Fix Bedrock embedding test stub missing meta attribute (#4287)
    * Fix Bedrock embedding test stub missing meta attribute
    
    * Increase test coverage so gate passes
  • Python / .NET Samples - Restructure and Improve Samples (Feature Branc… (#4092)
    * Python: .NET Samples - Restructure and Improve Samples (Feature Branch) (#4091)
    
    * Moved by agent (#4094)
    
    * Fix readme links
    
    * .NET Samples - Create `04-hosting` learning path step (#4098)
    
    * Agent move
    
    * Agent reorderd
    
    * Remove A2A section from README 
    
    Removed A2A section from the Getting Started README.
    
    * Agent fixed links
    
    * Fix broken sample links in durable-agents README (#4101)
    
    * Initial plan
    
    * Fix broken internal links in documentation
    
    Co-authored-by: crickman <66376200+crickman@users.noreply.github.com>
    
    * Revert template link changes; keep only durable-agents README fix
    
    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 Samples - Create `03-workflows` learning path step (#4102)
    
    * Fix solution project path
    
    * Python: Fix broken markdown links to repo resources (outside /docs) (#4105)
    
    * Initial plan
    
    * Fix broken markdown links to repo resources
    
    Co-authored-by: crickman <66376200+crickman@users.noreply.github.com>
    
    * Update README to rename .NET Workflows Samples section
    
    ---------
    
    Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>
    Co-authored-by: crickman <66376200+crickman@users.noreply.github.com>
    
    * .NET Samples - Create `02-agents` learning path step (#4107)
    
    * .NET: Fix broken relative link in GroupChatToolApproval README (#4108)
    
    * Initial plan
    
    * Fix broken link in GroupChatToolApproval README
    
    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>
    
    * Update labeler configuration for workflow samples
    
    * .NET - Reorder Agents samples to start from Step01 instead of Step04 (#4110)
    
    * Fix solution
    
    * Resolve new sample paths
    
    * Move new AgentSkills and AgentWithMemory_Step04 samples
    
    * Fix link
    
    * Fix readme path
    
    * fix: update stale dotnet/samples/Durable path reference in AGENTS.md
    
    Co-authored-by: crickman <66376200+crickman@users.noreply.github.com>
    
    * Moved new sample
    
    * Update solution
    
    * Resolve merge (new sample)
    
    * Sync to new sample - FoundryAgents_Step21_BingCustomSearch
    
    * Updated README
    
    * .NET Samples - Configuration Naming Update (#4149)
    
    * .NET: Restore AzureFunctions index parity with ConsoleApps under DurableAgents samples (#4221)
    
    * Clean-up `05_host_your_agent`
    
    * Config setting consistency
    
    * Refine samples
    
    * AGENTS.md
    
    * Move new samples
    
    * Re-order samples
    
    * Move new project and fixup solution
    
    * Fixup model config
    
    * Fix up new UT project
    
    ---------
    
    Co-authored-by: Copilot <198982749+Copilot@users.noreply.github.com>
  • Update Python package versions to rc2 (#4258)
    - Bump core and azure-ai to 1.0.0rc2
    - Bump preview packages to 1.0.0b260225
    - Update dependencies to >=1.0.0rc2
    - Add CHANGELOG entries for changes since rc1
    - Update uv.lock
    
    Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
  • Python: Phase 2: Embedding clients for Ollama, Bedrock, and Azure AI Inference (#4207)
    * Phase 2: Embedding clients for Ollama, Bedrock, and Azure AI Inference
    
    Add embedding client implementations to existing provider packages:
    
    - OllamaEmbeddingClient: Text embeddings via Ollama's embed API
    - BedrockEmbeddingClient: Text embeddings via Amazon Titan on Bedrock
    - AzureAIInferenceEmbeddingClient: Text and image embeddings via Azure AI
      Inference, supporting Content | str input with separate model IDs for
      text (AZURE_AI_INFERENCE_EMBEDDING_MODEL_ID) and image
      (AZURE_AI_INFERENCE_IMAGE_EMBEDDING_MODEL_ID) endpoints
    
    Additional changes:
    - Rename EmbeddingCoT -> EmbeddingT, EmbeddingOptionsCoT -> EmbeddingOptionsT
    - Add otel_provider_name passthrough to all embedding clients
    - Register integration pytest marker in all packages
    - Add lazy-loading namespace exports for Ollama and Bedrock embeddings
    - Add image embedding sample using Cohere-embed-v3-english
    - Add azure-ai-inference dependency to azure-ai package
    
    Part of #1188
    
    Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
    
    * Fix mypy duplicate name and ruff lint issues
    
    - Rename second 'vector' variable to 'img_vector' in image embedding loop
    - Combine nested with statements in tests
    - Remove unused result assignments in tests
    
    Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
    
    * updates from feedback
    
    * Fix CI failures in embedding usage handling
    
    - Fix Azure AI embedding mypy issues by normalizing vectors to list[float],
      safely accumulating optional usage token fields, and filtering None entries
      before constructing GeneratedEmbeddings
    - Avoid Bandit false positive by initializing usage details as an empty dict
    - Update OpenAI embedding tests to assert canonical usage keys
      (input_token_count/total_token_count)
    
    Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
    
    ---------
    
    Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
  • Python: Support Agent Skills (#4210)
    * Python: Support Agent Skills
    
    Add FileAgentSkillsProvider, a context provider that discovers and exposes
    Agent Skills from filesystem directories following the Agent Skills
    specification (https://agentskills.io/) progressive disclosure pattern:
    advertise, load, read resources.
    
    Changes:
    - FileAgentSkillsProvider - discovers SKILL.md files from configured
      directories, advertises skills via system prompt injection, and provides
      load_skill / read_skill_resource tools for on-demand access.
    - Internal helpers for skill discovery, frontmatter parsing, and secure
      resource reading (path traversal / symlink guards).
    - Unit tests covering discovery, loading, resource reading, and security
      scenarios.
    - Sample (basic_file_skills) demonstrating usage with an expense-report skill.
    
    Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
    
    * Python: Move skills sample to samples/02-agents/basic_skills/
    
    Align sample directory name with .NET equivalent (Agent_Step01_BasicSkills).
    
    Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
    
    * fix code quality checks
    
    * address pr review comment and code quality check issue
    
    * address pr review comments
    
    * move the sample to the skills folder
    
    * update readme
    
    * reame consts and use types for them
    
    * leverage pathlib for working with files
    
    * refactor the test
    
    * supply schema to functions
    
    * update readme
    
    * update sample name
    
    * address pr review comments
    
    * fix failing lint check
    
    * address failing check
    
    ---------
    
    Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
  • Python: Fixing issue #1366 - Thread corruption when max_iterations is reached. (#4234)
    * Fix thread corruption when max_iterations exhausted (#1366)
    
    When the function invocation loop exhausts max_iterations while the model
    keeps requesting tools, the failsafe code path (calling the model with
    tool_choice='none' and prepending fcc_messages) was unreachable because
    'if response is not None: return response' short-circuited before it.
    
    The fix removes the premature return so the failsafe always runs after
    loop exhaustion, making a final model call with tool_choice='none' to
    produce a clean text answer and prepending accumulated fcc_messages from
    prior iterations. This matches the existing pattern used by the error
    threshold and max_function_calls paths.
    
    Also unskips test_max_iterations_limit and test_streaming_max_iterations_limit
    which were previously skipped with 'needs investigation in unified API'.
    
    Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
    
    * Add fix report for issue #1366
    
    Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
    
    * Fix ruff formatting in _tools.py and test_issue_1366_thread_corruption.py
    
    Apply ruff format to fix multi-line string concatenation and function call
    formatting issues flagged by the linter.
    
    Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
    
    * Add quality review for issue #1366 fix
    
    Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
    
    * Remove temporary investigation docs.
    
    * Address PR review: explicit enabled check in log condition, clarify mock behavior in test
    
    - Add explicit function_invocation_configuration['enabled'] check to the
      'Maximum iterations reached' log condition in both non-streaming and
      streaming paths, making intent clearer when function invocation is disabled.
    - Add comment in test_thread_safe_after_max_iterations_with_agent explaining
      that the failsafe response (tool_choice='none') is provided automatically
      by the mock client, not from run_responses.
    
    * Blend fix and tests into project without issue-specific callouts
    
    - Remove issue #1366 references from _tools.py comments
    - Move regression tests from standalone test_issue_1366_thread_corruption.py
      into test_function_invocation_logic.py alongside existing max_iterations tests
    - Clean up test docstrings to describe behavior generically
    - Delete the standalone issue-specific test file
    
    ---------
    
    Co-authored-by: alliscode <bentho@microsoft.com>
    Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
  • [BREAKING] Python: Add InvokeFunctionTool action for declarative workflows (#3716)
    * add(declarative): Declarative workflow InvokeFunctionTool feature
    
    * Cleanup
    
    * Address PR feedback
    
    * Remove InvokeTool kind, consolidate to InvokeFunctionTool
    
    * Fix sample locations
    
    * pin azure-ai-projects to 2.0.0b3 due to breaking changes
  • Python: Fix workflow runner concurrent processing (#4143)
    * Fix workflow runner concurrent processing
    
    * Comments 1
    
    * Add test
  • 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 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>
  • 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>
  • 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>
  • 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>
  • 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>
  • Python: Fix hosted MCP tool approval flow for all session/streaming combinations (#4054)
    * fix openai hosted mcp samples
    
    * addressed copilot comments
    
    * Update python/samples/02-agents/providers/azure_openai/azure_responses_client_with_hosted_mcp.py
    
    Co-authored-by: Dmytro Struk <13853051+dmytrostruk@users.noreply.github.com>
    
    ---------
    
    Co-authored-by: Dmytro Struk <13853051+dmytrostruk@users.noreply.github.com>
  • Python: Fix sample bugs in file search and web search samples (#4049)
    - Fix file search samples: return vector_store.id string instead of
      Content object to avoid JSON serialization error
    - Fix web search sample: use correct web_search_options parameter for
      ChatClient instead of ResponsesClient's user_location parameter
    - Fix assistants client: pass tool_resources from options to run_options
      so vector store IDs reach thread creation
    - Add error handling for cleanup in Azure file search sample
    
    Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
  • Python: Fix Eval samples (#4033)
    * fix red team sample
    
    * Updated self-reflection
    
    * fix for workflow eval sample
    
    * fix test
  • Python: improve .env handling and observability samples (#4032)
    * Python: improve .env precedence and observability samples
    
    - Switch load_settings to explicit precedence: overrides -> explicit .env -> environment -> defaults\n- Raise when env_file_path is provided but missing\n- Update settings docs and tests for new behavior\n- Refresh observability samples and README guidance for env loading options\n\nCloses #3864\n\nCo-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
    
    * fixed some imports
    
    * Fix load_settings CI regressions
    
    Allow explicit env_file_path values that exist but are not regular files (for example /dev/null) by checking path existence before dotenv parsing, and restore a dict accumulator with typed return cast to satisfy mypy.
    
    Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
    
    * Avoid implicit dotenv in observability
    
    Only load dotenv in observability helpers when env_file_path is explicitly provided, and remove test os.devnull workarounds that are no longer necessary.
    
    Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
    
    ---------
    
    Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
  • Python: Fixed middleware and multimodal input samples (#4022)
    * Fix streaming branch in weather override middleware sample
    
    The streaming branch of weather_override_middleware only prefixed the
    original weather data via a transform hook instead of replacing the
    content with the 'perfect weather' override like the non-streaming
    branch does. Replace with a new ResponseStream that yields the override
    content as ChatResponseUpdate chunks.
    
    Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
    
    * Fixed exception handling middleware sample
    
    * Fixed runtime context delegation middleware example
    
    * Fixed multimodal input examples
    
    * Small update
    
    ---------
    
    Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
  • Python: Durable Support for Workflows (#3630)
    * Add workflow support for Azure Functions
    
    * fix compatability with latest framework changes and add integration tests
    
    * refactor code
    
    * remove white space
    
    Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
    
    * align help text with actual port used
    
    Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
    
    * replace instance id with a place holder
    
    Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
    
    * remove unused import
    
    Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
    
    * remove redundant typing import and fix SIM115
    
    * fix latest breaking changes
    
    * fix mypy issues
    
    * clean up imports
    
    * define source marker strings as constants
    
    * fix json module name
    
    * refactor _extract_message_content_from_dict
    
    * refactor serialization
    
    * add helper method for error response construction and remove _extract_message_content_from_dict since it is not needed
    
    * use strict tpe checking for edges
    
    * change how duplicate agent registrations are handled
    
    * cancel approval_task on HITL timeout
    
    * update docstring
    
    * fix: align azurefunctions package with core API changes after rebase
    
    - State.import_state/export_state are now sync (removed await)
    - Add State.commit() before export_state() in activity execution
    - Rename executor parameter shared_state -> state
    - Rename ctx.set_shared_state/get_shared_state -> set_state/get_state (sync)
    - WorkflowBuilder now takes start_executor as constructor kwarg
    - Update WorkflowOutputEvent -> WorkflowEvent with type='output'
    - Update RequestInfoEvent -> WorkflowEvent[Any]
    - Update SharedState -> State in test imports
    - Update duplicate agent name tests to match new warning behavior
    - Update sample README API references
    
    * fix sample check errors
    
    * fix mypy issues
    
    * fix trailing white spaces
    
    * fix test imports
    
    * feat: add durable workflow samples and adapt to main branch changes
    
    - Add workflow samples 09-12 to 04-hosting/azure_functions/
    - Adapt to ChatMessage -> Message rename from main
    - Adapt to pickle-based checkpoint encoding from main
    - Simplify _serialization.py to delegate to core encode/decode
    - Fix Message -> WorkflowMessage disambiguation in _context.py
    - Remove non-existent _checkpoint_summary import
    
    * fix: update create_checkpoint signature to match superclass
    
    * fix: correct relative link in HITL sample README
    
    * fix: resolve import breakage after rebase (State, DurableAgentThread, get_logger)
    
    ---------
    
    Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
    Co-authored-by: Dmytro Struk <13853051+dmytrostruk@users.noreply.github.com>
  • Python: Add missing system instruction attr to invoke_agent span (#4012)
    * Add missing sysmte instruction attr to invoke_agent span
    
    * Temp remove azure search gate
    
    * fix pipeline error
  • Python: [BREAKING] Scope provider state by source_id and standardize source IDs (#3995)
    * 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>
    
    * Fix core README workflows link
    
    Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
    
    * updated implementation and sample
    
    * Split out Foundry memory provider changes
    
    Remove FoundryMemoryProvider implementation/tests/sample plus export and docs mentions from this branch so only non-Foundry changes remain.
    
    Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
    
    * Trigger CI rerun for PR #3995
    
    Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
    
    ---------
    
    Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>
    Co-authored-by: eavanvalkenburg <13749212+eavanvalkenburg@users.noreply.github.com>
    Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
  • Python: feature: Inject OpenTelemetry trace context into MCP requests and update… (#3780)
    * feat: Inject OpenTelemetry trace context into MCP requests and update documentation
    
    * Update python/samples/getting_started/observability/README.md
    
    Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
    
    * Update python/packages/core/tests/core/test_mcp.py
    
    Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
    
    * refactor: move opentelemetry import to module level
    
    OpenTelemetry is a hard dependency of agent-framework-core (per
    pyproject.toml), so the try/except ImportError guard was dead code.
    Move the import to the top of the file to fail fast on missing
    dependencies instead of silently hiding installation issues.
    
    ---------
    
    Co-authored-by: Pete Roden <Pete.Roden@microsoft.com>
    Co-authored-by: Mark Wallace <127216156+markwallace-microsoft@users.noreply.github.com>
    Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
  • Python: Fix tool normalization and provider sample consolidation (#3953)
    * Fix tool normalization and provider samples
    
    - restore callable/single-tool normalization paths and unset tool-choice behavior\n- consolidate and expand chat/provider samples (OpenAI/Azure/Anthropic/Ollama/Bedrock)\n- migrate Bedrock lazy import surface to agent_framework.amazon and move provider samples
    
    Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
    
    * small fix in sample
    
    * Finalize provider, samples, and core cleanup
    
    Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
    
    * Fix CopilotTool passthrough in agent
    
    Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
    
    * fix link
    
    ---------
    
    Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
  • Python: [BREAKING] Fix #3613 chat/agent message typing alignment (#3920)
    * Fix #3613 message typing across chat and agents
    
    * Address #3613 review feedback and sample input style
    
    * refactor: use shared AgentRunMessages aliases (#3613)
    
    * refactor: rename agent run input aliases for #3613
    
    * samples: inline image content in run calls
    
    * core: export AgentRunInputs from package init
    
    * core: use explicit init re-exports without __all__
    
    * updated logging and inits
    
    * Fix core mypy export and samples XML note
    
    * Remove AgentRunInputsOrNone and dedupe loggers
    
    * Remove prepare_messages helper
    
    * fix integration tests
  • Python: [BREAKING] Remove FunctionTool[Any] compatibility shim for schema passthrough (#3600) (#3907)
    * Fix #3600: Pass JSON schemas through without Pydantic conversion
    
    This change optimizes FunctionTool and MCP flows by passing JSON schemas
    directly to providers without converting them to Pydantic models first.
    
    Key changes:
    - Store JSON schema as-is when supplied to FunctionTool
    - Skip Pydantic model_validate for schema-supplied tools in invoke()
    - Return MCP tool schemas directly without conversion
    - Add comprehensive tests for schema passthrough behavior
    
    Performance benefits:
    - Eliminates expensive Pydantic model creation for supplied schemas
    - Preserves exact schema structure (additionalProperties, custom fields, etc.)
    - Reduces memory overhead and initialization time
    
    Maintains backward compatibility:
    - Function signature inference still uses Pydantic models
    - Explicit Pydantic models passed as input_model work as before
    - All existing tests pass
    
    * Fix schema passthrough validation and remove helper
    
    * Simplify FunctionTool without generic model dependency
    
    * Fix FunctionTool typing fallout in 3600
    
    * Remove FunctionTool[Any] compatibility shim
    
    * Use serializable kwargs in OTEL tool args
  • Python: Replace wildcard imports with explicit imports (#3908)
    * Python: Replace wildcard imports with explicit imports
    
    - Replace all 'from ... import *' with explicit symbol imports
    - Add __all__ declarations to namespace packages for re-exports
    - Update CODING_STANDARD.md to prohibit wildcard imports
    - Maintain exported API and preserve all functionality
    
    fixes #3605
    
    * Refine wildcard guidance example text
    
    * Simplify explicit exports without self-aliases
  • Python: fix: prevent repeating instructions in continued Responses API conversations (#3909)
    * fix: prevent repeating instructions in continued Responses API conversations
    
    - Instructions are now only prepended to messages on the first turn
    - When conversation_id/response_id exists (continuation), instructions are skipped
    - Covers OpenAI and Azure Responses API paths
    - Adds regression tests for all continuation scenarios
    
    Fixes #3498
    
    * Apply lint fixes to continuation tests
    
    * Consolidate responses continuation tests
  • Python: Remove duplicate samples (#3899)
    * Remove duplicate samples
    
    * Correct paths
    
    * Update readme
    
    * Update readme
    
    * Fix ruff
    
    ---------
    
    Co-authored-by: Evan Mattson <35585003+moonbox3@users.noreply.github.com>
  • Python: Fix non-ascii chars in span attributes (#3894)
    * Fix non-ascii chars in span attributes
    
    * Comments
  • Python: Fix streamed workflow agent continuation context by finalizing AgentExecutor streams (#3882)
    * Fix streamed workflow agent continuation context by finalizing AgentExecutor streams
    
    * Fix stream handling
    
    * Fixes
    
    * Fix DevUI and tests
  • Python: [BREAKING] PR2 — Wire context provider pipeline, remove old types, update all consumers (#3850)
    * PR2: Wire context provider pipeline and update all internal consumers
    
    - Replace AgentThread with AgentSession across all packages
    - Replace ContextProvider with BaseContextProvider across all packages
    - Replace context_provider param with context_providers (Sequence)
    - Replace thread= with session= in run() signatures
    - Replace get_new_thread() with create_session()
    - Add get_session(service_session_id) to agent interface
    - DurableAgentThread -> DurableAgentSession
    - Remove _notify_thread_of_new_messages from WorkflowAgent
    - Wire before_run/after_run context provider pipeline in RawAgent
    - Auto-inject InMemoryHistoryProvider when no providers configured
    
    * fix: update all tests for context provider pipeline, fix lazy-loaders, remove old test files
    
    * refactor: update all sample files for context provider pipeline (AgentThread→AgentSession, ContextProvider→BaseContextProvider)
    
    * fix: update remaining ag-ui references (client docstring, getting_started sample)
    
    * fix: make get_session service_session_id keyword-only to avoid confusion with session_id
    
    * refactor: rename _RunContext.thread_messages to session_messages
    
    * refactor: remove _threads.py, _memory.py, and old provider files; migrate devui to use plain message lists
    
    * rename: remove _new_ prefix from test files
    
    * refactor: rewrite SlidingWindowChatMessageStore as SlidingWindowHistoryProvider(InMemoryHistoryProvider)
    
    * fix: read full history from session state directly instead of reaching into provider internals
    
    * fix: update stale .pyi stubs, sample imports, and README references for new provider types
    
    * fix: remove stale message_store, _notify_thread_of_new_messages, and session_id.key references in samples
    
    * refactor: merge context_providers and sessions sample folders into sessions, remove aggregate_context_provider
    
    * refactor: UserInfoMemory stores state in session.state instead of instance attributes
    
    * feat: add Pydantic BaseModel support to session state serialization
    
    Pydantic models stored in session.state are now automatically serialized
    via model_dump() and restored via model_validate() during to_dict()/from_dict()
    round-trips. Models are auto-registered on first serialization; use
    register_state_type() for cold-start deserialization.
    
    Also export register_state_type as a public API.
    
    * fix mem0
    
    * Update sample README links and descriptions for session terminology
    
    - Replace 'thread' with 'session' in sample descriptions across all READMEs
    - Update file links for renamed samples (mem0_sessions, redis_sessions, etc.)
    - Fix Threads section → Sessions section in main samples/README.md
    - Update tools, middleware, workflows, durabletask, azure_functions READMEs
    - Update architecture diagrams in concepts/tools/README.md
    - Update migration guides (autogen, semantic-kernel)
    
    * Fix broken Redis README link to renamed sample
    
    * Fix Mem0 OSS client search: pass scoping params as direct kwargs
    
    AsyncMemory (OSS) expects user_id/agent_id/run_id as direct kwargs,
    while AsyncMemoryClient (Platform) expects them in a filters dict.
    Adds tests for both client types.
    
    Port of fix from #3844 to new Mem0ContextProvider.
    
    * Fix rebase issues: restore missing _conversation_state.py and checkpoint decode logic
    
    - Add back _conversation_state.py (encode/decode_chat_messages) lost in rebase
    - Fix on_checkpoint_restore to decode cache/conversation with decode_chat_messages
    - Fix on_checkpoint_restore to use decode_checkpoint_value for pending requests
    - Add tests/workflow/__init__.py for relative import support
    - Fix test_agent_executor checkpoint selection (checkpoints[1] not superstep)
    
    * Add STORES_BY_DEFAULT ClassVar to skip redundant InMemoryHistoryProvider injection
    
    Chat clients that store history server-side by default (OpenAI Responses API,
    Azure AI Agent) now declare STORES_BY_DEFAULT = True. The agent checks this
    during auto-injection and skips InMemoryHistoryProvider unless the user
    explicitly sets store=False.
    
    * Fix broken markdown links in azure_ai and redis READMEs
    
    * Fix getting-started samples to use session API instead of removed thread/ContextProvider API
    
    * updates to workflow as agent
    
    * fix group chat import
    
    * Rename Thread→Session throughout, fix service_session_id propagation, remove stale AGUIThread
    
    - Fix: Propagate conversation_id from ChatResponse back to session.service_session_id
      in both streaming and non-streaming paths in _agents.py
    - Rename AgentThreadException → AgentSessionException
    - Remove stale AGUIThread from ag_ui lazy-loader
    - Rename use_service_thread → use_service_session in ag-ui package
    - Rename test functions from *_thread_* to *_session_*
    - Rename sample files from *_thread* to *_session*
    - Update docstrings and comments: thread → session
    - Update _mcp.py kwargs filter: add 'session' alongside 'thread'
    - Fix ContinuationToken docstring example: thread=thread → session=session
    - Fix _clients.py docstring: 'Agent threads' → 'Agent sessions'
    
    * Fix broken markdown links after thread→session file renames
    
    * fix azure ai test
  • Python: restructure: Python samples into progressive 01-05 layout (#3862)
    * restructure: Python samples into progressive 01-05 layout
    
    - 01-get-started/: 6 numbered steps (hello agent → hosting)
    - 02-agents/: all agent concept samples (tools, middleware, providers, etc.)
    - 03-workflows/: ALL existing workflow samples preserved as-is
    - 04-hosting/: azure-functions, durabletask, a2a
    - 05-end-to-end/: demos, evaluation, hosted agents
    - Old files moved to _to_delete/ for review
    - Added AGENTS.md with structure documentation
    - autogen-migration/ and semantic-kernel-migration/ preserved at root
    
    * fix: switch to AzureOpenAI Foundry, fix CI failures
    
    - Switch all 01-get-started samples to AzureOpenAIResponsesClient with
      Azure AI Foundry project endpoint (AZURE_AI_PROJECT_ENDPOINT +
      AZURE_OPENAI_RESPONSES_DEPLOYMENT_NAME + AzureCliCredential)
    - Add _to_delete/ and 05-end-to-end/ to pyrightconfig.samples.json excludes
    - Fix test paths in packages/ that referenced old getting_started/ dirs:
      durabletask conftest + streaming test, azurefunctions conftest,
      devui conftest + capture_messages + openai_sdk_integration
    - Fix workflow_as_agent_human_in_the_loop.py import (sibling import)
    - Update hosting READMEs and tool comment paths
    - Replace root README.md with new structure overview
    - Update AGENTS.md to document Azure OpenAI Foundry as default provider
    
    * cleanup: remove _to_delete folder, copy resource files to active dirs
    
    All files in _to_delete/ were either:
    - Exact duplicates of files in the new structure (240 files)
    - Same file with only comment path updates (100 files)
    - One import-fix diff (workflow_as_agent_human_in_the_loop.py)
    - One superseded minimal_sample.py
    
    Resource files (sample.pdf, countries.json, employees.pdf, weather.json)
    copied to 02-agents/sample_assets/ and 02-agents/resources/ since active
    samples reference them.
    
    * fix: address PR review comments, centralize resources, remove root duplicates
    
    - Fix type annotation in 04_memory.py (string union -> proper types)
    - Fix old sample paths in observability files
    - Fix grammar/spelling in observability samples
    - Move sample_assets/ and resources/ to shared/ folder
    - Remove 8 duplicate observability files from 02-agents root
    - Update resource path references in multimodal_input and provider samples
    
    * fix: update broken links from old getting_started paths to new structure
    
    - Update relative paths in READMEs: getting_started/ → 01-get-started/,
      02-agents/, 03-workflows/, 04-hosting/, 05-end-to-end/
    - Fix absolute GitHub URLs in package READMEs
    - Fix broken link in ollama package README
    
    * fix: convert absolute GitHub URLs to relative paths for link checker
    
    Absolute URLs to python/samples/ on main branch 404 until PR merges.
    Converted to relative paths that linkspector can verify locally.
    
    * fix: update link for handoff sample moved to orchestrations/
    
    * fix: update chatkit-integration README path from demos/ to 05-end-to-end/
    
    * fix: update broken links in orchestrations README to match flat directory structure
  • Python: Centralize tool result parsing in FunctionTool.invoke() (#3854)
    * Centralize tool result parsing in FunctionTool.invoke()
    
    - Add parse_result static method to FunctionTool that converts raw
      function return values to strings at invocation time
    - Add result_parser parameter to FunctionTool and @tool decorator
      for custom parsing
    - Remove prepare_function_call_results from all 9 consumer files
      and from the public API
    - Update MCPTool to parse MCP types directly to strings via
      _parse_tool_result_from_mcp and _parse_prompt_result_from_mcp
    - Change MCPTool parse_tool_results/parse_prompt_results type from
      Literal[True] | Callable | None to Callable | None
    - Remove ReturnT type parameter from FunctionTool (now single
      generic ArgsT since invoke() always returns str)
    - Update all subclass signatures and docstrings
    
    Fixes #1147
    
    * Fix test_mcp_tool_call_tool_with_meta_integration for string results
    
    The test was still accessing result[0].additional_properties but
    invoke() now returns a string, not a list of Content objects.
    
    * Fix SIM108 lint: use binary operator for output assignment
    
    * Fix bedrock: use FunctionTool.parse_result instead of str() fallback
    
    str(result) turns None into literal 'None' and dicts into Python reprs
    with single quotes, breaking JSON parsing. Use the shared parse_result
    which handles None as '' and serializes via json.dumps.
    
    * updated lock
    
    * updates from feedback
  • Python: (samples): adopt AzureOpenAIResponsesClient, reorganize orchestration examples, and fix workflow/orchestration bugs (#3873)
    * adopt AzureOpenAIResponsesClient, reorganize orchestration examples, and fix workflow/orchestration bugs
    
    * Updates
    
    * add comment
  • Python: Replace Pydantic Settings with TypedDict + load_settings() (#3843)
    * Replace Pydantic Settings with TypedDict + load_settings()
    
    - Remove pydantic-settings dependency, add python-dotenv
    - Delete _pydantic.py (AFBaseSettings, HTTPsUrl)
    - Add _settings.py with generic load_settings() function, SecretString,
      type coercion, and Required field validation (SettingNotFoundError)
    - Convert all 13 settings classes from AFBaseSettings subclasses to
      TypedDict definitions with load_settings() calls
    - Update all consumers from attribute access to dict access
    - Add 20 unit tests for load_settings() covering basic loading, dotenv,
      SecretString, type coercion, and required field validation
    - Update all existing tests for new settings patterns
    
    * Fix mypy type errors from settings conversion
    
    - Fix str | None attribute access in responses_client (walrus operator)
    - Fix SecretString | None narrowing in bedrock (type: ignore after guard)
    - Convert _context_provider.py attribute access to dict access (missed file)
    - Fix endpoint type narrowing in search_provider and context_provider
    - Fix purview: str | None .rstrip(), int | None defaults, urlparse bytes
    
    * Address PR review: required_fields param, type validation, fixes
    
    - Move required field validation from TypedDict annotations (Required)
      to a required_fields parameter on load_settings(), enabling runtime
      decisions about which fields are required
    - Remove Required imports and restore from __future__ import annotations
      in ollama and foundry_local
    - Add _check_override_type() for deterministic ServiceInitializationError
      on invalid override types (e.g. dict passed for str field)
    - Fix all multi-exception test catches back to single exception type
    - Fix Ollama host=None: use .get() so None is passed through to SDK default
    - Fix Purview processor: use explicit is-None checks instead of or operator
    - Remove unused BaseModel import from openai/_shared.py
    - Add 4 new tests (24 total): required_fields param, type validation
    
    * Fix type validation: allow int for float fields
    
    _check_override_type now permits int values for float-typed fields,
    matching Python's standard numeric promotion behavior.
    
    * fix: wrap urlparse arg with str() to fix mypy bytes endswith error
  • [BREAKING] Python: Checkpoint refactor: encode/decode, checkpoint format, etc (#3744)
    * WIP: Checkpoint refactor: encode/decode, checkpoint format, etc
    
    * WIP: Remove workflow ID in checkpoints
    
    * Refactor checkpointing
    
    * Add get_latest tests
    
    * Increase test coverage
    
    * Fix formatting
    
    * Fix unit tests
    
    * Fix samples
    
    * fix unit tests
    
    * fix pipeline
    
    * Copilot comments
    
    * Fix tests
    
    * Fix more tests
    
    * Address comments part 1
    
    * Address comments part 2
    
    * Comments
  • Python: Add more packages to unit test coverage gate (#3831)
    * Add more packages to unit test coverage gate
    
    * Trigger workflow
    
    * Remove azure ai search
    
    * Add purview
    
    * Add declarative to coverage report
  • Python: Allow AzureOpenAIResponsesClient creation with Foundry project endpoint (#3814)
    * Initial plan
    
    * feat: extend AzureOpenAIResponsesClient to support Foundry project endpoints
    
    Add project_client and project_endpoint parameters to allow creating
    the client via an Azure AI Foundry project. When provided, the client
    uses AIProjectClient.get_openai_client() to obtain the OpenAI client.
    The azure-ai-projects package is imported lazily and only required
    when using the project endpoint path.
    
    Co-authored-by: eavanvalkenburg <13749212+eavanvalkenburg@users.noreply.github.com>
    
    * fix: address code review - remove duplicate MagicMock imports in tests
    
    Co-authored-by: eavanvalkenburg <13749212+eavanvalkenburg@users.noreply.github.com>
    
    * fix: add type field to Responses API input items and add Foundry sample
    
    - Add 'type: message' to input items in _prepare_message_for_openai
      to comply with the Responses API schema requirement
    - Filter out empty dicts from unsupported content types to prevent
      sending items with invalid empty type values
    - Add azure_responses_client_with_foundry.py sample demonstrating
      AzureOpenAIResponsesClient with project_endpoint
    - Update README and pyrightconfig.samples.json accordingly
    
    * updates to response format and setup
    
    * fix: patch AIProjectClient at correct module path in test
    
    Patch agent_framework.azure._responses_client.AIProjectClient instead of
    azure.ai.projects.aio.AIProjectClient since the import is at module level.
    
    * docs: add Foundry sample to READMEs and document AZURE_AI_PROJECT_ENDPOINT env var
    
    ---------
    
    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>
  • Python: [BREAKING] Replace Hosted*Tool classes with tool methods (#3634)
    * Replace Hosted*Tool classes with client static factory methods
    
    * fixed failing test
    
    * mypy fix
    
    * mypy fix 2
    
    * declarative mypy fix
    
    * addressed comments
    
    * ToolProtocol removal
    
    * fixed test
    
    * agents mypy fix
    
    * fix failing tests
    
    * mypy fix
    
    * addressed comments
    
    * fixed tests
    
    * addressed comments + added factory method overrides for azureai v2 client
    
    * mypy fix
    
    * added kwargs to azureai tool methods
    
    * fixed in test
    
    * _sessions fix
    
    * test fix