Commit Graph

893 Commits

  • Python: Fix: Parse oauth_consent_request events in Azure AI client (#4197)
    * Fix: Parse oauth_consent_request events in Azure AI client (#3950)
    
    When Azure AI Agent Service returns an oauth_consent_request output item
    for OAuth-protected MCP tools, the base OpenAI responses parser drops it
    (hits case _ default branch). This causes agent runs to complete silently
    with zero content.
    
    Changes:
    - Add oauth_consent_request ContentType and Content.from_oauth_consent_request()
      factory with consent_link field and user_input_request=True
    - Override _parse_response_from_openai and _parse_chunk_from_openai in
      RawAzureAIClient to intercept Azure-specific oauth_consent_request items
    - Add _emit_oauth_consent helper in AG-UI to emit CustomEvent for frontends
    - Add tests proving base parser drops the event and Azure AI override catches it
    
    Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
    
    * addressed comment
    
    * addressed comments
    
    * addressed comments
    
    ---------
    
    Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
  • Python: Add file_ids and data_sources support to get_code_interpreter_tool() (#4201)
    * Python: Add file_ids and data_sources support to AzureAIAgentClient.get_code_interpreter_tool()
    
    Update the factory method to accept file_ids and data_sources keyword
    arguments, matching the underlying azure.ai.agents SDK CodeInterpreterTool
    constructor. This enables users to attach uploaded files for code
    interpreter analysis.
    
    Fixes #4050
    
    Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
    
    * addressed comments
    
    * addressed comments
    
    * Add per-message file attachment support for AzureAIAgentClient
    
    Add hosted_file handling in _prepare_messages() to convert
    Content.from_hosted_file() into MessageAttachment on ThreadMessageOptions.
    This enables per-message file scoping for code interpreter, matching the
    underlying Azure AI Agents SDK MessageAttachment pattern.
    
    - Add hosted_file case in _prepare_messages() match statement
    - Import MessageAttachment from azure.ai.agents.models
    - Add sample for per-message CSV file attachment with code interpreter
    - Add employees.csv test data file
    - Add 3 unit tests for hosted_file attachment conversion
    
    Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
    
    * Address PR review: validation, fix assertions, remove MessageAttachment
    
    - Add empty string validation in resolve_file_ids()
    - Add test for Content with file_id=None
    - Add test for empty string file_ids
    - Revert MessageAttachment/hosted_file handling from _prepare_messages()
      (moved to separate issue #4352 for proper design)
    - Remove per-message file upload sample and employees.csv
    - Keep data_sources assertion as-is (dict keyed by asset_identifier)
    
    Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
    
    ---------
    
    Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
  • Python: Fix workflow tests pyright warnings (#4362)
    * Fix workflow tests pyright warnings
    
    * Update uv.lock
    
    * Fix pyright
    
    * Comments
    
    * Update root pyproject pyright setting
    
    * Update core pyproject pyright setting
    
    * Update core pyproject pyright setting
  • Python: Add OpenTelemetry instrumentation to ClaudeAgent (#4278) (#4326)
    * Python: Add OpenTelemetry instrumentation to ClaudeAgent (#4278)
    
    Add inline telemetry to ClaudeAgent.run() so that enable_instrumentation()
    emits invoke_agent spans and metrics. Covers both streaming and
    non-streaming paths using the same observability helpers as
    AgentTelemetryLayer. Adds 5 unit tests for telemetry behavior.
    
    Co-Authored-By: amitmukh <amimukherjee@microsoft.com>
    
    * Address PR review feedback for ClaudeAgent telemetry
    
    - Add justification comment for private observability API imports
    - Pass system_instructions to capture_messages for system prompt capture
    - Use monkeypatch instead of try/finally for test global state isolation
    
    Co-Authored-By: amitmukh <amitmukh@users.noreply.github.com>
    Co-Authored-By: Claude <noreply@anthropic.com>
    
    * Adopt AgentTelemetryLayer instead of inline telemetry
    
    Restructure ClaudeAgent to inherit from AgentTelemetryLayer via a
    _ClaudeAgentRunImpl mixin, eliminating duplicated telemetry code and
    private API imports.
    
    MRO: ClaudeAgent → AgentTelemetryLayer → _ClaudeAgentRunImpl → BaseAgent
    
    - Remove inline _run_with_telemetry / _run_with_telemetry_stream methods
    - Remove private observability helper imports (_capture_messages, etc.)
    - Add default_options property mapping system_prompt → instructions
    - Net -105 lines by reusing core telemetry layer
    
    Co-Authored-By: amitmukh <amitmukh@users.noreply.github.com>
    Co-Authored-By: Claude <noreply@anthropic.com>
    
    * Fix mypy: align _ClaudeAgentRunImpl.run() signature with AgentTelemetryLayer.run()
    
    Remove explicit `options` parameter from mixin's run() signature and
    extract it from **kwargs to match AgentTelemetryLayer's signature.
    Also align overload return types (ResponseStream, Awaitable) to match.
    
    Co-Authored-By: Claude <noreply@anthropic.com>
    
    * Introduce RawClaudeAgent following framework's RawAgent/Agent pattern
    
    Replace private _ClaudeAgentRunImpl mixin with public RawClaudeAgent
    class that contains all core logic (init, run, lifecycle, tools).
    ClaudeAgent becomes a thin wrapper that adds AgentTelemetryLayer.
    
    - RawClaudeAgent(BaseAgent): full implementation without telemetry
    - ClaudeAgent(AgentTelemetryLayer, RawClaudeAgent): adds OTel tracing
    - Export RawClaudeAgent from package __init__.py
    
    Users who want to skip telemetry or provide their own can use
    RawClaudeAgent directly.
    
    Co-Authored-By: Claude <noreply@anthropic.com>
    
    * Address review nits: trim RawClaudeAgent docstring, fix import paths
    
    - Simplify RawClaudeAgent docstring to a single basic example (not the
      primary entry point for most users)
    - Use agent_framework.anthropic import path in docstrings instead of
      direct agent_framework_claude path
    - Add RawClaudeAgent to agent_framework.anthropic lazy re-exports
    
    Co-Authored-By: Claude <noreply@anthropic.com>
    
    ---------
    
    Co-authored-by: Amit Mukherjee <amimukherjee@microsoft.com>
    Co-authored-by: amitmukh <amitmukh@users.noreply.github.com>
    Co-authored-by: Claude <noreply@anthropic.com>
    Co-authored-by: Dmytro Struk <13853051+dmytrostruk@users.noreply.github.com>
  • Python: Fix StandardMagenticManager to propagate session to manager agent (#4409)
    * Fix #4371: Propagate session to manager agent in StandardMagenticManager
    
    StandardMagenticManager._complete() was calling self._agent.run(messages)
    without passing a session. This caused context providers (e.g.
    RedisHistoryProvider) configured on the manager agent to silently fail,
    as each call created a new ephemeral session with a different session_id.
    
    Changes:
    - Create an AgentSession in StandardMagenticManager.__init__()
    - Pass session=self._session in _complete() calls to agent.run()
    - Persist/restore the session in checkpoint save/restore methods
    - Add regression tests for session propagation and checkpoint round-trip
    
    Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
    
    * Add type: ignore[reportPrivateUsage] to private attribute assertions in tests
    
    Address PR review feedback: add # type: ignore[reportPrivateUsage] comments
    to _session attribute accesses in the new regression tests, matching the
    existing convention used elsewhere in test_magentic.py (e.g., lines 401-406).
    
    The @pytest.mark.asyncio decorator is not needed because pyproject.toml
    sets asyncio_mode = "auto".
    
    Fixes #4371
    
    Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
    
    * Address review: use getattr for private _session access in tests (#4371)
    
    Replace direct mgr._session access with getattr(mgr, "_session") to avoid
    reportPrivateUsage type-checking warnings without needing type: ignore comments.
    
    Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
    
    * Apply pre-commit auto-fixes
    
    * Address PR review: fix session restore guard and improve test robustness (#4371)
    
    - Use 'is not None' instead of truthiness check for session_payload restore
    - Use getattr() for private _session attribute access in tests
    - Add backward-compatibility test for on_checkpoint_restore with empty state
    
    Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
    
    * Make non-async tests plain def to avoid pytest-asyncio dependency (#4409)
    
    Tests that never await anything don't need to be async. Using plain def
    ensures they always run regardless of pytest-asyncio configuration.
    
    Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
    
    * Apply pre-commit auto-fixes
    
    ---------
    
    Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
  • 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: Fix IndexError when reasoning models produce reasoning-only messages in Magentic-One workflow (#4413)
    * Fix IndexError when reasoning models return no text content (#4384)
    
    In _prepare_message_for_openai(), the text_reasoning case unconditionally
    accessed all_messages[-1] to attach reasoning_details. When a reasoning
    model (e.g. gpt-5-mini) returns reasoning_details without text content,
    all_messages is empty, causing an IndexError.
    
    Guard the access by initializing all_messages with the current args dict
    when it is empty, so reasoning_details can be safely attached.
    
    Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
    
    * Address review: buffer reasoning details for valid message payloads (#4384)
    
    - Buffer pending reasoning details and attach to the next message with
      content/tool_calls, avoiding standalone reasoning-only messages.
    - When reasoning is the only content, emit a message with empty content
      to satisfy Chat Completions schema requirements.
    - Strengthen test assertions to verify text+reasoning co-location and
      that all messages with reasoning_details also have content or tool_calls.
    
    Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
    
    * Fix text_reasoning handling: always buffer and tighten tests (#4384)
    
    - Always buffer reasoning into pending_reasoning instead of conditionally
      attaching to the previous message via fragile all_messages emptiness check
    - Attach buffered reasoning to last message at end-of-loop when no subsequent
      content consumed it
    - Assert exact content values (content == '' not in ('', None))
    - Assert exact list lengths (== 1 not >= 1) for stronger regression guards
    - Add test for reasoning before FunctionCallContent
    
    Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
    
    * Apply pre-commit auto-fixes
    
    ---------
    
    Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
  • Python: Add Azure Cosmos history provider package (#4271)
    * Created cosmos history provider
    
    * add marker
    
    * Python: address Cosmos PR feedback
    
    - address provider/test/sample review feedback and cleanup typing
    - add cosmos integration test coverage and skip gating
    - add dedicated cosmos emulator jobs to python merge/integration workflows
    - switch cosmos workflow execution to package poe integration-tests task
    
    Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
    
    * Python: handle empty Cosmos session id
    
    - replace default partition fallback for empty session_id
    - log warning and generate GUID when session_id is empty
    - update unit tests to validate GUID fallback behavior
    
    Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
    
    * fix sample
    
    * fix cross partition query
    
    ---------
    
    Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
  • Python: Add regression tests for Entry JoinExecutor Workflow.Inputs initialization (#4335)
    * Python: Add regression tests for #3948 - Entry JoinExecutor initializes Workflow.Inputs
    
    Add tests verifying that when workflow.run() is called with a dict or string
    input, the Entry node (JoinExecutor with kind: 'Entry') correctly initializes
    Workflow.Inputs via _ensure_state_initialized so that:
    - Expressions like =inputs.age resolve to the correct value
    - Conditions like =Local.age < 13 evaluate based on actual input (not blank/0)
    - String inputs populate both inputs.input and System.LastMessage.Text
    
    Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
    
    * Apply pre-commit auto-fixes
    
    * Fix D420 and RUF070 lint errors across packages
    
    * Revert _workflow.py yield-inside-context-manager changes
    
    Moving yield inside `with _framework_event_origin()` blocks in the
    async generator causes ContextVar token reset failures on Python 3.12
    Windows. The token stays un-reset while the generator is suspended,
    and async generator finalization in a different contextvars.Context
    triggers ValueError, corrupting OpenTelemetry span state and causing
    test_span_creation_and_attributes to see leaked spans.
    
    Keep yields outside the context manager blocks to ensure tokens are
    reset immediately before the generator suspends.
    
    ---------
    
    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(python): Handle thread.message.completed event in Assistants API streaming (#4333)
    * fix: handle thread.message.completed event in Assistants API streaming
    
    Previously, `thread.message.completed` events fell through to the
    catch-all `else` branch and yielded empty `ChatResponseUpdate` objects,
    silently discarding fully-resolved annotation data (file citations,
    file paths, and their character-offset regions).
    
    This commit adds a dedicated handler for `thread.message.completed`
    that:
    - Walks the completed ThreadMessage.content array
    - Extracts text blocks with their fully-resolved annotations
    - Maps FileCitationAnnotation and FilePathAnnotation to the
      framework's Annotation type with proper TextSpanRegion data
    - Yields a ChatResponseUpdate containing the complete text and
      annotations
    
    Fixes #4322
    
    * test: add tests for thread.message.completed annotation handling
    
    Tests cover:
    - File citation annotation extraction
    - File path annotation extraction
    - Multiple annotations on a single text block
    - Text-only messages (no annotations)
    - Non-text blocks are skipped
    - Mixed content blocks (text + image)
    - Conversation ID propagation
    
    * fix: address Copilot review - add quote field and log unrecognized annotations
    
    - Include `quote` from `annotation.file_citation.quote` in
      `additional_properties` for FileCitationAnnotation, preserving the
      exact cited text snippet from the source file
    - Add `else` clause to log unrecognized annotation types at debug level,
      consistent with the pattern in `_responses_client.py`
    - Add `import logging` and module-level logger
    
    * test: add coverage for quote field and unrecognized annotation logging
    
    - test_message_completed_with_file_citation_quote: verifies quote is
      included in additional_properties
    - test_message_completed_with_file_citation_no_quote: verifies quote
      is omitted when None
    - test_message_completed_unrecognized_annotation_logged: verifies
      unknown annotation types are logged at debug level and skipped
    
    * fix: address reviewer nits — logger name convention + annotation type string
    
    Per @giles17's review:
    - Use logging.getLogger('agent_framework.openai') to match module convention
    - Simplify debug message to use annotation.type instead of type().__name__
    
    * refactor: move message.completed tests into consolidated test file
    
    Per @giles17's review: moved all tests from test_assistants_message_completed.py
    into test_openai_assistants_client.py and deleted the standalone file.
    
    * fix: resolve mypy no-redef and ruff RET504 lint errors
    
    - Remove duplicate type annotation for 'ann' variable (no-redef)
    - Return directly from fixture instead of unnecessary assignment (RET504)
    
    * fix: rename annotation variable in completed block to fix mypy type conflict
    
    The 'annotation' loop variable in thread.message.completed has type
    FileCitationAnnotation | FilePathAnnotation, which conflicts with the
    delta block's 'annotation' of type FileCitationDeltaAnnotation |
    FilePathDeltaAnnotation. Renamed to 'completed_annotation' to avoid
    mypy 'Incompatible types in assignment' error.
    
    * fix: remove quote field from FileCitationAnnotation handling
    
    ---------
    
    Co-authored-by: Giles Odigwe <79032838+giles17@users.noreply.github.com>
  • Python: fix(python): Use AgentResponse.value instead of model_validate_json in HITL sample (#4405)
    * fix(python): use AgentResponse.value instead of model_validate_json in HITL sample
    
    Since the agent is configured with response_format=GuessOutput, the
    AgentResponse already provides .value with the parsed Pydantic model.
    Using .value is more idiomatic and avoids redundant JSON parsing.
    
    Fixes #4396
    
    * fix: add safety guard for AgentResponse.value being None
    
    Address Copilot review feedback: .value is optional and may be None
    if response_format isn't propagated through the streaming path.
    Add an explicit None check with a clear error message.
  • Bump uv from 0.10.5 to 0.10.7 in /python (#4393)
    Bumps [uv](https://github.com/astral-sh/uv) from 0.10.5 to 0.10.7.
    - [Release notes](https://github.com/astral-sh/uv/releases)
    - [Changelog](https://github.com/astral-sh/uv/blob/main/CHANGELOG.md)
    - [Commits](https://github.com/astral-sh/uv/compare/0.10.5...0.10.7)
    
    ---
    updated-dependencies:
    - dependency-name: uv
      dependency-version: 0.10.7
      dependency-type: direct:development
      update-type: version-update:semver-patch
    ...
    
    Signed-off-by: dependabot[bot] <support@github.com>
    Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
  • Bump poethepoet from 0.42.0 to 0.42.1 in /python (#4392)
    Bumps [poethepoet](https://github.com/nat-n/poethepoet) from 0.42.0 to 0.42.1.
    - [Release notes](https://github.com/nat-n/poethepoet/releases)
    - [Commits](https://github.com/nat-n/poethepoet/compare/v0.42.0...v0.42.1)
    
    ---
    updated-dependencies:
    - dependency-name: poethepoet
      dependency-version: 0.42.1
      dependency-type: direct:development
      update-type: version-update:semver-patch
    ...
    
    Signed-off-by: dependabot[bot] <support@github.com>
    Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
  • Bump prek from 0.3.3 to 0.3.4 in /python (#4391)
    Bumps [prek](https://github.com/j178/prek) from 0.3.3 to 0.3.4.
    - [Release notes](https://github.com/j178/prek/releases)
    - [Changelog](https://github.com/j178/prek/blob/master/CHANGELOG.md)
    - [Commits](https://github.com/j178/prek/compare/v0.3.3...v0.3.4)
    
    ---
    updated-dependencies:
    - dependency-name: prek
      dependency-version: 0.3.4
      dependency-type: direct:development
      update-type: version-update:semver-patch
    ...
    
    Signed-off-by: dependabot[bot] <support@github.com>
    Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
  • Bump ruff from 0.15.2 to 0.15.4 in /python (#4390)
    Bumps [ruff](https://github.com/astral-sh/ruff) from 0.15.2 to 0.15.4.
    - [Release notes](https://github.com/astral-sh/ruff/releases)
    - [Changelog](https://github.com/astral-sh/ruff/blob/main/CHANGELOG.md)
    - [Commits](https://github.com/astral-sh/ruff/compare/0.15.2...0.15.4)
    
    ---
    updated-dependencies:
    - dependency-name: ruff
      dependency-version: 0.15.4
      dependency-type: direct:development
      update-type: version-update:semver-patch
    ...
    
    Signed-off-by: dependabot[bot] <support@github.com>
    Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
  • Bump rollup (#4386)
    Bumps [rollup](https://github.com/rollup/rollup) from 4.52.4 to 4.59.0.
    - [Release notes](https://github.com/rollup/rollup/releases)
    - [Changelog](https://github.com/rollup/rollup/blob/master/CHANGELOG.md)
    - [Commits](https://github.com/rollup/rollup/compare/v4.52.4...v4.59.0)
    
    ---
    updated-dependencies:
    - dependency-name: rollup
      dependency-version: 4.59.0
      dependency-type: indirect
    ...
    
    Signed-off-by: dependabot[bot] <support@github.com>
    Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
  • Bump rollup in /python/samples/demos/ag_ui_workflow_handoff/frontend (#4284)
    Bumps [rollup](https://github.com/rollup/rollup) from 4.57.1 to 4.59.0.
    - [Release notes](https://github.com/rollup/rollup/releases)
    - [Changelog](https://github.com/rollup/rollup/blob/master/CHANGELOG.md)
    - [Commits](https://github.com/rollup/rollup/compare/v4.57.1...v4.59.0)
    
    ---
    updated-dependencies:
    - dependency-name: rollup
      dependency-version: 4.59.0
      dependency-type: indirect
    ...
    
    Signed-off-by: dependabot[bot] <support@github.com>
    Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@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: Fix walrus operator precedence for model_id kwarg in AzureOpenAIResponsesClient (#4310)
    * Fix walrus operator precedence for model_id in AzureOpenAIResponsesClient (#4299)
    
    Add parentheses around the walrus assignment so model_id receives the
    actual string value instead of the boolean result of
    `kwargs.pop(...) and not deployment_name`.
    
    Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
    
    * Address review: replace walrus with explicit None check, add edge-case tests (#4299)
    
    - Replace walrus operator with explicit assignment and 'is not None'
      check to avoid boolean-coercion pitfalls (empty string now correctly
      surfaces as ValueError instead of silently falling back)
    - Add test: deployment_name takes precedence over model_id kwarg
    - Add test: model_id='' raises ValueError
    - Add test: model_id=None falls back to env var
    
    Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
    
    * Add explicit validation for empty model_id in AzureOpenAIResponsesClient
    
    Reject empty or whitespace-only model_id with ValueError instead of
    silently passing an empty deployment name downstream. This ensures the
    test_init_model_id_kwarg_empty_string test correctly validates behavior
    defined in production code rather than relying on downstream validation.
    
    Addresses PR review feedback for #4299.
    
    Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
    
    * Simplify model_id handling using walrus operator
    
    Addresses review comment on PR #4310.
    
    Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
    
    * Restore explicit model_id validation to fix test failures (#4299)
    
    The walrus operator refactor silently dropped the empty-string validation,
    causing test_init_model_id_kwarg_empty_string to fail. Restore the explicit
    None check and ValueError raise for empty model_id.
    
    Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
    
    * Revert "Restore explicit model_id validation to fix test failures (#4299)"
    
    This reverts commit 1d2965fff6.
    
    * Revert to walrus operator fix per review feedback
    
    ---------
    
    Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
  • Python: .NET: Fix .NET conversation memory in DevUI (#3484) (#4294)
    * Fix .NET conversation memory in DevUI (#3484)
    
    * formatting fixes
    
    * fix memory regression in python devui , fix for #4123
    
    * Fix for #3983: Added _get_event_type() helper that safely accesses event type on both objects (.type) and dicts (.get("type")). Replaced all 4 bare event.type accesses in _executor.py (lines 267, 477, 499, 523).
    
    Root cause: PR #3690 changed event.__class__.__name__ == "RequestInfoEvent" (safe) to event.type == "request_info" (crashes on dicts), but _execute_workflow still yields raw dicts on error paths.
    
    Test: test_workflow_error_yields_dict_event_without_crash — mocks a workflow that raises, verifies execute_entity consumes the dict error events without crashing.
    
    * format fixes
    
    * lint fixes
  • Python: Fix executor handler type resolution when using from __future__ import annotations (#4317)
    * Python: Fix Executor handler type checking with __future__ annotations (#3898)
    
    Use typing.get_type_hints() in _validate_handler_signature to resolve
    string annotations from `from __future__ import annotations`. This
    mirrors the fix applied to FunctionExecutor in #2308.
    
    When __future__ annotations are enabled, type annotations are stored as
    strings. The handler decorator was passing these strings directly to
    validate_workflow_context_annotation, which uses typing.get_origin and
    returns None for strings, causing a ValueError.
    
    Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
    
    * Address PR review feedback for #3898: improve error handling and test coverage
    
    - Wrap typing.get_type_hints() in try/except to provide a descriptive
      ValueError mentioning the handler name when annotations cannot be resolved
    - Strengthen bare context test to assert output_types and workflow_output_types
    - Add test for @handler(input=..., output=...) with future annotations
      covering the skip_message_annotation branch
    - Add test for union-type context annotations with future annotations
    
    Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
    
    * Narrow exception catch and add test for unresolvable annotations (#3898)
    
    - Narrow except clause from bare Exception to (NameError, AttributeError,
      TypeError) to avoid masking unexpected errors.
    - Add test_handler_unresolvable_annotation_raises to verify that a handler
      with a forward-reference to a non-existent type raises ValueError with
      the expected message.
    
    Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
    
    * Fix #3898: fall back to raw annotations when get_type_hints fails
    
    When typing.get_type_hints(func) raises NameError (unresolvable forward
    ref), AttributeError, RecursionError, or any other exception, fall back
    to the raw parameter annotations instead of raising a ValueError.
    This matches the suggestion from @moonbox3 on PR #4317.
    
    Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
    
    * Fix test to match new fallback behavior when get_type_hints fails (#3898)
    
    The code now falls back to raw string annotations instead of raising
    'Failed to resolve type annotations'. A ValueError is still raised when
    the raw string ctx annotation is not a valid WorkflowContext type, so
    update the test to match on ValueError without checking the message.
    
    Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
    
    * Apply pyupgrade: remove unnecessary string annotation quote
    
    * Add noqa for intentionally undefined name in annotation test
    
    ---------
    
    Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
  • Python: Tuning auto sample validation workflow (#4218)
    * Tuning validate-01-get-started
    
    * Add gh token
    
    * Add model
    
    * enable debug log
    
    * bump up timeout for testing purposes
    
    * Test cli is working
    
    * Fix end quote
    
    * Run gh auth
    
    * Run gh auth trail 2
    
    * Run gh auth trail 3
    
    * Test token
    
    * Add zcure login
    
    * Add zcure login 2
    
    * Add zcure login 3
    
    * Add zcure login 4
    
    * Extract common actions
    
    * Extract common actions 2
    
    * Correct env vars
    
    * Print outputs to action console
    
    * Disable end-to-end samples
    
    * Fix ruff errors
    
    * Fix ruff errors 2
    
    * Revert workflow changes to fix tests
    
    * Revert workflow changes to fix tests 2
    
    * Revert workflow changes to fix tests 3
    
    * Revert workflow changes to fix tests 4
  • Python: Fix agent option merge to support dict-defined tools (#4314)
    * Fix _merge_options dropping dict-defined tools (#4303)
    
    _merge_options used getattr(tool, 'name', None) to de-duplicate tools,
    which returns None for dict-style tool definitions. This caused all
    override dict tools to be treated as duplicates of each other and of any
    base dict tools, silently dropping them.
    
    Add _get_tool_name() helper that extracts the name from both object-style
    tools (via .name attribute) and dict-style tools (via tool['function']['name']).
    
    Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
    
    * Address review: fix None dedup bug and add comprehensive tests (#4303)
    
    - Exclude None from existing_names set so nameless/malformed tools are
      not silently deduplicated against each other
    - Add test for cross-type dedup (dict tool + object tool with same name)
    - Add test verifying nameless tools are preserved (not falsely deduped)
    - Add unit tests for _get_tool_name edge cases: missing function key,
      non-dict function value, missing name, no name attribute, non-dict
      inputs, and valid dict/object tools
    
    Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
    
    ---------
    
    Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
  • Python: Fix single-tool input handling in OpenAIResponsesClient._prepare_tools_for_openai (#4312)
    * Fix OpenAIResponsesClient mishandling single-tool inputs (#4304)
    
    Use normalize_tools() in _prepare_tools_for_openai to wrap single tools
    (FunctionTool or dict) in a list before iteration, consistent with the
    chat client implementation.
    
    Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
    
    * Address PR review feedback for #4304
    
    - Use precise type annotation matching normalize_tools/OpenAIChatClient signature
      instead of collapsed Sequence[Any] | Any | None
    - Move emptiness guard after normalize_tools() call so single falsy tool
      objects are not silently swallowed
    - Import ToolTypes for the type annotation
    - Expand test_prepare_tools_for_openai_single_function_tool assertions to
      verify parameters, strict, and parameter schema fields
    - Add test_prepare_tools_for_openai_none to verify None input returns []
    
    Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
    
    ---------
    
    Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
  • Python: Fix WorkflowAgent not persisting response messages to session history (#1694) (#4319)
    WorkflowAgent._run_impl() and _run_stream_impl() did not set
    session_context._response before calling _run_after_providers().
    This caused InMemoryHistoryProvider.after_run() to see context.response
    as None, so response messages were never stored in the session.
    
    On subsequent runs, the workflow only received prior user inputs without
    assistant responses, breaking multi-turn conversations.
    
    Fix: Set session_context._response to the workflow result before running
    after_run providers, matching the behavior of the regular Agent class.
    
    Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
  • Python: Map file citation annotations from TextDeltaBlock in Assistants API streaming (#4316) (#4320)
    During Assistants API streaming, TextDeltaBlock.text.annotations was
    ignored when creating Content objects. This caused raw placeholder
    strings like 【4:0†source】 to pass through to downstream consumers
    (including AG-UI) instead of being resolved to citation metadata.
    
    Map FileCitationDeltaAnnotation and FilePathDeltaAnnotation from
    delta_block.text.annotations to Annotation objects on the Content,
    consistent with the existing patterns in _responses_client.py and
    _chat_client.py.
    
    Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
  • Python: Preserve workflow run kwargs when continuing with run(responses=...) (#4296)
    * fix(python): preserve workflow run kwargs on response continuation (#4293)
    
    When continuing a paused workflow with run(responses=...), the existing
    run kwargs stored in state were unconditionally overwritten with an empty
    dict. This caused subsequent agent invocations to lose the original run
    context (e.g., custom_data, user tokens).
    
    Now kwargs are only overwritten when:
    - New kwargs are explicitly provided (override), or
    - State was just cleared for a fresh run (initialize to {})
    
    On continuation without new kwargs, existing kwargs are preserved.
    
    Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
    
    * Address PR review feedback for #4293
    
    - Use consistent get_state(key, {}) default pattern in _agent_executor.py
      and _workflow_executor.py instead of get_state(key) or {} to safely
      handle missing WORKFLOW_RUN_KWARGS_KEY
    - Add test for empty-value kwargs on continuation (custom_data={}) to
      verify the is-not-None boundary between overwrite and preserve
    - Add test for reset_context=True with no kwargs to exercise the elif
      branch that initializes WORKFLOW_RUN_KWARGS_KEY to {}
    - Add len assertion to override test for consistency
    - Document kwargs-collapsing behavior at the public API call site
    
    Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
    
    ---------
    
    Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
  • Python: Strip reserved kwargs in AgentExecutor to prevent duplicate-argument TypeError (#4298)
    * Python: Strip reserved kwargs in AgentExecutor to prevent collision (#4295)
    
    workflow.run(session=...) passed 'session' through to agent.run() via
    **run_kwargs while AgentExecutor also passes session=self._session
    explicitly, causing TypeError: got multiple values for keyword argument.
    
    _prepare_agent_run_args now strips reserved params (session, stream,
    messages) from run_kwargs and logs a warning when they are present.
    
    Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
    
    * Address PR review feedback for #4295
    
    - Use _RESERVED_RUN_PARAMS constant in stripping loop instead of
      hardcoded tuple to maintain single source of truth
    - Trim frozenset to only stripped keys (session, stream, messages);
      options and additional_function_arguments have separate merge logic
    - Fix caplog type annotation to use TYPE_CHECKING pattern
    - Assert options return value in reserved-kwarg stripping test
    - Add test for multiple reserved kwargs supplied simultaneously
    - Add integration test for messages= kwarg via workflow.run()
    
    Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
    
    ---------
    
    Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
  • Python: Tighten HandoffBuilder to require Agent instead of SupportsAgentRun (#4301) (#4302)
    HandoffBuilder.participants() accepted SupportsAgentRun by API contract,
    but build() failed at runtime because _prepare_agent_with_handoffs()
    requires Agent instances for cloning, tool injection, and middleware.
    
    Fix: Update all public type hints, docstrings, and validation in
    HandoffBuilder and HandoffAgentExecutor to require Agent explicitly.
    The isinstance check is now performed early in participants() with a
    clear error message explaining why Agent is required.
    
    Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
  • Python: Fix response_format resolution in streaming finalizer (#4291)
    * Python: Fix AgentResponse.value being None when streaming workflow (#3970)
    
    The streaming path in BaseAgent.run() used the raw 'options' parameter
    (passed by the caller) to bind response_format into the outer stream's
    finalizer. When response_format was set in default_options rather than
    runtime options, it was missing from the finalizer and value was None.
    
    Fix: Use the merged chat_options from the run context (via ctx_holder),
    matching the non-streaming path which already uses ctx['chat_options'].
    
    Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
    
    * Address review feedback for #3970: safer ctx access, add test coverage
    
    ---------
    
    Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
  • Python: Update workflow orchestration samples to use AzureOpenAIResponsesClient (#4285)
    * Update workflow orchestration samples to use AzureOpenAIResponsesClient
    
    * Fix broken link
  • Python: Fix Bedrock embedding test stub missing meta attribute (#4287)
    * Fix Bedrock embedding test stub missing meta attribute
    
    * Increase test coverage so gate passes
  • Python / .NET Samples - Restructure and Improve Samples (Feature Branc… (#4092)
    * Python: .NET Samples - Restructure and Improve Samples (Feature Branch) (#4091)
    
    * Moved by agent (#4094)
    
    * Fix readme links
    
    * .NET Samples - Create `04-hosting` learning path step (#4098)
    
    * Agent move
    
    * Agent reorderd
    
    * Remove A2A section from README 
    
    Removed A2A section from the Getting Started README.
    
    * Agent fixed links
    
    * Fix broken sample links in durable-agents README (#4101)
    
    * Initial plan
    
    * Fix broken internal links in documentation
    
    Co-authored-by: crickman <66376200+crickman@users.noreply.github.com>
    
    * Revert template link changes; keep only durable-agents README fix
    
    Co-authored-by: crickman <66376200+crickman@users.noreply.github.com>
    
    ---------
    
    Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>
    Co-authored-by: crickman <66376200+crickman@users.noreply.github.com>
    
    * .NET Samples - Create `03-workflows` learning path step (#4102)
    
    * Fix solution project path
    
    * Python: Fix broken markdown links to repo resources (outside /docs) (#4105)
    
    * Initial plan
    
    * Fix broken markdown links to repo resources
    
    Co-authored-by: crickman <66376200+crickman@users.noreply.github.com>
    
    * Update README to rename .NET Workflows Samples section
    
    ---------
    
    Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>
    Co-authored-by: crickman <66376200+crickman@users.noreply.github.com>
    
    * .NET Samples - Create `02-agents` learning path step (#4107)
    
    * .NET: Fix broken relative link in GroupChatToolApproval README (#4108)
    
    * Initial plan
    
    * Fix broken link in GroupChatToolApproval README
    
    Co-authored-by: crickman <66376200+crickman@users.noreply.github.com>
    
    ---------
    
    Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>
    Co-authored-by: crickman <66376200+crickman@users.noreply.github.com>
    
    * Update labeler configuration for workflow samples
    
    * .NET - Reorder Agents samples to start from Step01 instead of Step04 (#4110)
    
    * Fix solution
    
    * Resolve new sample paths
    
    * Move new AgentSkills and AgentWithMemory_Step04 samples
    
    * Fix link
    
    * Fix readme path
    
    * fix: update stale dotnet/samples/Durable path reference in AGENTS.md
    
    Co-authored-by: crickman <66376200+crickman@users.noreply.github.com>
    
    * Moved new sample
    
    * Update solution
    
    * Resolve merge (new sample)
    
    * Sync to new sample - FoundryAgents_Step21_BingCustomSearch
    
    * Updated README
    
    * .NET Samples - Configuration Naming Update (#4149)
    
    * .NET: Restore AzureFunctions index parity with ConsoleApps under DurableAgents samples (#4221)
    
    * Clean-up `05_host_your_agent`
    
    * Config setting consistency
    
    * Refine samples
    
    * AGENTS.md
    
    * Move new samples
    
    * Re-order samples
    
    * Move new project and fixup solution
    
    * Fixup model config
    
    * Fix up new UT project
    
    ---------
    
    Co-authored-by: Copilot <198982749+Copilot@users.noreply.github.com>
  • Update Python package versions to rc2 (#4258)
    - Bump core and azure-ai to 1.0.0rc2
    - Bump preview packages to 1.0.0b260225
    - Update dependencies to >=1.0.0rc2
    - Add CHANGELOG entries for changes since rc1
    - Update uv.lock
    
    Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
  • Python: Phase 2: Embedding clients for Ollama, Bedrock, and Azure AI Inference (#4207)
    * Phase 2: Embedding clients for Ollama, Bedrock, and Azure AI Inference
    
    Add embedding client implementations to existing provider packages:
    
    - OllamaEmbeddingClient: Text embeddings via Ollama's embed API
    - BedrockEmbeddingClient: Text embeddings via Amazon Titan on Bedrock
    - AzureAIInferenceEmbeddingClient: Text and image embeddings via Azure AI
      Inference, supporting Content | str input with separate model IDs for
      text (AZURE_AI_INFERENCE_EMBEDDING_MODEL_ID) and image
      (AZURE_AI_INFERENCE_IMAGE_EMBEDDING_MODEL_ID) endpoints
    
    Additional changes:
    - Rename EmbeddingCoT -> EmbeddingT, EmbeddingOptionsCoT -> EmbeddingOptionsT
    - Add otel_provider_name passthrough to all embedding clients
    - Register integration pytest marker in all packages
    - Add lazy-loading namespace exports for Ollama and Bedrock embeddings
    - Add image embedding sample using Cohere-embed-v3-english
    - Add azure-ai-inference dependency to azure-ai package
    
    Part of #1188
    
    Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
    
    * Fix mypy duplicate name and ruff lint issues
    
    - Rename second 'vector' variable to 'img_vector' in image embedding loop
    - Combine nested with statements in tests
    - Remove unused result assignments in tests
    
    Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
    
    * updates from feedback
    
    * Fix CI failures in embedding usage handling
    
    - Fix Azure AI embedding mypy issues by normalizing vectors to list[float],
      safely accumulating optional usage token fields, and filtering None entries
      before constructing GeneratedEmbeddings
    - Avoid Bandit false positive by initializing usage details as an empty dict
    - Update OpenAI embedding tests to assert canonical usage keys
      (input_token_count/total_token_count)
    
    Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
    
    ---------
    
    Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
  • Python: Support Agent Skills (#4210)
    * Python: Support Agent Skills
    
    Add FileAgentSkillsProvider, a context provider that discovers and exposes
    Agent Skills from filesystem directories following the Agent Skills
    specification (https://agentskills.io/) progressive disclosure pattern:
    advertise, load, read resources.
    
    Changes:
    - FileAgentSkillsProvider - discovers SKILL.md files from configured
      directories, advertises skills via system prompt injection, and provides
      load_skill / read_skill_resource tools for on-demand access.
    - Internal helpers for skill discovery, frontmatter parsing, and secure
      resource reading (path traversal / symlink guards).
    - Unit tests covering discovery, loading, resource reading, and security
      scenarios.
    - Sample (basic_file_skills) demonstrating usage with an expense-report skill.
    
    Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
    
    * Python: Move skills sample to samples/02-agents/basic_skills/
    
    Align sample directory name with .NET equivalent (Agent_Step01_BasicSkills).
    
    Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
    
    * fix code quality checks
    
    * address pr review comment and code quality check issue
    
    * address pr review comments
    
    * move the sample to the skills folder
    
    * update readme
    
    * reame consts and use types for them
    
    * leverage pathlib for working with files
    
    * refactor the test
    
    * supply schema to functions
    
    * update readme
    
    * update sample name
    
    * address pr review comments
    
    * fix failing lint check
    
    * address failing check
    
    ---------
    
    Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
  • Python: 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: Fixing issue #1366 - Thread corruption when max_iterations is reached. (#4234)
    * Fix thread corruption when max_iterations exhausted (#1366)
    
    When the function invocation loop exhausts max_iterations while the model
    keeps requesting tools, the failsafe code path (calling the model with
    tool_choice='none' and prepending fcc_messages) was unreachable because
    'if response is not None: return response' short-circuited before it.
    
    The fix removes the premature return so the failsafe always runs after
    loop exhaustion, making a final model call with tool_choice='none' to
    produce a clean text answer and prepending accumulated fcc_messages from
    prior iterations. This matches the existing pattern used by the error
    threshold and max_function_calls paths.
    
    Also unskips test_max_iterations_limit and test_streaming_max_iterations_limit
    which were previously skipped with 'needs investigation in unified API'.
    
    Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
    
    * Add fix report for issue #1366
    
    Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
    
    * Fix ruff formatting in _tools.py and test_issue_1366_thread_corruption.py
    
    Apply ruff format to fix multi-line string concatenation and function call
    formatting issues flagged by the linter.
    
    Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
    
    * Add quality review for issue #1366 fix
    
    Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
    
    * Remove temporary investigation docs.
    
    * Address PR review: explicit enabled check in log condition, clarify mock behavior in test
    
    - Add explicit function_invocation_configuration['enabled'] check to the
      'Maximum iterations reached' log condition in both non-streaming and
      streaming paths, making intent clearer when function invocation is disabled.
    - Add comment in test_thread_safe_after_max_iterations_with_agent explaining
      that the failsafe response (tool_choice='none') is provided automatically
      by the mock client, not from run_responses.
    
    * Blend fix and tests into project without issue-specific callouts
    
    - Remove issue #1366 references from _tools.py comments
    - Move regression tests from standalone test_issue_1366_thread_corruption.py
      into test_function_invocation_logic.py alongside existing max_iterations tests
    - Clean up test docstrings to describe behavior generically
    - Delete the standalone issue-specific test file
    
    ---------
    
    Co-authored-by: alliscode <bentho@microsoft.com>
    Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
  • [BREAKING] Python: Add InvokeFunctionTool action for declarative workflows (#3716)
    * add(declarative): Declarative workflow InvokeFunctionTool feature
    
    * Cleanup
    
    * Address PR feedback
    
    * Remove InvokeTool kind, consolidate to InvokeFunctionTool
    
    * Fix sample locations
    
    * pin azure-ai-projects to 2.0.0b3 due to breaking changes
  • Python: Fix workflow runner concurrent processing (#4143)
    * Fix workflow runner concurrent processing
    
    * Comments 1
    
    * Add test
  • Bump esbuild and vite (#4178)
    Bumps [esbuild](https://github.com/evanw/esbuild) to 0.27.3 and updates ancestor dependency [vite](https://github.com/vitejs/vite/tree/HEAD/packages/vite). These dependencies need to be updated together.
    
    
    Updates `esbuild` from 0.21.5 to 0.27.3
    - [Release notes](https://github.com/evanw/esbuild/releases)
    - [Changelog](https://github.com/evanw/esbuild/blob/main/CHANGELOG-2024.md)
    - [Commits](https://github.com/evanw/esbuild/compare/v0.21.5...v0.27.3)
    
    Updates `vite` from 5.4.21 to 7.3.1
    - [Release notes](https://github.com/vitejs/vite/releases)
    - [Changelog](https://github.com/vitejs/vite/blob/main/packages/vite/CHANGELOG.md)
    - [Commits](https://github.com/vitejs/vite/commits/v7.3.1/packages/vite)
    
    ---
    updated-dependencies:
    - dependency-name: esbuild
      dependency-version: 0.27.3
      dependency-type: indirect
    - dependency-name: vite
      dependency-version: 7.3.1
      dependency-type: direct:development
    ...
    
    Signed-off-by: dependabot[bot] <support@github.com>
    Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
  • Python: docs(observability): add Comet Opik setup example (#3940)
    * docs(observability): add Comet Opik setup example
    
    * Update README.md
  • Bump werkzeug from 3.1.5 to 3.1.6 in /python (#4125)
    Bumps [werkzeug](https://github.com/pallets/werkzeug) from 3.1.5 to 3.1.6.
    - [Release notes](https://github.com/pallets/werkzeug/releases)
    - [Changelog](https://github.com/pallets/werkzeug/blob/main/CHANGES.rst)
    - [Commits](https://github.com/pallets/werkzeug/compare/3.1.5...3.1.6)
    
    ---
    updated-dependencies:
    - dependency-name: werkzeug
      dependency-version: 3.1.6
      dependency-type: indirect
    ...
    
    Signed-off-by: dependabot[bot] <support@github.com>
    Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
  • Bump ruff from 0.15.1 to 0.15.2 in /python (#4182)
    Bumps [ruff](https://github.com/astral-sh/ruff) from 0.15.1 to 0.15.2.
    - [Release notes](https://github.com/astral-sh/ruff/releases)
    - [Changelog](https://github.com/astral-sh/ruff/blob/main/CHANGELOG.md)
    - [Commits](https://github.com/astral-sh/ruff/compare/0.15.1...0.15.2)
    
    ---
    updated-dependencies:
    - dependency-name: ruff
      dependency-version: 0.15.2
      dependency-type: direct:development
      update-type: version-update:semver-patch
    ...
    
    Signed-off-by: dependabot[bot] <support@github.com>
    Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
  • Bump poethepoet from 0.41.0 to 0.42.0 in /python (#4183)
    Bumps [poethepoet](https://github.com/nat-n/poethepoet) from 0.41.0 to 0.42.0.
    - [Release notes](https://github.com/nat-n/poethepoet/releases)
    - [Commits](https://github.com/nat-n/poethepoet/compare/v0.41.0...v0.42.0)
    
    ---
    updated-dependencies:
    - dependency-name: poethepoet
      dependency-version: 0.42.0
      dependency-type: direct:development
      update-type: version-update:semver-minor
    ...
    
    Signed-off-by: dependabot[bot] <support@github.com>
    Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
  • Python: Fix doubled tool_call arguments in MESSAGES_SNAPSHOT when streaming (#4200)
    * fix: prevent doubled tool_call arguments in MESSAGES_SNAPSHOT
    
    When streaming with client-side tools, some providers send a full-
    arguments replay after the streaming deltas complete. The `_emit_tool_call`
    function unconditionally appends every arguments delta to the internal
    `flow.tool_calls_by_id` tracking dictionary via `+=`. When the replay
    contains the exact same complete arguments string that was already
    accumulated from prior deltas, the arguments get doubled (e.g.,
    `{"todoText":"buy groceries"}{"todoText":"buy groceries"}`).
    
    This causes `MESSAGES_SNAPSHOT` events to contain invalid doubled JSON in
    `tool_calls[].function.arguments`, breaking any client or middleware that
    relies on snapshots for state reconstruction.
    
    The fix adds a guard (mirroring the existing duplicate guard in
    `_emit_text`) that detects when the incoming delta exactly equals the
    already-accumulated arguments string, indicating a full-arguments replay
    rather than an incremental delta. In this case the append is skipped,
    preventing the doubling.
    
    The `ToolCallArgsEvent` deltas are still emitted correctly for real-time
    streaming — only the internal snapshot accumulator is guarded.
    
    Fixes #4194
    
    * fix: move duplicate check before event emission + add test
    
    Address Copilot review feedback:
    1. Move duplicate full-arguments replay detection BEFORE emitting
       ToolCallArgsEvent, for consistency with _emit_text() which returns
       early without emitting any events on replay detection.
    2. Add test_emit_tool_call_skips_duplicate_full_arguments_replay() to
       verify the duplicate detection behavior for tool call arguments,
       matching the existing test pattern for text content.