* samples(hosting): add hosting Channels sample apps under samples/04-hosting/af-hosting Adds five end-to-end sample apps under ``python/samples/04-hosting/af-hosting/`` that exercise the ``agent-framework-hosting`` Channels stack from the simplest single-channel case up to a multi-channel deployment with cross-channel identity linking. Samples (ordered by complexity) ------------------------------- * ``foundry_hosted_agent/`` — minimal Responses + Invocations host with a Foundry-backed agent and ``FoundryHostedAgentHistoryProvider``. ``agd``-deployable; bundles a ``Dockerfile`` and ``scripts/vendor-packages.sh`` that copies workspace packages into ``_vendor/`` for self-contained builds. ``_vendor/`` is gitignored. * ``local_responses/`` — single-channel Responses host with a ``run_hook`` that strips caller-supplied options and forces a reasoning preset. Demonstrates the hook seam over the uniform ``ChannelRequest`` envelope. * ``local_responses_workflow/`` — Responses + Invocations exposing a three-agent workflow with per-conversation checkpoint storage. * ``local_telegram/`` — Responses + Telegram with a ``@tool``, ``FileHistoryProvider``, hooks, and a ``ResponseTarget`` multicast variant (``call_server_multicast.py``) that pushes a single Responses reply to a separate Telegram chat. * ``local_identity_link/`` — full surface: Responses + Invocations + Telegram + Activity Protocol (Teams) + the ``EntraIdentityLinkChannel`` sidecar. Resolves per-channel ids onto a single Entra object id so a user's history follows them across surfaces. Notes ----- * Samples that use Telegram/Teams via Activity Protocol depend on the renamed ``agent-framework-hosting-activity-protocol`` package (see the PR-5 series). * All samples use ``[tool.uv.sources]`` editable workspace deps, except ``foundry_hosted_agent/`` which uses the ``./_vendor/`` self-contained layout for ``azd`` Docker builds. * Each sample includes a ``README.md`` with run instructions and an ``app.py`` ASGI entrypoint plus a ``call_server.py`` client harness. Depends on the prior hosting PRs (foundry-hosted-agent refactor + hosting-core + the per-channel packages). After those merge, this branch can be rebased onto ``main`` cleanly. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * samples(hosting): point sample deps at the feature/python-hosting GitHub branch Switches every sample's ``[tool.uv.sources]`` from in-monorepo editable path deps (which only resolve when running inside the agent-framework workspace) to git refs targeting the ``feature/python-hosting`` branch on ``microsoft/agent-framework``. Samples now install standalone outside the monorepo while the ``agent-framework-hosting*`` packages are still pre-PyPI; once they publish, the ``[tool.uv.sources]`` block can be dropped and the declared deps resolve from PyPI. Cleanup ------- * Drops ``foundry_hosted_agent/scripts/vendor-packages.sh``, ``_vendor/`` from ``.gitignore``, the ``hooks.prepackage`` block in ``azure.yaml`` and the ``COPY _vendor/`` step in the Dockerfile — vendoring is no longer needed because git refs make the deps network-resolvable from any context. * Drops obsolete ``workspace.pyproject.toml`` reference and ``scripts/`` / ``workspace.pyproject.toml`` entries from ``Dockerfile.dockerignore``. * Updates the foundry sample's Dockerfile to ``uv sync --no-dev`` (no ``--frozen``) so it locks fresh against the GitHub-hosted deps at build time. * Drops every committed ``uv.lock`` because the resolver needs network access to ``feature/python-hosting`` to lock — they regenerate the first time a user runs ``uv sync`` after the branch lands. * Refreshes the per-sample READMEs to mention the GitHub install path instead of "in-tree workspace packages". Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * samples(hosting): address PR #5645 review comments - foundry_hosted_agent/call_server.py: replace hard-coded project_endpoint and service_session_id with FOUNDRY_PROJECT_ENDPOINT, FOUNDRY_HOSTED_AGENT_NAME, and optional FOUNDRY_HOSTED_SESSION_ID environment variables. Session-id is now optional so the sample exercises the new-conversation path by default. - local_identity_link/app.py: * make_telegram_hook: apply the reasoning bump regardless of identity-link state (the previous early-return on linked chats silently dropped the high-effort preset for the very flow the sample exists to demonstrate). * make_responses_hook: add a prominent DEV-ONLY warning that the client-supplied entra_oid shortcut bypasses identity verification and must be replaced by a JWT validator in production. * /link command: early-return when chat_id is missing instead of minting an authorize URL keyed on "telegram:None" (which would poison the link store with a binding any future chat_id-less update would collapse onto). * Switch ENTRA_CERT_PATH / ENTRA_CERT_PASSWORD env vars to the longer ENTRA_CERTIFICATE_PATH / ENTRA_CERTIFICATE_PASSWORD names that the README already documents. * channels: Sequence[Channel] -> list[Channel] (the next line appends, which a Sequence type doesn't expose). Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * chore(hosting-samples): apply sample formatting Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * fix(hosting-samples): guard command input text Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> --------- Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Multi-channel hosting samples
End-to-end samples for serving an agent-framework agent (or workflow)
through one or more channels with agent-framework-hosting.
The general hosting plumbing lives in
agent-framework-hosting; each channel is
its own package (agent-framework-hosting-responses,
agent-framework-hosting-invocations,
agent-framework-hosting-telegram, agent-framework-hosting-activity-protocol,
agent-framework-hosting-entra).
| Sample | What it shows | Packaging |
|---|---|---|
local_responses/ |
The minimal shape: one agent + one @tool + ResponsesChannel + a single run_hook that strips caller-supplied options and forces a reasoning preset. |
Local only. Start here to learn the run-hook seam. |
local_responses_workflow/ |
A 4-step Workflow (typed SloganBrief intake → writer → legal → formatter) hosted behind both the Responses and Invocations channels via a shared run_hook that parses inbound text/JSON into the workflow's typed input. The host writes per-conversation checkpoints via checkpoint_location=…. Demonstrates workflow targets + structured input adaptation + multi-channel + resume-across-turns. Includes a call_server.rest file with REST examples for both endpoints. |
Local only. |
foundry_hosted_agent/ |
One Foundry agent, Responses + Invocations only — the minimal shape that is runtime-compatible with the Foundry Hosted Agents platform. | Ships with Dockerfile + agent.yaml + agent.manifest.yaml + azure.yaml so the same image runs locally or as a Foundry Hosted Agent (azd up). |
local_telegram/ |
Adds Telegram, a @tool, FileHistoryProvider, run hooks (per-user / per-chat session keying), extra Telegram commands, and ResponseTarget multicast. Runs under Hypercorn with multiple workers. |
Local only. No Dockerfile / Foundry packaging. |
local_identity_link/ |
Everything in local_telegram/ plus Teams and the Entra identity-link sidecar (/auth/start + /auth/callback). Demonstrates linking a Telegram chat to an Entra user so multiple non-Entra channels can share one isolation key. |
Local only. No Dockerfile / Foundry packaging. |
Each sample is fully self-contained — its own pyproject.toml, uv.lock,
server app.py, calling script(s), and storage/ directory. Every
sample uses [tool.uv.sources] to wire its agent-framework-hosting*
dependencies to the
feature/python-hosting
branch of the upstream repo via git refs, so they install cleanly outside
the monorepo while the hosting packages are still pre-PyPI. Once those
packages publish, drop the [tool.uv.sources] block and let the
declared deps resolve from PyPI.
Relationship to ../foundry-hosted-agents/
The sibling ../foundry-hosted-agents/ directory
contains samples for the agent-framework-hosted stack — agents
that run inside the Foundry Hosted Agents platform using its
built-in protocol surface (Responses, Invocations, conversation store,
isolation, identity), with no agent-framework-hosting package
involved.
| Aspect | af-hosting/ (this directory) |
foundry-hosted-agents/ |
|---|---|---|
| Server stack | agent-framework-hosting + per-channel packages (-responses, -invocations, -telegram, -activity-protocol, -entra) |
agent-framework-hosted only — the Foundry Hosted Agents runtime owns the HTTP surface |
| Channels other than Responses / Invocations | Yes — Telegram, Activity Protocol (Teams), Entra identity-linking | No — the platform exposes Responses + Invocations only |
| Run target | Local Hypercorn (local_responses/, local_telegram/, local_identity_link/); Hosted Agents or local (foundry_hosted_agent/) |
Hosted Agents or local container; targets the Hosted Agents platform contract |
| When to pick this | You need extra channels (Telegram/Teams via Activity Protocol/…), custom hosting middleware, or want to run outside the Foundry runtime | You only need Responses/Invocations and want zero hosting boilerplate, leveraging the Foundry-managed surface |
foundry_hosted_agent/ is the bridge sample: it uses the
agent-framework-hosting stack but is packaged so the Foundry Hosted
Agents platform can run it as one of its own.
See ARCHITECTURE.md for the cross-sample story.