Commit Graph

54 Commits

  • Simplify Python hosting core (#6492)
    Remove linking, multicast, durable delivery, and host push machinery from the v1 hosting core. Keep those scenarios in a proposed follow-up ADR and update channel packages, samples, docs, tests, and workspace metadata around the smaller host/channel contract.
    
    Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
  • Python: feat(python): cross-channel hosting improvements (endpoint paths, Activity push, Telegram/Teams fixes) (#6307)
    * Update hosting channel endpoint paths
    
    Treat channel paths as concrete endpoint paths so built-in channels can be mounted at their defaults or at the app root without sample-specific subclasses. Update docs, tests, and the Foundry Telegram Invocations sample accordingly.
    
    Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
    
    * Add push support to ActivityProtocolChannel
    
    Implement the ChannelPush protocol so the Activity Protocol channel can
    receive cross-channel fan-out (ResponseTarget.all_linked) and echo_input
    replay as a non-originating destination:
    
    - Add push() that reconstructs a proactive Bot Framework activity (bot/user
      swap) from the stored conversation reference and POSTs it to
      /v3/conversations/{id}/activities.
    - Record a ChannelIdentity (service_url, conversation, bot, user, channel_id,
      locale) on ChannelRequest.identity so the host registers the channel under
      its isolation key for fan-out resolution.
    - Route the streaming path through deliver_response so Activity-originated
      turns broadcast like Telegram/Discord.
    - Add tests for push delivery, service_url validation, ChannelPush instance
      check, and inbound identity recording.
    
    Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
    
    * Don't delete Telegram webhook on shutdown by default
    
    The TelegramChannel deleted its webhook on shutdown in webhook mode. During
    a rolling redeploy the new revision registers the webhook on startup, then
    the old revision's shutdown deletes it, silently breaking inbound delivery
    until the next boot. setWebhook is overwriting/idempotent, so startup
    re-asserts the webhook every boot and no teardown is needed.
    
    Add a delete_webhook_on_shutdown flag (default False) so teardown is opt-in
    for ephemeral deployments, and leave the webhook in place otherwise.
    
    Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
    
    * Fix Activity channel streaming on non-Teams channels (405 on updateActivity)
    
    The Activity Protocol channel streamed replies the Teams way: POST a
    placeholder, then PUT-edit it as tokens arrive. Only Teams supports the
    updateActivity REST op; Web Chat, Direct Line and the Emulator return
    405 Method Not Allowed on the PUT, so the user saw only the placeholder.
    
    Gate the placeholder+edit flow on edit-capable channels (msteams). Other
    channels now buffer the stream and POST a single final message, mirroring
    the non-streaming path's fan-out and response-hook semantics. Also add a
    defensive 405 fallback inside the Teams edit loop so an unexpected 405
    can never strand the user on the placeholder.
    
    Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
    
    * fix(hosting-activity-protocol): don't parse Teams inline attachment content as a URI
    
    Teams message activities include a text/html attachment whose inline
    `content` is raw HTML (not a URL). _parse_activity fell back to
    `attachment["content"]` and passed it to Content.from_uri, raising
    ContentError ("URI must contain a scheme") and failing the whole turn,
    so Teams users got no response.
    
    Only treat `contentUrl` as a URI, require an absolute scheme, and skip
    unparseable attachments defensively instead of failing the message.
    
    Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
    
    * feat(hosting-activity-protocol): native slash-command dispatch for Teams/Activity
    
    Add a commands= parameter to ActivityProtocolChannel that intercepts a
    leading /command (after stripping the bot's own @mention) and dispatches
    to ChannelCommand handlers, mirroring the Telegram channel. Unknown
    commands fall through to the agent. The channel run_hook is applied to
    command requests so handlers observe the same resolved isolation key as
    ordinary messages, and handler errors are swallowed (200, no Bot Service
    retry of non-idempotent commands).
    
    Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
    
    * feat(hosting): silent attributed Telegram echoes + Teams markdown rendering
    
    - hosting-telegram: send cross-channel input echoes with disable_notification
      (silent) and detect echo payloads so they aren't re-broadcast.
    - hosting-activity-protocol: render outbound + push activities as textFormat
      'markdown' so Teams shows formatted replies (enables per-channel variants).
    
    Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
    
    * fix(hosting-activity-protocol): address PR #6307 review feedback
    
    Consult the host delivery pipeline even for empty streamed replies so
    ResponseTarget.none is honoured and non-originating fan-out is consulted
    instead of always emitting an originating "(no response)" message. Applies
    to both the progressive-edit (Teams) and buffered (Web Chat/Direct Line)
    streaming paths.
    
    Re-validate service_url against the allow-list in push(): the identity is
    read from a persisted store and push runs out-of-band, so the captured
    service_url must be re-checked before a bearer token is sent.
    
    Adds tests for empty-stream host consultation/suppression on both streaming
    paths and for push rejecting a disallowed service_url.
    
    Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
    
    ---------
    
    Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
  • Python: add agent-framework-hosting core package (#5638)
    * feat(hosting): add agent-framework-hosting core package
    
    New ``agent-framework-hosting`` package implementing ADR 0026 / SPEC-002:
    the channel-neutral host that lets a single ``Agent`` (or ``Workflow``)
    fan out across multiple wire protocols ("channels") behind one Starlette
    ASGI app.
    
    Surface (re-exported from ``agent_framework_hosting``):
    
    - ``AgentFrameworkHost`` — wraps a hostable target, mounts channels onto
      an ASGI app, owns per-isolation-key ``AgentSession`` reuse, threads
      request context (``response_id`` / ``previous_response_id``) into
      context providers via an ``ExitStack`` of ``bind_request_context``
      calls, and exposes an opt-in Hypercorn ``serve()`` helper (extra
      ``[serve]``).
    - ``Channel`` protocol + ``ChannelContribution`` — the surface a channel
      package implements (routes, lifespans, identity hooks, …).
    - ``ChannelRequest`` / ``ChannelSession`` / ``ChannelIdentity`` /
      ``ChannelPush`` / ``ChannelCommand[Context]`` / ``ChannelRunHook`` /
      ``ChannelStreamTransformHook`` / ``DeliveryReport`` /
      ``HostedRunResult`` / ``ResponseTarget`` / ``ResponseTargetKind`` /
      ``apply_run_hook`` — channel-side dataclasses + helpers.
    - ``IsolationKeys`` + ``ISOLATION_HEADER_USER`` / ``..._CHAT`` +
      ``get/set/reset_current_isolation_keys`` — the host's ASGI middleware
      reads the ``x-agent-{user,chat}-isolation-key`` headers off each
      inbound request and exposes them to the agent stack via a
      ``ContextVar`` so storage-side providers (e.g.
      ``FoundryHostedAgentHistoryProvider``) can apply per-tenant
      partitioning without channels having to forward anything.
    
    Includes 45 unit tests covering the host, channel contributions,
    isolation contextvar, and shared types. Registers the package in
    ``python/pyproject.toml`` ``[tool.uv.sources]`` and adds the matching
    pyright ``executionEnvironments`` entry for tests.
    
    Hypercorn is an optional dependency (``[serve]`` extra); the soft import
    in ``serve()`` is annotated for pyright since it isn't on the default
    install.
    
    Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
    
    * fix(hosting): address PR-2 review comments
    
    Source-code changes
    - _suppress_already_consumed: narrow contract — RuntimeError now logs
      at WARNING with exc_info; non-RuntimeError still logs at exception().
      Docstring clarifies that any non-clean teardown is observable.
    - _BoundResponseStream: add aclose() and route __await__ through
      get_final_response() so the binding is always released — fixes
      contextvar leak when channels abandon the stream or use the
      await-the-stream convenience.
    - Lifespan: aggregate startup/shutdown callback errors; every callback
      runs, all failures are logged with their qualname, and the first
      error is re-raised so Starlette still aborts boot.
    - _build_run_kwargs: switch session-cache write to dict.setdefault so
      concurrent racers cannot orphan a session if create_session ever
      yields.
    - _deliver_response: introduce DeliveryReport.failed for push outages
      vs explicit "no link" drops; an outage no longer triggers an
      originating fallback so the channel can decide degraded behaviour.
    
    Test additions
    - tests/test_isolation.py (new): full coverage of IsolationKeys, the
      contextvar helpers, header constants, and end-to-end ASGI
      middleware lift / reset / passthrough.
    - tests/test_host.py: TestBindRequestContext, TestBoundResponseStream
      (aclose / __await__ / __getattr__ forwarding / double-close
      idempotency), TestWrapInputListMessages (list[Message] LAST
      precedence), TestLifespanAggregation (startup + shutdown).
    - tests/test_types.py: TestApplyRunHook (sync/async/None), and
      TestDeliveryReport (new failed field).
    - Updated test_push_exception_marks_skipped ->
      test_push_exception_lands_in_failed_no_fallback to match the new
      delivery contract.
    
    Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
    
    * fix(hosting): address PR-2 round-2 review comments
    
    - Refactor workflow checkpoint restoration into shared helpers
      (_restore_workflow_checkpoint for blocking; the streaming sibling
      drains the rehydration stream) so the blocking and streaming paths
      rehydrate identically — clarifies the previously inline _maybe_restore
      by hoisting the pattern next to the blocking call site.
    - Document that blocking workflow output is text-only by design;
      richer modalities ride the streaming AgentResponseUpdate channel,
      which preserves all content parts.
    
    Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
    
    * review: address PR-4 _host.py round 2 feedback
    
    These review comments were filed on PR-4 (#5640) but target lines that
    live in the hosting-core package (PR-2 / #5638), so the fixes land here
    and PR-4's stack will pick them up on rebase.
    
    - _suppress_already_consumed: narrow the RuntimeError catch to the two
      documented benign messages (`Inner stream not available`, `Event loop
      is closed`); any other RuntimeError now logs at ERROR with a full
      traceback so executor bugs / runner-context state errors / checkpoint
      RuntimeErrors during the post-run flush no longer masquerade as
      benign cleanup noise. Still no propagation (we're in an
      async-generator finally during teardown) — see the docstring.
    - _restore_workflow_checkpoint{,_streaming}: log a WARNING when a
      non-None latest checkpoint drains to zero events, so a stale or
      partially-written checkpoint_id surfaces as an operator signal
      instead of a silent state-loss.
    
    (The `deliver_response` "no destinations resolvable" vs "every
    destination errored" concern raised in 3198268038 is already addressed
    by the existing `failed` vs `skipped` distinction surfaced through
    `DeliveryReport.failed` — see lines 1080-1102 and the
    `DeliveryReport` docstring.)
    
    Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
    
    * fix(hosting): reject path-traversal patterns in checkpoint isolation_key
    
    The host's `_resolve_checkpoint_storage` joined `request.session.isolation_key`
    directly into the configured `checkpoint_location`. The key is caller-
    controlled — sourced from inbound headers (`x-agent-{user,chat}-isolation-key`
    injected by the Foundry runtime), from channel-supplied derivations such as
    `telegram:<chat_id>` / `entra:<oid>`, or from values set by a channel
    `run_hook`. A value like `../../../etc/foo` or an absolute path would let
    the resulting checkpoint directory escape the configured root (CWE-22).
    This matches the path-traversal class fixed upstream in #5851 for the
    foundry_hosting checkpoint storage.
    
    New `_checkpoint_path_for_isolation_key(root, isolation_key)` helper:
    
    - Uses a denylist (not allowlist) so legitimate namespaced keys
      (`telegram:42`, `entra:abc-def`) continue to pass through unmodified.
    - Rejects path separators (`/`, `\`), NUL, all-dot reductions (`.`, `..`,
      `...`, ...), absolute paths (`os.path.isabs`), and drive-letter prefixes
      (`os.path.splitdrive` plus an explicit `^[A-Za-z]:` check so payloads
      crafted on a POSIX host still fail closed if the resulting directory
      ever round-trips to Windows storage).
    - After joining, resolves both sides and verifies
      `target.is_relative_to(root)` as defence-in-depth.
    
    `_resolve_checkpoint_storage` now logs a WARNING and returns `None` for
    invalid keys rather than crashing the request — checkpointing is best-
    effort and we prefer dropping it to letting one malformed key abort an
    otherwise valid agent run.
    
    Tests:
    
    - `TestCheckpointPathForIsolationKey` exercises the helper directly with
      legitimate keys (alphanumeric, `:`-namespaced, dotted, 200-char), all
      rejected traversal patterns from #5851's MSRC repro list, and
      non-string input.
    - `TestHostWorkflowCheckpointingPathTraversal` verifies the end-to-end
      request path: a traversal key (`../escape`) and an in-key separator
      (`evil/sub`) both produce a successful agent response with no files
      written under `checkpoint_location`, and the traversal case logs a
      WARNING citing `isolation_key`.
    
    Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
    
    * fix(hosting): address PR-2 round-3 review feedback + add response hooks
    
    Round-3 review comment fixes:
    
    - _types.py: drop the _EMPTY_MAPPING sentinel; ChannelIdentity.attributes
      uses plain dict() as the default — simpler, no extra symbol to track.
    - _host.py: drop the local `import asyncio` + `from typing import cast as
      _cast` inside `serve()`; rely on the module-level imports.
    - _host.py: switch `_log_incoming` to structured `extra={...}` payloads
      for both INFO and DEBUG so log aggregators get queryable fields.
    - _host.py: delete `_flat_context_providers` and stop descending into a
      `.providers` attribute. Aggregator providers (AggregateContextProvider /
      ContextProviderBase) are responsible for forwarding `response_context`
      to their children themselves; the host treats whatever
      `agent.context_providers` exposes as the final, flat list.
    - _host.py: stop collapsing agent / workflow output to text. `_invoke`
      forwards `AgentResponse.messages` (and `raw_response`) on the
      `HostedRunResult`. `_invoke_workflow` builds a per-event message list
      via a new `_workflow_output_to_messages` helper that preserves
      AgentResponse / AgentResponseUpdate / Message / Content branches and
      falls back to text only for arbitrary objects.
    - _host.py: `_workflow_event_to_update` carries Content payloads through
      unchanged so multi-modal workflow outputs (images, function-call
      metadata, ...) survive into channels.
    
    New features (per design discussion in the PR thread):
    
    - HostedRunResult: rebuilt around `messages: list[Message]` with
      `.text` / `.contents` as projections, a `raw_response` slot for the
      underlying AgentResponse, and a `replace(messages=..., raw_response=...)`
      clone helper used by the delivery layer for per-destination isolation.
      The `HostedRunResult(text="...")` ctor is preserved as a back-compat
      shim that synthesises a single assistant text message.
    - ResponseTarget: gain `echo_input: bool = False` (also exposed on
      `.channel(name, *, echo_input=...)` / `.channels([...], *, echo_input=...)`).
      When set, the host pushes the originating user message to each
      non-originating destination before the agent reply. Channels can
      filter or transform echoes via their response_hook.
    - DeliveryReport: add `echoed` / `echo_failed` tuples to surface
      per-destination outcomes of the new echo phase. Echo failures do not
      abort the corresponding response push on the same destination.
    - ChannelResponseHook + ChannelResponseContext + apply_response_hook:
      duck-typed `response_hook` attribute on channels for per-destination
      post-processing. Receives a clone of the HostedRunResult and a
      context carrying the request, channel name, destination identity,
      originating flag, and `is_echo` phase flag. Channels stay
      modality-aware (text-only wires flatten via the hook; card-capable
      channels render structured contents directly).
    - _deliver_response: clone-before-hook fan-out so a hook mutating one
      channel's payload cannot leak into another destination's view.
    
    Tests:
    
    - Update _FakeAgentResponse to expose `.messages` (single assistant text
      message synthesised from `text`) so existing tests pass unchanged on
      the new multi-modal _invoke path.
    - Replace the obsolete `test_bind_descends_one_level_into_providers_attribute`
      with a regression guard asserting the host does NOT descend into
      `.providers` (matches new contract).
    - New tests for HostedRunResult multi-modal preservation, echo_input
      fan-out with success + failure, response_hook applied per destination,
      per-destination mutation isolation, and is_echo phase observability.
    
    Docs:
    
    - spec 002: rewrite Canonical flow with the new input → run_hook → host
      → target → wrap → per-destination clone → response_hook → push
      pipeline; document multi-modality contract and per-destination
      cloning; add `echo_input` row to ResponseTarget table; rewrite
      HostedRunResult/HostedStreamResult row; add ChannelResponseHook /
      ChannelResponseContext / apply_response_hook table; log decisions
      Q28 (no host-side text collapse), Q29 (duck-typed response_hook),
      Q30 (opt-in `echo_input` on ResponseTarget).
    - ADR 0026: add ChannelResponseHook + multi-modality bullets;
      surface `echo_input` on the ResponseTarget bullet.
    
    Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
    
    * fix(hosting): drop HostedRunResult(text=...) back-compat shim; use from_text()
    
    Pre-release cleanup — no released callers to break, so consolidate on one
    canonical entry point plus a classmethod for the ergonomic
    single-text-message case:
    
    - HostedRunResult.__init__ takes ``messages`` positionally (required); no
      more ``text=`` kwarg overload, no more "synthesise an empty message
      when no args" path.
    - New HostedRunResult.from_text(text, *, role="assistant", raw_response=None)
      classmethod for the common "wrap a single text content as one message"
      case (tests, channels emitting plain strings, the echo-input phase
      wrapping a user's text turn).
    - ``_build_echo_payload`` uses ``HostedRunResult.from_text(raw, role="user")``
      for the ``str`` and fallback branches; the other branches use the plain
      ctor with explicit ``Message`` lists.
    - Tests rewritten to use ``from_text("reply")`` everywhere
      ``HostedRunResult(text="reply")`` appeared. Added an explicit
      ``test_from_text_role_kwarg_overrides_default`` regression guard.
    - spec 002: HostedRunResult row updated to describe the
      ``from_text(text, *, role="assistant")`` classmethod instead of the
      removed back-compat shim.
    
    Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
    
    * refactor(hosting-core): reshape HostedRunResult into generic typed envelope
    
    Replace the flattened multi-modal HostedRunResult (carrying
    messages/raw_response/.text projections) with a typed generic
    envelope around the target's full-fidelity output:
    
      class HostedRunResult(Generic[TResult]):
          result: TResult
          session: AgentSession | None
    
    - Agent targets produce HostedRunResult[AgentResponse]; channels
      read result.messages, result.text, result.value, result.response_id,
      result.usage_details directly off the underlying response.
    - Workflow targets produce HostedRunResult[WorkflowRunResult];
      channels iterate result.get_outputs() and inspect
      result.get_final_state() themselves (the host no longer collapses
      workflow outputs onto a synthesised message list).
    - The echo-input phase synthesises a HostedRunResult[AgentResponse]
      wrapping the user's turn so the same per-destination delivery
      machinery applies.
    - replace() is now {result, session} only; the host's clone is
      shallow — channels that need to mutate result itself are
      responsible for their own deep copy.
    
    Rationale: the earlier shape pre-shaped target output (collapsing
    workflows onto a Message list, losing per-executor outputs, final
    state, and structured value affordances). Carrying the target output
    unchanged keeps the host modality-agnostic, gives channel authors
    static typing where they want it, and removes 30+ lines of
    host-side projection helpers.
    
    Also updates ADR 0026 + spec 002 (Q3, Q28, Q29 amended; new Q31
    captures the generic-envelope decision and rationale).
    
    Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
    
    * docs(hosting-core): document echo vs response distinction for push channels
    
    The host already encodes the echo-vs-response phase via the
    underlying Message.role on the pushed HostedRunResult:
    
    - echo phase: payload.result.messages[*].role == "user"
    - response phase: payload.result.messages[*].role == "assistant"
    
    Both pushes go through the same ChannelPush.push(identity, payload)
    entry point. Channels distinguish either by inspecting role (which
    works for any push-capable channel) or — when a response_hook is
    wired — by branching on ChannelResponseContext.is_echo directly.
    
    Expand the ChannelPush Protocol docstring to make this discoverable
    for channel implementers (esp. chat bots that cannot impersonate
    the user on their wire and need to render echoes as quoted /
    prefixed blocks rather than as bot replies).
    
    Mirror the explanation into the spec's echo_input section.
    
    Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
    
    * docs(hosting-core): fix quickstart to use current Agent API
    
    ChatAgent was renamed to Agent and the preferred construction pattern
    is client.as_agent(...). Also drop the sibling channel import so the
    snippet imports only modules declared as dependencies of this package;
    point readers at the sibling packages instead.
    
    Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
    
    * test(hosting-core): drop redundant @pytest.mark.asyncio decorators
    
    asyncio_mode = "auto" is configured in pyproject.toml, so individual
    @pytest.mark.asyncio decorators are unnecessary.
    
    Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
    
    * docs(hosting): add authorization profiles + IdentityAllowlist seam to ADR/spec
    
    Composes `require_link` + `allowlist` into three named profiles (open,
    forced-link, allowlist) with the allowlist itself keyed on either the
    channel-native id (pre-link) or a verified IdP claim (post-link), plus
    `AnyOf`/`AllOf` combinators for mixed setups. Lifts the design into
    an explicit host seam (`host.authorize(...)` → `AuthorizationOutcome`
    of `Allowed` / `LinkRequired` / `Denied`) instead of leaving each
    channel to roll its own.
    
    Key contract bits:
    - Tri-state `AllowlistDecision` (ALLOW / DENY / ABSTAIN) so claim-based
      lists can ABSTAIN until claims are available without composition
      silently flipping that into DENY.
    - `AuthorizationContext` carries explicit `phase` + `claim_source`
      so allowlists can tell pre-link from post-link without overloading
      `verified_claims is None`.
    - Channel-side `allowlist: ... | Literal["inherit"] | None` with an
      explicit inheritance sentinel, so the host-level `default_allowlist`
      is opt-out, not opt-in.
    - Construction-time validator rejects silent-deny configurations
      (`LinkedClaimAllowlist` without a claim source) with a typed
      `ChannelConfigurationError`.
    - Group-chat denial mirrors the existing `LinkChallenge` DM-redirect
      pattern; only the redacted `user_message` reaches the wire,
      structured `log_details` stay in telemetry.
    
    Ships in two waves: the Protocol + `NativeIdAllowlist` + config
    validator land with the next core PR ahead of the linker; the full
    pipeline + `LinkedClaimAllowlist` enforcement land with the
    `IdentityLinker` core PR.
    
    Updates: ADR 0026 (summary bullet + conceptual-API table row + resolved
    Q16), spec 002 (new req #22, renumbered v1 fast-follow #23..#29 and
    stretch #30..#31, new "Authorization profiles and the IdentityAllowlist
    seam" subsection, inbound-ownership row, resolved Q32, follow-up entry).
    
    Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
    
    * feat(hosting): add DurableTaskRunner seam + runtime_mode auto-detect
    
    Introduces the explicit long-running vs ephemeral runtime distinction
    and a generic DurableTaskRunner Protocol that owns non-originating
    push dispatch — collapsing the previous deliveries[] per-destination
    state machine, SupportsDeliveryTracking provider capability, and
    Foundry update_item service ask down to a single immutable
    intended_targets[] write on the message.
    
    Spec / ADR:
    - New §"Runtime modes" with auto-detect markers + defaults matrix.
    - Rewrites §"Delivery tracking" → §"Intended targets + durable
      delivery": intent-only on the message, operational state lives in
      the runner.
    - New §"Durable task runner" defining DurableTaskRunner / RetryPolicy
      / TaskHandle / TaskStatus.
    - Drops §SupportsDeliveryTracking and §Foundry update_item gap.
    - Resolved Qs: 12, 18, 21, 26 revised; new 17/18/19 (ADR) and
      33/34/35 (spec).
    
    Code:
    - New _runner.py with InProcessTaskRunner (asyncio + bounded retry,
      bounded terminal-status cache, register-after-start guard,
      shutdown drain).
    - _host.py: runtime_mode + durable_task_runner ctor params;
      auto-detect via FOUNDRY_HOSTING_ENVIRONMENT /
      AZURE_FUNCTIONS_ENVIRONMENT / AWS_LAMBDA_FUNCTION_NAME;
      HOSTING_PUSH_TASK_NAME handler registered eagerly so
      _deliver_response can be called outside the lifespan;
      _handle_push_task does echo-then-response inline per destination;
      _deliver_response now schedules one task per destination via the
      runner (DeliveryReport.pushed = scheduled; .failed = schedule-time
      outage only).
    - _types.py: new DurableTaskRunner Protocol + RetryPolicy /
      TaskHandle / TaskStatus; DeliveryReport drops echoed /
      echo_failed (echo outcome owned by the runner).
    - __init__.py exports the new public surface.
    
    Tests: 132 passing, 90% coverage. New test_runner.py covers
    InProcessTaskRunner success/retry/terminal-failure/cancellation/
    register-after-start, runtime-mode auto-detect with synthetic env,
    and the warning-on-ephemeral-without-runner path. test_host.py
    delivery tests use a sync runner fake for deterministic assertions
    and validate the new "schedule succeeded vs runner backend
    unreachable" semantics.
    
    Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
    
    * feat(hosting): rubber-duck round-5 — strict ephemeral, codec seam, allowlist Wave-1, drop DeliveryReport
    
    Adopts the rubber-duck-approved package of changes from the round-5
    review of PR #5638 (modulo DeliveryReport.failed — the value type is
    removed entirely now that durable delivery covers the failure
    surface, per user direction).
    
    Code:
    - Drop DeliveryReport value type; host-internal _deliver_response
      returns bool. Failure observability is now logs (in-process) /
      runner backend (durable adapters).
    - Strict ephemeral default: ephemeral runtime_mode with the default
      in-process runner raises RuntimeError; opt-in via
      allow_in_process_runner=True (warns).
    - ChannelPushCodec Protocol + DurableTaskPayloadMode enum +
      _validate_runner_codec_pairing so JSON-mode runners can be safely
      paired with channels via codecs; _handle_push_task accepts both
      object- and JSON-envelope shapes.
    - ResponseTarget.identity(...) / .identities([...]) builders +
      IDENTITIES kind for explicit caller-supplied recipients; field
      rename identities → _target_identities (private) with a
      target_identities property to resolve the classmethod collision.
    - Intent-only audit: _annotate_intended_targets writes
      hosting.intended_targets / skipped_targets / includes_originating /
      originating_channel onto assistant messages — single immutable
      write per the runner-owned operational-state model.
    - InProcessTaskRunner: 2-phase drain on shutdown
      (shutdown_grace_seconds, default 5.0) so a clean shutdown does not
      abandon work mid-retry; payload_mode = OBJECT class-level.
    - Echo idempotency: _handle_push_task tracks an echo_done cursor on
      runner-owned task state so a retry that fires after the echo
      phase succeeded does not double-echo.
    
    Wave-1 authorization seam (full landing):
    - New _authorization.py with AllowlistDecision tri-state,
      AuthorizationContext, IdentityAllowlist Protocol, AllowAll /
      NativeIdAllowlist (with async loader cache + channel-scope ABSTAIN) /
      LinkedClaimAllowlist (raise-until-Wave-2) / AnyOfAllowlists /
      AllOfAllowlists / CallableAllowlist built-ins, Allowed /
      LinkRequired / Denied outcomes, ChannelConfigurationError.
    - Host(default_allowlist=..., identity_linker=...) + per-channel
      allowlist parameter with 'inherit' / None semantics.
    - _validate_channel_authorization enforces all three rules at
      construction: claim-source requirement, linker presence for
      require_link=True (elevated from no-op — must not ship
      unenforced), and NativeIdAllowlist(channel=...) typo detection.
      Combinator-walking via _flatten_allowlists catches nested
      misconfigs.
    - host.authorize(...) for the native-id pipeline: open path returns
      Allowed with auto-issued <channel>:<native_id> isolation key (or
      the existing key when the identity has been seen); ABSTAIN on a
      claim-required allowlist maps to
      Denied(reason_code='allowlist_requires_link') until Wave 2 wires
      the linker to convert it to LinkRequired.
    
    Spec / ADR:
    - docs/specs/002-python-hosting-channels.md: Wave-1 status updated
      to reflect the linker-presence rule elevation and the
      host.authorize landing; new sub-sections (codec contract, drain,
      echo cursor); Qs 18 / 21 DeliveryReport references purged; new
      resolved Qs 36–40 covering the strict-ephemeral default, codec
      contract, DeliveryReport removal, echo cursor, and drain.
    - docs/decisions/0026-hosting-channels.md: Q12 DeliveryReport
      reference purged; Q16 updated to reflect Wave-1 landing; new
      resolved Qs 20 (codec contract) + 21 (strict ephemeral / drain /
      echo cursor).
    
    Tests:
    - New tests/test_authorization.py (35 cases) covering every Wave-1
      built-in, the three validator rules, combinator decision
      semantics, and host.authorize across open / allow / deny /
      abstain-with-claim-dep / abstain-without-claim-dep paths plus
      existing-key reuse and verified-claims propagation.
    - tests/test_host.py: TestDeliverResponse rewritten for the bool
      return + runner.scheduled-count assertions; new tests for
      IDENTITIES variant + echo idempotency.
    - tests/test_runner.py: strict-ephemeral now expects RuntimeError;
      allow_in_process_runner opt-in tests; shutdown drain test;
      payload_mode default test.
    - tests/test_types.py: TestDeliveryReport removed; new
      TestDurableTaskPayloadMode + TestResponseTargetIdentities.
    
    Validation: 178 tests pass, 91% coverage, fmt + lint + pyright +
    mypy clean.
    
    Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
    
    * docs(hosting): add mermaid flow diagrams to ADR, spec, README
    
    Insert the 10 hosting flow diagrams reviewed in
    python/.user/hosting-diagrams.md into the public docs:
    
    - README: runtime topology (1a) + cross-link to the spec for the
      richer set.
    - ADR: runtime topology, channel contribution shape, and authorization
      decision (1a, 1b, 3) at the end of 'Conceptual API shape'.
    - Spec: all 10 diagrams — 1a/1b at the top of API Surface, 2 in
      Canonical flow, 3 in Authorization profiles, 4-7 in Scenarios 6-8,
      8 in Codec contract, 9 in Echo idempotency, 10 in Scenario 9.
    
    Doc-only; no API or behaviour change.
    
    Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
    
    * feat(hosting): add opt-in disk persistence via state_dir
    
    Long-running hosts (always-on container, single-VM bot, local dev) lose
    state on every restart today. Add an opt-in disk persistence layer under
    a new `state_dir` constructor parameter on `AgentFrameworkHost` that
    survives process restarts without taking on a heavyweight database
    dependency.
    
    Backed by `diskcache` (installed via the new `[disk]` optional extra).
    An OS-level advisory file lock guarantees single-owner semantics so two
    hosts pointed at the same directory cannot double-execute scheduled
    pushes.
    
    What persists when `state_dir` is set:
    
    - Pending durable-task records — scheduled-but-not-yet-completed pushes
      replay on the next host startup via `InProcessTaskRunner.resume()`.
      Records that crashed mid-attempt resume with the already-consumed
      retry budget (no full-budget re-grant).
    - `_session_aliases` — per-isolation-key session-id rewrites.
    - `_active` — most-recently-active channel per isolation key.
    - `_identities` — `ChannelIdentity` rows for fan-out targeting,
      including nested mutations of the form
      `self._identities[ik][channel] = identity`.
    
    The `state_dir` parameter accepts any of:
    
    - `None` — today's purely in-memory behaviour.
    - `str` / `PathLike` — single root; host auto-creates `runner/` and
      `sessions/` subfolders.
    - `HostStatePaths` TypedDict / plain mapping — per-component overrides
      routed to different roots. Unknown keys raise `ValueError` to surface
      typos early.
    
    Unpicklable push payloads raise `PushPayloadNotPicklable` eagerly from
    `schedule()` so issues surface at the call site rather than on the
    next restart. Corrupt on-disk records are quarantined-and-logged; the
    runner never crashes on resume.
    
    Live `AgentSession` objects stay in memory and are rehydrated lazily
    by the history provider on the next turn.
    
    - New modules: `_persistence.py` (lock + normalisation),
      `_state_store.py` (session-bookkeeping store).
    - Runner rewrite: 4-state model (`pending` / `succeeded` / `failed`
      / `cancelled`); the transient `running` state was a bug that caused
      resume to skip records that crashed mid-handler.
    - New tests: `test_runner_disk.py` (8 tests), `test_host_disk.py` (8
      tests). 194 passed total. pyright + mypy + ruff clean.
    - README: new "Optional disk persistence" section with code samples.
    
    Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
    
    * feat(hosting): add checkpoints to state_dir + fix host docstring
    
    Three related polish changes on top of the disk-persistence landing:
    
    1. Extend `state_dir` to cover workflow checkpoints. Adds
       `checkpoints` as a third `HostStatePaths` key. Single-path form
       (`state_dir="/foo"`) now also auto-derives `/foo/checkpoints/`
       for workflow targets (equivalent to passing
       `checkpoint_location="/foo/checkpoints"`). The mapping form lets
       workflow callers opt out by omitting the key, or route checkpoints
       to a different volume.
    
       Conflict / precedence rules:
       * Explicit `checkpoint_location` always wins over the state_dir
         derived path; a warning surfaces the double-config.
       * Single-path `state_dir` + non-Workflow target → checkpoints path
         silently ignored (no eager directory creation either).
       * Mapping form with `checkpoints` + non-Workflow target → warn
         (almost certainly dead config).
       * Derived path with a workflow that already has its own
         `checkpoint_storage` → same `RuntimeError` as the explicit
         parameter triggers, so ownership stays unambiguous.
    
       Checkpoint persistence uses `FileCheckpointStorage` from the
       framework core — no extra dependency. Only `runner` and
       `sessions` require the `[disk]` extra.
    
    2. Move `AgentFrameworkHost.__init__` parameter docs from `Args:` to
       `Keyword Args:` for every parameter after the `*`. Only `target`
       remains under `Args:`. Brings the docstring in line with the
       actual signature (the params have always been keyword-only).
    
    3. `HostStatePaths` already existed as a TypedDict but did not cover
       `checkpoints`; updated to document the new key with the same
       per-attribute docstring style as `runner` / `sessions` so editors
       can surface help on the keys.
    
    Validation: 201 tests pass (was 194; +7 checkpoint integration tests
    in test_host_disk.py). pyright + mypy + ruff + bandit clean.
    
    Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
    
    * feat(hosting): add core IdentityLinker authorization seam
    
    Fold the core IdentityLinker pieces into the hosting-core PR so the
    authorization surface no longer has a deferred Wave-2 placeholder.
    Provider-specific linkers (for example Entra OAuth helpers) can now plug
    into core without core depending on an IdP SDK.
    
    Core additions:
    - Add LinkChallenge, LinkedIdentity, LinkResolution, and IdentityLinker.
      IdentityLinker.resolve(identity) is a single-call decision that returns
      either a linked identity with verified claims or a challenge the channel
      can render.
    - Enable LinkedClaimAllowlist end-to-end. It now abstains pre-link and
      allows/denies post-link against verified claims, including multi-valued
      claims such as groups.
    - Add AuthPolicy factories for common allowlist shapes.
    - Extend Allowed with verified_claims and claim_source for audit/telemetry
      without requiring callers to re-derive how the decision was made.
    
    Host behavior:
    - identity_linker is now typed as IdentityLinker | None.
    - authorize() supports open, native-id, forced-link, and linked-claim
      profiles end-to-end.
    - require_link=True resolves via the linker and returns LinkRequired when
      the identity is not linked.
    - claim-based allowlists use channel-emitted verified_claims when present,
      or linker-resolved claims otherwise.
    - authorize() remains decision-only and does not mutate _identities/_active;
      identity registry writes remain on the actual request execution path.
    
    Docs/tests:
    - Remove Wave-1/Wave-2 language from core/spec/ADR surfaces touched here.
    - Update the spec/ADR to describe the core linker seam and provider-specific
      linker packages.
    - Add authorization tests for linker challenges, linked identities, linked
      claim allowlists, channel-emitted claims, AuthPolicy factories, and the
      no-mutation contract.
    
    Validation: 214 tests pass, pyright/mypy/ruff clean.
    
    Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
    
    * feat(hosting): add link-store path to state_dir
    
    Identity linking introduces host-adjacent state that needs the same state_dir treatment as runner, session, and checkpoint state. Add a links component to the host state paths so applications and linker packages have a typed, discoverable persistence location.
    
    Changes:
    - Extend HostStatePaths with links and include it in state_dir normalization (state_dir/links/ for the single-path form).
    - Add SupportsLinkStorePath, an optional protocol for identity linkers that accept a host-provided link-store path.
    - AgentFrameworkHost now offers state_dir links to compatible linkers, warns when an explicit links path is supplied without a linker, and warns when the configured linker manages persistence directly instead of implementing SupportsLinkStorePath.
    - Update README and spec text to document the link-store component and clarify that concrete linkers still own the storage format.
    - Add disk-state tests for compatible, missing, and non-configurable linkers.
    
    Validation: 217 tests pass, pyright/mypy/ruff clean.
    
    Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
    
    ---------
    
    Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
  • Python: Channel spec (#5549)
    * first iteration of channel spec
    
    * added deny link setup
    
    * clarify invocation hook role and dedupe ADR/spec
    
    ADR 0026:
    - Tighten Decision Outcome Summary so each concept is mentioned once;
      defer full definitions to the Terminology section.
    - Update ChannelInvocationHook bullet to match the clarified gap #7
      language (uniform ChannelRequest envelope, hook timing, illustrative
      examples).
    - Drop Decision Drivers bullets that just restated Business Goals;
      cross-link to the goals section instead.
    - Replace the More Information bullet list with a pointer to Non-Goals.
    
    Spec 002:
    - Trim requirement #21 to point at the canonical LinkPolicy section
      instead of restating the full contract.
    - Add a #linkpolicy-and-trust_level subsection anchor for cross-refs.
    - Trim the Terminology LinkPolicy entry's two-hosts caveat (canonical
      version stays in the Key Types section).
    
    Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
    
    * updated adr and spec
    
    * Update hosting channels ADR and spec
    
    - Document FoundryHostedAgentHistoryProvider roundtrip of additional_properties namespaces via the agent_framework container key on stored OutputItems.
    - Add Foundry storage gap subsection capturing the update_item service ask required for post-push delivery_tracking[] mutation.
    - Triage open questions: 18 resolved (now in a Resolved Questions decisions log), 3 notes-updated, 6 unchanged. Capture spec-body follow-ups implied by the resolutions in a new Decisions-driven follow-ups subsection.
    
    Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
    
    * Refine hosting ADR + spec: A2A/MCP-tool channels, store-parameter matrix, open-question pass
    
    - Surface A2A and MCP-tool channels as explicitly designed-in but fast-follow work after the first Responses + Invocations + Telegram release. Updated ADR business goals, non-goals, and More Information; added spec reqs #25 (A2AChannel) and #26 (MCPToolChannel) under v1 Fast Follow; renumbered the WhatsApp/Teams entry to #27.
    - New 'The Responses store parameter' subsection in the spec: 2x3 destination matrix making explicit that 'store' has no canonical meaning at the hosted-agent layer — the developer decides what it maps to across service-side, hosted-agent storage, and caller-side. Includes design properties on forwarding-vs-mapping, per-deployment documentation responsibility, and richer storage vocabulary via OpenAI's extra_body.
    - Fixed contradicting spec text that previously claimed ResponsesChannel maps store=False to session_mode=disabled by default; updated channel options table, session_mode terminology entry, and Scenario 3 prose/comment to match the new model.
    - Renamed FoundryHistoryProvider -> FoundryHostedAgentHistoryProvider throughout the spec (9 occurrences) so the name reinforces the intended hosted-agent use case.
    - ADR open-questions pass: walked through all 15 entries with the user. 13 resolved (moved to a new 'Resolved Questions (decisions log)' table), 2 kept open with refined wording (Q6 'Channel' GA name, Q14 Responses WS subprotocol). Added a 'Decisions-driven follow-ups' bullet list capturing the spec-body / sample edits implied by the resolutions.
    
    Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
    
    * Hosting ADR + spec: rename Teams channel to Activity Protocol, add multi-user conversation design
    
    - Rename the planned Teams channel to ActivityChannel (package agent-framework-hosting-activity). Promoted to req #27 (v1 fast follow) alongside A2A and MCP-tool, with native translations from Activity Protocol objects to AF types so the contract is explicit rather than implicit through Invocations. Channel sits behind Azure Bot Service, which fronts Teams / Web Chat / Slack / etc. Naming reserves a TeamsChannel name for any future direct-to-Teams transport that bypasses Bot Service (now stretch req #28 with WhatsApp). ResponseTarget channel ids and JSON examples updated from "teams" to "activity". Appendix B updated to acknowledge that ActivityChannel deliberately reuses the Bot Service connector model (the no-connector stance applies to the rest of the channel set).
    
    - Add first-class design for multi-user surfaces (Telegram groups / supergroups / forum topics; Activity Protocol groupChat and team channels). Cleanly separate user identity (ChannelIdentity.native_id = from.id / from.aadObjectId) from conversation locator (ChannelRequest.conversation_id = chat.id (+ message_thread_id / replyToId)). New per-channel options: conversation_scope (per_user / per_user_per_conversation (default in groups) / per_conversation) and accept_in_group addressing rule (mention_only (default) / command_only / mention_or_command / all). Specifies originating reply must include conversation + thread locator, ChannelPush behavior in groups, link-ceremony privacy (challenges redirected to user DMs), and the Activity-channel mapping for personal / groupChat / channel conversationType plus Teams replyToId threading. Broadcast Telegram Channels and adaptive-card Invoke activity flows scoped as fast follow.
    
    Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
    
    * docs(hosting): rename RunHandle → ContinuationToken; HostStateStore (file-based v1); align agentserver dependency posture
    
    - Rename RunHandle → ContinuationToken (opaque URL-safe `token` field) throughout
      ADR + spec; update routes to /{continuation_token}; spec out equivalent
      continuation-token support for the Invocations channel (Q20 done).
    - Introduce HostStateStore as the single persistence seam for host-execution
      metadata (continuation tokens, identity-link grants, last-seen records).
      V1 default: FileHostStateStore (atomic JSON-per-record under ./.af-hosting/,
      per-namespace TTLs) — background runs and link grants now survive host
      restarts. InMemoryHostStateStore for tests; pluggable Cosmos / SQL / Redis
      remain v1 fast follow under req #23. Closes Q9, Q11, Q14.
    - Drop blanket "no agentserver dependency" claims. Hosting core is still
      independent of agentserver, but channel packages MAY consume lower-level
      building blocks (notably the Foundry response-store SDK that
      FoundryHostedAgentHistoryProvider builds on).
    
    Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
    
    * docs(hosting): swap Scenarios 6 and 7 so the linker comes before cross-channel continuity
    
    Scenario 6 (cross-channel continuity) previously forward-referenced Scenario 7
    (linker) twice, since continuity depends on the link/merge ceremony. Invert the
    order so the linker scenario establishes the mechanism first and the continuity
    scenario builds on it. Update internal cross-references, the require_link
    section anchor, and Scenario 8's prerequisites/comment to match. Also tightened
    the new Scenario 7's closing note to point at HostStateStore (file-based
    default) for cross-host continuity, and dropped a stale MfaIdentityLinker
    reference from the linker variants paragraph (Q13 dropped MFA from phase 1).
    
    Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
    
    * docs(hosting): rewrite Scenario 7 as trusted-relay + add ResponseTarget.identities
    
    The previous Scenario 7 (cross-channel chat continuity) implied two independent
    auto-issued isolation_keys would converge by themselves — they don't, that
    needs a linker. Replace with a more realistic and complementary scenario:
    a trusted server-side application backend exposes Responses + Telegram against
    the same agent and uses extra_body to carry app-internal identity hints
    (app_user_id, push_to_telegram_chat_id) that a Responses run_hook translates
    into both an isolation_key promotion and a push to a known Telegram chat.
    Includes a closing variant pointing back at Scenario 6's linker for the
    no-app-table flow.
    
    Adds the ResponseTarget.identities([ChannelIdentity(...)]) variant to the
    type table and req #12 to support 'caller already knows the channel-native
    recipient' delivery without going through the link store. Bypasses the link
    store but still consults LinkPolicy per delivery.
    
    Drops MfaIdentityLinker references from req #11, req #24, and the linker
    helpers table (Q13 had already dropped MFA from phase 1; the spec body just
    hadn't caught up). Marks ADR Q8 follow-up done.
    
    Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
    
    * docs(hosting): wire FileCheckpointStorage into Scenario 9 + show resume-from-checkpoint flow
    
    Scenario 9 now builds the workflow with a FileCheckpointStorage so executor
    frames are persisted across runs, and demonstrates how the run_hook surfaces
    a caller-supplied resume_from_checkpoint into request.attributes so the host's
    workflow dispatch can pass it to Workflow.run(checkpoint_id=...). Closing
    paragraph clarifies that CheckpointStorage is workflow-runtime state, kept
    structurally separate from HostStateStore and ContextProvider — three
    protocols that MAY share a backend but stay independently typed.
    
    Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
    
    * docs(hosting): emphasize result richness in Scenario 10 (channels are not limited to result.text)
    
    Add a 'Result is rich, not just text' callout under the channel-authoring
    sample. Inventories the typed Contents on the underlying AgentRunResult
    (TextContent, DataContent, UriContent, FunctionCallContent /
    FunctionResultContent, HostedFile/VectorStoreContent, UsageContent,
    TextReasoningContent, ErrorContent + additional_properties), the typed
    structured output via result.value, and shows concrete examples per channel
    shape: Telegram (MarkdownV2 + sendPhoto/sendAudio + inline keyboards),
    Responses (full content-list round-trip), chat UI (GFM/HTML +
    collapsible tool/reasoning panels), voice (TTS + earcons), typed RPC
    (result.value first). result.text is positioned as a convenience for
    single-string channels, not the contract.
    
    Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
    
    * spec: add TeamsChannel (microsoft/teams.py) as fast-follow req #28
    
    Add a Teams-native channel package built on the MIT-licensed
    microsoft/teams.py SDK as fast-follow alongside the generic
    ActivityChannel (req #27). Where ActivityChannel targets the
    generic Activity Protocol surface, TeamsChannel exploits
    Teams-specific affordances the generic protocol does not surface
    natively: Adaptive Cards (typed builder), streamed replies,
    AI-generated badge, feedback controls + form, suggested-prompt
    chips, inline citations, modal Dialogs, Message Extensions
    (action / search / link unfurling), proactive / targeted /
    threaded messages, and SSO via MSAL.
    
    Mounts the SDK's App into the host's Starlette app via a custom
    HttpServerAdapter; reuses the same host-tracked-session family
    as ActivityChannel (from.aadObjectId -> ChannelIdentity). The
    SDK already ships a 'Build an agent using Microsoft Agent
    Framework' guide so the integration story is direct.
    
    Renumber the WhatsApp / direct-to-Teams stretch item to req #29
    and clarify its 'direct-to-Teams' placeholder is a future
    transport that bypasses both Bot Service and the teams.py SDK.
    
    Add the SDK to Dependencies & Commitment Status as a proposed
    runtime dep of agent-framework-hosting-teams.
    
    Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
    
    * spec: clarify direct-to-Teams stretch as speculative (no Bot Service)
    
    Split the WhatsApp + direct-to-Teams stretch entry into two
    distinct items and reword the direct-to-Teams item to be honest
    about its current feasibility:
    
    - It MUST not rely on Azure Bot Service (otherwise it is just
      ActivityChannel / TeamsChannel under a different name).
    - No such transport is publicly available today: Graph chat APIs
      and microsoft/teams.py both ultimately route through Bot Service
      for the bot-as-conversation-participant pattern.
    - The slot is kept on the roadmap to preserve the naming line in
      case Microsoft ships a Bot-Service-free transport (native Teams
      REST/RPC, a Graph subscription strong enough to drive both
      inbound and outbound message flow, ...).
    - Reaffirm TeamsChannel (req #28) as the canonical Teams channel
      until then.
    
    Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
    
    * spec: clarify TeamsChannel still rides on Bot Service in v1; add audience table
    
    Make explicit that TeamsChannel (req #28) uses Azure Bot Service
    in v1 — the microsoft/teams.py SDK is a higher-level Pythonic
    wrapper over the same Activity Protocol pipeline that
    ActivityChannel exposes raw. The difference is what the developer
    writes against, not the network path. A Bot-Service-free Teams
    transport is not currently possible and stays tracked as the
    speculative req #30.
    
    Add the ActivityChannel vs TeamsChannel audience comparison table
    to req #28 so the choice is obvious to readers:
    - ActivityChannel: maximum portability across all Bot Service-fronted channels.
    - TeamsChannel: Teams-first deployments wanting Cards / Dialogs /
      Message Extensions / citations / feedback / suggested prompts /
      SSO out of the box.
    
    Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
    
    ---------
    
    Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
  • .NET: Add Hosted-MemoryAgent sample with isolation key plumbing (#5692) (#5702)
    * .NET: Add Hosted-MemoryAgent sample with isolation key plumbing (#5692)
    
    Adds HostedSessionContext + HostedSessionIsolationKeyProvider in Microsoft.Agents.AI.Foundry.Hosting so AIContextProviders (notably FoundryMemoryProvider) can scope per user via the platform's x-agent-user-isolation-key / x-agent-chat-isolation-key headers.
    
    - New types: HostedSessionContext (sealed), HostedSessionContextExtensions (public Get, internal Set), abstract HostedSessionIsolationKeyProvider (async), internal PlatformHostedSessionIsolationKeyProvider mapping ResponseContext.Isolation.
    
    - AgentFrameworkResponseHandler now resolves the provider, tags fresh sessions, and validates resumed sessions against the live request (strict 403 'Hosted session identity context mismatch' on any mismatch; 500 on null keys).
    
    - New shared sample project Hosted_Shared_Contributor_Setup hosts DevTemporaryTokenCredential and DevTemporaryLocalSessionIsolationKeyProvider plus AddDevTemporaryLocalContributorSetup. All 9 existing responses samples migrated to consume it so local runs keep working under the strict isolation contract.
    
    - New Hosted-MemoryAgent sample: travel assistant wired through FoundryMemoryProvider with stateInitializer reading session.GetHostedContext().UserId. Includes Dockerfile, smoke.ps1, agent.yaml/manifest.
    
    - New IT scenario 'memory' in Foundry.Hosting.IntegrationTests + MemoryHostedAgentFixture + MemoryHostedAgentTests. Verified end to end against the tao Foundry project.
    
    - ADR 0026 captures the design tree.
    
    * Address PR review feedback
    
    - Dockerfile: add header noting it targets NuGet builds; contributors must use Dockerfile.contributor for ProjectReference source builds.
    
    - PlatformHostedSessionIsolationKeyProvider: doc said 'returns context with empty values'; corrected to 'returns null' which the handler treats as 500.
    
    - FakeHostedSessionIsolationKeyProvider: doc clarifies that null configurations are allowed for testing the handler error path.
    
    - HostedSessionContextExtensions.SetHostedContext: enforce write-once with InvalidOperationException; doc + xml exception updated.
    
    - AgentFrameworkResponseHandler: cache PlatformHostedSessionIsolationKeyProvider as static readonly to avoid per-request allocation.
    
    - MemoryHostedAgentTests: tighten waits from 20s to 5s (FoundryMemoryProvider defaults UpdateDelay=0; ingestion ~3s).
    
    - Sample Program.cs imports reordered to satisfy IDE0005.
    
    * Add HostedFoundryMemoryProviderScopes built-in helpers (#5692)
    
    Addresses review feedback from @lokitoth on Hosted-MemoryAgent/Program.cs:54.
    
    - New HostedFoundryMemoryProviderScopes static class with PerUser, PerChat, PerUserAndChat factories returning Func<AgentSession?, FoundryMemoryProvider.State>.
    
    - All helpers throw InvalidOperationException when GetHostedContext() is null, with a message pointing at writing a custom stateInitializer for non-hosted scenarios.
    
    - New HostedFoundryMemoryScope enum and AddHostedFoundryMemoryProvider DI extension (two overloads: explicit AIProjectClient and DI-resolved). Singleton lifetime. Default scope = PerUser.
    
    - Hosted-MemoryAgent sample and the memory IT scenario container both swap their inline lambdas for HostedFoundryMemoryProviderScopes.PerUser().
    
    - 14 new unit tests (241/241 hosting unit tests pass).
    
    * Replace HostedFoundryMemoryScope enum with Func<...> parameter (#5692)
    
    Address PR review feedback from @westey-m: enums are a breaking-change hazard when extended, and the enum was redundant with the existing HostedFoundryMemoryProviderScopes static class.
    
    - Delete HostedFoundryMemoryScope.cs.
    
    - AddHostedFoundryMemoryProvider DI extensions now take Func<AgentSession?, FoundryMemoryProvider.State>? stateInitializer = null. When null, default to HostedFoundryMemoryProviderScopes.PerUser().
    
    - Callers pick a built-in helper (PerUser/PerChat/PerUserAndChat) or pass a custom delegate. New built-ins are a single static method addition with zero impact on existing callers.
    
    - Tests updated; 244/244 hosting unit tests pass.
    
    * Fix isolation context resume for externally-created conversations (#5692)
    
    Branch on the session's existing hosted-context (not on conversation_id presence) so a conversation provisioned externally (e.g. via conversations.CreateProjectConversationAsync) is treated as fresh on first hosted-agent request and stamped, rather than rejected with 403 hosted_session_identity_mismatch. Strict equality is preserved on real resume of an already-stamped session.
    
    Also tighten dotnet/global.json to version 10.0.204 + rollForward latestPatch so local builds match the CI Docker image SDK and avoid 10.0.300 dotnet format stripping required usings.
    
    * Revert global.json SDK pin to upstream (#5692)
    
    The 10.0.204 + latestPatch pin from the previous commit broke the dotnet-format CI job (hostfxr_resolve_sdk2 could not find a compatible SDK in the mcr.microsoft.com/dotnet/sdk:10.0 image). Restore upstream 10.0.200 + minor; local Release builds with SDK 10.0.300 should set GITHUB_ACTIONS=true to bypass the auto-format-on-build target.
  • Python: information-flow control prompt injection defense (#5331)
    * Python: Information-flow control based prompt injection defense (#5024)
    
    * fides integration
    
    * documentation
    
    * documentation
    
    * documentation
    
    * human-approval on policy violation
    
    * numenous hyena 'works'
    
    * IFC based implementation
    
    * minor edits in documentation
    
    * rebasing the branch and running the email example
    
    * Add security tests for IFC middleware
    
    * Fix Role.TOOL NameError in approval handling
    
    * tiered labelling scheme
    
    * 3 tier labelling scheme in middleware
    
    * Adapt security middleware to list[Content] tool results
    
    * Refactor SecureAgentConfig as context provider and address Copilot review comments
    
    * Update FIDES docs to reflect context provider pattern and update code for ContextProvider rename
    
    * Fix security examples: use OpenAIChatClient instead of non-existent AzureOpenAIChatClient
    
    * Address PR review: consolidate security modules, remove ContentLineage, update docs
    
    * remove unrelated files
    
    * remove comment from _tools.py and rename decision file
    
    * Fix CI failures: Bandit B110, broken md links, hosted approval passthrough
    
    * apply template to decision doc 0024
    
    * minor fixes to decision doc 0024
    
    ---------
    
    Co-authored-by: Aashish <t-akolluri@microsoft.com>
    
    * Python: follow up FIDES security flow (#5330)
    
    * Python: follow up FIDES security flow
    
    Refine the secure approval path, mark the security classes with the FIDES experimental feature label, and clean up the related docs/tests. Also fix workspace-level validation regressions uncovered while running the full Python check suite.
    
    Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
    
    * Python: remove FIDES GitHub MCP sample
    
    Drop the GitHub MCP security sample from the FIDES follow-up branch while keeping the remaining security docs and samples intact.
    
    Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
    
    ---------
    
    Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
    
    * Address PR review: fix paths and update FIDES implementation (#5352)
    
    * Python: updated import naming and comment from review (#5421)
    
    * updated import naming and comment from review
    
    * Add approval replay None call-id test
    
    Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
    
    ---------
    
    Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
    
    * Python: Address PR 5331 comments and track sesssion while calling Agent in email_security_example (#5446)
    
    * Address PR review: fix paths and update FIDES implementation
    
    * Address PR comments and add session tracking in email example in samples
    
    * Fix session creation and resolve merge conflict in docstring example
    
    * Resolve merge conflict in docstring example
    
    * Python: add test for empty-message pruning in approval result replacement (#5617)
    
    Adds test coverage for the second-pass logic in
    `_replace_approval_contents_with_results` that removes messages whose
    `contents` list becomes empty after first-pass content removal.
    
    Addresses review comment on PR #5331:
    https://github.com/microsoft/agent-framework/pull/5331#discussion_r3129039445
    
    Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
    
    ---------
    
    Co-authored-by: shrutitople <shruti.tople@gmail.com>
    Co-authored-by: Aashish <t-akolluri@microsoft.com>
    Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
  • Python: Add support for Foundry Toolboxes (#5346)
    * Add support for the Foundry Toolbox in MAF
    
    Introduces a Foundry Toolbox integration: FoundryChatClient gains a
    get_toolbox() helper plus select_toolbox_tools(), normalize_tools in
    the core package flattens tool-collection wrappers (ToolboxVersionObject
    and generic iterables, while leaving Pydantic BaseModel instances
    alone), and the new agent_framework.foundry namespace re-exports the
    toolbox helpers. Ships with unit tests, a sample, and a design doc.
    
    azure-ai-projects is pinned to the public >=2.0.0,<3.0 range and the
    lockfile resolves from public PyPI. The toolbox test module skips when
    Toolbox* types are unavailable so CI stays green until the public 2.1.0
    SDK lands. OMC tooling directories (.omc/, .omx/) are gitignored.
    
    * Update to latest azure ai projects package
    
    * Improve sample
    
    * Rename ADR to 0025
    
    * Update ADR
    
    * Apply suggestion from @alliscode
    
    Co-authored-by: Ben Thomas <ben.thomas@microsoft.com>
    
    * Improve samples
    
    * Update test
    
    ---------
    
    Co-authored-by: Ben Thomas <ben.thomas@microsoft.com>
  • Python: Add Hyperlight CodeAct package and docs (#5185)
    * initial work on code_mode
    
    * updated samples
    
    * updates to codeact
    
    * udpated codeact
    
    * Draft CodeAct ADR and sample updates
    
    Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
    
    * initial implementation and adr and feature
    
    * Python: Limit Hyperlight wasm backend to Python <3.14
    
    Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
    
    * Python: Fix CI for Hyperlight CodeAct PR
    
    Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
    
    * Python: Run Hyperlight integration when available
    
    Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
    
    * Python: Address Hyperlight review feedback
    
    Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
    
    * Python: Simplify Hyperlight file mount inputs
    
    Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
    
    * Python: Accept Path host paths in Hyperlight mounts
    
    Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
    
    * Python: Fix Hyperlight mount typing for CI
    
    Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
    
    * temp run integration test
    
    * Python: Strengthen Hyperlight real sandbox tests
    
    Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
    
    * added additional tests
    
    * Python: Simplify Hyperlight CodeAct API
    
    Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
    
    * set tests as non-integration
    
    * Retry Hyperlight allowed-domain registration
    
    Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
    
    * Gate Hyperlight integration tests by runtime support
    
    Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
    
    * Fix Hyperlight skip test on Python 3.14
    
    Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
    
    * Delay Hyperlight runtime probe until test execution
    
    Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
    
    * Relax Hyperlight Windows integration stdout assertion
    
    Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
    
    * Scan Hyperlight output directory for artifacts
    
    Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
    
    * Retry Hyperlight output artifact collection
    
    Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
    
    * Harden Hyperlight integration output assertions
    
    Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
    
    * Retry Hyperlight read-back check in integration test
    
    Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
    
    * Simplify Hyperlight integration write assertion
    
    Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
    
    * Avoid pathlib in Hyperlight integration sandbox
    
    Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
    
    * Use socket network check in Hyperlight sandbox
    
    Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
    
    * Replace blocked Azure AI Search blog link
    
    Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
    
    * Clarify Hyperlight guest stdlib limits
    
    Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
    
    * Use _socket in Hyperlight integration sandbox
    
    Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
    
    * Handle Hyperlight mounted file paths
    
    Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
    
    * Broaden Hyperlight sandbox path fallbacks
    
    Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
    
    * Search Hyperlight guest mounts recursively
    
    Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
    
    * Split Hyperlight mount coverage
    
    Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
    
    * Split Hyperlight live network tests
    
    Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
    
    * Fix Hyperlight file-write test on Windows
    
    Enable the sandbox filesystem by providing a workspace_root so
    /output is mounted. Remove os.path.exists assertion (unsupported
    in WASM guest) and fix Content data assertion to use .uri.
    Skip the network integration test on Windows where the WASM
    sandbox lacks the encodings.idna codec.
    
    Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
    
    * Address PR review: ADR intro, manual wiring sample, doc clarifications
    
    - Add CodeAct introduction section to ADR for unfamiliar readers
    - Clarify 'less runtime efficient' con with specific overhead description
    - Add note in Python impl doc clarifying ADR vs impl doc split
    - Explain why before_run hooks must be per-run (CRUD, concurrency, approval)
    - Rename code_interpreter variable to codeact in E2E sample
    - Add manual static wiring sample (codeact_manual_wiring.py)
    - Add 'when to use which pattern' guidance to samples README
    
    Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
    
    * Address PR #5185 review comments and add .NET CodeAct design doc
    
    - Fix async callback: _make_sandbox_callback returns sync wrapper with
      thread + asyncio.run() bridge (was broken with real Wasm FFI)
    - Fix stale output: clear output_dir before each sandbox.run() call
    - Fix blocking event loop: _run_code now async with asyncio.to_thread()
    - Revert _agents.py options['tools'] injection (unnecessary; provider
      uses context.extend_tools())
    - Revert SessionContext.options docstring back to read-only
    - Add real-sandbox test fixtures (shared/restored/fresh)
    - Add 8 new real-sandbox tests for callback round-trip, stale output,
      event loop non-blocking, basic execution, stdout/stderr, errors,
      snapshot/restore, and tool registration
    - Add comprehensive .NET HyperlightCodeActProvider design document
    
    Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
    
    * Update hyperlight README with code snippets and remove Public API section
    
    Replace bare export list with Quick Start code examples covering the
    context provider, standalone tool, manual static wiring, and file
    mounts / network access patterns.
    
    Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
    
    ---------
    
    Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
  • Python: [BREAKING] Python: move Azure AI embeddings to Foundry (#5056)
    * renamed AzureAIINferenceEmbeddings and lazy load azure-cosmos and env var rename
    
    * updated coverage
    
    * fix readme
  • .NET: [BREAKING] Rename from ServiceStoredSimulatingChatClient to PerServiceCallChatHistoryPersistingChatClient (#4993)
    * Rename from ServiceStoredSimulatingChatClient to PerServiceCallChatHistoryPersistingChatClient
    
    * Address PR comment
  • Python: Foundry Evals integration for Python (#4750)
    * Foundry Evals integration for Python
    
    Merged and refactored eval module per Eduard's PR review:
    
    - Merge _eval.py + _local_eval.py into single _evaluation.py
    - Convert EvalItem from dataclass to regular class
    - Rename to_dict() to to_eval_data()
    - Convert _AgentEvalData to TypedDict
    - Simplify check system: unified async pattern with isawaitable
    - Parallelize checks and evaluators with asyncio.gather
    - Add all/any mode to tool_called_check
    - Fix bool(passed) truthy bug in _coerce_result
    - Remove deprecated function_evaluator/async_function_evaluator aliases
    - Remove _MinimalAgent, tighten evaluate_agent signature
    - Set self.name in __init__ (LocalEvaluator, FoundryEvals)
    - Limit FoundryEvals to AsyncOpenAI only
    - Type project_client as AIProjectClient
    - Remove NotImplementedError continuous eval code
    - Add evaluation samples in 02-agents/ and 03-workflows/
    - Update all imports and tests (167 passing)
    
    Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
    
    * fix: resolve mypy redundant-cast errors while keeping pyright happy
    
    Use cast(list[Any], x) with type: ignore[redundant-cast] comments to
    satisfy both mypy (which considers casting Any redundant) and pyright
    strict mode (which needs explicit casts to narrow Unknown types).
    
    Also fix evaluator decorator check_name type annotation to be
    explicitly str, resolving mypy str|Any|None mismatch.
    
    Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
    
    * fix: CI failures — pyupgrade, evaluator overloads, sample API, reset attr
    
    - Apply pyupgrade: Sequence from collections.abc, remove forward-ref quotes
    - Add @overload signatures to evaluator() for proper @evaluator usage
    - Fix evaluate_workflow sample to use WorkflowBuilder(start_executor=) API
    - Fix _workflow.py executor.reset() to use getattr pattern for pyright
    - Remove unused EvalResults forward-ref string in default_factory lambda
    
    Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
    
    * fix: skip gRPC-dependent observability test
    
    The test_configure_otel_providers_with_env_file_and_vs_code_port test
    triggers gRPC OTLP exporter creation, but the grpc dependency is
    optional and not installed by default. Add skipif decorator matching
    the pattern used by all other gRPC exporter tests in the same file.
    
    Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
    
    * fix: add nosec B101 for bandit assert check
    
    Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
    
    * style: align eval samples with repo conventions
    
    - Move module docstrings before imports (after copyright header)
    - Add -> None return type to all main() and helper functions
    - Fix line-too-long in multiturn sample conversation data
    - Add Workflow import for typed return in all_patterns_sample
    
    Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
    
    * Address PR review feedback: async fixes, sample bugs, deprecation warnings
    
    - Simplify _ensure_async_result to direct await (async-only clients)
    - Replace get_event_loop() with get_running_loop()
    - Narrow _fetch_output_items exception handling to specific types
    - Add warning log when _filter_tool_evaluators falls back to defaults
    - Add DeprecationWarning to options alias in Agent.__init__
    - Add DeprecationWarning to evaluate_response()
    - Rename raw key to _raw_arguments in convert_message fallback
    - Fix evaluate_agent_sample.py: replace evals.select() with FoundryEvals()
    - Fix evaluate_multiturn_sample.py: use Message/Content/FunctionTool types
    - Fix evaluate_workflow_sample.py: replace evals.select() with FoundryEvals()
    - Update test mocks to use AsyncMock for awaited API calls
    
    Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
    
    * Add test coverage for review feedback items
    
    - Add num_repetitions=2 positive test verifying 2×items and 4 agent calls
    - Add _poll_eval_run tests: timeout, failed, and canceled paths
    - Add evaluate_traces tests: validation error, response_ids path, trace_ids path
    - Add evaluate_foundry_target happy-path test with target/query verification
    
    Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
    
    * Fix ruff ISC004 lint error and apply formatter
    
    - Wrap implicit string concatenation in parens in evaluate_multiturn_sample.py
    - Apply ruff formatter to 6 other files with minor formatting drift
    
    Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
    
    * Remove core type changes (extracted to fix/workflow-stale-session branch)
    
    Reverts changes to _agents.py, _agent_executor.py, and _workflow.py
    back to upstream/main. These fixes are now in a separate PR.
    
    Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
    
    * Address PR review round 2: bugs, tests, and architecture
    
    Code fixes:
    - Fix _normalize_queries inverted condition (single query now replicates
      to match expected_count)
    - Fix substring match bug: 'end' in 'backend' matched; use exact set
      lookup for executor ID filtering
    - Fix used_available_tools sample: tool_definitions→tools param, use
      FunctionTool attribute access instead of dict .get()
    - Add None-check in _resolve_openai_client for misconfigured project
    - Add Returns section to evaluate_workflow docstring
    - Cache inspect.signature in @evaluator wrapper (avoid per-item reflection)
    
    Architecture:
    - Extract _evaluate_via_responses as module-level helper; evaluate_traces
      now calls it directly instead of creating a FoundryEvals instance
    - Move Foundry-specific typed-content conversion out of core to_eval_data;
      core now returns plain role/content dicts, FoundryEvals applies
      AgentEvalConverter in _evaluate_via_dataset
    
    Tests:
    - evaluate_response() deprecation warning emission and delegation
    - num_repetitions > 1 with expected_output and expected_tool_calls
    - Mock output_items.list in test_evaluate_calls_evals_api
    - Update to_eval_data assertions for plain-dict format
    - Unknown param error now raised at @evaluator decoration time
    
    Skipped (separate PR): executor reset loop, xfail removal, options alias
    
    Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
    
    * Fix CI: revert test_full_conversation, fix pyright errors
    
    - Revert test_full_conversation.py to upstream/main (the session
      preservation test was incorrectly changed to assert clearing)
    - Fix pyright reportUnnecessaryComparison on get_openai_client() None
      check by adding ignore comment
    - Fix pyright reportPrivateUsage: add public EvalItem.split_messages()
      method and use it in FoundryEvals._evaluate_via_dataset instead of
      accessing private _split_conversation
    
    Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
    
    * Address PR review round 3: reliability, test gaps, cleanup
    
    - Add try/except guard for non-numeric score in _coerce_result
    - Add poll_interval minimum bound (0.1s) to prevent tight loops
    - Add runtime async client check in _resolve_openai_client
    - Remove _ensure_async_result wrapper (10 call sites → direct await)
    - Better error message when queries provided without agent
    - Import-time asserts for evaluator set consistency
    - Remove 28 redundant @pytest.mark.asyncio decorators
    - Add doc note about _raw_arguments sensitive data
    - Tests: tool_called_check mode=any, _normalize_queries branches,
      _extract_result_counts paths, _extract_per_evaluator, bare check
      via evaluate_agent, output_items assertion, modulo wrapping,
      async client check, queries-without-agent error
    
    Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
    
    * Fix CI: ruff S101 assert, pyright and mypy arg-type errors
    
    - Replace module-level assert with if/raise for evaluator set
      consistency checks (ruff S101 disallows bare assert)
    - Add type: ignore[arg-type] and pyright: ignore[reportArgumentType]
      on OpenAI SDK evals API calls that pass dicts where typed params
      are expected (SDK accepts dicts at runtime)
    
    Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
    
    * Address PR review round 4: bugs, reliability, test fixes
    
    - Fix all_passed ignoring parent result_counts when sub_results present
    - Fix _extract_tool_calls: parse string arguments via json.loads before
      falling back to None (real LLM responses use string arguments)
    - Sanitize _raw_arguments to '[unparseable]' to avoid leaking sensitive
      tool-call data to external evaluation services
    - Add NOTE comment on to_eval_data message serialization dropping
      non-text content (tool calls, results)
    - Eliminate double conversation split in _evaluate_via_dataset: build
      JSONL dicts directly from split_messages + AgentEvalConverter
    - Raise poll_interval floor from 0.1s to 1.0s to prevent rate-limit
      exhaustion
    - Fix MagicMock(name=...) bug in test: sets display name not .name attr
    - Fix mock_output_item.sample: use MagicMock object instead of dict so
      _fetch_output_items exercises error/usage/input/output extraction
    
    Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
    
    * Address PR review round 5: reliability, docs, test coverage
    
    Code fixes:
    - Move import-time RuntimeError checks to unit tests (avoids breaking
      imports for all users on developer set-drift mistake)
    - _filter_tool_evaluators now raises ValueError when all evaluators
      require tools but no items have tools (was silently substituting)
    - Add poll_interval upper bound (60s) to prevent single-iteration sleep
    - Log exc_info=True in _fetch_output_items for debugging API changes
    - Fix evaluate() docstring: remove claim about Responses API optimization
    - Validate target dict has 'type' key in evaluate_foundry_target
    - Document to_eval_data() limitation: non-text content is omitted
    
    Tests:
    - TestEvaluatorSetConsistency: verify _AGENT/_TOOL subsets of _BUILTIN
    - TestEvaluateTracesAgentId: agent_id-only path with lookback_hours
    - TestFilterToolEvaluatorsRaises: ValueError on all-tool no-items
    - TestEvaluateFoundryTargetValidation: target without 'type' key
    - Assert items==[] on failed/canceled poll results
    - Mock output_items.list in response_ids test for full flow
    - TestAllPassedSubResults: result_counts=None + sub_results delegation
      and parent failures override sub_results
    - TestBuildOverallItemEmpty: empty workflow outputs returns None
    
    Skipped r5-07 (_raw_arguments length hint): marginal debugging value,
    could leak content size information.
    
    Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
    
    * Fix error message: evaluate_responses() → evaluate_traces(response_ids=...)
    
    The referenced function doesn't exist; the correct API is
    evaluate_traces(response_ids=...) from the azure-ai package.
    
    Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
    
    * Remove dead to_eval_data() method, fix docstring claims
    
    - Remove to_eval_data() from EvalItem (dead code after r4-05 JSONL refactor)
    - Migrate 15 tests from to_eval_data() to split_messages()
    - Update sample to use split_messages() + Message properties
    - Remove unimplemented Responses API optimization docstring claim
    - Update split_messages() docstring to not reference removed method
    
    Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
    
    * Reduce default eval timeout from 600s to 180s (3 minutes)
    
    Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
    
    * Remove dead _evaluate_via_responses method from FoundryEvals
    
    The method was never called — evaluate() uses _evaluate_via_dataset,
    and evaluate_traces() calls _evaluate_via_responses_impl directly.
    
    Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
    
    * Revert unrelated formatting changes to get-started samples
    
    Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
    
    * Fix pyright: remove phantom FoundryMemoryProvider import, apply ruff format
    
    - Remove import of non-existent _foundry_memory_provider module
      (incorrectly kept during rebase conflict resolution)
    - Apply ruff formatter to test_local_eval.py and get-started samples
    
    Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
    
    * Fix eval samples: use FoundryChatClient for Agent()
    
    The upstream provider-leading client refactor (#4818) made client=
    a required parameter on Agent(). Update the three getting-started
    eval samples to use FoundryChatClient with FOUNDRY_PROJECT_ENDPOINT,
    matching the standard pattern from 01-get-started samples.
    
    Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
    
    * Simplify self-reflection sample using FoundryEvals
    
    Replace ~80 lines of manual OpenAI evals API code (create_eval,
    run_eval, manual polling, raw JSONL params) with FoundryEvals:
    
    - evaluate_groundedness() uses FoundryEvals.evaluate() with EvalItem
    - Remove create_openai_client(), create_eval(), run_eval() functions
    - Remove openai SDK type imports (DataSourceConfigCustom, etc.)
    - run_self_reflection_batch creates FoundryEvals instance once,
      reuses it for all iterations across all prompts
    
    Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
    
    * Update eval samples to FoundryChatClient and FOUNDRY_PROJECT_ENDPOINT
    
    - Migrate all foundry_evals samples from AzureOpenAIResponsesClient to FoundryChatClient
    - Update env var from AZURE_AI_PROJECT_ENDPOINT to FOUNDRY_PROJECT_ENDPOINT
    - Use AzureCliCredential consistently across all samples
    - Fix README.md: correct function names (evaluate_dataset -> FoundryEvals.evaluate, evaluate_responses -> evaluate_traces)
    - Update self_reflection .env.example and README.md
    
    Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
    
    * Fix lint errors in eval samples (E501, ASYNC240, formatting)
    
    Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
    
    * Remove evaluate_all_patterns_sample.py (redundant with focused samples)
    
    Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
    
    * Fix async credential mismatch: use azure.identity.aio for async AIProjectClient
    
    AIProjectClient from azure.ai.projects.aio requires an async credential.
    Switch all foundry_evals samples from azure.identity.AzureCliCredential
    to azure.identity.aio.AzureCliCredential. Also pass project_client to
    FoundryChatClient instead of duplicating endpoint+credential.
    
    Close credential in self_reflection sample to avoid resource leak.
    
    Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
    
    * Revert test_observability.py to upstream/main (not our test)
    
    Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
    
    * Address moonbox3 review: sphinx docstrings, pagination, isinstance check
    
    - Convert all Example:: / Typical usage:: code blocks to .. code-block:: python
      format matching codebase convention (both _evaluation.py and _foundry_evals.py)
    - Add async pagination in _fetch_output_items via async for (handles large result sets)
    - Replace hasattr(__aenter__) with isinstance(client, AsyncOpenAI) in _resolve_openai_client
    - Move AsyncOpenAI import from TYPE_CHECKING to runtime (needed for isinstance)
    
    Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
    
    * Fix test failures and address remaining moonbox3 review comments
    
    - Fix tests: use MagicMock(spec=AsyncOpenAI) for project_client mocks
      (isinstance check now requires proper type, not duck-typing)
    - Fix tests: replace mock_page.__iter__ with _AsyncPage helper for async for
    - Fix evaluate_response: auto-extract queries from response messages when
      query is not provided (previously always raised ValueError)
    - Add debug logging when skipping internal _-prefixed executor IDs
    
    Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
    
    * Address Tao's PR review comments on Foundry Evals
    
    - T1: Add comment explaining builtin.* pass-through in _resolve_evaluator
    - T2: Add comment referencing OpenAI evals API for testing_criteria dict
    - T3: Document Mustache-style {{item.*}} template placeholders
    - T4: Document poll loop 60s sleep upper bound rationale
    - T5: Narrow run type to RunRetrieveResponse, use typed field access
      instead of vars()/getattr dance in _extract_result_counts and
      _extract_per_evaluator; use run.error and run.report_url directly
    - T6: Clarify openai_client docstring re: Azure Foundry endpoint
    - T8: Remove misleading empty expected_tool_calls from sample
    - Update tests to match real SDK PerTestingCriteriaResult shape
    
    Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
    
    * Remove unnecessary Any union from run type annotations
    
    RunRetrieveResponse is the correct type — no backward compat needed
    for a brand new feature.
    
    Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
    
    * Accept FoundryChatClient instead of raw AsyncOpenAI
    
    FoundryEvals now takes client: FoundryChatClient as its primary
    parameter instead of openai_client: AsyncOpenAI.  The builtin.*
    evaluators require a Foundry endpoint, so the type should reflect that.
    
    - FoundryEvals.__init__: client: FoundryChatClient replaces openai_client
    - evaluate_traces / evaluate_foundry_target: same change
    - _resolve_openai_client: extracts .client from FoundryChatClient
    - project_client fallback retained for standalone functions
    - All samples updated to construct FoundryChatClient and pass as client=
    - Tests updated (openai_client= → client=)
    
    Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
    
    * Remove implicit 60s upper bound on poll interval
    
    If a developer sets a higher poll_interval, respect it. Only clamp
    to remaining time and enforce a 1s minimum for rate-limit protection.
    
    Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
    
    * Remove 1s floor on poll interval — let the developer control it
    
    Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
    
    * Update python/samples/05-end-to-end/evaluation/foundry_evals/.env.example
    
    Co-authored-by: Eduard van Valkenburg <eavanvalkenburg@users.noreply.github.com>
    
    * Update python/samples/02-agents/evaluation/evaluate_agent.py
    
    Co-authored-by: Eduard van Valkenburg <eavanvalkenburg@users.noreply.github.com>
    
    * Address eavanvalkenburg review (round 2) on Python eval PR
    
    - Rename model_deployment -> model across FoundryEvals and all samples
    - Make model param optional, resolves from client.model
    - Convert EvalResults from dataclass to regular class
    - Remove deprecated evaluate_response() function
    - Refactor splitters: BUILT_IN_SPLITTERS dict + standalone functions
    - Change per_turn_items from classmethod to staticmethod
    - Simplify EvalCheck type alias to use Awaitable[CheckResult]
    - Remove errored property from EvalResults
    - Remove default value from Evaluator protocol eval_name
    - Rename assert_passed -> raise_for_status, add EvalNotPassedError
    - Type agent param as SupportsAgentRun | None
    - Fix Arguments docstring
    - Update __init__.py exports
    - Update all tests and samples
    
    Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
    
    * Move FoundryEvals to foundry package, split tool eval sample
    
    - Move _foundry_evals.py from azure-ai to foundry package
    - Move test_foundry_evals.py to foundry/tests/
    - Update lazy re-exports in agent_framework.foundry namespace
    - Update .pyi type stubs
    - All samples now import from agent_framework.foundry
    - Split tool-call evaluation into evaluate_tool_calls_sample.py
    - Fix all_passed to check errored count from result_counts
    - Fix raise_for_status to include errored item details
    
    Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
    
    * Auto-create FoundryChatClient from env vars when no client provided
    
    FoundryEvals() now works zero-config when FOUNDRY_PROJECT_ENDPOINT and
    FOUNDRY_MODEL environment variables are set. Auto-creates a FoundryChatClient
    under the hood, matching the established env var pattern.
    
    Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
    
    * Fix pyright errors: remove dead _normalize_queries, suppress EvalAPIError check
    
    - Remove unused _normalize_queries function and its tests
    - Add pyright ignore for EvalAPIError None check (defensive guard)
    
    Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
    
    * Support multimodal image content in eval pipeline
    
    Add image (data/uri) content handling to AgentEvalConverter.convert_message()
    so that Content.from_data() and Content.from_uri() image payloads are
    preserved as input_image parts in the Foundry evaluator format.
    
    - Handle Content type='data' and type='uri' → emit input_image parts
    - Add 6 unit tests for image content through convert_message/convert_messages
    - Add integration test verifying images flow through EvalItem → JSONL path
    - Add evaluate_multimodal.py sample demonstrating local image eval
    
    Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
    
    * Address remaining review comments
    
    - Fix project_client docstring to say async-only (not sync/async)
    - Add builtin evaluator name validation warning in _resolve_evaluator
    - Replace getattr with typed attribute access in _poll_eval_run,
      _extract_result_counts, _extract_per_evaluator, _fetch_output_items
    - Remove cast import from _foundry_evals (no longer needed)
    - Tighten _coerce_result: honour explicit 'passed' when both 'score'
      and 'passed' are present; remove performative cast
    - Fix self_reflection sample: add env file existence check
    - Fix traces sample: correct Pattern 2 section label
    - Update all Foundry eval samples to FoundryChatClient + FOUNDRY_MODEL
      (remove AIProjectClient + AZURE_AI_MODEL_DEPLOYMENT_NAME pattern)
    - Add eval_name and OpenAI client docs to FoundryEvals docstring
    - Update test mocks to match typed SDK objects (_MockResultCounts)
    
    Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
    
    * Fix ruff lint errors (E501, SIM108, SIM102)
    
    Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
    
    * Fix pyright errors: type-narrow dict to dict[str, Any], add ignore comments
    
    Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
    
    * Replace ConversationSplitter type alias with Protocol
    
    ConversationSplitter is now a runtime-checkable Protocol with a named
    'conversation' parameter, making the expected signature self-documenting.
    
    ConversationSplit enum members gain a __call__ method so they satisfy
    the protocol directly -- ConversationSplit.LAST_TURN(conversation) works.
    
    This simplifies _split_conversation from an isinstance dispatch to a
    single split(conversation) call.
    
    Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
    
    * Standardize on AZURE_AI_MODEL_DEPLOYMENT_NAME and fix Unicode in samples
    
    - Replace FOUNDRY_MODEL with AZURE_AI_MODEL_DEPLOYMENT_NAME in all
      eval samples to match repo convention
    - Replace Unicode symbols with ASCII equivalents in all eval sample
      print statements to avoid cp1252 encoding errors on Windows
    
    Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
    
    * Update python/samples/03-workflows/evaluation/evaluate_workflow.py
    
    Co-authored-by: Eduard van Valkenburg <eavanvalkenburg@users.noreply.github.com>
    
    * Apply suggestions from code review
    
    Co-authored-by: Eduard van Valkenburg <eavanvalkenburg@users.noreply.github.com>
    
    * Rename ADR 0020 to 0023 (foundry evals integration)
    
    Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
    
    ---------
    
    Co-authored-by: alliscode <bentho@microsoft.com>
    Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
    Co-authored-by: Eduard van Valkenburg <eavanvalkenburg@users.noreply.github.com>
  • .NET: Allow Simulating service stored ChatHistory to improve consistency (#4974)
    * Allow Simulating service stored ChatHistory to improve consistency
    
    * Fixing bug in ServiceStoredSimulatingChatClient
    
    * Addressing PR comments.
    
    * Address PR comments
    
    * Apply suggestion from @SergeyMenshykh
    
    Co-authored-by: SergeyMenshykh <68852919+SergeyMenshykh@users.noreply.github.com>
    
    * Fix bug
    
    ---------
    
    Co-authored-by: SergeyMenshykh <68852919+SergeyMenshykh@users.noreply.github.com>
  • .NET: [Breaking] Update Foundry Agents for Responses API (#4502)
    * Stage
    
    * Add FoundryAgentClient, model param, chatClientFactory, and RAPI samples
    
    - Add model parameter to FoundryAgentClient simple constructor
    - Add chatClientFactory parameter to both constructors
    - Switch to OpenAI.GetProjectResponsesClientForModel for direct Responses API usage
    - Add FoundryAgents-RAPI samples (Step01 Basics, Step02 Multiturn, Step03 FunctionTools)
    - Add solution folder entry for FoundryAgents-RAPI samples
    
    Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
    
    * Add auto-discovery constructor and simplify RAPI samples
    
    - Add FoundryAgentClient constructor that reads AZURE_AI_PROJECT_ENDPOINT and
      AZURE_AI_MODEL_DEPLOYMENT_NAME from environment variables with DefaultAzureCredential
    - Simplify RAPI samples to use auto-discovery (no env var or credential code)
    - Remove Azure.Identity direct references from sample csproj files
    - Update READMEs to document environment variable requirements
    
    Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
    
    * Add remaining RAPI samples (Step04-Step12)
    
    - Step04: Function tools with human-in-the-loop approvals
    - Step05: Structured output with typed responses
    - Step06: Persisted conversations with session serialization
    - Step07: Observability with OpenTelemetry
    - Step08: Dependency injection with hosted service
    - Step10: Image multi-modality
    - Step11: Agent as function tool (agent composition)
    - Step12: Middleware (PII, guardrails, function logging, HITL approval)
    - Update solution file and folder README with all new samples
    
    Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
    
    * Add all RAPI samples (Step09-Step23) and switch to AzureCliCredential
    
    - Step09: MCP client as tools (GitHub server via stdio)
    - Step13: Plugins with dependency injection
    - Step14: Code Interpreter tool
    - Step15: Computer Use tool with screenshot simulation
    - Step16: File Search with vector stores
    - Step17: OpenAPI tools (REST Countries API)
    - Step18: Bing Custom Search
    - Step19: SharePoint grounding
    - Step20: Microsoft Fabric
    - Step21: Web Search with citations
    - Step22: Memory Search with multi-turn conversations
    - Step23: Local MCP via HTTP (Microsoft Learn)
    - Switch all samples (Step04-Step12) to use AzureCliCredential with env vars
    - Update solution file and README with all 23 samples
    - All 23 samples build successfully, tested Step05/06/11/13/21
    
    Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
    
    * Switch Step01-03 samples to AzureCliCredential for consistency
    
    Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
    
    * Clarify connection ID format in SharePoint and Fabric READMEs
    
    Document that SHAREPOINT_PROJECT_CONNECTION_ID and FABRIC_PROJECT_CONNECTION_ID
    should use the connection name (e.g., 'SharepointTestTool'), not the full ARM
    resource URI.
    
    Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
    
    * Normalize env vars, fix structured output, update READMEs with connection ID formats
    
    - Normalize AZURE_FOUNDRY_PROJECT_* env vars to AZURE_AI_PROJECT_ENDPOINT / AZURE_AI_MODEL_DEPLOYMENT_NAME across all samples (Steps 18-22 READMEs + Steps 19-20 Program.cs)
    - Fix RAPI Step05 StructuredOutput to use full constructor with ResponseFormat for streaming JSON
    - Update Deep Research sample to use AzureCliCredential
    - Enrich Bing Grounding README with full ARM resource URI format
    - Fix Bing Custom Search README env var mismatch (BING_CUSTOM_SEARCH_* -> AZURE_AI_CUSTOM_SEARCH_*)
    - Add finding instructions for connection ID and instance name in Bing Custom Search READMEs
    
    Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
    
    * Refactor memory samples and switch to DefaultAzureCredential
    
    - Refactor RAPI Step22 MemorySearch: extract store setup to EnsureMemoryStoreAsync local function
    - Refactor non-RAPI Step22 MemorySearch: same pattern with explicit memory lifecycle
    - Set UpdateDelay=0 on MemoryUpdateOptions and MemorySearchPreviewTool for faster ingestion
    - Use WaitForMemoriesUpdateAsync with 500ms polling interval
    - Switch Step19 SharePoint, Step20 Fabric, Step22 MemorySearch (both) to DefaultAzureCredential
    - Remove SearchOptions from MemorySearchPreviewTool (causes unknown parameter error)
    
    Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
    
    * Switch all RAPI samples to DefaultAzureCredential and format
    
    - Replace AzureCliCredential with DefaultAzureCredential across all 20 RAPI samples
    - Run dotnet format on all RAPI and non-RAPI Foundry samples
    - AzureAI unit tests: 341 passed (net10.0 + net472)
    
    Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
    
    * Rename to Microsoft Foundry, add metadata, rename RAPI folder
    
    - Replace 'Azure AI Foundry' / 'Azure Foundry' with 'Microsoft Foundry' in all docs, comments, and XML docs
    - Update FoundryAgentClient metadata provider name to 'microsoft.foundry'
    - Rename FoundryAgents-RAPI folder to FoundryResponseAgents
    - Rewrite FoundryResponseAgents README with comparison table vs Foundry Agents
    - Update slnx and parent README with new folder references
    
    Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
    
    * Address PR review: simplify sample comments and fix DeepResearch credential
    
    - Remove 'no server-side agent' and 'Responses API directly' phrasing from comments
    - Simplify to 'Create a FoundryAgentClient' per review feedback
    - Switch Agent_Step15_DeepResearch to DefaultAzureCredential
    
    Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
    
    * Restore full DefaultAzureCredential warning comment in DeepResearch sample
    
    Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
    
    * Add ADR 0020: Foundry agent type naming convention
    
    Proposes naming options for a new MAF type wrapping versioned
    Foundry agents (Prompt, ContainerApp, Hosted, Workflow) to
    distinguish from the existing FoundryResponsesAgent (RAPI path).
    
    Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
    
    * Simplify FoundryResponsesAgent samples with env-var constructors and rename folders
    
    - Add env-var constructors to FoundryResponsesAgent (simple + options-based)
    - Fix Constructor 1 model optionality (no longer throws on missing AZURE_AI_MODEL_DEPLOYMENT_NAME)
    - Add ApplyModelDeploymentFallback helper for options-based constructor
    - Update all 23 FoundryResponseAgents samples to remove Environment.GetEnvironmentVariable boilerplate
    - Condense 6 simple samples to one-liner constructor calls
    - Add XML doc remarks about auto-resolved parameters on all constructors
    - Rename FoundryAgents -> FoundryVersionedAgents (server-side, versioned)
    - Rename FoundryResponseAgents -> FoundryAgents (now the default path forward)
    - Update .slnx and README cross-references for new folder names
    
    Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
    
    * Add FoundryAITool factory, rename RAPI folders, and clean up references
    
    - Create FoundryAITool static factory class with 17 methods wrapping AgentTool.Create* and ResponseTool.Create* into AITool returns
    - Rename 23 FoundryAgentsRAPI_* subfolders to FoundryAgents_* (drop RAPI prefix)
    - Rename .csproj files and update .slnx references accordingly
    - Update 12 samples (6 FoundryAgents + 6 FoundryVersionedAgents) to use FoundryAITool
    - Replace all FoundryResponsesAgent references with FoundryAgent in comments and READMEs
    - Update sample READMEs to reference FoundryAITool methods
    
    Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
    
    * Rename FoundryVersionedAgents subfolders from FoundryAgents_* to FoundryVersionedAgents_*
    
    Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
    
    * Add FoundryVersionedAgent class and refactor extension method internals
    
    - Create FoundryVersionedAgent with private ctor and async static factory methods
      (CreateAIAgentAsync/GetAIAgentAsync) with env-var and explicit endpoint tiers
    - Extract shared internal helpers from AzureAIProjectChatClientExtensions:
      CreateChatClientAgent, CreateAgentVersionFromOptionsAsync,
      CreateAgentVersionWithProtocolAsync (tools overload),
      CreateChatClientAgentOptions, GetAgentRecordByNameAsync, ThrowIfInvalidAgentName
    - Extension methods now delegate to shared internal helpers
    - All 49 existing samples continue to build successfully
    
    Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
    
    * Add CreateConversationSessionAsync, DeleteAIAgentAsync, auto-resolve model, simplify samples
    
    - Add CreateConversationSessionAsync to FoundryAgent and FoundryVersionedAgent
      (returns ChatClientAgentSession, creates server-side conversation + session in one call)
    - Add DeleteAIAgentAsync static method to FoundryVersionedAgent
    - Make model parameter optional in env-var factory overloads (auto-resolves from
      AZURE_AI_MODEL_DEPLOYMENT_NAME)
    - Update all FoundryVersionedAgents samples to use DeleteAIAgentAsync
    - Remove deploymentName env var from samples where only used for model parameter
    - Use CreateConversationSessionAsync in Step02_MultiturnConversation
    - Use explicit types instead of var for agent/session variables
    - All 49 samples build successfully
    
    Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
    
    * Remove manual AIProjectClient construction from FoundryVersionedAgents samples
    
    - Replace manual AIProjectClient construction with GetService<AIProjectClient>()
      from the FoundryVersionedAgent in all dual-option and tool-specific samples
    - Remove AZURE_AI_PROJECT_ENDPOINT env var reads from updated samples
    - Remove Azure.Identity usings where no longer needed
    - Only Step01.1, Step01.2, Eval_Step01 retain manual construction (pedagogical samples)
    - All 49 samples build successfully
    
    Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
    
    * Replace aiProjectClient extension calls with FoundryVersionedAgent factories in all samples
    
    - Replace aiProjectClient.CreateAIAgentAsync with FoundryVersionedAgent.CreateAIAgentAsync
      in Option 2 (Native SDK) paths across Steps 14-21
    - Replace aiProjectClient.Agents.DeleteAgentAsync with FoundryVersionedAgent.DeleteAIAgentAsync
    - Remove unused AIProjectClient variables and using directives
    - Only Step01.1, Step01.2, Eval_Step01 retain direct AIProjectClient usage (pedagogical)
    - Step16, Step22 use GetService<AIProjectClient>() for file/memory operations
    
    Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
    
    * Remove unused using directives from Step01.2, Step09, Eval_Step02
    
    Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
    
    * Update ADR 0020 with accepted decision: Option 6
    
    - Add Option 6 detailing FoundryAgent, FoundryVersionedAgent, FoundryAITool,
      env-var auto-discovery, and self-contained factory patterns
    - Mark decision as accepted with rationale
    - Update current state and metadata sections
    
    Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
    
    * Update Step01 basics samples to use FoundryVersionedAgent factories
    
    - Step01.1: Replace manual AIProjectClient/AsAIAgent with FoundryVersionedAgent.CreateAIAgentAsync/GetAIAgentAsync/DeleteAIAgentAsync
    - Step01.2: Replace manual AIProjectClient with FoundryVersionedAgent.CreateAIAgentAsync/DeleteAIAgentAsync
    - Remove env var boilerplate and Azure.Identity dependency
    
    Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
    
    * Add DeleteAIAgentVersionAsync to FoundryVersionedAgent
    
    - DeleteAIAgentAsync: deletes the agent and all its versions (existing)
    - DeleteAIAgentVersionAsync: deletes only the specific version associated with the agent instance
    - Internally delegates to Agents.DeleteAgentAsync vs Agents.DeleteAgentVersionAsync
    
    Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
    
    * Fix cleanup comments: DeleteAIAgentAsync deletes the agent and all its versions
    
    Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
    
    * Update all FoundryVersionedAgents READMEs for FoundryVersionedAgent and auto-discovery
    
    - Rewrite main README with FoundryVersionedAgent usage, auto-discovery table, code example
    - Fix sample table links from FoundryAgents_Step* to FoundryVersionedAgents_Step*
    - Add FoundryAITool references in tool-specific sample descriptions
    - Update individual READMEs: fix stale paths, add auto-discovery note after env var blocks
    - Update tool references: AgentTool/ResponseTool -> FoundryAITool
    - Update parent 02-agents/README.md with FoundryVersionedAgent description
    
    Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
    
    * Revert unrelated AGUI and Hosting.OpenAI formatting changes to main
    
    Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
    
    * Remove env-var auto-discovery, add AsAIAgent, mark extensions Obsolete
    
    - Remove 2 env-var constructors from FoundryAgent (keep explicit endpoint ctors)
    - Remove 5 env-var factory methods from FoundryVersionedAgent (keep explicit ones)
    - Add 3 AsAIAgent static methods to FoundryVersionedAgent (AgentVersion/AgentRecord/AgentReference)
    - Mark all 8 AIProjectClient extension methods as [Obsolete] pointing to FoundryVersionedAgent
    - Remove ApplyModelDeploymentFallback, env var constants, Azure.Identity usings from source
    
    Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
    
    * Update all samples to use explicit endpoint, credential, and model parameters
    
    - Add explicit Environment.GetEnvironmentVariable reads for AZURE_AI_PROJECT_ENDPOINT
      and AZURE_AI_MODEL_DEPLOYMENT_NAME to all 48 sample files
    - Pass new Uri(endpoint), new DefaultAzureCredential(), deploymentName to
      FoundryAgent constructors and FoundryVersionedAgent factory methods
    - Add using Azure.Identity where missing
    - Matches repo-wide pattern used by other non-Foundry samples
    - All 49 samples build successfully
    
    Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
    
    * Migrate remaining samples and source from obsoleted extension methods
    
    - Migrate AgentProviders, AgentWithRAG, AgentWithMemory, HostedWorkflow samples to FoundryVersionedAgent
    - Migrate AzureAgentProvider.cs to FoundryVersionedAgent.AsAIAgent
    - Migrate AzureAIProjectChatClientTests.cs to FoundryVersionedAgent.GetAIAgentAsync
    - Remove pragma suppressions from migrated files
    
    Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
    
    * Add unit tests for FoundryAgent and FoundryVersionedAgent
    
    - FoundryAgentTests.cs: 14 tests covering constructors, validation,
      properties, metadata, GetService, chat client factory, user-agent header
    - FoundryVersionedAgentTests.cs: 31 tests covering CreateAIAgentAsync,
      GetAIAgentAsync, AsAIAgent (3 overloads), DeleteAIAgentAsync,
      DeleteAIAgentVersionAsync, validation, invalid names, metadata, GetService
    
    Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
    
    * Finalize Foundry agent migration
    
    Align FoundryAgent and FoundryVersionedAgent samples, docs, and tests with the explicit configuration model, clean up stale README guidance, and fix AzureAI unit test validation/build issues.
    
    Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
    
    * Apply formatter cleanup after validation
    
    Capture the dotnet format follow-up changes produced during branch validation so the committed state matches the successfully built and tested branch.
    
    Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
    
    * Add integration tests for FoundryAgent and FoundryVersionedAgent
    
    Mark old AIProjectClient extension-method integration tests as obsolete and add new integration test suites for both FoundryAgent (Responses API) and FoundryVersionedAgent (versioned agents). All 71 non-skipped tests pass against the live Foundry service.
    
    Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
    
    * Update ADR 0020 with test coverage details
    
    Add integration test coverage note to the Current State section of ADR 0020.
    
    * Simplify Foundry agents and validate moved samples
    
    * Rename FoundryAgent integration tests to ResponsesAgent
    
    The test classes exercise the non-versioned Responses path via
    AIProjectClient.AsAIAgent(), not the removed FoundryAgent wrapper type.
    Rename files and class names to reflect the actual test surface.
    
    * Update documentation for ChatClientAgent usage
    
    Added example usage of ChatClientAgent with JokerAgent.
    
    * Refactor ChatClientAgent instantiation for clarity
    
    * Revise agent type naming and usage examples
    
    Updated documentation to reflect changes in agent creation methods and added examples for using `ChatClientAgent`.
    
    * Fix Azure SDK namespace migration after rebase
    
    Update Azure.AI.Projects.OpenAI references to Azure.AI.Projects.Agents
    and Azure.AI.Extensions.OpenAI to match Azure.AI.Projects 2.0.0-beta.2.
    
    - Replace deprecated namespace across samples, tests, and src
    - Fix renamed types: OpenAPIFunctionDefinition -> OpenApiFunctionDefinition,
      BingCustomSearchToolParameters -> BingCustomSearchToolOptions,
      BrowserAutomationToolParameters -> BrowserAutomationToolOptions
    - Fix API changes: AgentRecord.Versions -> GetLatestVersion(),
      ResponsesClient constructor, FunctionApprovalRequestContent ->
      ToolApprovalRequestContent
    - Apply dotnet format
    
    Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
    
    * Address merge markers
    
    * Replace obsolete GetAIAgentAsync with AsAIAgent in samples
    
    Switch Agent_Step07_AsMcpTool and A2AServer to use the non-obsolete
    PersistentAgentsClient.AsAIAgent(PersistentAgent) extension instead
    of the deprecated GetAIAgentAsync, fixing CS0618 build errors.
    
    Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
    
    * Fix broken markdown links in Responses sample READMEs
    
    Replace stale ChatClientAgents_Step* folder references with the
    correct Agent_Step* names across all Responses sample READMEs.
    
    Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
    
    * Fix format errors and address PR review comments
    
    - Fix charset and remove unused using in AzureAIProjectResponsesChatClient
    - Fix doc comment tags (code -> c) in FoundryAITool
    - Fix stray period in LocalMCP sample comment
    - Fix grammar in FoundryMemoryProvider xmldoc
    - Fix AIProjectClientAgentRunStreamingConversationTests base class
    
    Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
    
    * Apply dotnet format fixes to PR-changed files
    
    Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
    
    * Fix build errors from format pass and apply naming conventions
    
    - Fix static call to CreateSessionAsync in Step02 samples and extension tests
    - Use expression-bodied lambda in FoundryMemoryProvider (RCS1021)
    - Apply PascalCase naming to const fields in ResponsesAgentExtensionCreateTests (IDE1006)
    
    Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
    
    * Introduce FoundryAgent sealed type and update AsAIAgent extensions
    
    - Add FoundryAgent sealed class wrapping ChatClientAgent with:
      - Public ctors: (projectEndpoint, credential, model, instructions) and (agentEndpoint, credential)
      - Internal ctor: (AIProjectClient, ChatClientAgent) for extension use
      - CreateConversationSessionAsync() for server-side conversations
      - GetService<ChatClientAgent>() and GetService<AIProjectClient>()
      - MEAI user-agent policy on internally-created AIProjectClient
    - Change all AsAIAgent extension return types from ChatClientAgent to FoundryAgent
    - Update all samples and tests to use FoundryAgent type
    - Add 16 FoundryAgentTests covering ctors, GetService, UserAgent, RunAsync
    - Fix pre-existing Agent_Step12_Plugins build error
    
    Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
    
    * Collapse sample folders and add FoundryAgent_Step01 sample
    
    - Move all Responses/* samples up to AgentsWithFoundry/ (flat structure)
    - Remove entire Versioned/ folder (26 samples)
    - Add FoundryAgent_Step01 sample showing direct FoundryAgent ctor usage
    - Update slnx to reflect flat folder structure
    - Fix csproj ProjectReference paths for new depth
    
    Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
    
    * Update READMEs for flat AgentsWithFoundry structure
    
    - Rewrite AgentsWithFoundry/README.md with FoundryAgent quick start
    - Fix cd commands and paths in 11 sample READMEs
    - Update 02-agents/README.md to single Foundry link
    - Update AGENTS.md tree to flat structure
    - Fix AgentWithMemory cross-reference
    
    Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
    
    * Fix FoundryAgent_Step01 sample with full create/run/delete lifecycle
    
    Show the complete server-side agent lifecycle: create version with
    native SDK, wrap as FoundryAgent via AsAIAgent, run, then delete.
    
    Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
    
    * Revert RAPI samples to use AIAgent instead of FoundryAgent
    
    RAPI samples should not reference FoundryAgent directly. Restored
    original sample code with only ChatClientAgent -> AIAgent type change
    to accommodate the AsAIAgent return type.
    
    Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
    
    * Convert versioned-pattern samples to pure RAPI
    
    Step09, Step13, Step17, Step22 were using CreateAgentVersionAsync +
    PromptAgentDefinition which is the versioned pattern. Converted to
    use AsAIAgent(model, instructions, tools) which is the RAPI path.
    
    Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
    
    * Fix format issues from Docker CI check
    
    - FoundryAgent_Step01: CRLF -> LF
    - Agent_Step09: missing final newline
    - Agent_Step11_Middleware: add internal modifier, final newline
    - Agent_Step02: remove redundant cast (IDE0004)
    - Agent_Step08: simplify name (IDE0001)
    - FoundryAgentTests: s_ prefix, Async suffix naming conventions
    
    Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
    
    * Switch Step09 MCP sample to Microsoft Learn HTTP endpoint
    
    Replace npx stdio GitHub MCP server with the public Microsoft Learn
    MCP endpoint (https://learn.microsoft.com/api/mcp) using HTTP transport.
    No external tooling required to run.
    
    Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
    
    * Fix missing final newline in Step09 MCP sample
    
    Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
    
    * Address PR review: use DelegatingAIAgent, clean up Step01 sample
    
    - FoundryAgent now inherits DelegatingAIAgent instead of AIAgent,
      removing manual delegation boilerplate (westey-m feedback)
    - Simplified Agent_Step01_Basics to single agent creation path,
      moved composable IChatClient approach to README (westey-m feedback)
    - Fixed FoundryAgentTests param name assertion
    
    Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
    
    * Update sample using Project specialized type instead
    
    * Address PR review feedback: DefaultAzureCredential warnings, sample simplifications, format fixes
    
    - Add DefaultAzureCredential production warning comments to ~25 samples
    - Simplify Anthropic and OpenAI Step01 samples to single agent
    - Convert Step11 Middleware regex patterns to [GeneratedRegex]
    - Remove unnecessary cleanup comment from Step06
    - Fix Step09 README MCP transport description
    - Enhance FoundryAgent xmldoc with non-persistent agent comparison
    
    Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
    
    * Split Step02, simplify RAG Step04, sharpen Step23 differentiation
    
    - Split Step02 into 02.1 (simple multi-turn via sessions) and 02.2 (server-side conversations via CreateConversationSessionAsync)
    - RAG Step04: replace HostedFileSearchTool + MEAI wrapping with native OpenAI FileSearchTool
    - Step23: clarify DelegatingAIFunction wrapping pattern vs Step09 basic MCP
    
    Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
    
    * Fix Hosted MCP sample: use ResponseTool.CreateMcpTool and move tool to PromptAgentDefinition
    
    Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
    
    * Fix broken README link after Step02 split
    
    Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
    
    * Address Sergey round 3 feedback: branding, README nav, sample rename
    
    - Replace 'Azure AI Foundry' with 'Microsoft Foundry' in ADR 0020
    - Fix 3 READMEs: 'ChatClientAgents' → 'AgentsWithFoundry' sample directory
    - Rename FoundryAgent_Step01 → Agent_Step00_FoundryAgentLifecycle for naming consistency
    
    Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
    
    ---------
    
    Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
  • ADR to support a multi-source architecture for agent skills (#4787)
    * add  adr suggesting a new design to support a multi-source architecture for agent skills
    
    * add deciders
    
    * move the adr to the decisions folder
    
    * remove unnecessary section
    
    * describe adding a custom skill source
    
    * update
    
    * address comments
    
    * add constructor overloads to inline skill resource and script
    
    * consider ai-function as an alternative for skill script and skill resource model classes
    
    * update decision outcome section and sync adr with latest changes in the code
  • Add ADR to decide consistency of Chat History Persistence (#4816)
    * Add ADR to decide consitency of Chat History Persistence
    
    * Add example
    
    * Update ADR with review results
    
    * Remove unecessary clarification
    
    * Rename ADR to no 22
  • Python: [BREAKING] Python: Provider-leading client design & OpenAI package extraction (#4818)
    * Python: Provider-leading client design & OpenAI package extraction
    
    Major refactoring of the Python Agent Framework client architecture:
    
    - Extract OpenAI clients into new `agent-framework-openai` package
    - Core package no longer depends on openai, azure-identity, azure-ai-projects
    - Rename clients for discoverability: OpenAIResponsesClient → OpenAIChatClient,
      OpenAIChatClient → OpenAIChatCompletionClient
    - Unify `model_id`/`deployment_name`/`model_deployment_name` → `model` param
    - New FoundryChatClient for Azure AI Foundry Responses API
    - New FoundryAgent/FoundryAgentClient for connecting to pre-configured Foundry agents
    - Remove OpenAIBase/OpenAIConfigMixin from non-deprecated client MRO
    - Deprecate AzureOpenAI* clients, AzureAIClient, OpenAIAssistantsClient
    - Reorganize samples: azure_openai+azure_ai+azure_ai_agent → azure/
    - ADR-0020: Provider-Leading Client Design
    
    Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
    
    * fix: missing Agent imports in samples, .model_id → .model in foundry_local sample
    
    Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
    
    * fix: CI failures — mypy errors, coverage targets, sample imports
    
    - azure-ai mypy: add type ignores for TypedDict total=, model arg, forward ref
    - Coverage: replace core.azure/openai targets with openai package target
    - project_provider: add type annotation for opts dict
    
    Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
    
    * fix: populate openai .pyi stub, fix broken README links, coverage targets
    
    Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
    
    * fixes
    
    * updated observabilitty
    
    * reset azure init.pyi
    
    * fix errors
    
    * updated adr number
    
    * fix foundry local
    
    * fixed not renamed docstrings and comments, and added deprecated markers to old classes
    
    * fix tests and pyprojects
    
    * fix test vars
    
    * updated function tests
    
    * update durable
    
    * updated test setup for functions
    
    * Fix Foundry auth in workflow samples
    
    Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
    
    * Stabilize Python integration workflows
    
    Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
    
    * Update hosting samples for Foundry
    
    Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
    
    * Trigger full CI rerun
    
    Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
    
    * Trigger CI rerun again
    
    Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
    
    * trigger rerun
    
    * trigger rerun
    
    * fix for litellm
    
    * undo durabletask changes
    
    * Move Foundry APIs into foundry namespace
    
    Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
    
    * Fix Foundry pyproject formatting
    
    Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
    
    * Split provider samples by Foundry surface
    
    Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
    
    * Restore hosting sample requirements
    
    Also fix the Foundry Local sample link after the provider sample move.
    
    Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
    
    * updated tests
    
    * udpated foundry integration tests
    
    * removed dist from azurefunctions tests
    
    * Use separate Foundry clients for concurrent agents
    
    Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
    
    * fix client setup in azfunc and durable
    
    * disabled two tests
    
    * updated setup for some function and durable tests
    
    * improved azure openai setup with new clients
    
    * ignore deprecated
    
    * fixes
    
    * skip 11
    
    * remove openai assistants int tests
    
    ---------
    
    Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
  • Add ADR-0020: Foundry Evals integration (#4731)
    * Add ADR-0020: Foundry Evals integration design
    
    Captures the design for integrating Azure AI Foundry Evaluations with
    agent-framework. Key decisions:
    
    - EvalItem with conversation (list[Message]) as single source of truth
    - query/response derived from configurable conversation split strategies
    - Tools as list[FunctionTool] (including auto-extracted MCP tools)
    - FoundryEvals provider with auto-detection of evaluator capabilities
    - LocalEvaluator with @function_evaluator decorator for local checks
    - Consistent Python/C# APIs: evaluate_agent, evaluate_workflow
    
    Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
    
    * Mark ADR 0020 Foundry Evals as accepted
    
    Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
    
    ---------
    
    Co-authored-by: alliscode <bentho@microsoft.com>
    Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
  • [BREAKING] Python: clean up kwargs across agents, chat clients, tools, and sessions (#4581)
    * Python: clean up kwargs across agents, chat clients, tools, and sessions (#3642)
    
    Audit and refactor public **kwargs usage across core agents, chat clients,
    tools, sessions, and provider packages per the migration strategy codified
    in CODING_STANDARD.md.
    
    Key changes:
    - Add explicit runtime buckets: function_invocation_kwargs and client_kwargs
      on RawAgent.run() and chat client get_response() layers.
    - Refactor FunctionTool to prefer explicit ctx: FunctionInvocationContext
      injection; legacy **kwargs tools still work via _forward_runtime_kwargs.
    - Refactor Agent.as_tool() to use direct JSON schema, always-streaming
      wrapper, approval_mode parameter, and UserInputRequiredException
      propagation (integrates PR #4568 behavior).
    - Remove implicit session bleeding into FunctionInvocationContext; tools
      that need a session must receive it via function_invocation_kwargs.
    - Lower chat-client layers after FunctionInvocationLayer accept only
      compatibility **kwargs (client_kwargs flattened, function_invocation_kwargs
      ignored).
    - Add layered docstring composition from Raw... implementations via
      _docstrings.py helper.
    - Clean up provider constructors to use explicit additional_properties.
    - Deprecation warnings on legacy direct kwargs paths.
    - Update samples, tests, and typing across all 23 packages.
    
    Resolves #3642
    
    Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
    
    * clarified docstring
    
    * feedback fixes
    
    * Add unit tests for _docstrings.py build/apply helpers
    
    Tests cover: no docstring source, no extra kwargs, appending to existing
    Keyword Args section, inserting after Args, inserting in plain docstrings,
    multiline descriptions, ordering, and apply_layered_docstring.
    
    Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
    
    * Add test for propagate_session TypeError on non-AgentSession values
    
    Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
    
    * Add tests for multi-content and empty UserInputRequiredException propagation
    
    Cover the branching logic in _try_execute_function_calls for:
    - Multiple user_input_request items in a single exception (extra_user_input_contents path)
    - Empty contents list (fallback function_result path)
    
    Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
    
    * Add tests for DurableAIAgent.get_session forwarding service_session_id
    
    Verifies get_session correctly forwards service_session_id and session_id
    to the executor's get_new_session, replacing the removed kwargs test.
    
    Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
    
    * Simplify ag-ui test stub to read session from client_kwargs only
    
    Remove dual-mode detection (client_kwargs vs raw kwargs fallback) from
    the test mock. Session is now read exclusively from client_kwargs,
    matching the settled public calling convention.
    
    Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
    
    * updated create and get sessions in durable
    
    * fixed docstrings
    
    * fix test
    
    * updated session handling
    
    * updated from main
    
    * updated tests
    
    ---------
    
    Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
  • Python: Implement annotation-based context compaction (#4469)
    * Implement annotation-based context compaction
    
    Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
    
    * Handle missing compaction attributes in BaseChatClient
    
    Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
    
    * Fix CI typing and bandit issues
    
    Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
    
    * Optimize incremental compaction annotation pass
    
    Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
    
    * refinement
    
    * Python: add ToolResultCompactionStrategy and CompactionProvider
    
    Add ToolResultCompactionStrategy that collapses older tool-call groups
    into short summary messages (e.g. [Tool calls: get_weather]) while
    keeping the most recent groups verbatim. This mirrors the .NET
    ToolResultCompactionStrategy from PR #4533.
    
    Add CompactionProvider as a context-provider that auto-applies compaction
    before each agent turn and stores compacted history in session state
    after each turn.
    
    Includes tests and samples for both features.
    
    Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
    
    * refinement and alignment with dotnet PR
    
    * updated tool result compaction
    
    * updated tool result compaction
    
    * Python: add ToolResultCompactionStrategy, CompactionProvider, and skip_excluded
    
    - ToolResultCompactionStrategy collapses older tool-call groups into
      [Tool results: func_name: result] summaries with bidirectional tracing
      (same pattern as SummarizationStrategy).
    - CompactionProvider as BaseContextProvider with separate before_strategy
      and after_strategy parameters. before_strategy compacts loaded context;
      after_strategy compacts stored history via history_source_id.
    - InMemoryHistoryProvider gains skip_excluded flag to filter out messages
      marked as excluded by compaction strategies.
    - Tests, samples, and exports updated.
    
    Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
    
    * fixed checks
    
    * fix mypy
    
    * Fix: ensure summary messages from both strategies get full compaction annotations
    
    SummarizationStrategy was not calling annotate_message_groups after
    inserting its summary message, so the summary lacked core group
    annotations (id, kind, index, has_reasoning, _excluded). Added the
    missing call. ToolResultCompactionStrategy already had it.
    
    Added tests verifying both strategies produce fully annotated summaries.
    
    Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
    
    * updated propagation
    
    * fix mypy
    
    ---------
    
    Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
  • Fix Strands Agents documentation links in ADR (#4584)
    * Initial plan
    
    * Fix broken Strands Agents documentation links in ADR 0001
    
    Replace 5 broken strandsagents.com URLs (returning 404) with stable
    GitHub source code links in docs/decisions/0001-agent-run-response.md.
    
    The Strands Agents docs site restructured from /api-reference/python/
    to /api/python/, breaking the old links.
    
    Co-authored-by: SergeyMenshykh <68852919+SergeyMenshykh@users.noreply.github.com>
    
    * Update Strands Agents links to use official documentation site
    
    Replace GitHub source links with official strandsagents.com/docs/api/python/
    documentation URLs in docs/decisions/0001-agent-run-response.md.
    
    Co-authored-by: SergeyMenshykh <68852919+SergeyMenshykh@users.noreply.github.com>
    
    * Update Strands Agents links to use specific documentation URLs
    
    - Streaming: strandsagents.com/docs/user-guide/concepts/streaming/
    - Structured output: strandsagents.com/docs/user-guide/concepts/agents/structured-output/
    - AgentResult/stop_reason: strandsagents.com/docs/api/python/strands.agent.agent_result/#agentresult
    
    Co-authored-by: SergeyMenshykh <68852919+SergeyMenshykh@users.noreply.github.com>
    
    * Deduplicate Strands AgentResult link in stop-reason row
    
    Replaced the duplicate hyperlink on `stop_reason` with inline code,
    keeping a single AgentResult link to the same URL.
    
    Co-authored-by: SergeyMenshykh <68852919+SergeyMenshykh@users.noreply.github.com>
    
    ---------
    
    Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>
    Co-authored-by: SergeyMenshykh <68852919+SergeyMenshykh@users.noreply.github.com>
  • ADR: Python context compaction strategy (#3802)
    * Add ADR for Python context compaction strategy
    
    * Remove async vs sync open question - compact() is async
    
    * updated adr
    
    * docs: refine context compaction ADR
    
    Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
    
    * updated adr
    
    * further refinement
    
    * renamed and numbered
    
    * remove XX version
    
    ---------
    
    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.
  • Python: Update workflow orchestration samples to use AzureOpenAIResponsesClient (#4285)
    * Update workflow orchestration samples to use AzureOpenAIResponsesClient
    
    * Fix broken link
  • Add Additional Properties ADR (#4246)
    * Add Additional Properties ADR
    
    * Address PR comments
  • Python: Add Foundry Memory Context Provider (#3943)
    * Initial plan
    
    * Add FoundryMemoryProvider and tests
    
    Co-authored-by: eavanvalkenburg <13749212+eavanvalkenburg@users.noreply.github.com>
    
    * Add sample and documentation for FoundryMemoryProvider
    
    Co-authored-by: eavanvalkenburg <13749212+eavanvalkenburg@users.noreply.github.com>
    
    * Address code review feedback for FoundryMemoryProvider
    
    Co-authored-by: eavanvalkenburg <13749212+eavanvalkenburg@users.noreply.github.com>
    
    * Address PR review comments: Add DEFAULT_SOURCE_ID, use logging.getLogger, move state to session.state
    
    Co-authored-by: eavanvalkenburg <13749212+eavanvalkenburg@users.noreply.github.com>
    
    * Fix Foundry memory ItemParam usage and exports
    
    Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
    
    * Refactor provider hook state and standardize source IDs
    
    Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
    
    * Support endpoint-based Foundry memory init
    
    Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
    
    * updated implementation and sample
    
    * updated code and samples
    
    * Fix foundry memory provider tests: mock structure and field names
    
    - Use Mock objects with memory_item.content for memory mocks
    - Assert 'content' instead of 'text' on SDK message items
    - Update exception types from ServiceInitializationError to ValueError
    - Remove unused ServiceInitializationError import
    
    Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
    
    * Fix mypy errors in foundry memory provider
    
    Add type: ignore[arg-type] for scope (str | None vs str) and items
    (list variance) passed to Azure SDK methods.
    
    Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
    
    * fix import
    
    ---------
    
    Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>
    Co-authored-by: eavanvalkenburg <13749212+eavanvalkenburg@users.noreply.github.com>
    Co-authored-by: eavanvalkenburg <github@vanvalkenburg.eu>
    Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
  • Python: [BREAKING] Scope provider state by source_id and standardize source IDs (#3995)
    * Initial plan
    
    * Add FoundryMemoryProvider and tests
    
    Co-authored-by: eavanvalkenburg <13749212+eavanvalkenburg@users.noreply.github.com>
    
    * Add sample and documentation for FoundryMemoryProvider
    
    Co-authored-by: eavanvalkenburg <13749212+eavanvalkenburg@users.noreply.github.com>
    
    * Address code review feedback for FoundryMemoryProvider
    
    Co-authored-by: eavanvalkenburg <13749212+eavanvalkenburg@users.noreply.github.com>
    
    * Address PR review comments: Add DEFAULT_SOURCE_ID, use logging.getLogger, move state to session.state
    
    Co-authored-by: eavanvalkenburg <13749212+eavanvalkenburg@users.noreply.github.com>
    
    * Fix Foundry memory ItemParam usage and exports
    
    Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
    
    * Refactor provider hook state and standardize source IDs
    
    Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
    
    * Support endpoint-based Foundry memory init
    
    Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
    
    * Fix core README workflows link
    
    Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
    
    * updated implementation and sample
    
    * Split out Foundry memory provider changes
    
    Remove FoundryMemoryProvider implementation/tests/sample plus export and docs mentions from this branch so only non-Foundry changes remain.
    
    Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
    
    * Trigger CI rerun for PR #3995
    
    Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
    
    ---------
    
    Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>
    Co-authored-by: eavanvalkenburg <13749212+eavanvalkenburg@users.noreply.github.com>
    Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
  • .NET: [Breaking] Structured Output improvements (#3761)
    * .NET: Delete AgentResponse.{Try}Deserialize<T> methods (#3518)
    
    * delete deserialize method of agent response
    
    * order usings
    
    * Update dotnet/samples/GettingStarted/FoundryAgents/FoundryAgents_Step05_StructuredOutput/Program.cs
    
    Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
    
    * Update dotnet/samples/GettingStarted/Workflows/_Foundational/08_WriterCriticWorkflow/Program.cs
    
    Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
    
    * Update dotnet/samples/GettingStarted/AGUI/Step05_StateManagement/Server/SharedStateAgent.cs
    
    Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
    
    * Update dotnet/samples/AGUIClientServer/AGUIDojoServer/SharedState/SharedStateAgent.cs
    
    Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
    
    * Update dotnet/samples/M365Agent/Agents/WeatherForecastAgent.cs
    
    Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
    
    ---------
    
    Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
    
    * .NET:[Breaking] Add support for structured output (#3658)
    
    * add support for so
    
    * restore lost xml comment part
    
    * fix using ordering
    
    * Update dotnet/src/Microsoft.Agents.AI.Abstractions/AIAgentStructuredOutput.cs
    
    Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
    
    * Update dotnet/src/Microsoft.Agents.AI.Abstractions/AIAgentStructuredOutput.cs
    
    Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
    
    * Update dotnet/tests/Microsoft.Agents.AI.UnitTests/ChatClient/ChatClientAgent_SO_WithFormatResponseTests.cs
    
    Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
    
    * addressw pr review comments
    
    * address pr review feedback
    
    * address pr review comments
    
    * fix compilation issues after the latest merge with main
    
    * remove unnecessry options
    
    * remove RunAsync<object> methods
    
    * address code review feedback
    
    * address pr review feedback
    
    * make copy constructor protected
    
    * address pr review feedback
    
    ---------
    
    Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
    
    * .NET: Add decorator for structured output support (#3694)
    
    * add decorator that adds structured output support to agents that don't natively support it.
    
    * Update dotnet/src/Microsoft.Agents.AI/StructuredOutput/StructuredOutputAgentResponse.cs
    
    Co-authored-by: westey <164392973+westey-m@users.noreply.github.com>
    
    * Update dotnet/samples/GettingStarted/Agents/Agent_Step05_StructuredOutput/Program.cs
    
    Co-authored-by: westey <164392973+westey-m@users.noreply.github.com>
    
    * address pr review feedback
    
    ---------
    
    Co-authored-by: westey <164392973+westey-m@users.noreply.github.com>
    
    * .NET: Support primitives and arrays for SO (#3696)
    
    * wrap primitives and arrays
    
    * fix file encoding
    
    * address review comments
    
    * add adr
    
    * add missed change
    
    * fix compilation issue
    
    * address review comments
    
    * rename adr file name
    
    * reflect decision to have SO decorator as a reference implementation in samples
    
    * .NET: Move SO agent to samples (#3820)
    
    * move SO agent to samples
    
    * change file encoding
    
    * fix files encoding
    
    * .NET: Preserve caller context (#3803)
    
    * fix stuck orchestration
    
    * add previously removed RunAsync<T> method to DurableAIAgent
    
    * suppress IDE0005 warning
    
    * update changelog and remove unused constructor of AgentResponse<T>
    
    * updatge the changelog
    
    * address PR review feedback
    
    * .NET: Disable irrelevant integration test (#3913)
    
    * disable irrelevant integration test
    
    * Update dotnet/tests/AzureAI.IntegrationTests/AIProjectClientAgentStructuredOutputRunTests.cs
    
    Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
    
    ---------
    
    Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
    
    * forgotten change
    
    * address pr review feedback
    
    * disable intermittently failing integration test.
    
    ---------
    
    Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
    Co-authored-by: westey <164392973+westey-m@users.noreply.github.com>
  • Python: restructure: Python samples into progressive 01-05 layout (#3862)
    * restructure: Python samples into progressive 01-05 layout
    
    - 01-get-started/: 6 numbered steps (hello agent → hosting)
    - 02-agents/: all agent concept samples (tools, middleware, providers, etc.)
    - 03-workflows/: ALL existing workflow samples preserved as-is
    - 04-hosting/: azure-functions, durabletask, a2a
    - 05-end-to-end/: demos, evaluation, hosted agents
    - Old files moved to _to_delete/ for review
    - Added AGENTS.md with structure documentation
    - autogen-migration/ and semantic-kernel-migration/ preserved at root
    
    * fix: switch to AzureOpenAI Foundry, fix CI failures
    
    - Switch all 01-get-started samples to AzureOpenAIResponsesClient with
      Azure AI Foundry project endpoint (AZURE_AI_PROJECT_ENDPOINT +
      AZURE_OPENAI_RESPONSES_DEPLOYMENT_NAME + AzureCliCredential)
    - Add _to_delete/ and 05-end-to-end/ to pyrightconfig.samples.json excludes
    - Fix test paths in packages/ that referenced old getting_started/ dirs:
      durabletask conftest + streaming test, azurefunctions conftest,
      devui conftest + capture_messages + openai_sdk_integration
    - Fix workflow_as_agent_human_in_the_loop.py import (sibling import)
    - Update hosting READMEs and tool comment paths
    - Replace root README.md with new structure overview
    - Update AGENTS.md to document Azure OpenAI Foundry as default provider
    
    * cleanup: remove _to_delete folder, copy resource files to active dirs
    
    All files in _to_delete/ were either:
    - Exact duplicates of files in the new structure (240 files)
    - Same file with only comment path updates (100 files)
    - One import-fix diff (workflow_as_agent_human_in_the_loop.py)
    - One superseded minimal_sample.py
    
    Resource files (sample.pdf, countries.json, employees.pdf, weather.json)
    copied to 02-agents/sample_assets/ and 02-agents/resources/ since active
    samples reference them.
    
    * fix: address PR review comments, centralize resources, remove root duplicates
    
    - Fix type annotation in 04_memory.py (string union -> proper types)
    - Fix old sample paths in observability files
    - Fix grammar/spelling in observability samples
    - Move sample_assets/ and resources/ to shared/ folder
    - Remove 8 duplicate observability files from 02-agents root
    - Update resource path references in multimodal_input and provider samples
    
    * fix: update broken links from old getting_started paths to new structure
    
    - Update relative paths in READMEs: getting_started/ → 01-get-started/,
      02-agents/, 03-workflows/, 04-hosting/, 05-end-to-end/
    - Fix absolute GitHub URLs in package READMEs
    - Fix broken link in ollama package README
    
    * fix: convert absolute GitHub URLs to relative paths for link checker
    
    Absolute URLs to python/samples/ on main branch 404 until PR merges.
    Converted to relative paths that linkspector can verify locally.
    
    * fix: update link for handoff sample moved to orchestrations/
    
    * fix: update chatkit-integration README path from demos/ to 05-end-to-end/
    
    * fix: update broken links in orchestrations README to match flat directory structure
  • Python: ADR: Unifying Context Management with ContextMiddleware (Python) (#3609)
    * Add ADR for Python ContextMiddleware unification
    
    * Add session serialization/deserialization design to ADR
    
    * Add Related Issues section mapping to ADR
    
    * Update session management: create_session, get_session_by_id, agent.serialize_session
    
    * ADR: Add hooks alternative, context compaction discussion, and PR feedback
    
    - Add Option 3: ContextHooks with before_run/after_run pattern
    - Add detailed pros/cons for both wrapper and hooks approaches
    - Add Open Discussion section on context compaction strategies
    - Clarify response_messages is read-only (use AgentMiddleware for modifications)
    - Add SimpleRAG examples showing input-only filtering
    - Clarify default storage only added when NO middleware configured
    - Add RAGWithBuffer examples for self-managed history
    - Rename hook methods to before_run/after_run
    
    * ADR: Restructure and add .NET comparison
    
    - Add class hierarchy clarification for both options
    - Merge detailed design sections (side-by-side comparison)
    - Move detailed design before decision outcome
    - Move compaction discussion after decision
    - Add .NET implementation comparison (feature equivalence)
    - Update .NET method names to match actual implementation
    - Rename hook methods to before_run/after_run
    - Fix storage context table for injected context
    
    * tweaks
    
    * fix smart load
    
    * ADR: Add naming discussion note for ContextHooks
    
    - Note that class and method names are open for discussion
    - Add alternative method naming options table
    - Include invoking/invoked as option matching current Python and .NET
    
    * Update context middleware design: remove smart mode, add attribution filtering
    
    - Remove smart mode for load_messages (now explicit bool, default True)
    - Add attribution marker in additional_properties for message filtering
    - Update validation to warn on multiple or zero storage loaders
    - Add note about ChatReducer naming from .NET
    - Note that attribution should not be propagated to storage
    
    * Add Decision 2: Instance Ownership (instances in session vs agent)
    
    - Option A: Instances in Session (current proposal)
    - Option B: Instances in Agent, State in Session
      - B1: Simple dict state with optional return
      - B2: SessionState object with mutable wrapper
    - Updated examples to use Hooks pattern (before_run/after_run)
    - Added open discussion on hook factories in Option B model
    
    * Update ADR: Choose ContextPlugin with before_run/after_run and Option B1
    
    Decision outcomes:
    - Option 3 (Hooks pattern) with ContextPlugin class name
    - Methods: before_run/after_run
    - Option B1: Instances in Agent, State in Session (simple dict)
    - Whole state dict passed to plugins (mutable, no return needed)
    - Added trust note: plugins reason over messages, so they're trusted by default
    
    Status changed from proposed to accepted.
    
    * Add agent and session params to before_run/after_run methods
    
    Signature now: before_run(agent, session, context, state)
    
    * Remove ContextPluginRunner, store plugins directly on agent
    
    Simpler design: agent stores Sequence[ContextPlugin] and calls
    before_run/after_run directly in the run method.
    
    * Update workplan to 2 PRs for simpler review
    
    * updated doc
    
    * Refine ADR: serialization, ownership, decorators, session methods, exports
    
    - Add to_dict()/from_dict() on AgentSession with 'type' discriminator
    - Present serialization as Option A (direct) vs Option B (through agent)
    - Rewrite ownership section as 2x2 matrix (orthogonal decision)
    - Move Instance Ownership Options before Decision Outcome
    - Fix get_session to use service_session_id, split from create_session
    - Add decorator-based provider convenience API (@before_run/@after_run)
    - Add _ prefix naming strategy for all PR1 types (core + external)
    - Constructor compatibility table for existing providers
    - Add load_messages=False skip logic to all agent run loops
    - Clarify abstract vs non-abstract in execution pattern samples
    - Update auto-provision: trigger on conversation_id or store=True
    - Document root package exports (ContextProvider, HistoryProvider, etc.)
    - Rename section heading to 'Key Design Considerations'
    
    * Rename ADR to 0016-python-context-middleware.md
    
    * Fix broken link: #3-unified-storage-middleware → #3-unified-storage
  • Python: [BREAKING] Moved to a single get_response and run API (#3379)
    * WIP
    
    * big update to new ResponseStream model
    
    * fixed tests and typing
    
    * fixed tests and typing
    
    * fixed tools typevar import
    
    * fix
    
    * mypy fix
    
    * mypy fixes and some cleanup
    
    * fix missing quoted names
    
    * and client
    
    * fix  imports agui
    
    * fix anthropic override
    
    * fix agui
    
    * fix ag ui
    
    * fix import
    
    * fix anthropic types
    
    * fix mypy
    
    * refactoring
    
    * updated typing
    
    * fix 3.11
    
    * fixes
    
    * redid layering of chat clients and agents
    
    * redid layering of chat clients and agents
    
    * Fix lint, type, and test issues after rebase
    
    - Add @overload decorators to AgentProtocol.run() for type compatibility
    - Add missing docstring params (middleware, function_invocation_configuration)
    - Fix TODO format (TD002) by adding author tags
    - Fix broken observability tests from upstream:
      - Replace non-existent use_instrumentation with direct instantiation
      - Replace non-existent use_agent_instrumentation with AgentTelemetryLayer mixin
      - Fix get_streaming_response to use get_response(stream=True)
      - Add AgentInitializationError import
      - Update streaming exception tests to match actual behavior
    
    * Fix AgentExecutionException import error in test_agents.py
    
    - Replace non-existent AgentExecutionException with AgentRunException
    
    * Fix test import and asyncio deprecation issues
    
    - Add 'tests' to pythonpath in ag-ui pyproject.toml for utils_test_ag_ui import
    - Replace deprecated asyncio.get_event_loop().run_until_complete with asyncio.run
    
    * Fix azure-ai test failures
    
    - Update _prepare_options patching to use correct class path
    - Fix test_to_azure_ai_agent_tools_web_search_missing_connection to clear env vars
    
    * Convert ag-ui utils_test_ag_ui.py to conftest.py
    
    - Move test utilities to conftest.py for proper pytest discovery
    - Update all test imports to use conftest instead of utils_test_ag_ui
    - Remove old utils_test_ag_ui.py file
    - Revert pythonpath change in pyproject.toml
    
    * fix: use relative imports for ag-ui test utilities
    
    * fix agui
    
    * Rename Bare*Client to Raw*Client and BaseChatClient
    
    - Renamed BareChatClient to BaseChatClient (abstract base class)
    - Renamed BareOpenAIChatClient to RawOpenAIChatClient
    - Renamed BareOpenAIResponsesClient to RawOpenAIResponsesClient
    - Renamed BareAzureAIClient to RawAzureAIClient
    - Added warning docstrings to Raw* classes about layer ordering
    - Updated README in samples/getting_started/agents/custom with layer docs
    - Added test for span ordering with function calling
    
    * Fix layer ordering: FunctionInvocationLayer before ChatTelemetryLayer
    
    This ensures each inner LLM call gets its own telemetry span, resulting in
    the correct span sequence: chat -> execute_tool -> chat
    
    Updated all production clients and test mocks to use correct ordering:
    - ChatMiddlewareLayer (first)
    - FunctionInvocationLayer (second)
    - ChatTelemetryLayer (third)
    - BaseChatClient/Raw...Client (fourth)
    
    * Remove run_stream usage
    
    * Fix conversation_id propagation
    
    * Python: Add BaseAgent implementation for Claude Agent SDK (#3509)
    
    * Added ClaudeAgent implementation
    
    * Updated streaming logic
    
    * Small updates
    
    * Small update
    
    * Fixes
    
    * Small fix
    
    * Naming improvements
    
    * Updated imports
    
    * Addressed comments
    
    * Updated package versions
    
    * Update Claude agent connector layering
    
    * fix test and plugin
    
    * Store function middleware in invocation layer
    
    * Fix telemetry streaming and ag-ui tests
    
    * Remove legacy ag-ui tests folder
    
    * updates
    
    * Remove terminate flag from FunctionInvocationContext, use MiddlewareTermination instead
    
    - Remove terminate attribute from FunctionInvocationContext
    - Add result attribute to MiddlewareTermination to carry function results
    - FunctionMiddlewarePipeline.execute() now lets MiddlewareTermination propagate
    - _auto_invoke_function captures context.result in exception before re-raising
    - _try_execute_function_calls catches MiddlewareTermination and sets should_terminate
    - Fix handoff middleware to append to chat_client.function_middleware directly
    - Update tests to use raise MiddlewareTermination instead of context.terminate
    - Add middleware flow documentation in samples/concepts/tools/README.md
    - Fix ag-ui to use FunctionMiddlewarePipeline instead of removed create_function_middleware_pipeline
    
    * fix: remove references to removed terminate flag in purview tests, add type ignore
    
    * fix: move _test_utils.py from package to test folder
    
    * fix: call get_final_response() to trigger context provider notification in streaming test
    
    * fix: correct broken links in tools README
    
    * docs: clarify default middleware behavior in summary table
    
    * fix: ensure inner stream result hooks are called when using map()/from_awaitable()
    
    * Fix mypy type errors
    
    * Address PR review comments on observability.py
    
    - Remove TODO comment about unconsumed streams, add explanatory note instead
    - Remove redundant _close_span cleanup hook (already called in _finalize_stream)
    - Clarify behavior: cleanup hooks run after stream iteration, if stream is not
      consumed the span remains open until garbage collected
    
    * Remove gen_ai.client.operation.duration from span attributes
    
    Duration is a metrics-only attribute per OpenTelemetry semantic conventions.
    It should be recorded to the histogram but not set as a span attribute.
    
    * Remove duration from _get_response_attributes, pass directly to _capture_response
    
    Duration is a metrics-only attribute. It's now passed directly to _capture_response
    instead of being included in the attributes dict that gets set on the span.
    
    * Remove redundant _close_span cleanup hook in AgentTelemetryLayer
    
    _finalize_stream already calls _close_span() in its finally block,
    so adding it as a separate cleanup hook is redundant.
    
    * Use weakref.finalize to close span when stream is garbage collected
    
    If a user creates a streaming response but never consumes it, the cleanup
    hooks won't run. Now we register a weak reference finalizer that will close
    the span when the stream object is garbage collected, ensuring spans don't
    leak in this scenario.
    
    * Fix _get_finalizers_from_stream to use _result_hooks attribute
    
    Renamed function to _get_result_hooks_from_stream and fixed it to
    look for the _result_hooks attribute which is the correct name in
    ResponseStream class.
    
    * Add missing asyncio import in test_request_info_mixin.py
    
    * Fix leftover merge conflict marker in image_generation sample
    
    * Update integration tests
    
    * Fix integration tests: increase max_iterations from 1 to 2
    
    Tests with tool_choice options require at least 2 iterations:
    1. First iteration to get function call and execute the tool
    2. Second iteration to get the final text response
    
    With max_iterations=1, streaming tests would return early with only
    the function call/result but no final text content.
    
    * Fix duplicate function call error in conversation-based APIs
    
    When using conversation_id (for Responses/Assistants APIs), the server
    already has the function call message from the previous response. We
    should only send the new function result message, not all messages
    including the function call which would cause a duplicate ID error.
    
    Fix: When conversation_id is set, only send the last message (the tool
    result) instead of all response.messages.
    
    * Add regression test for conversation_id propagation between tool iterations
    
    Port test from PR #3664 with updates for new streaming API pattern.
    Tests that conversation_id is properly updated in options dict during
    function invocation loop iterations.
    
    * Fix tool_choice=required to return after tool execution
    
    When tool_choice is 'required', the user's intent is to force exactly one
    tool call. After the tool executes, return immediately with the function
    call and result - don't continue to call the model again.
    
    This fixes integration tests that were failing with empty text responses
    because with tool_choice=required, the model would keep returning function
    calls instead of text.
    
    Also adds regression tests for:
    - conversation_id propagation between tool iterations (from PR #3664)
    - tool_choice=required returns after tool execution
    
    * Document tool_choice behavior in tools README
    
    - Add table explaining tool_choice values (auto, none, required)
    - Explain why tool_choice=required returns immediately after tool execution
    - Add code example showing the difference between required and auto
    - Update flow diagram to show the early return path for tool_choice=required
    
    * Fix tool_choice=None behavior - don't default to 'auto'
    
    Remove the hardcoded default of 'auto' for tool_choice in ChatAgent init.
    When tool_choice is not specified (None), it will now not be sent to the
    API, allowing the API's default behavior to be used.
    
    Users who want tool_choice='auto' can still explicitly set it either in
    default_options or at runtime.
    
    Fixes #3585
    
    * Fix tool_choice=none should not remove tools
    
    In OpenAI Assistants client, tools were not being sent when
    tool_choice='none'. This was incorrect - tool_choice='none' means
    the model won't call tools, but tools should still be available
    in the request (they may be used later in the conversation).
    
    Fixes #3585
    
    * Add test for tool_choice=none preserving tools
    
    Adds a regression test to ensure that when tool_choice='none' is set but
    tools are provided, the tools are still sent to the API. This verifies
    the fix for #3585.
    
    * Fix tool_choice=none should not remove tools in all clients
    
    Apply the same fix to OpenAI Responses client and Azure AI client:
    - OpenAI Responses: Remove else block that popped tool_choice/parallel_tool_calls
    - Azure AI: Remove tool_choice != 'none' check when adding tools
    
    When tool_choice='none', the model won't call tools, but tools should
    still be sent to the API so they're available for future turns.
    
    Also update README to clarify tool_choice=required supports multiple tools.
    
    Fixes #3585
    
    * Keep tool_choice even when tools is None
    
    Move tool_choice processing outside of the 'if tools' block in OpenAI
    Responses client so tool_choice is sent to the API even when no tools
    are provided.
    
    * Update test to match new parallel_tool_calls behavior
    
    Changed test_prepare_options_removes_parallel_tool_calls_when_no_tools to
    test_prepare_options_preserves_parallel_tool_calls_when_no_tools to reflect
    that parallel_tool_calls is now preserved even when no tools are present,
    consistent with the tool_choice behavior.
    
    * Fix ChatMessage API and Role enum usage after rebase
    
    - Update ChatMessage instantiation to use keyword args (role=, text=, contents=)
    - Fix Role enum comparisons to use .value for string comparison
    - Add created_at to AgentResponse in error handling
    - Fix AgentResponse.from_updates -> from_agent_run_response_updates
    - Fix DurableAgentStateMessage.from_chat_message to convert Role enum to string
    - Add Role import where needed
    
    * Fix additional ChatMessage API and method name changes
    
    - Fix ChatMessage usage in workflow files (use text= instead of contents= for strings)
    - Fix AgentResponse.from_updates -> from_agent_run_response_updates in workflow files
    - Fix test files for ChatMessage and Role enum usage
    
    * Fix remaining ChatMessage API usage in test files
    
    * Fix more ChatMessage and Role API changes in source and test files
    
    - Fix ChatMessage in _magentic.py replan method
    - Fix Role enum comparison in test assertions
    - Fix remaining test files with old ChatMessage syntax
    
    * Fix ChatMessage and Role API changes across packages
    
    - Add Role import where missing
    - Fix ChatMessage signature: positional args to keyword args (role=, text=, contents=)
    - Fix Role enum comparisons: .role.value instead of .role string
    - Fix FinishReason enum usage in ag-ui event converters
    - Rename AgentResponse.from_updates to from_agent_run_response_updates in ag-ui
    
    Fixes API compatibility after Types API Review improvements merge
    
    * Fix ChatMessage and Role API changes in github_copilot tests
    
    * Fix ChatMessage and Role API changes in redis and github_copilot packages
    
    - Fix redis provider: Role enum comparison using .value
    - Fix redis tests: ChatMessage signature and Role comparisons
    - Fix github_copilot tests: ChatMessage signature and Role comparisons
    - Update docstring examples in redis chat message store
    
    * Fix ChatMessage and Role API changes in devui package
    
    - Fix executor: ChatMessage signature change
    - Fix conversations: Role enum to string conversion in two places
    - Fix tests: ChatMessage signatures and Role comparisons
    
    * Fix ChatMessage and Role API changes in a2a and lab packages
    
    - Fix a2a tests: Role comparisons and ChatMessage signatures
    - Fix lab tau2 source: Role enum comparison in flip_messages, log_messages, sliding_window
    - Fix lab tau2 tests: ChatMessage signatures and Role comparisons
    
    * Remove duplicate test files from ag-ui/tests (tests are in ag_ui_tests)
    
    * Fix ChatMessage and Role API changes across packages
    
    After rebasing on upstream/main which merged PR #3647 (Types API Review
    improvements), fix all packages to use the new API:
    
    - ChatMessage: Use keyword args (role=, text=, contents=) instead of
      positional args
    - Role: Compare using .value attribute since it's now an enum
    
    Packages fixed:
    - ag-ui: Fixed Role value extraction bugs in _message_adapters.py
    - anthropic: Fixed ChatMessage and Role comparisons in tests
    - azure-ai: Fixed Role comparison in _client.py
    - azure-ai-search: Fixed ChatMessage and Role in source/tests
    - bedrock: Fixed ChatMessage signatures in tests
    - chatkit: Fixed ChatMessage and Role in source/tests
    - copilotstudio: Fixed ChatMessage and Role in tests
    - declarative: Fixed ChatMessage in _executors_agents.py
    - mem0: Fixed ChatMessage and Role in source/tests
    - purview: Fixed ChatMessage in source/tests
    
    * Fix mypy errors for ChatMessage and Role API changes
    
    - durabletask: Use str() fallback in role value extraction
    - core: Fix ChatMessage in _orchestrator_helpers.py to use keyword args
    - core: Add type ignore for _conversation_state.py contents deserialization
    - ag-ui: Fix type ignore comments (call-overload instead of arg-type)
    - azure-ai-search: Fix get_role_value type hint to accept Any
    - lab: Move get_role_value to module level with Any type hint
    
    * Improve CI test timeout configuration
    
    - Increase job timeout from 10 to 15 minutes
    - Reduce per-test timeout to 60s (was 900s/300s)
    - Add --timeout_method thread for better timeout handling
    - Add --timeout-verbose to see which tests are slow
    - Reduce retries from 3 to 2 and delay from 10s to 5s
    
    This ensures individual test timeouts are shorter than the job
    timeout, providing better visibility when tests hang.
    
    With 60s timeout and 2 retries, worst case per test is ~180s.
    
    * Fix ChatMessage API usage in docstrings and source
    
    - Fix ChatMessage positional args in docstrings: _serialization.py, _threads.py, _middleware.py
    - Fix ChatMessage in tau2 runner.py
    - Fix role comparison in _orchestrator_helpers.py to use .value
    - Fix role comparison in _group_chat.py docstring example
    - Fix role assertions in test_durable_entities.py to use .value
    
    * Revert tool_choice/parallel_tool_calls changes - must be removed when no tools
    
    OpenAI API requires tool_choice and parallel_tool_calls to only be
    present when tools are specified. Restored the logic that removes
    these options when there are no tools.
    
    - Restored check in _chat_client.py to remove tool_choice and
      parallel_tool_calls when no tools present
    - Restored same logic in _responses_client.py
    - Reverted test to expect the correct behavior
    
    * fixed issue in tests
    
    * fix: resolve merge conflict markers in ag-ui tests
    
    * fix: restructure ag-ui tests and fix Role/FinishReason to use string types
    
    * fix: streaming function invocation and middleware termination
    
    - Refactor streaming function invocation to use get_final_response() on inner streams
    - Fix MiddlewareTermination to accept result parameter for passing results
    - Fix _AutoHandoffMiddleware to use MiddlewareTermination instead of context.terminate
    - Fix AgentMiddlewareLayer.run() to properly forward function/chat middleware
    - Remove duplicate middleware registration in AgentMiddlewareLayer.__init__
    - Fix exception handling in _auto_invoke_function to properly capture termination
    - Fix mypy errors in core package
    - Update tests to use stream=True parameter for unified run API
    
    * fix all tests command
    
    * Refactor integration tests to use pytest fixtures
    
    - Merge testutils.py into conftest.py for azurefunctions integration tests
    - Merge dt_testutils.py into conftest.py for durabletask integration tests
    - Convert all integration tests to use fixtures instead of direct imports
      (fixes ModuleNotFoundError with --import-mode=importlib)
    - Add sample_helper fixture for azurefunctions tests
    - Add agent_client_factory and orchestration_helper fixtures for durabletask
    - Integration tests now skip with descriptive messages when services unavailable
    - Restructure devui tests into tests/devui/ with proper conftest.py
    - Add test organization guidelines to CODING_STANDARD.md
    - Remove __init__.py from test directories per pytest best practices
    
    * Fix pytest_collection_modifyitems to only skip integration tests
    
    The hook was skipping all tests in the test session, not just
    integration tests. Now it only skips items in the integration_tests
    directory.
    
    * Fix mem0 tests failing on Python 3.13
    
    Use patch.object on the imported module instead of @patch with string
    path to ensure the mock takes effect regardless of import timing.
    
    * fix mem0
    
    * another attempt for mem0
    
    * fix for mem0
    
    * fix mem0
    
    * Increase worker initialization wait time in durabletask tests
    
    Increase from 2 to 8 seconds to allow time for:
    - Python startup and module imports
    - Azure OpenAI client creation
    - Agent registration with DTS worker
    - Worker connection to DTS
    
    This helps prevent test failures in CI where the first tests may run
    before the worker is fully ready to process requests.
    
    * Fix streaming test to use ResponseStream with finalizer
    
    The _consume_stream method now expects a ResponseStream that can provide
    a final AgentResponse via get_final_response(). Update the test to use
    ResponseStream with AgentResponse.from_updates as the finalizer.
    
    * Fix MockToolCallingAgent to use new ResponseStream API and update samples
    
    * small updates to run_stream to run
    
    * fix sub workflow
    
    * temp fix for az func test
    
    ---------
    
    Co-authored-by: Dmytro Struk <13853051+dmytrostruk@users.noreply.github.com>
  • .NET: Adding AgentRunContext to allow accessing agent run info in external downstream components (#3476)
    * Add an AsyncLocal AgentRunContext
    
    * Update AgentRunContext session naming
    
    * Make AgentRunContext readonly and add ADR
    
    * Make session nullable and add unit tests
    
    * Add unit tests for setting the context in AIAgent
    
    * Apply suggestions from code review
    
    Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
    
    * Fix sample in ADR
    
    * Fix broken unit test
    
    * Add unit test for checking if middleware can access AgentRunContext
    
    * Fix build error after merge.
    
    * Fix AgentRunContextTests after merge from main
    
    ---------
    
    Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
  • .NET: [Breaking] RenameAgentRunResponse and AgentRunResponseUpdate classes (#3197)
    * rename AgentRunResponse and AgentRunResponseUpdate classes - part1
    
    * rename varialbles, parameters, methods and tests
    
    * rollback unnecessary changes
  • Python: ADR for simplified get response (#3098)
    * ADR for simplified get response
    
    * updated some language, added agent option and code comparison
    
    * small update in sample
    
    * added workflows and expanded some points
    
    * changed decision and number
    
    * updated with stream=False default
  • Python: ADR for create/get agent API (#2618)
    * ADR for create/get agent API
    
    * Updated ADR with implementation options
    
    * Small updates
    
    * Updated decision outcome section
    
    * Updated broken links
    
    * Small updates
    
    * Fixed merge conflicts
    
    * Small fix
    
    * Updated decision outcome section
    
    * Small fixes
    
    * Updated provider naming based on client SDK
  • Python: [BREAKING]: Introducing Options as TypedDict and Generic (#3140)
    * WIP typeddict for options
    
    * updated all clients and ChatAgents
    
    * updated everything
    
    * added ADR
    
    * fix mypy
    
    * proper typevar imports
    
    * fixed import
    
    * fixed other imports
    
    * slight update in the sample
    
    * updated from feedback
    
    * fixes
    
    * fixed missing covariants and test fixes
    
    * fixed typing
    
    * updated anthropic thinking config
    
    * ruff fixes
    
    * fixed int tests
    
    * fix tests and mypy
    
    * updated integration tests
    
    * updated docstring and test fix
    
    * improved options handling in obser
    
    * mypy fix
    
    * updated a host of integration tests
    
    * fix tests
    
    * bedrock fix
  • Fix broken strands urls. (#3102)
    * Fix broken strands urls.
    
    * Fix typos
  • .NET: AG-UI support for .NET (#1776)
    * Initial plan
    
    * Infrastructure setup
    
    * Plan for minimal client
    
    * Plan update
    
    * Basic agentic chat
    
    * cleanup
    
    * Cleanups
    
    * More cleanups
    
    * Cleanups
    
    * More cleanups
    
    * Test plan
    
    * Sample
    
    * Fix streaming and error handling
    
    * Fix notifications
    
    * Cleanups
    
    * cleanup sample
    
    * Additional tests
    
    * Additional tests
    
    * Run dotnet format
    
    * Remove unnecessary files
    
    * Mark packages as non packable
    
    * Fix build
    
    * Address feedback
    
    * Fix build
    
    * Fix remaining warnings
    
    * Feedback
    
    * Feedback and cleanup
    
    * Cleanup
    
    * Cleanups
    
    * Cleanups
    
    * Cleanups
    
    * Retrieve existing messages from the store to send them along the way and update the sample client
    
    * Run dotnet format
    
    * Add ADR for AG-UI
    
    * Switch to use the SG and use a convention for run ids
    
    * Cleanup MapAGUI API
    
    * Fix formatting
    
    * Fix solution
    
    * Fix solution
  • Python: Lab: Updates to GAIA module (#1763)
    * Lab: Updates to GAIA module
    
    * update
    
    * emoj!
    
    * fix lint
    
    * update lab test workflow to only trigger for python changes
    
    * lint
    
    * lint
    
    * Fix broken OpenAI agents JS documentation link
  • .NET: Add support for background responses (#1501)
    * add support for background responses
    
    * Update dotnet/src/Microsoft.Agents.AI.Abstractions/AgentRunResponseUpdate.cs
    
    Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
    
    * fix broken link
    
    * fix xml comments and background responses properties override funcitonity
    
    * change ai model provider
    
    * use Run{Streaming}Async overloads that don't require messages
    
    * stop using m: prefix in cref attribute of <see/> element.
    
    * reject input messages provided with continuation token + don't extract messages from message store and context provide if continuation token is provided
    
    * use agent thread for background-responses sample
    
    * require agent thread for background responses
    
    * Update dotnet/src/Microsoft.Agents.AI/ChatClient/ChatClientAgent.cs
    
    Co-authored-by: Roger Barreto <19890735+rogerbarreto@users.noreply.github.com>
    
    * Update dotnet/src/Microsoft.Agents.AI/ChatClient/ChatClientAgent.cs
    
    Co-authored-by: Roger Barreto <19890735+rogerbarreto@users.noreply.github.com>
    
    * remove CA1200
    
    * Update dotnet/src/Microsoft.Agents.AI.Abstractions/AgentRunOptions.cs
    
    Co-authored-by: westey <164392973+westey-m@users.noreply.github.com>
    
    * Update dotnet/src/Microsoft.Agents.AI.Abstractions/AgentRunResponse.cs
    
    Co-authored-by: westey <164392973+westey-m@users.noreply.github.com>
    
    * Update dotnet/src/Microsoft.Agents.AI.Abstractions/AgentRunResponse.cs
    
    Co-authored-by: westey <164392973+westey-m@users.noreply.github.com>
    
    * address pr review comments
    
    * Update dotnet/samples/GettingStarted/Agents/Agent_Step17_BackgroundResponses/Program.cs
    
    Co-authored-by: westey <164392973+westey-m@users.noreply.github.com>
    
    ---------
    
    Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
    Co-authored-by: Roger Barreto <19890735+rogerbarreto@users.noreply.github.com>
    Co-authored-by: westey <164392973+westey-m@users.noreply.github.com>
  • .NET: Add sample showing how to create ai function per a2a skill (#1452)
    * add sample showing how to create ai function per a2a skill
    
    * Update dotnet/src/Microsoft.Agents.AI.A2A/Extensions/A2AAgentCardExtensions.cs
    
    Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
    
    * Update dotnet/samples/GettingStarted/A2A/A2AAgent_AsFunctionTools/Program.cs
    
    Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
    
    * Update dotnet/samples/GettingStarted/A2A/A2AAgent_AsFunctionTools/Program.cs
    
    Co-authored-by: Roger Barreto <19890735+rogerbarreto@users.noreply.github.com>
    
    * address pr review comments
    
    * rename local function
    
    * add readmes
    
    * fix broken links
    
    ---------
    
    Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
    Co-authored-by: Roger Barreto <19890735+rogerbarreto@users.noreply.github.com>
  • .NET: Add link inspector (#1062)
    * Add link inspector
    
    * Comment out excludedirs while it's empty
    
    * Fix broken links
    
    * More links fixes
    
    * Push further fixes
    
    * Fix more links
  • .NET: Workflow observability (#959)
    * Add basic Workflow telemetry
    
    * Add sample
    
    * Add source propagation for executor spans
    
    * Fix tests and address comments
    
    * Fix formatting
    
    * Fix declarative unit tests
    
    * Address comments
    
    * Remove Microsoft.Extensions.AI.Agents.EnableTelemetry
    
    * Formatting
    
    * Formatting
    
    * Formatting
    
    * fix solution
    
    * Address comments
    
    * Add workflow json definition for serialization
    
    * Formmating
    
    * Address comments
  • .NET: Add Agent Filtering Middleware (#478)
    * WIP
    
    * Wip
    
    * Updated ADR
    
    * Updated ADR
    
    * Update files
    
    * Address copilot comments
    
    * Update filters from Task<T> to Task only
    
    * Project endpoint
    
    * Add agent ctor filter
    
    * Other Agent Framework investigation
    
    * Remove SK Java, no support
    
    * Update LlamaIndex info
    
    * Removing unrelated files
    
    * Implementation with specialization
    
    * Remove the specialization option as extra unecessary complexity
    
    * Move middleware responsibility to a decorator
    
    * Update readme
    
    * Function invocation wip
    
    * Add Agent Builder
    
    * Adding comparison samples
    
    * Reorganize Samples and Processor vs Decorator
    
    * Remove merge files
    
    * Address formating warnigs
    
    * Update ADR
    
    * Step13 README's update
    
    * Address PR feedback
    
    * Address PR feedback
    
    * Remove configure await from ADR samples
    
    * Update variables
    
    * Address feedback
    
    * Address Agent level tool invocation with Options.ToolsTransformer strategy
    
    * Removing the Processor approach
    
    * Proposal design for Middleware in CreateAIAgent extensions
    
    * Examples clean up and consolitation
    
    * Update middlewares to work with ApprovalREquiredFunction
    
    * Clean-up sample
    
    * Update override function call sample
    
    * Drop configuration from the extensions, looks overkill
    
    * Builder interface ..
    
    * Revert IAIBuilder interface approach
    
    * Cleanup sample
    
    * Adding unit tests
    
    * Fix UT
    
    * Cleanup sample
    
    * Remove unneeded dependency
    
    * Address PR comment + Readme Samples
    
    * Add missing comments for Program.cs Middleware
    
    * Address mor PR comments + add client factory for OpenAI extensions
    
    * Add OpenAI UnitTests for extensions
    
    * Add AzureAI PersistentChatClient UT
    
    * Addess feedback
    
    * Add function invoking UT
    
    * Add builder extension UT
    
    * Address feedback + Rearange abstractions + UT fixes
    
    * Drop context based middleware for full decorating impl
    
    * Update unit tests
    
    * Update UT coverage
    
    * Removing Middelware namespace
    
    * Add missing UT
    
    * Remove internal ToolTransformation Property
    
    * Adjust xmldoc
    
    * Remove transient file
    
    * Address merge conflict
    
    * Add xmldoc remark for clarity
    
    * Address comment
    
    * Address feedback
    
    * Update UT
    
    ---------
    
    Co-authored-by: Chris <66376200+crickman@users.noreply.github.com>
  • Python: update to packaging section of python package design doc (#727)
    * update to packaging section
    
    * added options
    
    * clarification and typo
    
    * updated python packaging guidance, moved discussion to appendix
    
    * moved discussion into ADR
    
    * updated folder strcutre
  • Add user approval ADR document (#731)
    * Add user approval adr
    
    * Address PR comments
  • Python: name changes executed (#607)
    * name changes executed
    
    * updated adr to accepted
    
    * renamed openai base config
    
    * renamed openai config to mixin
    
    * added renames in user docs
    
    * reverted mcperror
    
    * fix tests
    
    * remove sse from tests
  • ADR: python naming changes (#599)
    * python naming changes
    
    * small updates
    
    ---------
    
    Co-authored-by: Eric Zhu <ekzhu@users.noreply.github.com>
  • Decision on where Foundry SDK extensions should live (#442)
    * Decision on where Foundry SDK extensions should live
    
    * Address code review feedback