22 Commits

  • Python: [BREAKING] Upgrade github-copilot-sdk to v1.0.0 (stable) (#6292)
    * Python: Upgrade github-copilot-sdk to v1.0.0 (stable)
    
    Upgrade agent-framework-github-copilot from github-copilot-sdk 1.0.0b2 to the
    stable 1.0.0 release, adapting to all breaking API changes.
    
    Source changes (_agent.py):
    - SubprocessConfig removed: use RuntimeConnection.for_stdio(path=...) +
      CopilotClient kwargs (connection, log_level, base_directory)
    - Import paths: copilot.generated.session_events -> copilot.session_events
    - Settings: copilot_home -> base_directory (env GITHUB_COPILOT_BASE_DIRECTORY)
    - Default deny handler: PermissionDecisionUserNotAvailable() (from
      copilot.generated.rpc)
    
    Test changes:
    - Updated imports and client-construction assertions (kwargs-based)
    - Permission handler tests use concrete decision types
      (PermissionDecisionApproveOnce, PermissionDecisionDeniedInteractivelyByUser)
    
    Sample changes:
    - Permission handlers use PermissionHandler.approve_all or sync
      approve_and_log pattern (v1.0.0 protocol v3 dispatch is incompatible
      with blocking input() in permission handlers)
    - Function approval sample uses asyncio.to_thread for interactive prompts
    - Simplified imports across all samples
    
    Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
    
    * Address PR review: scope permission handlers, widen type, add test
    
    - Shell sample: only approve kind='shell', deny others
    - URL sample: only approve kind='url', deny others
    - Use getattr() for kind-specific attributes to satisfy pyright
    - Widen PermissionHandlerType to accept async handlers (matches SDK)
    - Add test for _deny_all_permissions return value
    
    Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
    
    * Fix validation script and strengthen test assertion
    
    - Update scripts/sample_validation/create_dynamic_workflow_executor.py to
      use copilot.session_events imports and PermissionHandler.approve_all
    - Assert isinstance(result, PermissionDecisionUserNotAvailable) instead of
      stringly-typed kind check
    
    Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
    
    * Add integration tests for GitHubCopilotAgent
    
    Add 6 integration tests mirroring .NET coverage:
    - Basic non-streaming response
    - Streaming response
    - Function tool invocation
    - Session context (multi-turn)
    - Session resume by ID
    - Shell command execution
    
    Tests require COPILOT_GITHUB_TOKEN env var (skipped otherwise).
    Each test cleans up its Copilot session via delete_session.
    
    Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
    
    ---------
    
    Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
  • Python: Fix GitHubCopilotAgent to include tools added by ContextProvider.before_run in session creation (#5780)
    * Fix GitHubCopilotAgent ignoring tools from context providers (#5736)
    
    _create_session and _resume_session only forwarded self._tools (constructor
    tools) to CopilotClient.create_session, dropping any tools contributed by
    context providers via session_context.extend_tools() during before_run.
    
    Merge provider-contributed tools into runtime_options in both _run_impl and
    _stream_updates before session creation, mirroring how RawAgent handles the
    merge at lines 1435-1440 in _agents.py. Update _create_session and
    _resume_session to combine self._tools with the merged runtime tools.
    
    Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
    
    * Python: Fix GitHubCopilotAgent to include tools added by ContextProvider.before_run in session creation
    
    Fixes #5736
    
    * Fix provider tool merge to avoid mutating caller's list
    
    - Replace in-place .extend() with fresh list creation in both
      _run_impl and _stream_updates paths to prevent mutating the
      caller-provided options['tools'] list (shallow copy issue)
    - Also handles immutable Sequence types (e.g. tuple) correctly
    - Add test for provider tools forwarded via _resume_session path
    
    Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
    
    * Address review feedback for #5736: review comment fixes
    
    ---------
    
    Co-authored-by: Copilot <copilot@github.com>
    Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
  • Python: Upgrade github-copilot-sdk to v1.0.0b2 with new features (#5665)
    * Upgrade github-copilot-sdk to v1.0.0b1 and implement new features
    
    - Bump github-copilot-sdk dependency from 0.2.1 to 1.0.0b1
    - Fix breaking type renames: ErrorClass -> ToolExecutionCompleteError,
      Result -> ToolExecutionCompleteResult
    - Add instruction_directories support in GitHubCopilotOptions (session-level)
    - Add copilot_home support in GitHubCopilotSettings (client-level)
    - Add sample: github_copilot_with_instruction_directories.py
    - Update README with new env var and sample entry
    - Add 8 new unit tests covering the new features (103 total, 96% coverage)
    
    Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
    
    * mypy fix
    
    * small fix
    
    * Address PR feedback: fix resume path, remove copilot_home from Options, bump to beta.2
    
    - Forward runtime_options through _resume_session (fixes silent drop of
      instruction_directories/model/etc on resumed sessions)
    - Remove copilot_home from GitHubCopilotOptions (client-level setting only
      consumed at startup, not per-call)
    - Bump github-copilot-sdk from 1.0.0b1 to 1.0.0b2
    - Add test for instruction_directories override on resumed sessions
    - Update existing resume test to match new _resume_session signature
    
    Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
    
    ---------
    
    Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
  • Python: Enforce approval_mode in Claude and GitHub Copilot agents (#5562)
    * Python: Enforce approval_mode in Claude and GitHub Copilot agents
    
    Tools declared with approval_mode="always_require" were bypassed by the
    ClaudeAgent and GitHubCopilotAgent because their SDK-managed tool-calling
    loops invoke FunctionTool.invoke() directly via package-supplied handlers,
    skipping the standard _try_execute_function_calls approval gate.
    
    Per discussion on #5494, the fix lives in the agents (not in FunctionTool):
    any flag added to the tool itself can be spoofed by code with the same
    level of access, so the security boundary is the agent that owns the
    tool-calling loop.
    
    - Add on_function_approval option to ClaudeAgentOptions and
      GitHubCopilotOptions. Callback receives a FunctionCallContent describing
      the pending call and returns bool (sync or async).
    - Gate FunctionTool.invoke() inside each agent's existing tool-handler
      closure when approval_mode == "always_require". Default policy is deny;
      callbacks that raise also deny safely.
    - Deny path returns a tool-error to the model (Claude: text content;
      Copilot: ToolResult(result_type="failure", error="approval_denied"))
      so the LLM can react gracefully instead of silently failing.
    - Tests for both agents covering: deny by default, sync False, sync True,
      async True, callback-raises -> deny, no-op for never_require tools.
    - Samples demonstrating sync, async, and deny-by-default flows for both
      agents.
    
    Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
    
    * Address PR review: preserve empty arg dicts, reject runtime approval override
    
    - _resolve_function_approval no longer collapses {} into None when building
      the FunctionCallContent passed to the callback (Claude + Copilot).
    - Claude _apply_runtime_options and Copilot _run_impl/_stream_updates now
      raise ValueError if on_function_approval is supplied via per-run options,
      instead of silently ignoring it. Approval policy must be set at agent
      construction time.
    - Drop unnecessary # type: ignore[attr-defined] on Content.name/.arguments
      in samples (Content is a unified class with both attributes defined).
    - Add regression tests for the new runtime-options validation.
    
    Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
    
    * warning when non callback handler and approval needed
    
    ---------
    
    Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
  • Python: Bump Python package versions for 1.2.0 release (#5468)
    * Bump Python package versions for 1.2.0 release
    
    Released tier bumps 1.1.1 -> 1.2.0 (core, openai, foundry, root) to
    reflect additive public APIs landed since 1.1.0: functional workflow API
    (#4238) and FunctionTool SKIP_PARSING sentinel (#5424). All beta packages
    stamped 1.0.0b260424, alpha packages 1.0.0a260424. All 26 non-core
    agent-framework-core floors raised to >=1.2.0,<2. CHANGELOG consolidates
    the never-tagged 1.1.1 entries with the post-merge additions into [1.2.0].
    
    * Update CHANGELOG footer links for 1.2.0
    
    Advance [Unreleased] comparison base from python-1.1.0 to python-1.2.0
    and add a [1.2.0] reference link comparing python-1.1.0...python-1.2.0
    so the heading links resolve correctly.
    
    * Fix CHANGELOG: restore [1.1.1] section and add proper [1.2.0]
    
    Previous commit incorrectly renamed the [1.1.1] header to [1.2.0], which
    wiped the historical 1.1.1 entries and wrongly attributed them to 1.2.0.
    This restores [1.1.1] to its origin/main content and adds a new [1.2.0]
    section above containing only the commits in python-1.1.1..HEAD:
    
    - #4238 functional workflow API
    - #5142 GitHub Copilot OpenTelemetry
    - #2403 A2A bridge support
    - #5070 oauth_consent_request events in Foundry clients
    - #5447 FoundryAgent hosted agent sessions
    - #5459 hosting server dependency upgrade + types
    - #5389 AG-UI reasoning/multimodal parsing fix
    - #5440 stop [TOOLBOXES] warning spam
    - #5455 user agent prefix fix
    
    Also corrects the [1.2.0] compare base to python-1.1.1 (not 1.1.0) and
    adds the missing [1.1.1] reference link.
  • Python: Add OpenTelemetry integration for GitHubCopilotAgent (#5142)
    * Python: Add OpenTelemetry integration for GitHubCopilotAgent
    
    - Split GitHubCopilotAgent into RawGitHubCopilotAgent (core, no OTel) and
      GitHubCopilotAgent(AgentTelemetryLayer, RawGitHubCopilotAgent) with tracing
    - Add default_options property to expose model for span attributes
    - Export RawGitHubCopilotAgent from all public namespaces
    - Add github_copilot_with_observability.py sample and update README
    
    * Python: Fix OTEL_SERVICE_NAME default in GitHub Copilot README
    
    Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
    
    * Python: Add unit tests for RawGitHubCopilotAgent.default_options property
    
    * Python: Address review feedback on GitHubCopilotAgent OTel integration
    
    - Add middleware param to GitHubCopilotAgent.run() overloads so per-call
      middleware is explicitly forwarded through AgentTelemetryLayer
    - Remove github_copilot_with_observability.py sample per feedback; replace
      with inline snippet + link to observability samples in README
    
    * Python: Address review feedback on log_level and session kwargs typing
    
    - Add middleware param to RawGitHubCopilotAgent.run() overloads for interface
      compatibility with AgentTelemetryLayer
    - Fix import in README observability snippet to use agent_framework.github
    
    * Python: Add AgentMiddlewareLayer to GitHubCopilotAgent MRO
    
    Follow FoundryAgent pattern: AgentMiddlewareLayer runs outside the telemetry
    span so middleware execution time is not captured in traces. Overloads removed
    as AgentMiddlewareLayer.run() handles dispatch via MRO.
    
    * Python: Add explicit __init__ to GitHubCopilotAgent for auto-complete and docstrings
    
    * Python: Address review feedback on middleware warning and test assertions
    
    - Add assert "timeout" not in opts to test_default_options_includes_model_for_telemetry
      to document the intentional asymmetry where timeout is extracted into _settings
      and not returned in default_options.
    - Replace silent del middleware with a logged warning when per-run middleware is
      passed to RawGitHubCopilotAgent, making it clear that the GitHub Copilot SDK
      handles tool execution internally and chat/function middleware cannot be injected.
    
    * Python: Use Self for __aenter__ return type in RawGitHubCopilotAgent
    
    Address review feedback: use typing.Self (3.11+) / typing_extensions.Self
    (3.10) for __aenter__ so subclasses like GitHubCopilotAgent get the correct
    return type from async context manager usage.
    
    ---------
    
    Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
  • Python: Migrate GitHub Copilot package to SDK 0.2.x (#5107)
    * Python: Migrate GitHub Copilot package to SDK 0.2.x
    
    Replace all imports from the non-existent copilot.types module with
    correct SDK 0.2.x module paths (copilot.session, copilot.client,
    copilot.tools, copilot.generated.session_events). Fix PermissionRequest
    attribute access from dict-style .get() to dataclass attribute access.
    Add OTel telemetry support to Copilot samples via configure_otel_providers
    and document new telemetry environment variables in samples README.
    
    * Python: Fix remaining copilot.types import in sample validation script
    
    * Python: Include model in default_options for telemetry span attributes
    
    * Python: Address review feedback on log_level and session kwargs typing
    
    * Python: Scope PR to SDK 0.2.x migration only, remove net-new OTel features
    
    - Remove RawGitHubCopilotAgent split and AgentTelemetryLayer inheritance
    - Remove TelemetryConfig plumbing and OTLP/file telemetry settings
    - Remove configure_otel_providers() calls from samples
    - Remove telemetry env var rows from samples README
    - Retain only: import path fixes, PermissionRequest attribute access fix,
      log_level default fix, session kwargs typed fix, dependency pin
    
    * Python: Update tests for SDK 0.2.x API changes
    
    - SubprocessConfig replaces CopilotClientOptions dict
    - create_session and resume_session now use keyword args
    - send and send_and_wait take plain string prompt instead of MessageOptions
    - on_permission_request is always required; deny-all fallback replaces omission
    
    * Python: Pin github-copilot-sdk to >=0.2.0,<=0.2.0
    
    Tighten the upper bound from <0.3.0 to <=0.2.0 to avoid pulling in 0.2.1+
    which has breaking API changes relative to 0.2.0. The lower bound stays at
    >=0.2.0 since this migration requires the 0.2.x import paths; 0.1.x would
    fail at import time.
    
    * Python: Pin github-copilot-sdk to >=0.2.1,<=0.2.1
    
    ---------
    
    Co-authored-by: Evan Mattson <35585003+moonbox3@users.noreply.github.com>
  • Python: Fix GitHubCopilotAgent to invoke context provider before_run/after_run hooks (#5013)
    * Fix GitHubCopilotAgent not calling context provider hooks (#3984)
    
    GitHubCopilotAgent accepted context_providers in its constructor but
    never called before_run()/after_run() on them in _run_impl() or
    _stream_updates(), silently ignoring all context providers.
    
    Add _run_before_providers() helper to create SessionContext and invoke
    before_run on each provider. Both _run_impl() and _stream_updates() now
    run the full provider lifecycle: before_run before sending the prompt
    (with provider instructions prepended) and after_run after receiving the
    response. This follows the same pattern used by A2AAgent.
    
    Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
    
    * Python: Fix GitHubCopilotAgent to invoke context provider before_run/after_run hooks
    
    Fixes #3984
    
    * fix(#3984): address review feedback for context provider integration
    
    - Build prompt from session_context.get_messages(include_input=True) so
      provider-injected context_messages are included in both non-streaming
      and streaming paths (review comments #1, #2)
    - Preserve timeout in opts (use get instead of pop) so providers can
      observe it via context.options (review comment #3)
    - Eliminate streaming double-buffer: move after_run invocation to a
      ResponseStream result_hook (matching Agent class pattern) instead of
      maintaining a separate updates list in the generator (review comment #4)
    - Improve _run_before_providers docstring
    
    Add tests for:
    - Context messages included in prompt (non-streaming + streaming)
    - Error path: after_run NOT called when send_and_wait/streaming raises
    - Multiple providers: forward before_run, reverse after_run ordering
    - BaseHistoryProvider with load_messages=False is skipped
    - Streaming after_run response contains aggregated updates
    - Streaming with no updates still sets empty response
    - Timeout preserved in session context options for providers
    
    Note: _run_before_providers remains on GitHubCopilotAgent for now. A
    follow-up PR should extract it to BaseAgent so subclasses can reuse it
    without duplicating the provider iteration logic.
    
    Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
    
    * Address review feedback for #3984: Python: [Bug]: GitHubCopilotAgent Memory Example
    
    * refactor(#3984): promote _run_before_providers to BaseAgent
    
    Move _run_before_providers from GitHubCopilotAgent into BaseAgent,
    mirroring the existing _run_after_providers helper. Agent's
    _prepare_session_and_messages now delegates to the shared base method,
    eliminating the near-duplicate provider iteration logic that could
    drift as the provider contract evolves.
    
    Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
    
    * Address review feedback for #3984: Python: [Bug]: GitHubCopilotAgent Memory Example
    
    * revert: keep _run_before_providers in GitHubCopilotAgent only
    
    Undo the promotion of _run_before_providers to BaseAgent. The method
    stays in GitHubCopilotAgent where it is needed, and _agents.py
    retains its original inline provider iteration in RawAgent.
    
    Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
    
    * fix: replace deprecated BaseContextProvider/BaseHistoryProvider with ContextProvider/HistoryProvider
    
    Update imports and usages in GitHubCopilotAgent and its tests to use
    the new non-deprecated class names from the core package.
    
    Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
    
    * fix: address review feedback - reorder providers before session, wrap streaming after_run in try/except, assert after_run on skipped HistoryProvider
    
    - Move _run_before_providers before _get_or_create_session so provider
      contributions can affect session configuration
    - Wrap _run_after_providers in try/except in streaming _after_run_hook
      to prevent provider errors from replacing successful responses
    - Add after_run assertion to test_history_provider_skip_when_load_messages_false
    
    Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
    
    ---------
    
    Co-authored-by: Copilot <copilot@github.com>
    Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
  • Python: Emit tool call events in GitHubCopilotAgent streaming (#4711)
    * Emit tool call events in GitHubCopilotAgent streaming
    
    _stream_updates now yields FunctionCallContent for TOOL_EXECUTION_START
    and FunctionResultContent for TOOL_EXECUTION_COMPLETE events from the
    Copilot SDK session. This enables DevUI and other consumers to display
    tool calls during streaming agent execution. Previously only ASSISTANT_MESSAGE_DELTA, SESSION_IDLE, and SESSION_ERROR
    were handled — tool execution events were silently dropped.
    
    Signed-off-by: James Sturtevant <jsturtevant@gmail.com>
    
    * Add some tests
    
    Signed-off-by: James Sturtevant <jsturtevant@gmail.com>
    
    * Respond to feedback
    
    Signed-off-by: James Sturtevant <jsturtevant@gmail.com>
    
    * Fix TOOL_EXECUTION_COMPLETE to use correct SDK types
    
    - Read result text from session_events.Result.content (not ToolResult.text_result_for_llm)
    - Read failure state from event.data.success/error (not result_obj.result_type/error)
    - Handle ErrorClass.message and plain string errors
    - Update tests to use session_events.Result and ErrorClass
    - Add tests for string errors, success-with-error, and COMPLETE missing fields
    
    Signed-off-by: James Sturtevant <jsturtevant@gmail.com>
    
    ---------
    
    Signed-off-by: James Sturtevant <jsturtevant@gmail.com>
  • Python: chore(python): improve dependency range automation (#4343)
    * chore(python): improve dependency range automation
    
    - tighten dependency bounds and coding standards guidance\n- add dependency range validation workflow, reporting, and issue automation\n- update related tests and dependency pins for compatibility
    
    Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
    
    * updated text and pyarrow
    
    * new lock
    
    * fixed workflow
    
    * updated deps
    
    * fix tiktoken
    
    * chore(python): refine dependency validation workflows
    
    Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
    
    * docs(python): add high-level dependency validation comments
    
    Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
    
    * WIP
    
    * added additional comments and excludes
    
    * added dev dependency handling and workflow and updates to package ranges
    
    * added readme and simplified commands
    
    * fix markers
    
    * chore(python): address dependency review feedback
    
    Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
    
    * Tighten dependency bounds, remove stale overrides, restore Python 3.10 support
    
    - Apply dependency bound policy across all packages: stable >=1.0 deps use
      >=floor,<next_major; pre-1.0/prerelease deps use validated hard-bounded ranges
    - Remove stale root tool.uv.override-dependencies (uvicorn, websockets, grpcio)
    - Lower github_copilot requires-python to >=3.10 with github-copilot-sdk gated
      behind python_version >= 3.11 marker; import raises ImportError on 3.10
    - Skip github_copilot pyright/mypy/test tasks on Python <3.11
    - Use version-conditional pyrightconfig for samples on Python 3.10
    - Add compatibility fix in core responses client for older openai typed dicts
    - Normalize uv.lock prerelease mode and refresh dev dependencies
    - Update CODING_STANDARD.md, DEV_SETUP.md, and package management skill docs
    
    Closes #902
    
    Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
    
    * small tweaks
    
    * add note in workflow
    
    * fix workflows and several versions
    
    * fix duplicate
    
    ---------
    
    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: [BREAKING] Redesign Python exception hierarchy (#4082)
    * [BREAKING] Redesign Python exception hierarchy
    
    Replace the flat ServiceException family with domain-scoped branches:
    - AgentException (with InvalidAuth, InvalidRequest, InvalidResponse, ContentFilter)
    - ChatClientException (same consistent suberrors)
    - IntegrationException (same + InitializationError)
    - WorkflowException (Runner, Convergence, Checkpoint, Validation, Action, Declarative)
    - ContentError (AdditionItemMismatch)
    - ToolException / ToolExecutionException (unchanged)
    - MiddlewareException / MiddlewareTermination (unchanged)
    
    Key changes:
    - All Service* exceptions removed (ServiceException, ServiceInitializationError, etc.)
    - AgentExecutionException split into AgentInvalidRequest/ResponseException
    - AgentInvocationError removed, split into AgentInvalidRequest/ResponseException
    - Workflow exceptions moved from _workflows/_exceptions.py into main exceptions.py
    - _workflows/__init__.py emptied; main __init__.py imports directly from submodules
    - Purview exceptions re-parented under IntegrationException hierarchy
    - Init validation errors use built-in ValueError/TypeError instead of custom exceptions
    - CODING_STANDARD.md updated with hierarchy design and rationale
    
    Fixes microsoft/agent-framework#3410
    
    Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
    
    * Clarify ToolException vs ToolExecutionException docstrings
    
    ToolException: base class for all tool-related exceptions (preconditions,
    connection/init failures).
    ToolExecutionException: runtime call failures (tool call failed, reconnect
    failed, MCP errors).
    
    Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
    
    * Fix remaining stale imports from agent_framework._workflows
    
    - azurefunctions: _context.py, _app.py, _serialization.py, test_func_utils.py
      used 'from agent_framework._workflows import X' which broke after
      emptying _workflows/__init__.py; changed to direct submodule imports
    - azure-ai-search: test still referenced ServiceInitializationError;
      updated to ValueError to match production code
    
    Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
    
    ---------
    
    Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
  • Python: [BREAKING] PR2 — Wire context provider pipeline, remove old types, update all consumers (#3850)
    * PR2: Wire context provider pipeline and update all internal consumers
    
    - Replace AgentThread with AgentSession across all packages
    - Replace ContextProvider with BaseContextProvider across all packages
    - Replace context_provider param with context_providers (Sequence)
    - Replace thread= with session= in run() signatures
    - Replace get_new_thread() with create_session()
    - Add get_session(service_session_id) to agent interface
    - DurableAgentThread -> DurableAgentSession
    - Remove _notify_thread_of_new_messages from WorkflowAgent
    - Wire before_run/after_run context provider pipeline in RawAgent
    - Auto-inject InMemoryHistoryProvider when no providers configured
    
    * fix: update all tests for context provider pipeline, fix lazy-loaders, remove old test files
    
    * refactor: update all sample files for context provider pipeline (AgentThread→AgentSession, ContextProvider→BaseContextProvider)
    
    * fix: update remaining ag-ui references (client docstring, getting_started sample)
    
    * fix: make get_session service_session_id keyword-only to avoid confusion with session_id
    
    * refactor: rename _RunContext.thread_messages to session_messages
    
    * refactor: remove _threads.py, _memory.py, and old provider files; migrate devui to use plain message lists
    
    * rename: remove _new_ prefix from test files
    
    * refactor: rewrite SlidingWindowChatMessageStore as SlidingWindowHistoryProvider(InMemoryHistoryProvider)
    
    * fix: read full history from session state directly instead of reaching into provider internals
    
    * fix: update stale .pyi stubs, sample imports, and README references for new provider types
    
    * fix: remove stale message_store, _notify_thread_of_new_messages, and session_id.key references in samples
    
    * refactor: merge context_providers and sessions sample folders into sessions, remove aggregate_context_provider
    
    * refactor: UserInfoMemory stores state in session.state instead of instance attributes
    
    * feat: add Pydantic BaseModel support to session state serialization
    
    Pydantic models stored in session.state are now automatically serialized
    via model_dump() and restored via model_validate() during to_dict()/from_dict()
    round-trips. Models are auto-registered on first serialization; use
    register_state_type() for cold-start deserialization.
    
    Also export register_state_type as a public API.
    
    * fix mem0
    
    * Update sample README links and descriptions for session terminology
    
    - Replace 'thread' with 'session' in sample descriptions across all READMEs
    - Update file links for renamed samples (mem0_sessions, redis_sessions, etc.)
    - Fix Threads section → Sessions section in main samples/README.md
    - Update tools, middleware, workflows, durabletask, azure_functions READMEs
    - Update architecture diagrams in concepts/tools/README.md
    - Update migration guides (autogen, semantic-kernel)
    
    * Fix broken Redis README link to renamed sample
    
    * Fix Mem0 OSS client search: pass scoping params as direct kwargs
    
    AsyncMemory (OSS) expects user_id/agent_id/run_id as direct kwargs,
    while AsyncMemoryClient (Platform) expects them in a filters dict.
    Adds tests for both client types.
    
    Port of fix from #3844 to new Mem0ContextProvider.
    
    * Fix rebase issues: restore missing _conversation_state.py and checkpoint decode logic
    
    - Add back _conversation_state.py (encode/decode_chat_messages) lost in rebase
    - Fix on_checkpoint_restore to decode cache/conversation with decode_chat_messages
    - Fix on_checkpoint_restore to use decode_checkpoint_value for pending requests
    - Add tests/workflow/__init__.py for relative import support
    - Fix test_agent_executor checkpoint selection (checkpoints[1] not superstep)
    
    * Add STORES_BY_DEFAULT ClassVar to skip redundant InMemoryHistoryProvider injection
    
    Chat clients that store history server-side by default (OpenAI Responses API,
    Azure AI Agent) now declare STORES_BY_DEFAULT = True. The agent checks this
    during auto-injection and skips InMemoryHistoryProvider unless the user
    explicitly sets store=False.
    
    * Fix broken markdown links in azure_ai and redis READMEs
    
    * Fix getting-started samples to use session API instead of removed thread/ContextProvider API
    
    * updates to workflow as agent
    
    * fix group chat import
    
    * Rename Thread→Session throughout, fix service_session_id propagation, remove stale AGUIThread
    
    - Fix: Propagate conversation_id from ChatResponse back to session.service_session_id
      in both streaming and non-streaming paths in _agents.py
    - Rename AgentThreadException → AgentSessionException
    - Remove stale AGUIThread from ag_ui lazy-loader
    - Rename use_service_thread → use_service_session in ag-ui package
    - Rename test functions from *_thread_* to *_session_*
    - Rename sample files from *_thread* to *_session*
    - Update docstrings and comments: thread → session
    - Update _mcp.py kwargs filter: add 'session' alongside 'thread'
    - Fix ContinuationToken docstring example: thread=thread → session=session
    - Fix _clients.py docstring: 'Agent threads' → 'Agent sessions'
    
    * Fix broken markdown links after thread→session file renames
    
    * fix azure ai test
  • Python: Replace Pydantic Settings with TypedDict + load_settings() (#3843)
    * Replace Pydantic Settings with TypedDict + load_settings()
    
    - Remove pydantic-settings dependency, add python-dotenv
    - Delete _pydantic.py (AFBaseSettings, HTTPsUrl)
    - Add _settings.py with generic load_settings() function, SecretString,
      type coercion, and Required field validation (SettingNotFoundError)
    - Convert all 13 settings classes from AFBaseSettings subclasses to
      TypedDict definitions with load_settings() calls
    - Update all consumers from attribute access to dict access
    - Add 20 unit tests for load_settings() covering basic loading, dotenv,
      SecretString, type coercion, and required field validation
    - Update all existing tests for new settings patterns
    
    * Fix mypy type errors from settings conversion
    
    - Fix str | None attribute access in responses_client (walrus operator)
    - Fix SecretString | None narrowing in bedrock (type: ignore after guard)
    - Convert _context_provider.py attribute access to dict access (missed file)
    - Fix endpoint type narrowing in search_provider and context_provider
    - Fix purview: str | None .rstrip(), int | None defaults, urlparse bytes
    
    * Address PR review: required_fields param, type validation, fixes
    
    - Move required field validation from TypedDict annotations (Required)
      to a required_fields parameter on load_settings(), enabling runtime
      decisions about which fields are required
    - Remove Required imports and restore from __future__ import annotations
      in ollama and foundry_local
    - Add _check_override_type() for deterministic ServiceInitializationError
      on invalid override types (e.g. dict passed for str field)
    - Fix all multi-exception test catches back to single exception type
    - Fix Ollama host=None: use .get() so None is passed through to SDK default
    - Fix Purview processor: use explicit is-None checks instead of or operator
    - Remove unused BaseModel import from openai/_shared.py
    - Add 4 new tests (24 total): required_fields param, type validation
    
    * Fix type validation: allow int for float fields
    
    _check_override_type now permits int values for float-typed fields,
    matching Python's standard numeric promotion behavior.
    
    * fix: wrap urlparse arg with str() to fix mypy bytes endswith error
  • Python: [BREAKING] Simplify API: ChatAgent -> Agent, ChatMessage -> Message (#3747)
    * [BREAKING] Rename ChatAgent -> Agent, ChatMessage -> Message, ChatClientProtocol -> SupportsChatGetResponse
    
    Simplify the public API by removing redundant 'Chat' prefix from core types:
    - ChatAgent -> Agent
    - RawChatAgent -> RawAgent
    - ChatMessage -> Message
    - ChatClientProtocol -> SupportsChatGetResponse
    
    Also renamed internal WorkflowMessage (was Message in _runner_context) to avoid collision.
    
    No backward compatibility aliases - this is a clean breaking change.
    
    * [BREAKING] Rename Agent chat_client parameter to client
    
    * Fix rebase issues: WorkflowMessage references and broken markdown links
    
    * Fix formatting and lint issues from code quality checks
    
    * Fix import ordering in workflow sample files
    
    * fixed rebase
    
    * Fix test failures: use WorkflowMessage and A2AMessage after ChatMessage→Message rename
    
    - Replace Message(data=..., source_id=...) with WorkflowMessage(...) in workflow tests
    - Fix isinstance check in A2A agent to use A2AMessage instead of Message
    - Fix import in test_workflow_observability.py (Message→WorkflowMessage)
    
    * Fix lint, fmt, and sample errors after ChatMessage→Message rename
    
    - Auto-fix 70+ ruff lint issues across samples (ChatMessage→Message refs)
    - Fix HostedVectorStoreContent→Content.from_hosted_vector_store in file search sample
    - Fix _normalize_messages→normalize_messages in custom agent sample
    - Fix context.terminate→raise MiddlewareTermination in middleware samples
    - Fix with_update_hook→with_transform_hook in override middleware sample
    - Add TOptions_co import back to custom_chat_client sample
    - Add noqa for FastAPI File() default in chatkit sample
    - Fix B023 loop variable capture in weather agent sample
    
    * fix: update Agent constructor calls from chat_client to client in declaration-only tool tests
    
    * fix: add register_cleanup to devui lazy-loading proxy and type stub
    
    * fixed tests and updated new pieces
    
    * fix agui typevar
    
    * fix merge errors
    
    * fix merge conflicts
    
    * fiux merge
    
    * Remove unused links
    
    ---------
    
    Co-authored-by: Evan Mattson <evan.mattson@microsoft.com>
  • Python: [BREAKING] Moved to a single get_response and run API (#3379)
    * WIP
    
    * big update to new ResponseStream model
    
    * fixed tests and typing
    
    * fixed tests and typing
    
    * fixed tools typevar import
    
    * fix
    
    * mypy fix
    
    * mypy fixes and some cleanup
    
    * fix missing quoted names
    
    * and client
    
    * fix  imports agui
    
    * fix anthropic override
    
    * fix agui
    
    * fix ag ui
    
    * fix import
    
    * fix anthropic types
    
    * fix mypy
    
    * refactoring
    
    * updated typing
    
    * fix 3.11
    
    * fixes
    
    * redid layering of chat clients and agents
    
    * redid layering of chat clients and agents
    
    * Fix lint, type, and test issues after rebase
    
    - Add @overload decorators to AgentProtocol.run() for type compatibility
    - Add missing docstring params (middleware, function_invocation_configuration)
    - Fix TODO format (TD002) by adding author tags
    - Fix broken observability tests from upstream:
      - Replace non-existent use_instrumentation with direct instantiation
      - Replace non-existent use_agent_instrumentation with AgentTelemetryLayer mixin
      - Fix get_streaming_response to use get_response(stream=True)
      - Add AgentInitializationError import
      - Update streaming exception tests to match actual behavior
    
    * Fix AgentExecutionException import error in test_agents.py
    
    - Replace non-existent AgentExecutionException with AgentRunException
    
    * Fix test import and asyncio deprecation issues
    
    - Add 'tests' to pythonpath in ag-ui pyproject.toml for utils_test_ag_ui import
    - Replace deprecated asyncio.get_event_loop().run_until_complete with asyncio.run
    
    * Fix azure-ai test failures
    
    - Update _prepare_options patching to use correct class path
    - Fix test_to_azure_ai_agent_tools_web_search_missing_connection to clear env vars
    
    * Convert ag-ui utils_test_ag_ui.py to conftest.py
    
    - Move test utilities to conftest.py for proper pytest discovery
    - Update all test imports to use conftest instead of utils_test_ag_ui
    - Remove old utils_test_ag_ui.py file
    - Revert pythonpath change in pyproject.toml
    
    * fix: use relative imports for ag-ui test utilities
    
    * fix agui
    
    * Rename Bare*Client to Raw*Client and BaseChatClient
    
    - Renamed BareChatClient to BaseChatClient (abstract base class)
    - Renamed BareOpenAIChatClient to RawOpenAIChatClient
    - Renamed BareOpenAIResponsesClient to RawOpenAIResponsesClient
    - Renamed BareAzureAIClient to RawAzureAIClient
    - Added warning docstrings to Raw* classes about layer ordering
    - Updated README in samples/getting_started/agents/custom with layer docs
    - Added test for span ordering with function calling
    
    * Fix layer ordering: FunctionInvocationLayer before ChatTelemetryLayer
    
    This ensures each inner LLM call gets its own telemetry span, resulting in
    the correct span sequence: chat -> execute_tool -> chat
    
    Updated all production clients and test mocks to use correct ordering:
    - ChatMiddlewareLayer (first)
    - FunctionInvocationLayer (second)
    - ChatTelemetryLayer (third)
    - BaseChatClient/Raw...Client (fourth)
    
    * Remove run_stream usage
    
    * Fix conversation_id propagation
    
    * Python: Add BaseAgent implementation for Claude Agent SDK (#3509)
    
    * Added ClaudeAgent implementation
    
    * Updated streaming logic
    
    * Small updates
    
    * Small update
    
    * Fixes
    
    * Small fix
    
    * Naming improvements
    
    * Updated imports
    
    * Addressed comments
    
    * Updated package versions
    
    * Update Claude agent connector layering
    
    * fix test and plugin
    
    * Store function middleware in invocation layer
    
    * Fix telemetry streaming and ag-ui tests
    
    * Remove legacy ag-ui tests folder
    
    * updates
    
    * Remove terminate flag from FunctionInvocationContext, use MiddlewareTermination instead
    
    - Remove terminate attribute from FunctionInvocationContext
    - Add result attribute to MiddlewareTermination to carry function results
    - FunctionMiddlewarePipeline.execute() now lets MiddlewareTermination propagate
    - _auto_invoke_function captures context.result in exception before re-raising
    - _try_execute_function_calls catches MiddlewareTermination and sets should_terminate
    - Fix handoff middleware to append to chat_client.function_middleware directly
    - Update tests to use raise MiddlewareTermination instead of context.terminate
    - Add middleware flow documentation in samples/concepts/tools/README.md
    - Fix ag-ui to use FunctionMiddlewarePipeline instead of removed create_function_middleware_pipeline
    
    * fix: remove references to removed terminate flag in purview tests, add type ignore
    
    * fix: move _test_utils.py from package to test folder
    
    * fix: call get_final_response() to trigger context provider notification in streaming test
    
    * fix: correct broken links in tools README
    
    * docs: clarify default middleware behavior in summary table
    
    * fix: ensure inner stream result hooks are called when using map()/from_awaitable()
    
    * Fix mypy type errors
    
    * Address PR review comments on observability.py
    
    - Remove TODO comment about unconsumed streams, add explanatory note instead
    - Remove redundant _close_span cleanup hook (already called in _finalize_stream)
    - Clarify behavior: cleanup hooks run after stream iteration, if stream is not
      consumed the span remains open until garbage collected
    
    * Remove gen_ai.client.operation.duration from span attributes
    
    Duration is a metrics-only attribute per OpenTelemetry semantic conventions.
    It should be recorded to the histogram but not set as a span attribute.
    
    * Remove duration from _get_response_attributes, pass directly to _capture_response
    
    Duration is a metrics-only attribute. It's now passed directly to _capture_response
    instead of being included in the attributes dict that gets set on the span.
    
    * Remove redundant _close_span cleanup hook in AgentTelemetryLayer
    
    _finalize_stream already calls _close_span() in its finally block,
    so adding it as a separate cleanup hook is redundant.
    
    * Use weakref.finalize to close span when stream is garbage collected
    
    If a user creates a streaming response but never consumes it, the cleanup
    hooks won't run. Now we register a weak reference finalizer that will close
    the span when the stream object is garbage collected, ensuring spans don't
    leak in this scenario.
    
    * Fix _get_finalizers_from_stream to use _result_hooks attribute
    
    Renamed function to _get_result_hooks_from_stream and fixed it to
    look for the _result_hooks attribute which is the correct name in
    ResponseStream class.
    
    * Add missing asyncio import in test_request_info_mixin.py
    
    * Fix leftover merge conflict marker in image_generation sample
    
    * Update integration tests
    
    * Fix integration tests: increase max_iterations from 1 to 2
    
    Tests with tool_choice options require at least 2 iterations:
    1. First iteration to get function call and execute the tool
    2. Second iteration to get the final text response
    
    With max_iterations=1, streaming tests would return early with only
    the function call/result but no final text content.
    
    * Fix duplicate function call error in conversation-based APIs
    
    When using conversation_id (for Responses/Assistants APIs), the server
    already has the function call message from the previous response. We
    should only send the new function result message, not all messages
    including the function call which would cause a duplicate ID error.
    
    Fix: When conversation_id is set, only send the last message (the tool
    result) instead of all response.messages.
    
    * Add regression test for conversation_id propagation between tool iterations
    
    Port test from PR #3664 with updates for new streaming API pattern.
    Tests that conversation_id is properly updated in options dict during
    function invocation loop iterations.
    
    * Fix tool_choice=required to return after tool execution
    
    When tool_choice is 'required', the user's intent is to force exactly one
    tool call. After the tool executes, return immediately with the function
    call and result - don't continue to call the model again.
    
    This fixes integration tests that were failing with empty text responses
    because with tool_choice=required, the model would keep returning function
    calls instead of text.
    
    Also adds regression tests for:
    - conversation_id propagation between tool iterations (from PR #3664)
    - tool_choice=required returns after tool execution
    
    * Document tool_choice behavior in tools README
    
    - Add table explaining tool_choice values (auto, none, required)
    - Explain why tool_choice=required returns immediately after tool execution
    - Add code example showing the difference between required and auto
    - Update flow diagram to show the early return path for tool_choice=required
    
    * Fix tool_choice=None behavior - don't default to 'auto'
    
    Remove the hardcoded default of 'auto' for tool_choice in ChatAgent init.
    When tool_choice is not specified (None), it will now not be sent to the
    API, allowing the API's default behavior to be used.
    
    Users who want tool_choice='auto' can still explicitly set it either in
    default_options or at runtime.
    
    Fixes #3585
    
    * Fix tool_choice=none should not remove tools
    
    In OpenAI Assistants client, tools were not being sent when
    tool_choice='none'. This was incorrect - tool_choice='none' means
    the model won't call tools, but tools should still be available
    in the request (they may be used later in the conversation).
    
    Fixes #3585
    
    * Add test for tool_choice=none preserving tools
    
    Adds a regression test to ensure that when tool_choice='none' is set but
    tools are provided, the tools are still sent to the API. This verifies
    the fix for #3585.
    
    * Fix tool_choice=none should not remove tools in all clients
    
    Apply the same fix to OpenAI Responses client and Azure AI client:
    - OpenAI Responses: Remove else block that popped tool_choice/parallel_tool_calls
    - Azure AI: Remove tool_choice != 'none' check when adding tools
    
    When tool_choice='none', the model won't call tools, but tools should
    still be sent to the API so they're available for future turns.
    
    Also update README to clarify tool_choice=required supports multiple tools.
    
    Fixes #3585
    
    * Keep tool_choice even when tools is None
    
    Move tool_choice processing outside of the 'if tools' block in OpenAI
    Responses client so tool_choice is sent to the API even when no tools
    are provided.
    
    * Update test to match new parallel_tool_calls behavior
    
    Changed test_prepare_options_removes_parallel_tool_calls_when_no_tools to
    test_prepare_options_preserves_parallel_tool_calls_when_no_tools to reflect
    that parallel_tool_calls is now preserved even when no tools are present,
    consistent with the tool_choice behavior.
    
    * Fix ChatMessage API and Role enum usage after rebase
    
    - Update ChatMessage instantiation to use keyword args (role=, text=, contents=)
    - Fix Role enum comparisons to use .value for string comparison
    - Add created_at to AgentResponse in error handling
    - Fix AgentResponse.from_updates -> from_agent_run_response_updates
    - Fix DurableAgentStateMessage.from_chat_message to convert Role enum to string
    - Add Role import where needed
    
    * Fix additional ChatMessage API and method name changes
    
    - Fix ChatMessage usage in workflow files (use text= instead of contents= for strings)
    - Fix AgentResponse.from_updates -> from_agent_run_response_updates in workflow files
    - Fix test files for ChatMessage and Role enum usage
    
    * Fix remaining ChatMessage API usage in test files
    
    * Fix more ChatMessage and Role API changes in source and test files
    
    - Fix ChatMessage in _magentic.py replan method
    - Fix Role enum comparison in test assertions
    - Fix remaining test files with old ChatMessage syntax
    
    * Fix ChatMessage and Role API changes across packages
    
    - Add Role import where missing
    - Fix ChatMessage signature: positional args to keyword args (role=, text=, contents=)
    - Fix Role enum comparisons: .role.value instead of .role string
    - Fix FinishReason enum usage in ag-ui event converters
    - Rename AgentResponse.from_updates to from_agent_run_response_updates in ag-ui
    
    Fixes API compatibility after Types API Review improvements merge
    
    * Fix ChatMessage and Role API changes in github_copilot tests
    
    * Fix ChatMessage and Role API changes in redis and github_copilot packages
    
    - Fix redis provider: Role enum comparison using .value
    - Fix redis tests: ChatMessage signature and Role comparisons
    - Fix github_copilot tests: ChatMessage signature and Role comparisons
    - Update docstring examples in redis chat message store
    
    * Fix ChatMessage and Role API changes in devui package
    
    - Fix executor: ChatMessage signature change
    - Fix conversations: Role enum to string conversion in two places
    - Fix tests: ChatMessage signatures and Role comparisons
    
    * Fix ChatMessage and Role API changes in a2a and lab packages
    
    - Fix a2a tests: Role comparisons and ChatMessage signatures
    - Fix lab tau2 source: Role enum comparison in flip_messages, log_messages, sliding_window
    - Fix lab tau2 tests: ChatMessage signatures and Role comparisons
    
    * Remove duplicate test files from ag-ui/tests (tests are in ag_ui_tests)
    
    * Fix ChatMessage and Role API changes across packages
    
    After rebasing on upstream/main which merged PR #3647 (Types API Review
    improvements), fix all packages to use the new API:
    
    - ChatMessage: Use keyword args (role=, text=, contents=) instead of
      positional args
    - Role: Compare using .value attribute since it's now an enum
    
    Packages fixed:
    - ag-ui: Fixed Role value extraction bugs in _message_adapters.py
    - anthropic: Fixed ChatMessage and Role comparisons in tests
    - azure-ai: Fixed Role comparison in _client.py
    - azure-ai-search: Fixed ChatMessage and Role in source/tests
    - bedrock: Fixed ChatMessage signatures in tests
    - chatkit: Fixed ChatMessage and Role in source/tests
    - copilotstudio: Fixed ChatMessage and Role in tests
    - declarative: Fixed ChatMessage in _executors_agents.py
    - mem0: Fixed ChatMessage and Role in source/tests
    - purview: Fixed ChatMessage in source/tests
    
    * Fix mypy errors for ChatMessage and Role API changes
    
    - durabletask: Use str() fallback in role value extraction
    - core: Fix ChatMessage in _orchestrator_helpers.py to use keyword args
    - core: Add type ignore for _conversation_state.py contents deserialization
    - ag-ui: Fix type ignore comments (call-overload instead of arg-type)
    - azure-ai-search: Fix get_role_value type hint to accept Any
    - lab: Move get_role_value to module level with Any type hint
    
    * Improve CI test timeout configuration
    
    - Increase job timeout from 10 to 15 minutes
    - Reduce per-test timeout to 60s (was 900s/300s)
    - Add --timeout_method thread for better timeout handling
    - Add --timeout-verbose to see which tests are slow
    - Reduce retries from 3 to 2 and delay from 10s to 5s
    
    This ensures individual test timeouts are shorter than the job
    timeout, providing better visibility when tests hang.
    
    With 60s timeout and 2 retries, worst case per test is ~180s.
    
    * Fix ChatMessage API usage in docstrings and source
    
    - Fix ChatMessage positional args in docstrings: _serialization.py, _threads.py, _middleware.py
    - Fix ChatMessage in tau2 runner.py
    - Fix role comparison in _orchestrator_helpers.py to use .value
    - Fix role comparison in _group_chat.py docstring example
    - Fix role assertions in test_durable_entities.py to use .value
    
    * Revert tool_choice/parallel_tool_calls changes - must be removed when no tools
    
    OpenAI API requires tool_choice and parallel_tool_calls to only be
    present when tools are specified. Restored the logic that removes
    these options when there are no tools.
    
    - Restored check in _chat_client.py to remove tool_choice and
      parallel_tool_calls when no tools present
    - Restored same logic in _responses_client.py
    - Reverted test to expect the correct behavior
    
    * fixed issue in tests
    
    * fix: resolve merge conflict markers in ag-ui tests
    
    * fix: restructure ag-ui tests and fix Role/FinishReason to use string types
    
    * fix: streaming function invocation and middleware termination
    
    - Refactor streaming function invocation to use get_final_response() on inner streams
    - Fix MiddlewareTermination to accept result parameter for passing results
    - Fix _AutoHandoffMiddleware to use MiddlewareTermination instead of context.terminate
    - Fix AgentMiddlewareLayer.run() to properly forward function/chat middleware
    - Remove duplicate middleware registration in AgentMiddlewareLayer.__init__
    - Fix exception handling in _auto_invoke_function to properly capture termination
    - Fix mypy errors in core package
    - Update tests to use stream=True parameter for unified run API
    
    * fix all tests command
    
    * Refactor integration tests to use pytest fixtures
    
    - Merge testutils.py into conftest.py for azurefunctions integration tests
    - Merge dt_testutils.py into conftest.py for durabletask integration tests
    - Convert all integration tests to use fixtures instead of direct imports
      (fixes ModuleNotFoundError with --import-mode=importlib)
    - Add sample_helper fixture for azurefunctions tests
    - Add agent_client_factory and orchestration_helper fixtures for durabletask
    - Integration tests now skip with descriptive messages when services unavailable
    - Restructure devui tests into tests/devui/ with proper conftest.py
    - Add test organization guidelines to CODING_STANDARD.md
    - Remove __init__.py from test directories per pytest best practices
    
    * Fix pytest_collection_modifyitems to only skip integration tests
    
    The hook was skipping all tests in the test session, not just
    integration tests. Now it only skips items in the integration_tests
    directory.
    
    * Fix mem0 tests failing on Python 3.13
    
    Use patch.object on the imported module instead of @patch with string
    path to ensure the mock takes effect regardless of import timing.
    
    * fix mem0
    
    * another attempt for mem0
    
    * fix for mem0
    
    * fix mem0
    
    * Increase worker initialization wait time in durabletask tests
    
    Increase from 2 to 8 seconds to allow time for:
    - Python startup and module imports
    - Azure OpenAI client creation
    - Agent registration with DTS worker
    - Worker connection to DTS
    
    This helps prevent test failures in CI where the first tests may run
    before the worker is fully ready to process requests.
    
    * Fix streaming test to use ResponseStream with finalizer
    
    The _consume_stream method now expects a ResponseStream that can provide
    a final AgentResponse via get_final_response(). Update the test to use
    ResponseStream with AgentResponse.from_updates as the finalizer.
    
    * Fix MockToolCallingAgent to use new ResponseStream API and update samples
    
    * small updates to run_stream to run
    
    * fix sub workflow
    
    * temp fix for az func test
    
    ---------
    
    Co-authored-by: Dmytro Struk <13853051+dmytrostruk@users.noreply.github.com>
  • Python: [BREAKING] Types API Review improvements (#3647)
    * Replace Role and FinishReason classes with NewType + Literal
    
    - Remove EnumLike metaclass from _types.py
    - Replace Role class with NewType('Role', str) + RoleLiteral
    - Replace FinishReason class with NewType('FinishReason', str) + FinishReasonLiteral
    - Update all usages across codebase to use string literals
    - Remove .value access patterns (direct string comparison now works)
    - Add backward compatibility for legacy dict serialization format
    - Update tests to reflect new string-based types
    
    Addresses #3591, #3615
    
    * Simplify ChatResponse and AgentResponse type hints (#3592)
    
    - Remove overloads from ChatResponse.__init__
    - Remove text parameter from ChatResponse.__init__
    - Remove | dict[str, Any] from finish_reason and usage_details params
    - Remove **kwargs from AgentResponse.__init__
    - Both now accept ChatMessage | Sequence[ChatMessage] | None for messages
    - Update docstrings and examples to reflect changes
    - Fix tests that were using removed kwargs
    - Fix Role type hint usage in ag-ui utils
    
    * Remove text parameter from ChatResponseUpdate and AgentResponseUpdate (#3597)
    
    - Remove text parameter from ChatResponseUpdate.__init__
    - Remove text parameter from AgentResponseUpdate.__init__
    - Remove **kwargs from both update classes
    - Simplify contents parameter type to Sequence[Content] | None
    - Update all usages to use contents=[Content.from_text(...)] pattern
    - Fix imports in test files
    - Update docstrings and examples
    
    * Rename from_chat_response_updates to from_updates (#3593)
    
    - ChatResponse.from_chat_response_updates → ChatResponse.from_updates
    - ChatResponse.from_chat_response_generator → ChatResponse.from_update_generator
    - AgentResponse.from_agent_run_response_updates → AgentResponse.from_updates
    
    * Remove try_parse_value method from ChatResponse and AgentResponse (#3595)
    
    - Remove try_parse_value method from ChatResponse
    - Remove try_parse_value method from AgentResponse
    - Remove try_parse_value calls from from_updates and from_update_generator methods
    - Update samples to use try/except with response.value instead
    - Update tests to use response.value pattern
    - Users should now use response.value with try/except for safe parsing
    
    * Add agent_id to AgentResponse and clarify author_name documentation (#3596)
    
    - Add agent_id parameter to AgentResponse class
    - Document that author_name is on ChatMessage objects, not responses
    - Update ChatResponse docstring with author_name note
    - Update AgentResponse docstring with author_name note
    
    * Simplify ChatMessage.__init__ signature (#3618)
    
    - Make contents a positional argument accepting Sequence[Content | str]
    - Auto-convert strings in contents to TextContent
    - Remove overloads, keep text kwarg for backward compatibility with serialization
    - Update _parse_content_list to handle string items
    - Update all usages across codebase to use new format: ChatMessage("role", ["text"])
    
    * Allow Content as input on run and get_response
    
    - Update prepare_messages and normalize_messages to accept Content
    - Update type signatures in _agents.py and _clients.py
    - Add tests for Content input handling
    
    * Fix ChatMessage usage across packages and samples
    
    Update all remaining ChatMessage(role=..., text=...) to use new
    ChatMessage('role', ['text']) signature.
    
    * Fix Role string usage and response format parsing
    
    - Fix redis provider: remove .value access on string literals
    - Fix durabletask ensure_response_format: set _response_format before accessing .value
    
    * Fix ollama .value and ai_model_id issues, handle None in content list
    
    - Fix ollama _chat_client: remove .value on string literals
    - Fix ollama _chat_client: rename ai_model_id to model_id
    - Fix _parse_content_list: skip None values gracefully
    
    * Fix A2AAgent type signature to include Content
    
    * Fix Role/FinishReason NewType dict annotations and improve test coverage to 95%
    
    * Fix mypy errors for Role/FinishReason NewType usage
    
    * Fix Role.TOOL and Role.ASSISTANT usage in _orchestrator_helpers.py
    
    * Fix Role NewType usage in durabletask _models.py
  • Python: Updated instructions/system_message logic in GitHub Copilot agent (#3625)
    * Updated instructions handling
    
    * Small improvement
    
    * Included runtime options in session creation logic
  • .NET: Python: [BREAKING] Renamed Github to GitHub (#3486)
    * Renamed Github to GitHub
    
    * Small fix
    
    * Updated package versions
  • Python: [BREAKING] changed AIFunction to FunctionTool and @ai_function to @tool (#3413)
    * changed AIFunction to FunctionTool and @ai_function to @tool
    
    * test and mypy fixes
    
    * mypy fix
    
    * switch function tool to always_require
    
    * fix noop
    
    * fix github copilot imports
    
    * test fixes
    
    * fix ollama test
    
    * fixes for tests
    
    * fix tests
    
    * reverted change to always_require and extended timeout
    
    * fix test
  • Python: Add BaseAgent implementation for GitHub Copilot SDK (#3404)
    * Added GithubCopilotAgent
    
    * Fixed errors
    
    * Updated examples
    
    * Updated naming and tests
    
    * Resolved comments and more tests
    
    * Updated tool handling
    
    * Updated tool handling
    
    * Small fixes
    
    * Removed default permission handler
    
    * Resolved comments
    
    * Updated positional args
    
    * Updated docstrings
    
    * Small fixes and more examples
    
    * Added example with MCP