Commit Graph

1779 Commits

  • .NET: Skip OffThread observability test (#4399)
    * Skip flaky OffThread observability test
    
    Temporarily skip CreatesWorkflowEndToEndActivities_WithCorrectName_OffThreadAsync
    due to intermittent failures. Tracked in #4398.
    
    Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
    
    * Update dotnet/tests/Microsoft.Agents.AI.Workflows.UnitTests/ObservabilityTests.cs
    
    Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
    
    ---------
    
    Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
    Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
  • .NET: AuthN & AuthZ sample with asp.net service and web client (#4354)
    * Add sample demonstrating authentication and user access in agent tools
    
    * Add fixes to enable running on windows
    
    * Add launchsettings, add docker-compose to slnx and fix formatting
    
    * Switch to Expenses rather than todo based sample and address PR comments
    
    * Rename sample
    
    * Fix formatting
  • .NET: Fixing issue with invalid node Ids when visualizing dotnet workflows. (#4269)
    * Fix Mermaid rendering errors in WorkflowVisualizer.ToMermaidString
    
    Fix two bugs in the Mermaid diagram output:
    
    1. Use safe node aliases (node_0, node_1, ...) instead of raw executor IDs
       as Mermaid node identifiers. Raw IDs containing spaces, dots, or
       non-ASCII characters (e.g. Japanese) caused Mermaid parse errors.
    
    2. Fix conditional edge arrow syntax from '.--> ' (invalid) to '.-> '
       (valid Mermaid dotted arrow syntax).
    
    Fixes #1406
    
    Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
    
    * Use recognizable sanitized IDs for Mermaid node identifiers\n\nReplace generic node_0/node_1 aliases with IDs derived from the original\nexecutor names. ASCII letters, digits, and underscores are preserved;\nother characters become underscores (collapsed, trimmed). Leading digits\nget an n_ prefix. Collisions are resolved with a numeric suffix.\n\nThis keeps node IDs readable in the Mermaid source while the display\nlabels continue to show the full original names."
    
    * Remove issue number references from test names and comments"
    
    * Address PR review feedback from Copilot\n\n- Add Throw.IfNull(id) guard to SanitizeMermaidNodeId\n- Add safety limit (10,000) to collision resolution loop\n- Restore missing edge assertions (middle1/middle2 --> end)\n- Fix comment to show actual sanitized ID (n_1_User_input)\n- Use stricter regex in Unicode test (must start with letter/underscore)"
    
    * Address second round of PR review feedback\n\n- Escape node display labels via EscapeMermaidLabel to handle quotes,\n  brackets, and newlines in executor IDs\n- Fix XML doc on SanitizeMermaidNodeId to accurately describe that\n  existing consecutive underscores in input are preserved\n- Restore specific edge assertion (mid --> end) in conditional edge test\n- Restore fan-in routing assertions (s1/s2 through intermediate node,\n  no direct edges to t) in fan-in test"
    
    ---------
    
    Co-authored-by: alliscode <bentho@microsoft.com>
    Co-authored-by: Copilot <223556219+Copilot@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>
  • .Net: Add additional Hosted Agent Samples (#4325)
    * Add 3 new hosted agent samples: AgentWithTools, AgentWithLocalTools, AgentThreadAndHITL
    
    - AgentWithTools: Foundry tools (MCP + code interpreter) via UseFoundryTools
    - AgentWithLocalTools: Local C# function tool (Seattle hotel search) with AIProjectClient
    - AgentThreadAndHITL: Human-in-the-loop with ApprovalRequiredAIFunction and thread persistence
    
    All samples follow agent-framework conventions (net10.0, AzureCliCredential, CPM disabled).
    AgentWithTools includes comprehensive README with setup guide and troubleshooting.
    
    Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
    
    * Add root HostedAgents README, replace test_requests.py with .http, update sample READMEs
    
    - Create root README.md with shared prerequisites, Azure AI Foundry setup,
      troubleshooting, and samples index
    - Replace test_requests.py with run-requests.http in AgentThreadAndHITL
    - Add pointer to root README in all 6 sample READMEs
    - Trim AgentWithTools README to concise style
    
    Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
    
    * Fix dotnet format issues in AgentWithLocalTools/Program.cs
    
    - Add UTF-8 BOM (CHARSET)
    - Sort System.ClientModel.Primitives import alphabetically (IMPORTS)
    - Use target-typed new for AIProjectClient (IDE0090)
    - Add internal accessibility modifier to Hotel record (IDE0040)
    
    Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
    
    * Address PR review: align model names and package versions
    
    - Change default model from gpt-4.1-mini to gpt-4o-mini in AgentWithLocalTools
      (Program.cs, agent.yaml, README.md) to match existing samples
    - Change README example from gpt-5.2 to gpt-4o-mini in AgentWithTools and root README
    - Align AgentWithLocalTools package versions with other samples:
      Azure.AI.AgentServer.AgentFramework beta.6 -> beta.8
      Azure.AI.OpenAI 2.8.0-beta.1 -> 2.7.0-beta.2
      Microsoft.Extensions.AI.OpenAI 10.2.0-preview -> 10.1.1-preview
    
    Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
    
    * Upgrade new samples to latest package versions
    
    - Azure.AI.OpenAI: 2.7.0-beta.2 -> 2.8.0-beta.1
    - Microsoft.Extensions.AI.OpenAI: 10.1.1-preview -> 10.3.0
    
    Aligns with AgentWithHostedMCP which uses the latest versions.
    
    Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
    
    * Pin AgentThreadAndHITL to Microsoft.Extensions.AI.OpenAI 10.1.1
    
    Azure.AI.AgentServer.AgentFramework beta.8 was compiled against
    Microsoft.Extensions.AI.Abstractions with the single-param
    FunctionApprovalRequestContent.CreateResponse(bool). Version 10.3.0
    changed the signature to include an optional reason parameter, causing
    a binary incompatibility at runtime. Pin to 10.1.1 until the framework
    is recompiled against the newer abstractions.
    
    Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
    
    ---------
    
    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>
  • .NET: AgentThread serialization alternatives ADR (#3062)
    * AgentThread serialization alternatives ADR
    
    * Update decision drivers.
    
    * Address some Copilot PR comments.
    
    * Fix typo.
    
    * Add ChatClientAgentThread to sample code
    
    * Address comments, rename ADR and update SLNX.
  • .NET: Add helpers to more easily access in-memory ChatHistory and make ChatHistoryProvider management more configurable. (#4224)
    * Add helpers to more easily access in-memory ChatHistory and make ChatHistoryProvider management more configurable.
    
    * Apply suggestion from @Copilot
    
    Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
    
    ---------
    
    Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
  • .NET: Support hosted code interpreter for skill script execution (#4192)
    * support script execution by code interpretor
    
    * improve the instruction prompt
    
    * Add DefaultAzureCredential production warning to AgentSkills samples
    
    Add the standard three-line WARNING comment about DefaultAzureCredential
    production considerations to both AgentSkills sample Program.cs files,
    matching the convention used in all other GettingStarted/Agents samples.
    
    Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
    
    * address pr review comments
    
    * address feedback
    
    * rename Skill* types to FileAgentSkill* prefix for consistency
    
    - Rename SkillFrontmatter -> FileAgentSkillFrontmatter
    - Rename SkillScriptExecutor -> FileAgentSkillScriptExecutor
    - Add FileAgentSkillScriptExecutionContext and FileAgentSkillScriptExecutionDetails
    - Update sample, provider, loader, and tests accordingly
    
    Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
    
    * reorder usings
    
    * use set for props initialization instead of init
    
    * rename HostedCodeInterpreterSkillScriptExecutor
    
    ---------
    
    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>
  • .NET: Fixing issue where OpenTelemetry span is never exported in .NET in-process workflow execution (#4196)
    * 1. Add reproduction test for issue #4155: workflow.run Activity never stopped in streaming OffThread path
    
    The WorkflowRunActivity_IsStopped_Streaming_OffThread test demonstrates that
    the workflow.run OpenTelemetry Activity created in StreamingRunEventStream.RunLoopAsync
    is started but never stopped when using the OffThread/Default streaming execution.
    The background run loop keeps running after event consumption completes, so the
    using Activity? declaration never disposes until explicit StopAsync() is called.
    
    Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
    
    2. Fix workflow.run Activity never stopped in streaming OffThread execution (#4155)
    
    The workflow.run OpenTelemetry Activity in StreamingRunEventStream.RunLoopAsync
    was scoped to the method lifetime via 'using'. Since the run loop only exits on
    cancellation, the Activity was never stopped/exported until explicit disposal.
    
    Fix: Remove 'using' and explicitly dispose the Activity when the workflow reaches
    Idle status (all supersteps complete). A safety-net disposal in the finally block
    handles cancellation and error paths.
    
    Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
    
    * Add root-level workflow.session activity spanning run loop lifetime\n\nImplements two-level telemetry hierarchy per PR feedback from lokitoth:\n- workflow.session: spans the entire run loop / stream lifetime\n- workflow_invoke: per input-to-halt cycle, nested within the session\n\nThis ensures the session activity stays open across multiple turns,\nwhile individual run activities are created and disposed per cycle.\n\nAlso fixes linkedSource CancellationTokenSource disposal leak in\nStreamingRunEventStream (added using declaration)."
    
    * Address Copilot review: fix Activity/CTS disposal, rename activity, add error tag\n\n1. LockstepRunEventStream: Remove 'using' from Activity in async iterator\n   and manually dispose in finally block (fixes #4155 pattern). Also dispose\n   linkedSource CTS in finally to prevent leak.\n2. Tags.cs: Add ErrorMessage (\"error.message\") tag for runtime errors,\n   distinct from BuildErrorMessage (\"build.error.message\").\n3. ActivityNames: Rename WorkflowRun from \"workflow_invoke\" to \"workflow.run\"\n   for cross-language consistency.\n4. WorkflowTelemetryContext: Fix XML doc to say \"outer/parent span\" instead\n   of \"root-level span\".\n5. ObservabilityTests: Assert WorkflowSession absence when DisableWorkflowRun\n   is true.\n6. WorkflowRunActivityStopTests: Fix streaming test race by disposing\n   StreamingRun before asserting activities are stopped.\n7. StreamingRunEventStream/LockstepRunEventStream: Use Tags.ErrorMessage\n   instead of Tags.BuildErrorMessage for runtime error events."
    
    * Review fixes: revert workflow_invoke rename, use 'using' for linkedSource, move SessionStarted earlier\n\n- Revert ActivityNames.WorkflowRun back to \"workflow_invoke\" (OTEL semantic convention contract)\n- Use 'using' declaration for linkedSource CTS in LockstepRunEventStream (no timing sensitivity)\n- Move SessionStarted event before WaitForInputAsync in StreamingRunEventStream to match Lockstep behavior"
    
    * Improve naming and comments in WorkflowRunActivityStopTests"
    
    * Prevent session Activity.Current leak in lockstep mode, add nesting test
    
    Save and restore Activity.Current in LockstepRunEventStream.Start() so the
    session activity doesn't leak into caller code via AsyncLocal. Re-establish
    Activity.Current = sessionActivity before creating the run activity in
    TakeEventStreamAsync to preserve parent-child nesting.
    
    Add test verifying app activities after RunAsync are not parented under the
    session, and that the workflow_invoke activity nests under the session."
    
    * Fix stale XML doc: WorkflowRun -> WorkflowInvoke in ObservabilityTests
    
    ---------
    
    Co-authored-by: alliscode <bentho@microsoft.com>
    Co-authored-by: Copilot <223556219+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>
  • .NET: Support InvokeMcpTool for declarative workflows (#4204)
    * Initial implementation of InvokeMcpTool in declarative workflow
    
    * Cleaned up sample implementation
    
    * Updated sample comments.
    
    * Added missing executor routing attribute
    
    * Fix PR comments.
    
    * Updated based on PR comments.
    
    * Updated based on PR comments.
    
    * Removed unnecessary using statement.
  • 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>
  • Update .NET package version to rc2 (#4257)
    - Bump RCNumber from 1 to 2
    - Update GitTag to 1.0.0-rc2
    - Update preview date stamps from 260219 to 260225
    
    Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
  • Add Additional Properties ADR (#4246)
    * Add Additional Properties ADR
    
    * Address PR comments
  • 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>
  • .NET: Implement Task support for A2A Hosting package (#3732)
    * implement task support?
    
    * some metadata + session store impl
    
    * address PR comments x1
    
    * API reivew
    
    * llast changes
    
    * More test
    
    * remove unsued import
    
    * fix moq override
    
    * refactoring
    
    * ontaskupdated
    
    * adjust to delegate
    
    * fix encoding
    
    * address PR comments: rework
    
    * init 1
    
    * renaming
    
    * fix tests
    
    * fix comment
    
    * runmode rename
    
    * rename
    
    * rename
    
    * use exxperimental api, allow experimental on project level
    
    * throw on refereceTaskIds
  • 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>
  • .NET: Fix JSON arrays of objects parsed as empty records when no schema is defined (#4199)
    * fix: use HasSchema check in DetermineElementType to prevent empty records
    
    When parsing JSON arrays containing objects without a predefined schema,
    `DetermineElementType()` was creating a `VariableType` with an empty
    (non-null) schema via `targetType.Schema?.Select(...) ?? []`. This caused
    `ParseRecord` to take the schema-based parsing path, iterating over zero
    schema fields and silently discarding all JSON properties.
    
    The fix checks `targetType.HasSchema` and falls back to
    `VariableType.RecordType` (which has `Schema = null`) when no schema is
    defined, ensuring `ParseRecord` takes the dynamic `ParseValues()` path
    that preserves all JSON properties.
    
    Closes #4195
    
    * test: add regression tests for schema-less JSON array-of-objects parsing (#4195)
    
    Add two regression tests to JsonDocumentExtensionsTests:
    
    1. ParseRecord_ObjectWithArrayOfObjects_NoSchema_PreservesNestedProperties
       - Parses a JSON object containing an array of objects using
         VariableType.RecordType (no schema) and verifies that nested
         object properties (name, role) are preserved in each element.
       - This is the exact scenario from issue #4195 where objects in
         arrays were being returned as empty dictionaries.
    
    2. ParseList_ArrayOfObjects_NoSchema_PreservesProperties
       - Parses a JSON array of objects directly via ParseList with
         VariableType.ListType (no schema) and verifies all properties
         are preserved.
    
    Both tests follow the existing Arrange/Act/Assert pattern and would
    have failed before the DetermineElementType() fix (empty dictionaries
    instead of populated ones).
  • 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
  • .NET: Add Foundry Agents Tool Sample - Bing Custom Search (#3701)
    * .NET: Add Bing Custom Search sample #3674
    
    * Apply format fixes
    
    * .NET: Improve Bing Custom Search sample with dual MEAI/Native SDK options
    
    - Add MEAI (Option 1) and Native SDK (Option 2) agent creation patterns
    - Add DefaultAzureCredential with standard WARNING comment
    - Add sample to solution file and FoundryAgents README index
    - Improve README with connection ID/instance name guidance
    - Fix missing newline at EOF in .csproj
    - Suppress CS8321 for unused local function pattern
    
    Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
    
    * Address PR review comments for Bing Custom Search sample
    
    - Add Async suffix to CreateAgentWithMEAI and CreateAgentWithNativeSDK methods
    - Clarify comment to reference ResponseTool instead of BingCustomSearchTool
    - Update README Option 1 description to accurately reflect SDK usage
    
    Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
    
    ---------
    
    Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
  • 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>