1aca7601b8
* Add Python hosting protocol helper surface Introduce AgentFrameworkState and SessionStore for app-owned hosting routes, add Responses run conversion/rendering helpers, and update the local Responses sample to use native FastAPI routing with streaming support. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * Fix CI failures, session continuity, and streaming model reporting - Fix constrained TargetT TypeVar in AgentFrameworkState: split __init__ into per-shape overloads (instance/sync factory/async factory/awaitable) since a bound TypeVar combined with one big Callable/Awaitable union parameter was unsolvable across pyright/pyrefly/ty/zuban. - Fix _FakeAgent test fixtures to structurally satisfy SupportsAgentRun (matching attribute types and overloaded run()), which the above surfaced. - Add SessionStore.put() to alias an additional session id to an already-resolved session, and use it in the local_responses sample to fix a real session-continuity bug: previous_response_id rotates every turn, so without aliasing the newly minted response id, turn 3+ of a conversation silently lost all prior history. Verified against a live Foundry model across a 3-turn conversation. - Fix responses_stream_events_from_run to report the real model instead of the "agent" fallback: AgentResponse.from_updates never carries a raw representation forward, so capture model from the individual streamed updates' raw representations instead. Verified live. - Add response_model=None to the sample's FastAPI route (it could not boot at all: FastAPI tried to build a Pydantic response model from the JSONResponse | StreamingResponse return annotation). - Map responses_to_run's ValueError to HTTP 400 instead of a 500. - Add HTTP round-trip integration tests (packages/hosting-responses) that exercise the same FastAPI + AgentFrameworkState + Responses helper wiring as the sample via httpx.ASGITransport, including a regression test for the session-continuity fix. - Add Workflow-target test coverage, SessionStore.put/reset_session tests, and TypeError-path coverage to packages/hosting/tests/hosting/test_state.py. - Extend call_server.py / call_server_af.py to a third conversation turn so they actually exercise the continuity chain (previous scripts stopped at turn 2, which would never have revealed the bug above). Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * Simplify session-continuity aliasing: fold put() into get() Per feedback: the growth of SessionStore was not the problem -- it's intentional, since OpenAI's previous_response_id is designed to let a caller continue (fork) from any earlier response, not just the latest one, so every response id has to stay independently resolvable. That part stays as-is. What was too complex was the call site: routes had to manually fetch a session and then conditionally alias it with a separate put() call. Folded that into a single get(session_id, alias=...) call instead: - SessionStore.get() gains an optional `alias` keyword that registers an additional id for the same session in the same call (no-op if alias is None or equal to session_id). Removed the separate put() method. - AgentFrameworkState.get_session() passes `alias` through. - local_responses sample and the HTTP round-trip integration tests now do `await state.get_session(lookup_id, alias=response_id)` instead of pulling the store out and orchestrating get()/put() by hand. - Documented that this in-memory SessionStore intentionally never evicts (by design, to support forking), and that a storage-backed replacement (Redis, a database, ...) is responsible for its own TTL/eviction policy. Verified against a live Foundry model across a 3-turn previous_response_id chain after the simplification. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * Refine hosting state helpers Split the shared state surface into AgentState and WorkflowState, keep SessionStore and CheckpointStore as plain storage, and make state helpers responsible for get-or-create behavior. Update the Responses sample and HTTP round-trip tests to store the post-run session explicitly under the minted response id, and support WorkflowBuilder/orchestration-style builders via structural build() support. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * Fix hosting state test protocol fakes Widen fake agents' get_session service_session_id parameter to match the SupportsAgentRun protocol under the Python 3.11 test typing checkers. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * Simplify Responses stream helper naming Rename responses_stream_events_from_run to responses_stream_from_run across exports, tests, docs, and the local Responses sample to align with the generic <protocol>_stream_from_run helper convention. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * Add state-level storage setters Add AgentState.set_session and WorkflowState.set_checkpoint_storage so app code can pair get-or-create helpers with explicit post-run storage without reaching into the underlying stores. Update Responses docs, tests, and sample to use state.set_session. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * Simplify WorkflowState checkpoint handling Remove CheckpointStore from WorkflowState so workflow checkpointing uses the existing CheckpointStorage abstraction directly. Keep WorkflowState focused on resolving workflow targets, including builders, and update hosting docs/tests accordingly. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * Rename Responses streaming run helper Rename responses_stream_from_run to responses_from_streaming_run across the hosting-responses exports, tests, docs, and local Responses sample. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * Align Python hosting spec with protocol helpers Rewrite SPEC-002 to match the accepted helper-first hosting ADR and the implementation PR: AgentState, WorkflowState, SessionStore, Responses helpers, app-owned security/state responsibilities, and the minimal FastAPI Responses shape. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * Remove old Python hosting channel implementation Remove the unreleased AgentFrameworkHost/channel implementation, the old hosting-telegram package, and old host/channel samples. Keep agent-framework-hosting focused on AgentState, WorkflowState, and SessionStore, and keep hosting-responses focused on helper-first Responses conversion. Update SPEC-002 to match the accepted helper-first ADR and the implementation surface. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * Restore helper-first workflow sample Rebuild the local Responses workflow sample on the protocol-helper surface, add production-readiness cautions to the local hosting samples, and align file-backed workflow checkpoint/cursor storage under one sample storage root. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * Address hosting helper review feedback Handle streaming failures as terminal Responses SSE events, guard concurrent target/session initialization, and scope workflow sample checkpoint storage per continuation. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * Clarify Responses sample continuation behavior Document unknown conversation_id behavior in the agent sample and make the workflow sample explicitly reject conversation_id while continuing to use responses_session_id for previous_response_id. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * Clarify Responses sample option policy Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> --------- Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Hosting Samples
This directory contains Python samples that demonstrate different ways to host Agent Framework agents. Use this page to choose the hosting model that best fits your scenario, then continue to the README in the relevant subdirectory.
Hosting Options
| Option | Use this when you need... | Start here |
|---|---|---|
| A2A | Agent-to-Agent protocol interoperability or remote agent invocation. | a2a/README.md |
| Azure Functions | HTTP or serverless hosting on Azure Functions. | azure_functions/README.md |
| Durable Task | Durable execution, long-running flows, or orchestration patterns. | durabletask/README.md |
| Foundry Hosted Agents | Azure AI Foundry hosted agent deployment. | foundry-hosted-agents/README.md |
How to Choose
- Start with A2A if you want one agent to call or expose another agent over the A2A protocol.
- Start with Azure Functions if you want an HTTP-hosted or serverless entry point using Azure Functions.
- Start with Durable Task if you need persistent state, durable workflows, or orchestration across multiple steps.
- Start with Foundry Hosted Agents if you want to package and deploy an agent as a hosted agent in Azure AI Foundry.
Common Prerequisites
Most hosting samples share a small set of prerequisites:
- A supported Python environment for running the samples locally.
- An Azure AI Foundry project endpoint and model deployment name for
FOUNDRY_PROJECT_ENDPOINTandFOUNDRY_MODEL. - Azure CLI authentication via
az loginwhen the sample usesAzureCliCredential. - Any hosting-specific tools or extra services called out in the subdirectory README.
Next Steps
- Pick the hosting approach that matches your scenario.
- Open the corresponding README for setup and run instructions.
- Follow that sample's environment, dependency, and execution steps.