Skip to content

Telegram Integration ​

Purpose ​

Telegram is the current interactive transport for JARVIS. The runtime uses a small polling bridge to receive messages and callback actions, routes them through the orchestrator, and renders the result back into Telegram-friendly text, HTML, buttons, and optional patch attachments.

Setup ​

JARVIS reads Telegram configuration from environment variables in src/jarvis/settings.py.

Required variables:

  • JARVIS_TELEGRAM_BOT_TOKEN for the bot token created with BotFather
  • JARVIS_TELEGRAM_ALLOWED_CHAT_IDS for the comma-separated allowlist of chat IDs

Optional variable:

  • JARVIS_TELEGRAM_POLL_TIMEOUT_SECONDS to control long-poll duration

Example:

bash
export JARVIS_TELEGRAM_BOT_TOKEN="123456:example-token"
export JARVIS_TELEGRAM_ALLOWED_CHAT_IDS="123456789"
export JARVIS_TELEGRAM_POLL_TIMEOUT_SECONDS="30"
python -m jarvis.main

If the bot token is missing, src/jarvis/main.py does not start the Telegram polling loop. It falls back to a local sample flow and prints a /status response to stdout.

Runtime Flow ​

The Telegram path is wired in src/jarvis/main.py.

text
Telegram user
  -> Telegram Bot API
  -> TelegramBridge.get_next_instruction()
  -> OrchestratorAgent
  -> TelegramPresenter
  -> TelegramBridge.send_response() / send_document()

The concrete behavior is:

  1. TelegramBridge long-polls getUpdates for message and callback_query.
  2. Incoming chat IDs are checked against JARVIS_TELEGRAM_ALLOWED_CHAT_IDS.
  3. Normal text messages are normalized into TelegramInstruction.
  4. OrchestratorAgent.handle_telegram_instruction() routes and executes the request.
  5. TelegramPresenter formats the structured result into Telegram-ready output.
  6. TelegramBridge.send_response() sends the message back, splitting long replies when needed.
  7. If a diff attachment is present, send_document() uploads it as a file.

How Interaction Works ​

Plain messages ​

Normal messages are handled as instructions. The orchestrator decides whether they are:

  • authority commands such as /write
  • workspace queries
  • repo activation requests
  • code-change proposals
  • approval or rejection replies

Workspace responses and code-change previews are rendered as HTML so Telegram can show structured headings, inline code, and formatted previews.

Approval buttons ​

For pending code changes, JARVIS can render inline buttons built in src/jarvis/presentation/telegram/keyboards.py:

  • Approve
  • Reject

Those buttons carry compact callback payloads of the form approve:<pending_change_id> and reject:<pending_change_id>.

When a user taps one:

  1. Telegram sends a callback_query.
  2. TelegramBridge extracts callback_data.
  3. OrchestratorAgent.handle_callback_payload() parses the action.
  4. The orchestrator resolves the pending change for that chat.
  5. The approval or rejection path is dispatched through the canonical pending-change flow.
  6. JARVIS answers the callback query to stop Telegram's loading spinner.
  7. The resulting status message is sent back into the chat.

Screens ​

Code review flow ​

Telegram code review flow

Action flow ​

Telegram action flow

Relevant Source Files ​

  • src/jarvis/main.py
  • src/jarvis/services/telegram_bridge.py
  • src/jarvis/presentation/telegram/presenter.py
  • src/jarvis/presentation/telegram/formatters.py
  • src/jarvis/presentation/telegram/keyboards.py
  • src/jarvis/presentation/telegram/callbacks.py