* Python: Add Telegram channel for agent-framework-hosting - Add agent-framework-hosting-telegram package with TelegramChannel supporting polling and webhook transports, streaming edits with Telegram Bot API rate limiting, per-chat serial workers, and multi-modal inbound/outbound (text, photo, document, voice) - Add local_telegram sample demonstrating multi-channel hosting with a TelegramChannel alongside ResponsesChannel, using per-chat FileHistoryProvider and a run_hook for Telegram persona temperature - Fix test layout: move tests to tests/hosting_telegram/ (no __init__.py) - Remove old [tool.mypy] section and mypy poe task; source type-checking is handled by pyright via shared_tasks - Update uv.lock, pyproject.toml workspace sources, and PACKAGE_STATUS.md Fixes #6588 Refs #6265 Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * Python: Address Telegram channel CI failures and review feedback - Fix webhook secret validation to use constant-time compare_digest - Harden webhook update parsing: require integer chat IDs and guard slash-only commands - Fix streaming edge cases in TelegramChannel: - prevent edit worker deadlocks when text exceeds 4096 chars - prevent deadlock when placeholder send fails (message_id stays None) - enforce edit throttling with minimum interval sleep - honor send_typing_action=False in streaming mode - always forward final multimodal output (e.g. images), while avoiding duplicate text sends - Expand Telegram tests for slash-only command handling, non-int chat IDs, and streaming behavior (long text, final images, typing toggle) - Fix sample/docs feedback: - rename sample package to agent-framework-hosting-sample-local-telegram - switch sample uv.sources from feature branch to main - align docs/tool names with lookup_weather - fix broken links and server run instructions in README/call_server.py - align local_telegram app docstrings with reasoning hook behavior and strip model in responses_hook Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * Python: Fix TelegramChannel streaming to iterate contents for multimodal support - Remove stale PR reference from module docstring - Add Google-style docstring to TelegramChannel.__init__ documenting all keyword args - Fix _stream_to_chat to iterate update.contents instead of using getattr(update, 'text', None); text chunks are extracted from Content items with type='text', non-text content in updates is correctly ignored (images etc. are forwarded via the final response) - Update _FakeStreamUpdate test helper to use contents list matching the real AgentResponseUpdate API; add from_text/from_image class methods - Update _FakeResponseStream to accept _FakeStreamUpdate objects directly - Add test verifying multimodal stream updates don't corrupt text accumulator Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * Python: Split local_telegram into simple Telegram-only and new multi-channel sample local_telegram is now a focused Telegram-only sample: - Removes ResponsesChannel and all responses_hook code - Removes call_server.py (no HTTP endpoint to call) - Uses a deterministic lookup_weather tool (hash-based, not random) - Single run_hook that strips model and raises reasoning effort - Drops agent-framework-hosting-responses dependency New local_multi_channel sample shows running both channels at once: - ResponsesChannel + TelegramChannel sharing a FileHistoryProvider - Cross-channel session resumption via previous_response_id - call_server.py moved here (the Responses endpoint lives here now) - Demonstrates the multi-channel coordination story Update README table to list both samples with clear descriptions. Also delete personal_assistant/.venv which was not tracked but caused pyright to crawl the entire installed venv (thousands of files), making sample pyright checks hang indefinitely. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * Python: Fallback when Telegram final edit fails - only mark final edit as sent after a confirmed 2xx edit response - fall back to sendMessage when final edit returns a non-success status - add regression test covering failed final edit fallback behavior Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * Python: Fix optional await_args typing in telegram test - assert await_args is not None before reading kwargs in streaming fallback test - resolves test-typing failures across mypy/pyright/ty/zuban for hosting-telegram 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. This first sample set includes
agent-framework-hosting-responses.
| 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 the Responses channel via a 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 + resume-across-turns. Includes a call_server.rest file with REST examples. |
Local only. |
local_telegram/ |
Telegram bot with @tool, FileHistoryProvider, run_hook, and slash commands (/new, /whoami, /weather). Pure Telegram — no HTTP endpoint. |
Local only. Start here to learn the Telegram channel. |
local_multi_channel/ |
Same agent behind two channels at once: ResponsesChannel + TelegramChannel. Shared FileHistoryProvider enables cross-channel session resumption (resume a Telegram chat from the Responses endpoint by passing the Telegram isolation key as previous_response_id). |
Local only. |
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
main
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 + agent-framework-hosting-responses |
agent-framework-hosted only — the Foundry Hosted Agents runtime owns the HTTP surface |
| Channels | Responses only in this initial sample set | The platform exposes Responses + Invocations |
| Run target | Local Hypercorn (local_responses/, local_responses_workflow/) |
Hosted Agents or local container; targets the Hosted Agents platform contract |
| When to pick this | You want to learn the host/channel seams locally or need custom hosting middleware | You want zero hosting boilerplate, leveraging the Foundry-managed surface |
The table above summarizes the cross-sample story.