feat: add Telegram bot example documentation demonstrating kagent A2A…#335
feat: add Telegram bot example documentation demonstrating kagent A2A…#335
Conversation
There was a problem hiding this comment.
Pull request overview
Adds a new kagent documentation example showing how to integrate a Telegram bot with a kagent Agent via the A2A protocol, and links it from the Examples index.
Changes:
- Added a new MDX doc page: Telegram bot architecture, agent manifest, Python bot code, and Kubernetes deployment steps.
- Linked the new Telegram Bot example from the kagent examples landing page.
Reviewed changes
Copilot reviewed 2 out of 2 changed files in this pull request and generated 4 comments.
| File | Description |
|---|---|
| src/app/docs/kagent/examples/telegram-bot/page.mdx | New end-to-end Telegram bot + A2A integration guide (agent YAML, bot code, deployment). |
| src/app/docs/kagent/examples/page.mdx | Adds a QuickLink entry pointing to the new Telegram bot example. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
You can also share your feedback on Copilot code review. Take the survey.
… integration. Signed-off-by: Sebastian Maniak <sebastian@maniak.io>
e7422e5 to
50a4e9d
Compare
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com> Signed-off-by: Sebastian Maniak <sebastian@maniak.io>
Rewrote the page to lead with screenshots, cut design-doc tone, and speak directly to platform/k8s engineers. Added image references for real Telegram conversation screenshots. Signed-off-by: Sebastian Maniak <sebastian@maniak.io> Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
7112be0 to
4928e69
Compare
Updated the introduction to provide a clearer overview of the Telegram bot's capabilities and architecture, emphasizing its AI integration and operational features. Signed-off-by: Sebastian Maniak <sebastian@maniak.io>
Signed-off-by: Sebastian Maniak <sebastian@maniak.io>
Signed-off-by: Sebastian Maniak <sebastian@maniak.io>
Signed-off-by: Sebastian Maniak <sebastian@maniak.io>
There was a problem hiding this comment.
Pull request overview
Adds a new kagent example doc page that walks users through building and deploying a Telegram bot that talks to a kagent agent via A2A, and links it from the examples index.
Changes:
- Added a full “Telegram Bot” walkthrough page (architecture, agent manifest, bot code, Docker/K8s deploy steps).
- Added the Telegram Bot entry to the kagent examples landing page.
Reviewed changes
Copilot reviewed 2 out of 3 changed files in this pull request and generated 6 comments.
| File | Description |
|---|---|
| src/app/docs/kagent/examples/telegram-bot/page.mdx | New end-to-end Telegram bot example documentation (includes sample Python bot and deployment snippets). |
| src/app/docs/kagent/examples/page.mdx | Adds a QuickLink to the new Telegram bot example page. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
You can also share your feedback on Copilot code review. Take the survey.
|
|
||
| Here’s what we’re building: | ||
|
|
||
|  |
| async def send_a2a_task(message_text: str, session_id: str) -> str: | ||
| """Send a message to the kagent A2A endpoint and return the response.""" | ||
| task_id = str(uuid.uuid4()) | ||
| payload = { | ||
| "jsonrpc": "2.0", | ||
| "id": task_id, | ||
| "method": "message/send", | ||
| "params": { | ||
| "id": task_id, | ||
| "message": { | ||
| "role": "user", | ||
| "parts": [{"kind": "text", "text": message_text}], | ||
| }, | ||
| }, | ||
| } |
| The bot is ~460 lines of Python using python-telegram-bot (polling mode) and httpx for A2A calls. It handles three main concerns: A2A communication with session continuity, HITL approval flow via Telegram inline keyboards, and robust response parsing. | ||
|
|
||
| * The critical detail: contextId goes inside the message object, not in params. On the first message, we omit it — kagent returns a contextId in the result. We store that per Telegram user and send it on every subsequent message. This is what makes “tell me about nginx” followed by “now scale it to 3” work as a coherent conversation. | ||
|
|
||
|
|
||
| Let’s walk through it section by section. | ||
|
|
||
| * A2A Communication: The core of the bot — sending messages to kagent and tracking contextId for session continuity: | ||
| * Response Parsing: kagent returns text in different locations depending on the response state. The bot tries three sources in order: | ||
| * HITL Approval Flow: When kagent returns input-required, the bot parses the adk_request_confirmation data to figure out what tool the agent wants to run, then shows Telegram inline keyboard buttons: | ||
|
|
||
|
|
| The bot is ~460 lines of Python using python-telegram-bot (polling mode) and httpx for A2A calls. It handles three main concerns: A2A communication with session continuity, HITL approval flow via Telegram inline keyboards, and robust response parsing. | ||
|
|
||
| * The critical detail: contextId goes inside the message object, not in params. On the first message, we omit it — kagent returns a contextId in the result. We store that per Telegram user and send it on every subsequent message. This is what makes “tell me about nginx” followed by “now scale it to 3” work as a coherent conversation. | ||
|
|
||
|
|
||
| Let’s walk through it section by section. | ||
|
|
||
| * A2A Communication: The core of the bot — sending messages to kagent and tracking contextId for session continuity: | ||
| * Response Parsing: kagent returns text in different locations depending on the response state. The bot tries three sources in order: | ||
| * HITL Approval Flow: When kagent returns input-required, the bot parses the adk_request_confirmation data to figure out what tool the agent wants to run, then shows Telegram inline keyboard buttons: |
| result = data.get("result", {}) | ||
| artifacts = result.get("artifacts", []) | ||
| if artifacts: | ||
| parts = artifacts[-1].get("parts", []) | ||
| texts = [p.get("text", "") for p in parts if p.get("kind") == "text"] | ||
| if texts: | ||
| return "\n".join(texts) | ||
| return "Agent returned no text response." |
| else: | ||
| await update.message.reply_text(chunk) | ||
| except Exception as e: | ||
| await thinking_msg.edit_text(f"Error contacting agent: {e}") |
… integration.