Commit Graph

114 Commits

  • Python: [BREAKING] update context provider APIs, middleware, and per-service-call history persistence (#4992)
    * Rename provider base APIs
    
    Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
    
    * Allow provider-added chat and function middleware
    
    Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
    
    * Simulate service-stored history per model call
    
    Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
    
    * Fix typing regressions in CI
    
    Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
    
    * Fix response ID suppression review feedback
    
    Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
    
    * Rename per-service-call history persistence APIs
    
    Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
    
    * Address context persistence review feedback
    
    Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
    
    * Stabilize markdown sample docs
    
    Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
    
    * Persist service continuation state per call
    
    Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
    
    ---------
    
    Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
  • Python: fixed middleware samples (#5026)
    * fixed samples
    
    * small update to explanation
    
    * add snippet fix on root readme
  • Python: updated azure ai inference sample (#5028)
    * updated azure ai inference sample
    
    * openai multimodel fix
    
    * update language
  • Python: Remove unsupported memory scoping params from mem0/redis samples and docs (#4367)
    * Python: Remove unsupported memory scoping params from samples and docs
    
    Fixes #4353
    
    The `Mem0ContextProvider` and `RedisContextProvider` no longer support
    `thread_id` or `scope_to_per_operation_thread_id` parameters. This commit
    updates the affected samples and READMEs to use only the currently
    supported API (`user_id`, `agent_id`, `application_id`).
    
    Changes:
    - mem0_sessions.py: Remove `thread_id` and
      `scope_to_per_operation_thread_id` from examples 1 and 2, rewrite to
      demonstrate user-scoped and agent-scoped memory patterns
    - redis_sessions.py: Update module docstring to remove references to
      removed thread scoping params
    - mem0/README.md: Update Memory Scoping docs to reflect current API
    - redis/README.md: Remove `thread_id` and
      `scope_to_per_operation_thread_id` references from docs
    
    * Address Copilot review: rename thread_scope functions, fix docstring
    
    - Rename `example_global_thread_scope` -> `example_global_memory_scope`
    - Rename `example_per_operation_thread_scope` -> `example_agent_scoped_memory`
    - Update example 2 docstring to mention `application_id` alongside
      `user_id` and `agent_id` since it's set in the provider config
    - Update module docstring scenario 2 to include `application_id`
    
    * fix: rebase onto main, address giles17 review feedback
    
    - Resolve merge conflicts by rebasing all 4 original files onto current main
    - Address giles17's agent review suggestions:
      - mem0_basic.py: update comment to remove thread_id from scoping list
      - mem0_oss.py: update comment to remove thread_id from scoping list
      - redis_sessions.py: rename Example 2 from "Agent-Scoped Memory" to
        "Hybrid Vector Search" to accurately describe what it demonstrates
      - redis/README.md: update Example 2 description to match renamed example
    
    ---------
    
    Co-authored-by: Tao Chen <taochen@microsoft.com>
    Co-authored-by: Giles Odigwe <79032838+giles17@users.noreply.github.com>
  • Python: [BREAKING] Remove deprecated Python OpenAI/Azure AI surfaces (#4990)
    * [BREAKING] Remove deprecated Python OpenAI/Azure AI surfaces
    
    Also clean up follow-on docs, environment guidance, package metadata, and lab test stability.
    
    Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
    
    * Fix deleted semantic-kernel sample links
    
    Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
    
    * Address PR review feedback
    
    Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
    
    * improve foundry language
    
    * Fix A2A Foundry sample regression
    
    Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
    
    ---------
    
    Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
  • Python: Add Python feature lifecycle decorators for released APIs (#4975)
    * Add Python feature lifecycle decorators
    
    Introduce reusable experimental and release-candidate decorators for released packages, migrate the Skills APIs to the new staged metadata and warning system, and add lifecycle guidance plus samples.
    
    Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
    
    * Fix Python CI follow-ups
    
    Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
    
    * Address PR review feedback
    
    Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
    
    * Preserve protocol runtime checks
    
    Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
    
    ---------
    
    Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
  • Python: Add header_provider to Streamable HTTP MCP servers (#4849)
    * Python: Add header_provider to MCPStreamableHTTPTool (#4808)
    
    Add a header_provider callback parameter to MCPStreamableHTTPTool that
    enables injecting dynamic per-request HTTP headers from runtime kwargs
    (originating from FunctionInvocationContext.kwargs set in agent middleware).
    
    The implementation uses contextvars and httpx event hooks to ensure headers
    are task-local and safe for concurrent tool calls:
    
    - header_provider receives the runtime kwargs dict and returns headers
    - call_tool sets a ContextVar before delegating to MCPTool.call_tool
    - An httpx request event hook reads from the ContextVar and injects headers
    
    Example usage:
        mcp_tool = MCPStreamableHTTPTool(
            name="web-api",
            url="https://api.example.com/mcp",
            header_provider=lambda kwargs: {
                "X-Auth-Token": kwargs.get("auth_token", ""),
            },
        )
    
    Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
    
    * Address review feedback for #4808: Python: [Bug]: Unable to pass AgentContext to MCPStreamableHTTPTool
    
    * Add test for header_provider via FunctionTool.invoke with FunctionInvocationContext
    
    Addresses PR review comment: exercises the full pipeline from
    FunctionInvocationContext.kwargs through FunctionTool.invoke to
    MCPStreamableHTTPTool.call_tool and header_provider, rather than
    testing call_tool in isolation.
    
    Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
    
    * Address review feedback for #4808: review comment fixes
    
    * Fix streamable MCP transport defaults
    
    Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
    
    * Fix Azure AI test client mocks
    
    Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
    
    * Fix MCP runtime kwarg regressions
    
    Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
    
    * Stabilize MCP tool runtime kwargs
    
    Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
    
    * Use context kwargs in MCP wrappers
    
    Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
    
    * updated mcp samples
    
    * fix link
    
    ---------
    
    Co-authored-by: Copilot <copilot@github.com>
    Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
  • Python: Fix sample bugs: incorrect API params, wrong client types, and invalid options (#4983)
    * Fix sample bugs: incorrect API params, wrong client types, and invalid options
    
    - typed_options.py: Fix AnthropicClient model->model_id, wrap raw strings in Message objects for get_response(), fix reasoning_effort->reasoning dict, fix budget_tokens minimum (1024), use OpenAIChatClient not FoundryChatClient, remove unused import
    
    - client_reasoning.py: Fix deprecated model_id to model param
    
    - client_with_hosted_mcp.py: Remove invalid store=True kwarg from Agent.run()
    
    - code_defined_skill.py: Fix precision kwarg to use function_invocation_kwargs
    
    - Various other samples: Fix deprecated API usage and incorrect params
    
    Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
    
    * Address PR review comments
    
    - client_with_hosted_mcp.py: Fix remaining store=True kwarg on line 68 to use options dict
    
    - client_with_session.py: Change store=True to store=False to match in-memory persistence demo intent
    
    - typed_options.py: Remove non-existent import and model key from docstring example
    
    Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
    
    * new sample fixes
    
    ---------
    
    Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
  • Python: Foundry Evals integration for Python (#4750)
    * Foundry Evals integration for Python
    
    Merged and refactored eval module per Eduard's PR review:
    
    - Merge _eval.py + _local_eval.py into single _evaluation.py
    - Convert EvalItem from dataclass to regular class
    - Rename to_dict() to to_eval_data()
    - Convert _AgentEvalData to TypedDict
    - Simplify check system: unified async pattern with isawaitable
    - Parallelize checks and evaluators with asyncio.gather
    - Add all/any mode to tool_called_check
    - Fix bool(passed) truthy bug in _coerce_result
    - Remove deprecated function_evaluator/async_function_evaluator aliases
    - Remove _MinimalAgent, tighten evaluate_agent signature
    - Set self.name in __init__ (LocalEvaluator, FoundryEvals)
    - Limit FoundryEvals to AsyncOpenAI only
    - Type project_client as AIProjectClient
    - Remove NotImplementedError continuous eval code
    - Add evaluation samples in 02-agents/ and 03-workflows/
    - Update all imports and tests (167 passing)
    
    Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
    
    * fix: resolve mypy redundant-cast errors while keeping pyright happy
    
    Use cast(list[Any], x) with type: ignore[redundant-cast] comments to
    satisfy both mypy (which considers casting Any redundant) and pyright
    strict mode (which needs explicit casts to narrow Unknown types).
    
    Also fix evaluator decorator check_name type annotation to be
    explicitly str, resolving mypy str|Any|None mismatch.
    
    Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
    
    * fix: CI failures — pyupgrade, evaluator overloads, sample API, reset attr
    
    - Apply pyupgrade: Sequence from collections.abc, remove forward-ref quotes
    - Add @overload signatures to evaluator() for proper @evaluator usage
    - Fix evaluate_workflow sample to use WorkflowBuilder(start_executor=) API
    - Fix _workflow.py executor.reset() to use getattr pattern for pyright
    - Remove unused EvalResults forward-ref string in default_factory lambda
    
    Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
    
    * fix: skip gRPC-dependent observability test
    
    The test_configure_otel_providers_with_env_file_and_vs_code_port test
    triggers gRPC OTLP exporter creation, but the grpc dependency is
    optional and not installed by default. Add skipif decorator matching
    the pattern used by all other gRPC exporter tests in the same file.
    
    Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
    
    * fix: add nosec B101 for bandit assert check
    
    Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
    
    * style: align eval samples with repo conventions
    
    - Move module docstrings before imports (after copyright header)
    - Add -> None return type to all main() and helper functions
    - Fix line-too-long in multiturn sample conversation data
    - Add Workflow import for typed return in all_patterns_sample
    
    Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
    
    * Address PR review feedback: async fixes, sample bugs, deprecation warnings
    
    - Simplify _ensure_async_result to direct await (async-only clients)
    - Replace get_event_loop() with get_running_loop()
    - Narrow _fetch_output_items exception handling to specific types
    - Add warning log when _filter_tool_evaluators falls back to defaults
    - Add DeprecationWarning to options alias in Agent.__init__
    - Add DeprecationWarning to evaluate_response()
    - Rename raw key to _raw_arguments in convert_message fallback
    - Fix evaluate_agent_sample.py: replace evals.select() with FoundryEvals()
    - Fix evaluate_multiturn_sample.py: use Message/Content/FunctionTool types
    - Fix evaluate_workflow_sample.py: replace evals.select() with FoundryEvals()
    - Update test mocks to use AsyncMock for awaited API calls
    
    Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
    
    * Add test coverage for review feedback items
    
    - Add num_repetitions=2 positive test verifying 2×items and 4 agent calls
    - Add _poll_eval_run tests: timeout, failed, and canceled paths
    - Add evaluate_traces tests: validation error, response_ids path, trace_ids path
    - Add evaluate_foundry_target happy-path test with target/query verification
    
    Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
    
    * Fix ruff ISC004 lint error and apply formatter
    
    - Wrap implicit string concatenation in parens in evaluate_multiturn_sample.py
    - Apply ruff formatter to 6 other files with minor formatting drift
    
    Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
    
    * Remove core type changes (extracted to fix/workflow-stale-session branch)
    
    Reverts changes to _agents.py, _agent_executor.py, and _workflow.py
    back to upstream/main. These fixes are now in a separate PR.
    
    Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
    
    * Address PR review round 2: bugs, tests, and architecture
    
    Code fixes:
    - Fix _normalize_queries inverted condition (single query now replicates
      to match expected_count)
    - Fix substring match bug: 'end' in 'backend' matched; use exact set
      lookup for executor ID filtering
    - Fix used_available_tools sample: tool_definitions→tools param, use
      FunctionTool attribute access instead of dict .get()
    - Add None-check in _resolve_openai_client for misconfigured project
    - Add Returns section to evaluate_workflow docstring
    - Cache inspect.signature in @evaluator wrapper (avoid per-item reflection)
    
    Architecture:
    - Extract _evaluate_via_responses as module-level helper; evaluate_traces
      now calls it directly instead of creating a FoundryEvals instance
    - Move Foundry-specific typed-content conversion out of core to_eval_data;
      core now returns plain role/content dicts, FoundryEvals applies
      AgentEvalConverter in _evaluate_via_dataset
    
    Tests:
    - evaluate_response() deprecation warning emission and delegation
    - num_repetitions > 1 with expected_output and expected_tool_calls
    - Mock output_items.list in test_evaluate_calls_evals_api
    - Update to_eval_data assertions for plain-dict format
    - Unknown param error now raised at @evaluator decoration time
    
    Skipped (separate PR): executor reset loop, xfail removal, options alias
    
    Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
    
    * Fix CI: revert test_full_conversation, fix pyright errors
    
    - Revert test_full_conversation.py to upstream/main (the session
      preservation test was incorrectly changed to assert clearing)
    - Fix pyright reportUnnecessaryComparison on get_openai_client() None
      check by adding ignore comment
    - Fix pyright reportPrivateUsage: add public EvalItem.split_messages()
      method and use it in FoundryEvals._evaluate_via_dataset instead of
      accessing private _split_conversation
    
    Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
    
    * Address PR review round 3: reliability, test gaps, cleanup
    
    - Add try/except guard for non-numeric score in _coerce_result
    - Add poll_interval minimum bound (0.1s) to prevent tight loops
    - Add runtime async client check in _resolve_openai_client
    - Remove _ensure_async_result wrapper (10 call sites → direct await)
    - Better error message when queries provided without agent
    - Import-time asserts for evaluator set consistency
    - Remove 28 redundant @pytest.mark.asyncio decorators
    - Add doc note about _raw_arguments sensitive data
    - Tests: tool_called_check mode=any, _normalize_queries branches,
      _extract_result_counts paths, _extract_per_evaluator, bare check
      via evaluate_agent, output_items assertion, modulo wrapping,
      async client check, queries-without-agent error
    
    Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
    
    * Fix CI: ruff S101 assert, pyright and mypy arg-type errors
    
    - Replace module-level assert with if/raise for evaluator set
      consistency checks (ruff S101 disallows bare assert)
    - Add type: ignore[arg-type] and pyright: ignore[reportArgumentType]
      on OpenAI SDK evals API calls that pass dicts where typed params
      are expected (SDK accepts dicts at runtime)
    
    Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
    
    * Address PR review round 4: bugs, reliability, test fixes
    
    - Fix all_passed ignoring parent result_counts when sub_results present
    - Fix _extract_tool_calls: parse string arguments via json.loads before
      falling back to None (real LLM responses use string arguments)
    - Sanitize _raw_arguments to '[unparseable]' to avoid leaking sensitive
      tool-call data to external evaluation services
    - Add NOTE comment on to_eval_data message serialization dropping
      non-text content (tool calls, results)
    - Eliminate double conversation split in _evaluate_via_dataset: build
      JSONL dicts directly from split_messages + AgentEvalConverter
    - Raise poll_interval floor from 0.1s to 1.0s to prevent rate-limit
      exhaustion
    - Fix MagicMock(name=...) bug in test: sets display name not .name attr
    - Fix mock_output_item.sample: use MagicMock object instead of dict so
      _fetch_output_items exercises error/usage/input/output extraction
    
    Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
    
    * Address PR review round 5: reliability, docs, test coverage
    
    Code fixes:
    - Move import-time RuntimeError checks to unit tests (avoids breaking
      imports for all users on developer set-drift mistake)
    - _filter_tool_evaluators now raises ValueError when all evaluators
      require tools but no items have tools (was silently substituting)
    - Add poll_interval upper bound (60s) to prevent single-iteration sleep
    - Log exc_info=True in _fetch_output_items for debugging API changes
    - Fix evaluate() docstring: remove claim about Responses API optimization
    - Validate target dict has 'type' key in evaluate_foundry_target
    - Document to_eval_data() limitation: non-text content is omitted
    
    Tests:
    - TestEvaluatorSetConsistency: verify _AGENT/_TOOL subsets of _BUILTIN
    - TestEvaluateTracesAgentId: agent_id-only path with lookback_hours
    - TestFilterToolEvaluatorsRaises: ValueError on all-tool no-items
    - TestEvaluateFoundryTargetValidation: target without 'type' key
    - Assert items==[] on failed/canceled poll results
    - Mock output_items.list in response_ids test for full flow
    - TestAllPassedSubResults: result_counts=None + sub_results delegation
      and parent failures override sub_results
    - TestBuildOverallItemEmpty: empty workflow outputs returns None
    
    Skipped r5-07 (_raw_arguments length hint): marginal debugging value,
    could leak content size information.
    
    Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
    
    * Fix error message: evaluate_responses() → evaluate_traces(response_ids=...)
    
    The referenced function doesn't exist; the correct API is
    evaluate_traces(response_ids=...) from the azure-ai package.
    
    Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
    
    * Remove dead to_eval_data() method, fix docstring claims
    
    - Remove to_eval_data() from EvalItem (dead code after r4-05 JSONL refactor)
    - Migrate 15 tests from to_eval_data() to split_messages()
    - Update sample to use split_messages() + Message properties
    - Remove unimplemented Responses API optimization docstring claim
    - Update split_messages() docstring to not reference removed method
    
    Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
    
    * Reduce default eval timeout from 600s to 180s (3 minutes)
    
    Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
    
    * Remove dead _evaluate_via_responses method from FoundryEvals
    
    The method was never called — evaluate() uses _evaluate_via_dataset,
    and evaluate_traces() calls _evaluate_via_responses_impl directly.
    
    Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
    
    * Revert unrelated formatting changes to get-started samples
    
    Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
    
    * Fix pyright: remove phantom FoundryMemoryProvider import, apply ruff format
    
    - Remove import of non-existent _foundry_memory_provider module
      (incorrectly kept during rebase conflict resolution)
    - Apply ruff formatter to test_local_eval.py and get-started samples
    
    Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
    
    * Fix eval samples: use FoundryChatClient for Agent()
    
    The upstream provider-leading client refactor (#4818) made client=
    a required parameter on Agent(). Update the three getting-started
    eval samples to use FoundryChatClient with FOUNDRY_PROJECT_ENDPOINT,
    matching the standard pattern from 01-get-started samples.
    
    Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
    
    * Simplify self-reflection sample using FoundryEvals
    
    Replace ~80 lines of manual OpenAI evals API code (create_eval,
    run_eval, manual polling, raw JSONL params) with FoundryEvals:
    
    - evaluate_groundedness() uses FoundryEvals.evaluate() with EvalItem
    - Remove create_openai_client(), create_eval(), run_eval() functions
    - Remove openai SDK type imports (DataSourceConfigCustom, etc.)
    - run_self_reflection_batch creates FoundryEvals instance once,
      reuses it for all iterations across all prompts
    
    Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
    
    * Update eval samples to FoundryChatClient and FOUNDRY_PROJECT_ENDPOINT
    
    - Migrate all foundry_evals samples from AzureOpenAIResponsesClient to FoundryChatClient
    - Update env var from AZURE_AI_PROJECT_ENDPOINT to FOUNDRY_PROJECT_ENDPOINT
    - Use AzureCliCredential consistently across all samples
    - Fix README.md: correct function names (evaluate_dataset -> FoundryEvals.evaluate, evaluate_responses -> evaluate_traces)
    - Update self_reflection .env.example and README.md
    
    Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
    
    * Fix lint errors in eval samples (E501, ASYNC240, formatting)
    
    Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
    
    * Remove evaluate_all_patterns_sample.py (redundant with focused samples)
    
    Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
    
    * Fix async credential mismatch: use azure.identity.aio for async AIProjectClient
    
    AIProjectClient from azure.ai.projects.aio requires an async credential.
    Switch all foundry_evals samples from azure.identity.AzureCliCredential
    to azure.identity.aio.AzureCliCredential. Also pass project_client to
    FoundryChatClient instead of duplicating endpoint+credential.
    
    Close credential in self_reflection sample to avoid resource leak.
    
    Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
    
    * Revert test_observability.py to upstream/main (not our test)
    
    Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
    
    * Address moonbox3 review: sphinx docstrings, pagination, isinstance check
    
    - Convert all Example:: / Typical usage:: code blocks to .. code-block:: python
      format matching codebase convention (both _evaluation.py and _foundry_evals.py)
    - Add async pagination in _fetch_output_items via async for (handles large result sets)
    - Replace hasattr(__aenter__) with isinstance(client, AsyncOpenAI) in _resolve_openai_client
    - Move AsyncOpenAI import from TYPE_CHECKING to runtime (needed for isinstance)
    
    Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
    
    * Fix test failures and address remaining moonbox3 review comments
    
    - Fix tests: use MagicMock(spec=AsyncOpenAI) for project_client mocks
      (isinstance check now requires proper type, not duck-typing)
    - Fix tests: replace mock_page.__iter__ with _AsyncPage helper for async for
    - Fix evaluate_response: auto-extract queries from response messages when
      query is not provided (previously always raised ValueError)
    - Add debug logging when skipping internal _-prefixed executor IDs
    
    Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
    
    * Address Tao's PR review comments on Foundry Evals
    
    - T1: Add comment explaining builtin.* pass-through in _resolve_evaluator
    - T2: Add comment referencing OpenAI evals API for testing_criteria dict
    - T3: Document Mustache-style {{item.*}} template placeholders
    - T4: Document poll loop 60s sleep upper bound rationale
    - T5: Narrow run type to RunRetrieveResponse, use typed field access
      instead of vars()/getattr dance in _extract_result_counts and
      _extract_per_evaluator; use run.error and run.report_url directly
    - T6: Clarify openai_client docstring re: Azure Foundry endpoint
    - T8: Remove misleading empty expected_tool_calls from sample
    - Update tests to match real SDK PerTestingCriteriaResult shape
    
    Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
    
    * Remove unnecessary Any union from run type annotations
    
    RunRetrieveResponse is the correct type — no backward compat needed
    for a brand new feature.
    
    Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
    
    * Accept FoundryChatClient instead of raw AsyncOpenAI
    
    FoundryEvals now takes client: FoundryChatClient as its primary
    parameter instead of openai_client: AsyncOpenAI.  The builtin.*
    evaluators require a Foundry endpoint, so the type should reflect that.
    
    - FoundryEvals.__init__: client: FoundryChatClient replaces openai_client
    - evaluate_traces / evaluate_foundry_target: same change
    - _resolve_openai_client: extracts .client from FoundryChatClient
    - project_client fallback retained for standalone functions
    - All samples updated to construct FoundryChatClient and pass as client=
    - Tests updated (openai_client= → client=)
    
    Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
    
    * Remove implicit 60s upper bound on poll interval
    
    If a developer sets a higher poll_interval, respect it. Only clamp
    to remaining time and enforce a 1s minimum for rate-limit protection.
    
    Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
    
    * Remove 1s floor on poll interval — let the developer control it
    
    Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
    
    * Update python/samples/05-end-to-end/evaluation/foundry_evals/.env.example
    
    Co-authored-by: Eduard van Valkenburg <eavanvalkenburg@users.noreply.github.com>
    
    * Update python/samples/02-agents/evaluation/evaluate_agent.py
    
    Co-authored-by: Eduard van Valkenburg <eavanvalkenburg@users.noreply.github.com>
    
    * Address eavanvalkenburg review (round 2) on Python eval PR
    
    - Rename model_deployment -> model across FoundryEvals and all samples
    - Make model param optional, resolves from client.model
    - Convert EvalResults from dataclass to regular class
    - Remove deprecated evaluate_response() function
    - Refactor splitters: BUILT_IN_SPLITTERS dict + standalone functions
    - Change per_turn_items from classmethod to staticmethod
    - Simplify EvalCheck type alias to use Awaitable[CheckResult]
    - Remove errored property from EvalResults
    - Remove default value from Evaluator protocol eval_name
    - Rename assert_passed -> raise_for_status, add EvalNotPassedError
    - Type agent param as SupportsAgentRun | None
    - Fix Arguments docstring
    - Update __init__.py exports
    - Update all tests and samples
    
    Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
    
    * Move FoundryEvals to foundry package, split tool eval sample
    
    - Move _foundry_evals.py from azure-ai to foundry package
    - Move test_foundry_evals.py to foundry/tests/
    - Update lazy re-exports in agent_framework.foundry namespace
    - Update .pyi type stubs
    - All samples now import from agent_framework.foundry
    - Split tool-call evaluation into evaluate_tool_calls_sample.py
    - Fix all_passed to check errored count from result_counts
    - Fix raise_for_status to include errored item details
    
    Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
    
    * Auto-create FoundryChatClient from env vars when no client provided
    
    FoundryEvals() now works zero-config when FOUNDRY_PROJECT_ENDPOINT and
    FOUNDRY_MODEL environment variables are set. Auto-creates a FoundryChatClient
    under the hood, matching the established env var pattern.
    
    Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
    
    * Fix pyright errors: remove dead _normalize_queries, suppress EvalAPIError check
    
    - Remove unused _normalize_queries function and its tests
    - Add pyright ignore for EvalAPIError None check (defensive guard)
    
    Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
    
    * Support multimodal image content in eval pipeline
    
    Add image (data/uri) content handling to AgentEvalConverter.convert_message()
    so that Content.from_data() and Content.from_uri() image payloads are
    preserved as input_image parts in the Foundry evaluator format.
    
    - Handle Content type='data' and type='uri' → emit input_image parts
    - Add 6 unit tests for image content through convert_message/convert_messages
    - Add integration test verifying images flow through EvalItem → JSONL path
    - Add evaluate_multimodal.py sample demonstrating local image eval
    
    Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
    
    * Address remaining review comments
    
    - Fix project_client docstring to say async-only (not sync/async)
    - Add builtin evaluator name validation warning in _resolve_evaluator
    - Replace getattr with typed attribute access in _poll_eval_run,
      _extract_result_counts, _extract_per_evaluator, _fetch_output_items
    - Remove cast import from _foundry_evals (no longer needed)
    - Tighten _coerce_result: honour explicit 'passed' when both 'score'
      and 'passed' are present; remove performative cast
    - Fix self_reflection sample: add env file existence check
    - Fix traces sample: correct Pattern 2 section label
    - Update all Foundry eval samples to FoundryChatClient + FOUNDRY_MODEL
      (remove AIProjectClient + AZURE_AI_MODEL_DEPLOYMENT_NAME pattern)
    - Add eval_name and OpenAI client docs to FoundryEvals docstring
    - Update test mocks to match typed SDK objects (_MockResultCounts)
    
    Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
    
    * Fix ruff lint errors (E501, SIM108, SIM102)
    
    Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
    
    * Fix pyright errors: type-narrow dict to dict[str, Any], add ignore comments
    
    Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
    
    * Replace ConversationSplitter type alias with Protocol
    
    ConversationSplitter is now a runtime-checkable Protocol with a named
    'conversation' parameter, making the expected signature self-documenting.
    
    ConversationSplit enum members gain a __call__ method so they satisfy
    the protocol directly -- ConversationSplit.LAST_TURN(conversation) works.
    
    This simplifies _split_conversation from an isinstance dispatch to a
    single split(conversation) call.
    
    Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
    
    * Standardize on AZURE_AI_MODEL_DEPLOYMENT_NAME and fix Unicode in samples
    
    - Replace FOUNDRY_MODEL with AZURE_AI_MODEL_DEPLOYMENT_NAME in all
      eval samples to match repo convention
    - Replace Unicode symbols with ASCII equivalents in all eval sample
      print statements to avoid cp1252 encoding errors on Windows
    
    Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
    
    * Update python/samples/03-workflows/evaluation/evaluate_workflow.py
    
    Co-authored-by: Eduard van Valkenburg <eavanvalkenburg@users.noreply.github.com>
    
    * Apply suggestions from code review
    
    Co-authored-by: Eduard van Valkenburg <eavanvalkenburg@users.noreply.github.com>
    
    * Rename ADR 0020 to 0023 (foundry evals integration)
    
    Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
    
    ---------
    
    Co-authored-by: alliscode <bentho@microsoft.com>
    Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
    Co-authored-by: Eduard van Valkenburg <eavanvalkenburg@users.noreply.github.com>
  • Python: Fix samples (#4980)
    * First samples 1st batch
    
    * Fix sample paths
    
    * Fix workflow samples
    
    * Fix workflow dependency
    
    * Correct env vars
    
    * Increase idle timeout
    
    * Fix workflows HIL sample
    
    * Fix more workflow samples
  • Python: Fix broken samples for GitHub Copilot, declarative, and Responses API (#4915)
    * Python: Fix broken samples for GitHub Copilot, declarative, and Responses API
    
    - Add missing on_permission_request handler to github_copilot_basic and
      github_copilot_with_session samples (required by copilot SDK)
    - Increase timeout for remote MCP query in github_copilot_with_mcp sample
    - Soften session isolation claim in github_copilot_with_session sample
    - Fix inline_yaml sample: pass project_endpoint via client_kwargs instead
      of relying on YAML connection block (AzureAIClient expects
      project_endpoint, not endpoint)
    - Handle raw JSON schemas in Responses client _convert_response_format
      so declarative outputSchema works with the Responses API
    
    Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
    
    * Improve raw JSON schema detection heuristic and add tests
    
    - Broaden raw schema detection to handle anyOf, oneOf, allOf, $ref, $defs
      keywords and JSON Schema primitive types, not just 'properties'
    - Apply same raw schema handling to azure-ai _shared.py for consistency
    - Add unit tests for both openai and azure-ai response_format conversion
    
    Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
    
    ---------
    
    Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
  • [BREAKING] Python: fix OpenAI Azure routing and provider samples (#4925)
    * Python: fix OpenAI Azure routing and provider samples
    
    Prefer OpenAI when OPENAI_API_KEY is present unless Azure is explicitly requested. Clarify constructor docs, keep deprecated Azure wrappers compatible with stricter settings validation, and refresh the provider samples and tests to use the current client patterns.
    
    Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
    
    * fix bandit
    
    * Python: align OpenAI embedding Azure routing
    
    Extend the shared OpenAI-vs-Azure routing and credential behavior to the embedding client, add Azure embedding regression coverage, and refresh the embedding samples to use the generic client path.
    
    Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
    
    * Python: fix embedding client pyright check
    
    Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
    
    * Python: thin OpenAI embedding wrapper
    
    Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
    
    * Python: document embedding overload routing
    
    Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
    
    * Python: fix callable OpenAI key routing
    
    Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
    
    * Python: fix Azure credential routing tests
    
    Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
    
    * Python: address OpenAI review feedback
    
    Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
    
    * Python: narrow Azure routing markers
    
    Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
    
    * Python: refine OpenAI model fallback order
    
    Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
    
    * Python: narrow Azure deployment docs
    
    Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
    
    * Python: remove embedding routing wording
    
    Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
    
    * Python: run embedding Azure integration tests
    
    Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
    
    * changed variable name
    
    * Python: expand OpenAI package README
    
    Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
    
    * clarified readme
    
    * Python: fix Azure OpenAI integration setup
    
    Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
    
    * Python: correct Azure integration env mapping
    
    Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
    
    * updated code to fix int tests
    
    * test updates
    
    * test fix
    
    * fix test setup
    
    * updates to tests and setup
    
    * remove openai assistants int tests
    
    * improvements in int tests
    
    * fix env var
    
    * fix env vars
    
    * fix azure responses test
    
    * trigger actions
    
    ---------
    
    Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
  • Python: [BREAKING] Python: Provider-leading client design & OpenAI package extraction (#4818)
    * Python: Provider-leading client design & OpenAI package extraction
    
    Major refactoring of the Python Agent Framework client architecture:
    
    - Extract OpenAI clients into new `agent-framework-openai` package
    - Core package no longer depends on openai, azure-identity, azure-ai-projects
    - Rename clients for discoverability: OpenAIResponsesClient → OpenAIChatClient,
      OpenAIChatClient → OpenAIChatCompletionClient
    - Unify `model_id`/`deployment_name`/`model_deployment_name` → `model` param
    - New FoundryChatClient for Azure AI Foundry Responses API
    - New FoundryAgent/FoundryAgentClient for connecting to pre-configured Foundry agents
    - Remove OpenAIBase/OpenAIConfigMixin from non-deprecated client MRO
    - Deprecate AzureOpenAI* clients, AzureAIClient, OpenAIAssistantsClient
    - Reorganize samples: azure_openai+azure_ai+azure_ai_agent → azure/
    - ADR-0020: Provider-Leading Client Design
    
    Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
    
    * fix: missing Agent imports in samples, .model_id → .model in foundry_local sample
    
    Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
    
    * fix: CI failures — mypy errors, coverage targets, sample imports
    
    - azure-ai mypy: add type ignores for TypedDict total=, model arg, forward ref
    - Coverage: replace core.azure/openai targets with openai package target
    - project_provider: add type annotation for opts dict
    
    Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
    
    * fix: populate openai .pyi stub, fix broken README links, coverage targets
    
    Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
    
    * fixes
    
    * updated observabilitty
    
    * reset azure init.pyi
    
    * fix errors
    
    * updated adr number
    
    * fix foundry local
    
    * fixed not renamed docstrings and comments, and added deprecated markers to old classes
    
    * fix tests and pyprojects
    
    * fix test vars
    
    * updated function tests
    
    * update durable
    
    * updated test setup for functions
    
    * Fix Foundry auth in workflow samples
    
    Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
    
    * Stabilize Python integration workflows
    
    Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
    
    * Update hosting samples for Foundry
    
    Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
    
    * Trigger full CI rerun
    
    Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
    
    * Trigger CI rerun again
    
    Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
    
    * trigger rerun
    
    * trigger rerun
    
    * fix for litellm
    
    * undo durabletask changes
    
    * Move Foundry APIs into foundry namespace
    
    Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
    
    * Fix Foundry pyproject formatting
    
    Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
    
    * Split provider samples by Foundry surface
    
    Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
    
    * Restore hosting sample requirements
    
    Also fix the Foundry Local sample link after the provider sample move.
    
    Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
    
    * updated tests
    
    * udpated foundry integration tests
    
    * removed dist from azurefunctions tests
    
    * Use separate Foundry clients for concurrent agents
    
    Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
    
    * fix client setup in azfunc and durable
    
    * disabled two tests
    
    * updated setup for some function and durable tests
    
    * improved azure openai setup with new clients
    
    * ignore deprecated
    
    * fixes
    
    * skip 11
    
    * remove openai assistants int tests
    
    ---------
    
    Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
  • Python: Update sample validation scripts (#4870)
    * Update sample validation scripts
    
    * Adjust prompt
    
    * Update autogen-migration samples
    
    * Add fix suggestion
    
    * Split jobs
    
    * Add .env
    
    * Create trend report
    
    * Add timestamp
    
    * Add more env vars
    
    * Comments
    
    * force node24
    
    * force node24
    
    * force node22
  • Python: [BREAKING] Refactor middleware layering and split Anthropic raw client (#4746)
    * [BREAKING] Refactor middleware layering and raw clients
    
    Reorder chat client layers so function invocation wraps chat middleware, and chat middleware stays outside telemetry while still running for each inner model call. Add middleware pipeline caching, refresh docs and samples, and split Anthropic into raw and public clients to match the standard layering model.
    
    Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
    
    * Tighten typing ignores in ancillary modules
    
    Add targeted typing ignores in workflow visualization and lab modules so pyright stays clean alongside the middleware refactor work.
    
    Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
    
    * Fix categorize_middleware to unpack tuple/Sequence and use relative MRO assertions
    
    - Broaden isinstance check in categorize_middleware from list to Sequence
      so tuples and other Sequence types are properly unpacked instead of
      being appended as a single item.
    - Replace fragile hardcoded MRO index assertions in anthropic test with
      relative ordering via mro.index().
    - Add regression tests for categorize_middleware with tuple, list, and
      None inputs.
    
    Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
    
    * Fix middleware string decomposition, add middleware param to FunctionInvocationLayer, and add tests (#4710)
    
    - Guard categorize_middleware Sequence check against str/bytes to prevent
      character-by-character decomposition of accidentally passed strings
    - Add explicit middleware parameter to FunctionInvocationLayer.get_response
      and merge it into client_kwargs before categorization, fixing the
      inconsistency where only OpenAIChatClient supported this parameter
    - Add assertions that RawAnthropicClient does not inherit convenience layers
    - Add chat middleware cache test with non-empty base middleware
    - Add tests for single unwrapped middleware item and string input
    
    Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
    
    * Apply pre-commit auto-fixes
    
    * Apply pre-commit auto-fixes
    
    * Address review feedback for #4710: review comment fixes
    
    ---------
    
    Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
    Co-authored-by: Copilot <copilot@github.com>
  • Python: Simplify Python Poe tasks and unify package selectors (#4722)
    * updated automation tasks and commands, with alias for the time being
    
    * Restore aggregate test exclusions
    
    Preserve the legacy all-tests scope for test --all by excluding lab and devui from the default aggregate sweep, while still allowing explicit package selection. Also ignore hidden/generated test directories such as .mypy_cache during aggregate discovery.
    
    Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
    
    * updated versions in pre-commit
    
    ---------
    
    Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
  • [BREAKING] Python: clean up kwargs across agents, chat clients, tools, and sessions (#4581)
    * Python: clean up kwargs across agents, chat clients, tools, and sessions (#3642)
    
    Audit and refactor public **kwargs usage across core agents, chat clients,
    tools, sessions, and provider packages per the migration strategy codified
    in CODING_STANDARD.md.
    
    Key changes:
    - Add explicit runtime buckets: function_invocation_kwargs and client_kwargs
      on RawAgent.run() and chat client get_response() layers.
    - Refactor FunctionTool to prefer explicit ctx: FunctionInvocationContext
      injection; legacy **kwargs tools still work via _forward_runtime_kwargs.
    - Refactor Agent.as_tool() to use direct JSON schema, always-streaming
      wrapper, approval_mode parameter, and UserInputRequiredException
      propagation (integrates PR #4568 behavior).
    - Remove implicit session bleeding into FunctionInvocationContext; tools
      that need a session must receive it via function_invocation_kwargs.
    - Lower chat-client layers after FunctionInvocationLayer accept only
      compatibility **kwargs (client_kwargs flattened, function_invocation_kwargs
      ignored).
    - Add layered docstring composition from Raw... implementations via
      _docstrings.py helper.
    - Clean up provider constructors to use explicit additional_properties.
    - Deprecation warnings on legacy direct kwargs paths.
    - Update samples, tests, and typing across all 23 packages.
    
    Resolves #3642
    
    Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
    
    * clarified docstring
    
    * feedback fixes
    
    * Add unit tests for _docstrings.py build/apply helpers
    
    Tests cover: no docstring source, no extra kwargs, appending to existing
    Keyword Args section, inserting after Args, inserting in plain docstrings,
    multiline descriptions, ordering, and apply_layered_docstring.
    
    Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
    
    * Add test for propagate_session TypeError on non-AgentSession values
    
    Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
    
    * Add tests for multi-content and empty UserInputRequiredException propagation
    
    Cover the branching logic in _try_execute_function_calls for:
    - Multiple user_input_request items in a single exception (extra_user_input_contents path)
    - Empty contents list (fallback function_result path)
    
    Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
    
    * Add tests for DurableAIAgent.get_session forwarding service_session_id
    
    Verifies get_session correctly forwards service_session_id and session_id
    to the executor's get_new_session, replacing the removed kwargs test.
    
    Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
    
    * Simplify ag-ui test stub to read session from client_kwargs only
    
    Remove dual-mode detection (client_kwargs vs raw kwargs fallback) from
    the test mock. Session is now read exclusively from client_kwargs,
    matching the settled public calling convention.
    
    Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
    
    * updated create and get sessions in durable
    
    * fixed docstrings
    
    * fix test
    
    * updated session handling
    
    * updated from main
    
    * updated tests
    
    ---------
    
    Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
  • Python: Implement annotation-based context compaction (#4469)
    * Implement annotation-based context compaction
    
    Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
    
    * Handle missing compaction attributes in BaseChatClient
    
    Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
    
    * Fix CI typing and bandit issues
    
    Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
    
    * Optimize incremental compaction annotation pass
    
    Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
    
    * refinement
    
    * Python: add ToolResultCompactionStrategy and CompactionProvider
    
    Add ToolResultCompactionStrategy that collapses older tool-call groups
    into short summary messages (e.g. [Tool calls: get_weather]) while
    keeping the most recent groups verbatim. This mirrors the .NET
    ToolResultCompactionStrategy from PR #4533.
    
    Add CompactionProvider as a context-provider that auto-applies compaction
    before each agent turn and stores compacted history in session state
    after each turn.
    
    Includes tests and samples for both features.
    
    Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
    
    * refinement and alignment with dotnet PR
    
    * updated tool result compaction
    
    * updated tool result compaction
    
    * Python: add ToolResultCompactionStrategy, CompactionProvider, and skip_excluded
    
    - ToolResultCompactionStrategy collapses older tool-call groups into
      [Tool results: func_name: result] summaries with bidirectional tracing
      (same pattern as SummarizationStrategy).
    - CompactionProvider as BaseContextProvider with separate before_strategy
      and after_strategy parameters. before_strategy compacts loaded context;
      after_strategy compacts stored history via history_source_id.
    - InMemoryHistoryProvider gains skip_excluded flag to filter out messages
      marked as excluded by compaction strategies.
    - Tests, samples, and exports updated.
    
    Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
    
    * fixed checks
    
    * fix mypy
    
    * Fix: ensure summary messages from both strategies get full compaction annotations
    
    SummarizationStrategy was not calling annotate_message_groups after
    inserting its summary message, so the summary lacked core group
    annotations (id, kind, index, has_reasoning, _excluded). Added the
    missing call. ToolResultCompactionStrategy already had it.
    
    Added tests verifying both strategies produce fully annotated summaries.
    
    Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
    
    * updated propagation
    
    * fix mypy
    
    ---------
    
    Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
  • Python: Support skill scripts execution (#4558)
    * support skill scripts execution
    
    * fix mixed line endings
    
    * address comments and fix syntax issues
    
    * use few try/except instead of one
    
    * change samples
    
    * validate either script path or script resource is set not both
    
    * fix: separate LLM args from runtime kwargs in skill script execution
    
    * address pr review comments
    
    * address PR review comments
    
    * Update python/packages/core/agent_framework/_skills.py
    
    Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
    
    * Update python/packages/core/agent_framework/_skills.py
    
    Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
    
    * Update python/packages/core/agent_framework/_skills.py
    
    Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
    
    * 1. Fixing the caching bug where parameters_schema would re-inspect on every call when the result was None
       2. Updating the arguments tool description to be more generic (not CLI-specific)
    
    * fix failing tests
    
    * address pr review comments
    
    * address pr review comments
    
    * allow resource function returning any instead of sting
    
    * address PR review comments
    
    ---------
    
    Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
  • Fix chat_response_cancellation sample to use Message objects (#4532)
    The sample was passing raw strings in a list to get_response(), which
    expects Message objects. This caused an AttributeError since strings
    don't have a 'role' attribute.
    
    Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
  • Python: [Breaking] Upgrade to azure-ai-projects 2.0+ (#4536)
    * Prepare azure-ai-projects 2.0 GA compatibility
    
    Add allow_preview support for internal AIProjectClient creation, keep backward compatibility for renamed SDK model classes, and align Azure AI/core paths and tests for GA validation workflows.
    
    Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
    
    * upgrade to ai-project==2.0.0
    
    * Python: remove azure-ai-projects keyword-guard paths
    
    Assume azure-ai-projects 2.0+ in Azure AI client/provider/responses code paths by removing _supports_keyword_argument gating and related fallback branching.
    
    Also fix pyright typing in FoundryMemoryProvider memory store calls by using ResponseInputItemParam-typed items.
    
    Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
    
    * check fixes
    
    * Python: remove unsupported foundry_features option
    
    Drop foundry_features from Azure AI client and provider surfaces because azure-ai-projects 2.0.0 does not expose that create_version parameter.
    
    Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
    
    * Python: add allow_preview to Foundry memory provider
    
    Propagate allow_preview when FoundryMemoryProvider constructs an AIProjectClient and update tests accordingly.
    
    Also finish wiring allow_preview through AzureAIClient-facing surfaces and related docs.
    
    Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
    
    * aligning docstrings
    
    * udpated lock
    
    ---------
    
    Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
  • [BREAKING] Python: Update github-copilot-sdk integration to use ToolInvocation/ToolResult types (#4551)
    * Update github_copilot package for github-copilot-sdk>=0.1.32 (#4549)
    
    - Update requires-python from >=3.10 to >=3.11
    - Remove Python 3.10 classifier
    - Update mypy python_version to 3.11
    - Update dependency to github-copilot-sdk>=0.1.32
    - Fix ToolResult API: use snake_case kwargs (text_result_for_llm,
      result_type) instead of camelCase (textResultForLlm, resultType)
    - Update test assertions to use attribute access on ToolResult
    - Add ToolResult type assertions to tool handler tests
    
    Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
    
    * Fix tests to use ToolInvocation dataclass instead of plain dict (#4549)
    
    Update test_github_copilot_agent.py to pass ToolInvocation objects to tool
    handlers instead of plain dicts, matching the github-copilot-sdk>=0.1.32 API
    where ToolInvocation is a dataclass with an .arguments attribute.
    
    Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
    
    * Add regression tests for ToolInvocation contract (#4549)
    
    Add tests to lock in the new ToolInvocation-based calling convention:
    - test_tool_handler_rejects_raw_dict_invocation: verifies passing a raw
      dict (old calling convention) raises TypeError/AttributeError
    - test_tool_handler_with_empty_arguments: verifies ToolInvocation with
      empty arguments works correctly for no-arg tools
    
    Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
    
    * Revert requires-python to >=3.10 to avoid breaking CI (#4549)
    
    The repo CI runs with Python 3.10 (uv sync --all-packages) and all other
    packages require >=3.10. Raising this package to >=3.11 would break the
    shared install flow. The SDK dependency version constraint (>=0.1.32) will
    enforce any Python version requirement from the SDK itself.
    
    Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
    
    * Fix min Python version for github_copilot package to >=3.11
    
    github-copilot-sdk>=0.1.32 requires Python>=3.11, which conflicts
    with the package's declared >=3.10 minimum, breaking uv sync.
    
    * Bump py version for GH workflows to 3.11, exclude GHCP sdk from 3.10 items
    
    * Fix uv command
    
    * Fixes
    
    * Update samples
    
    ---------
    
    Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
  • Python: Forward runtime kwargs to skill resource functions (#4417)
    * support code skills
    
    * address pr review comments
    
    * address package and syntax checks
    
    * address pr review comments
    
    * address pr review comment
    
    * address failed check
    
    * rename agentskill and agetnskillprovider
    
    * move agent skills related assets to _skills.py
    
    * address pr review comments
    
    * address review comments
    
    * support kwargs
    
    * address pr review feedback
  • Python: Add propagate_session to as_tool() for session sharing in agent-as-tool scenarios (#4439)
    * Python: Add propagate_session parameter to as_tool() for session sharing
    
    Add opt-in session propagation in agent-as-tool scenarios. When
    propagate_session=True, the parent agent's AgentSession is forwarded
    to the sub-agent's run() call, allowing both agents to share session
    state (history, metadata, session_id).
    
    - Add propagate_session parameter to BaseAgent.as_tool() (default False)
    - Include session in additional_function_arguments so it flows to tools
    - Add 3 tests for propagation on/off and shared state verification
    - Add sample showing session propagation with observability middleware
    
    Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
    
    * Clarify propagate_session docstring per review feedback
    
    Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
    
    ---------
    
    Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
  • Python: [BREAKING] Support code-defined agent skills (#4387)
    * support code skills
    
    * address pr review comments
    
    * address package and syntax checks
    
    * address pr review comments
    
    * address pr review comment
    
    * address failed check
    
    * rename agentskill and agetnskillprovider
    
    * move agent skills related assets to _skills.py
    
    * address pr review comments
    
    * address review comments
  • Python: Upgraded azure-ai-projects to 2.0.0b4 (#4438)
    * Upgraded azure-ai-projects to 2.0.0b4
    
    * Fixed tests
  • Python: Added Shell tool (#4339)
    * Added shell tool
    
    * Fixed CI error
    
    * Add ShellTool support for OpenAI and Anthropic providers
    
    - Add shell_tool_call, shell_tool_result, and shell_command_output content types
    - Add ShellTool class and shell_tool decorator to core
    - Add get_hosted_shell_tool() to OpenAI Responses client
    - Handle shell_call and shell_call_output parsing in OpenAI (sync and streaming)
    - Map ShellTool to Anthropic bash tool API format
    - Parse bash_code_execution_tool_result as shell_tool_result in Anthropic
    - Add unit tests for all new functionality
    - Add sample scripts for hosted and local shell execution
    
    Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
    
    * Addressed comments
    
    * Reverted ruff change
    
    * Fixed tests
    
    * Addressed comments
    
    ---------
    
    Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
  • Python: Add auto_retry.py sample for rate limit handling (#4223)
    * Initial plan
    
    * Add auto_retry.py sample for rate limiting handling
    
    Co-authored-by: eavanvalkenburg <13749212+eavanvalkenburg@users.noreply.github.com>
    
    * Update auto_retry sample to use class decorator for get_response retries
    
    Co-authored-by: eavanvalkenburg <13749212+eavanvalkenburg@users.noreply.github.com>
    
    * Address review feedback on auto_retry sample header and wrapper usage
    
    Co-authored-by: eavanvalkenburg <13749212+eavanvalkenburg@users.noreply.github.com>
    
    * Restore class-decorator retry sample and address reviewer feedback
    
    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: eavanvalkenburg <13749212+eavanvalkenburg@users.noreply.github.com>
  • Python: Fix samples discovered by auto validation pipeline (#4355)
    * Fix samples discovered by auto validation pipeline
    
    * Update python/samples/02-agents/devui/in_memory_mode.py
    
    Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
    
    ---------
    
    Co-authored-by: Copilot <175728472+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: Azure AI Search provider improvements - EmbeddingGenerator, async context manager, KB message handling (#4212)
    * small updates and improvements in the azure AISearch provider
    
    * Fix mypy errors and embedding function test
    
    - Use separate variable for embeddings result to avoid mypy type reassignment error
    - Fix test_vectorized_query_with_embedding_function: use real async function
      instead of AsyncMock which falsely matches SupportsGetEmbeddings protocol
    
    Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
    
    * fixes from feedback
    
    ---------
    
    Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
  • Python: docs(observability): add Comet Opik setup example (#3940)
    * docs(observability): add Comet Opik setup example
    
    * Update README.md
  • 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: 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: 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: (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 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: 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>
  • Python: Quick Redis sample fix (#4066)
    * REDIS URL fix
    
    * copilot fix
  • Python: Fix Redis samples for session migration and configurable REDIS_URL (#4060)
    * fix: update Redis samples for session migration and configurable REDIS_URL
    
    - Replace hardcoded redis://localhost:6379 with configurable REDIS_URL env var
    - Fix SessionContext usage: use input_messages kwarg instead of removed extend_messages
    - Remove obsolete scope_to_per_operation_thread_id parameter
    - Remove stale commented-out overwrite_redis_index/drop_redis_index params
    
    Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
    
    * Remove docker commands from comments to avoid security scan flags
    
    Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
    
    ---------
    
    Co-authored-by: Copilot <223556219+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: Fixed declarative samples (#4051)
    * Updated declarative kind mapping
    
    * Fixed required property handling
    
    * Updated inline yaml sample
    
    * Fixed remaining declarative samples
    
    * Added lazy initialization for PowerFx engine
    
    * Small fix
  • 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>