Python: Add Telegram hosting helpers and samples#7047
Conversation
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: 5d6987cd-1b67-4ba1-8b54-3c50da6e7607
Python Test Coverage Report •
Python Unit Test Overview
|
|||||||||||||||||||||||||||||||||||
There was a problem hiding this comment.
Pull request overview
Adds a new Python hosting “protocol seam” for Telegram by introducing a helper-only package that converts Telegram Bot API update shapes into Agent Framework run inputs and renders AF results/streams back into Telegram operation payloads, alongside self-contained local polling and webhook samples.
Changes:
- Introduces
agent-framework-hosting-telegram(alpha) with parsing helpers (telegram_to_run, session/chat/command/media extraction) and rendering helpers (telegram_from_run,telegram_from_streaming_run), plus focused unit tests. - Adds a local Telegram hosting sample with two independent entry points:
aiogrampolling and FastAPI webhook (PEP 723 script metadata), demonstrating app-owned commands, session reset, media handling, and streaming edit throttling. - Updates Python workspace metadata/lockfile and hosting documentation (spec + ADR) to reflect the new Telegram helper package and sample guidance.
Reviewed changes
Copilot reviewed 18 out of 19 changed files in this pull request and generated 6 comments.
Show a summary per file
| File | Description |
|---|---|
| python/uv.lock | Adds the new workspace member/package entry for agent-framework-hosting-telegram. |
| python/pyproject.toml | Registers agent-framework-hosting-telegram as a workspace package. |
| python/PACKAGE_STATUS.md | Marks the new Telegram hosting package as alpha. |
| python/samples/AGENTS.md | Adds a samples guideline to keep alternative entry points self-contained. |
| python/samples/04-hosting/af-hosting/README.md | Adds local_telegram/ to the hosting samples index and updates positioning language. |
| python/samples/04-hosting/af-hosting/local_telegram/README.md | Documents the Telegram sample, responsibilities split, and operational notes. |
| python/samples/04-hosting/af-hosting/local_telegram/pyproject.toml | Declares the sample project dependencies and uv sources for unreleased packages. |
| python/samples/04-hosting/af-hosting/local_telegram/polling_app.py | Implements the polling entry point with aiogram + AF telegram helpers. |
| python/samples/04-hosting/af-hosting/local_telegram/app.py | Implements the webhook entry point with FastAPI + aiogram + AF telegram helpers. |
| python/packages/hosting-telegram/pyproject.toml | Defines the new package metadata, dependencies, and test configuration. |
| python/packages/hosting-telegram/README.md | Documents helper scope, responsibilities, and usage patterns. |
| python/packages/hosting-telegram/LICENSE | Adds MIT license file for the new package. |
| python/packages/hosting-telegram/agent_framework_hosting_telegram/init.py | Exposes the public helper APIs and constants. |
| python/packages/hosting-telegram/agent_framework_hosting_telegram/_parsing.py | Implements update parsing/session/command/media extraction and telegram_to_run. |
| python/packages/hosting-telegram/agent_framework_hosting_telegram/_rendering.py | Implements final/streaming renderers producing Telegram method/payload operations. |
| python/packages/hosting-telegram/tests/hosting_telegram/test_parsing.py | Adds unit tests covering parsing and conversion behavior. |
| python/packages/hosting-telegram/tests/hosting_telegram/test_rendering.py | Adds unit tests covering final + streaming rendering behavior. |
| docs/specs/002-python-hosting-channels.md | Updates hosting spec to include Telegram package helpers and validation scope. |
| docs/decisions/0027-hosting-channels.md | Updates ADR examples to reflect Telegram session-id shape/semantics. |
There was a problem hiding this comment.
Automated Code Review
Reviewers: 5 | Confidence: 89%
✓ Correctness
The implementation is well-structured and correct. The Telegram parsing helpers properly handle all documented update shapes (message, edited_message, callback_query), session isolation follows Telegram's native boundaries, and the rendering helpers correctly produce cumulative edit operations with appropriate deduplication and truncation. Types are used consistently with the framework's AgentRunArgs, AgentResponse, ResponseStream, and Content definitions. No correctness bugs found.
✓ Security Reliability
The helper library is well-implemented from a security/reliability standpoint: all extraction functions defensively validate types and return None for unexpected shapes, the webhook sample uses timing-safe secret comparison, text is truncated at Telegram's documented limits, and errors propagate rather than being swallowed. The one notable gap is in the sample's file-size guard, which can be bypassed when Telegram omits the file_size field, but this is mitigated by Telegram's own 20MB platform limit and is clearly documented as sample code requiring production hardening.
✓ Test Coverage
The test suite is thorough with good coverage of core helpers, edge cases, and error propagation. Two meaningful test coverage gaps exist: (1) caption truncation at TELEGRAM_MAX_CAPTION_LENGTH (1024) is exercised in production code but never tested with over-length input, and (2) the streaming rendering path for responses containing both text and images is untested. Both are nonblocking since the underlying logic is simple and composed of individually tested pieces.
✓ Failure Modes
The library code handles failure modes well: errors during stream iteration and finalization propagate to calers (confirmed by tests), ValueError is raised for unprocessable inputs rather than producing silent empty results, and no exceptions are swallowed in the helper functions. The sample code has documented limitations around orphaned placeholders on mid-stream errors and webhook background task failures, but these are explicitly called out in the README's production-readiness section as app-owned responsibilities. No silent failure paths or lost errors were found in the diff.
✗ Design Approach
The Telegram helper package is mostly aligned with the helper-first design described in the PR, but the text/caption boundary enforcement is implemented with Python character counts rather than Telegram's UTF-16 unit limits. That means certain valid Python strings containing astral-plane emoji can still produce over-limit Bot API payloads, so I would request a fix before merging.
Flagged Issues
- python/packages/hosting-telegram/agent_framework_hosting_telegram/_rendering.py:41-43 truncates by Python code point count, so inputs such as "😀" * 4096 are left unchanged even though Telegram counts them as 8192 UTF-16 code units. The helper therefore does not actually enforce the documented Telegram size boundary for send/edit/caption payloads.
Automated review by eavanvalkenburg's agents
|
Flagged issue python/packages/hosting-telegram/agent_framework_hosting_telegram/_rendering.py:41-43 truncates by Python code point count, so inputs such as "😀" * 4096 are left unchanged even though Telegram counts them as 8192 UTF-16 code units. The helper therefore does not actually enforce the documented Telegram size boundary for send/edit/caption payloads. Source: automated DevFlow PR review |
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: 5d6987cd-1b67-4ba1-8b54-3c50da6e7607
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: 5d6987cd-1b67-4ba1-8b54-3c50da6e7607
|
|
||
| # Persist the updated AgentSession back under the stable per-chat key after | ||
| # streaming has finalized and the history provider has recorded the turn. | ||
| await state.set_session(session_id, session) |
There was a problem hiding this comment.
Could an in-flight update resurrect the session after /new? Webhook updates run as independent background tasks, so an older run can retain this AgentSession, /new can delete the mapping, and then this unconditional write restores the old history or overwrites a fresh session created meanwhile. Should updates be serialized per session, or should this write be conditional on the mapping still pointing to this session?
Motivation & Context
Telegram applications need a small conversion seam between Bot API values and Agent Framework types without reintroducing the deleted channel host, routing registry, or transport lifecycle abstractions. This adds that helper-first integration together with native aiogram and FastAPI examples that keep transport and application policy visible.
Description & Review Guide
agent-framework-hosting-telegrampackage for update parsing, session/command/media extraction, final response rendering, and streaming Telegram operations. Adds self-contained webhook and polling samples using an actual Foundry-backed agent, aiogram, FastAPI, PEP 723 dependencies, app-owned commands, media handling, session reset, webhook authentication, and edit throttling. Updates package metadata, sample guidance, the hosting ADR, and the helper-first implementation spec.bot + userfor private chats andbot + chatfor shared groups), streaming operation semantics, and whether the two self-contained sample entry points make the app-owned responsibilities clear.Related Issue
Closes #6588
Contribution Checklist
breaking changelabel (or add "[BREAKING]" to the title prefix, before or after any language prefix) — a workflow keeps the label and title prefix in sync automatically.