Files
oh-my-pi-telegram/README.md
T
2026-10-13 21:47:35 -03:00

12 KiB

oh-my-pi-telegram

A Telegram companion hub for live Oh My Pi (omp) sessions — queue prompts, stream replies, send files and voice, and supervise your agent from your phone.

Version Node License

Install · Features · How it works · Limitations · Development · CI/CD

pi-telegram running in Telegram

Note

Project status: fork of @llblab/[email protected] (SHA afe09c5), repackaged as @evandrodevbr/oh-my-pi-telegram and declared as an omp extension. Per CHANGELOG.md, the fork passes the upstream gates (typecheck, 1229/1230 tests with one platform-only skip, npm audit with 0 vulnerabilities, clean npm pack --dry-run). The latest commit adds a design spec for an OMP 17 status-bar segment (docs/superpowers/specs/); that spec needs a new OMP core API and is not implemented in this repository yet.

Important

This is a runtime adapter, not a remote terminal. Telegram prompts are normal model turns in the instance's currently active session and inherit its post-compaction context, so token cost is not proportional only to the new mobile message. Telegram can compact the current session, but cannot create, resume, fork, browse or switch sessions, and arbitrary slash commands are never forwarded to the TUI.

Installation

Requires omp ≥ 16.5.2 (@oh-my-pi/pi-coding-agent) and Node.js ≥ 22.19.0.

# From git (this repository)
omp plugin install https://git.evandro.dev.br/evandro/oh-my-pi-telegram.git

# From npm (once the package is published)
omp plugin install npm:@evandrodevbr/oh-my-pi-telegram

# From a local checkout (development)
omp plugin link /path/to/oh-my-pi-telegram

Restart (or reload) omp so the extension loads, then:

  1. Create a bot with @BotFather (/newbot) and copy the token.
  2. In omp, run /telegram-setup and paste the token.
  3. Run /telegram-connect to activate polling for this instance.
  4. In the bot DM, send /start.

Warning

The first Telegram user to message the bot becomes the allowed owner; everyone else is ignored. Pair right after /telegram-connect, and never put the bot token in chat, source, committed config or logs. Setup can prefill the token from TELEGRAM_BOT_TOKEN, TELEGRAM_BOT_KEY, TELEGRAM_TOKEN or TELEGRAM_KEY; the saved config lives in ~/.pi/agent/telegram.json.

Why this fork and not upstream

llblab/[email protected] targets the Pi extension platform (@earendil-works/pi-*). omp consumes the same platform republished as @oh-my-pi/pi-coding-agent. This fork:

  1. Renames the package to @evandrodevbr/oh-my-pi-telegram so it is unambiguous in the omp extension registry.
  2. Keeps the upstream peerDependencies on @earendil-works/pi-{ai,agent-core,coding-agent} >=0.80.6, the runtime surface omp consumes — no code changes or shims.
  3. Declares the extension through an omp block in package.json (extensions, display name and compatibleWith: >=16.5.2); the old pi block was replaced by it.
  4. Re-runs every upstream gate (typecheck → test → audit → pack:check) on the v0.22.0 source.

Lineage: badlogic/pi-telegram → llblab/pi-telegram (0.22.0) → this fork.

What it does

Surface What you can do
Prompt intake Send text, replies, edits, images, files, albums and voice notes into the session
Queue control Messages sent while the agent is busy become queued turns; inspect, delete, promote, continue, abort, stop or force the next one
Operator menu /start opens status, prompt templates, model, thinking level, settings, queue and extension sections
Prompt templates Run Pi prompt templates as Telegram-safe commands such as /fix_tests
Model and thinking Switch model or reasoning level through safe continuation flows; confirm /compact
Rich replies Native Rich Markdown (default) or legacy Markdown-to-HTML for final answers; optional live draft previews; native …typing status while the agent works
Files Inbound files land in <agent-dir>/tmp/telegram (50 MiB default limit); telegram_attach returns artifacts as real files
Voice Inbound voice through command-template, programmatic or STT handlers; outbound via telegram_voice and TTS providers
Buttons Hidden telegram_button comments become inline buttons whose callbacks re-enter the session
Threaded Mode One leader plus visible follower omp instances, each with its own Telegram thread, through one bot
Named profiles Run independent bots from one agent directory with isolated polling, diagnostics and bus transport
Extension platform Companion extensions add commands, menu sections, status rows, update/callback handlers, inbound/outbound handlers and voice providers
Diagnostics /telegram-status shows connection, mode, queue, transport and recent redacted events
Commands

In the bot DM:

Command Purpose
/start Pair when needed and open the operator menu
/compact Confirm and run session compaction when safe
/next Dispatch the next queued turn, aborting first if needed
/continue Enqueue a priority continuation prompt
/abort Abort the active run, keeping the queue
/stop Abort the active run and clear waiting Telegram turns

/help, /status, /model, /thinking, /queue and /settings are hidden shortcuts into the same menus.

Inside omp:

Command Purpose
/telegram-setup [profile] Save or update the default (or a named-profile) bot token
/telegram-connect [profile] Activate a profile and acquire its transport ownership
/telegram-disconnect Stop polling and release ownership
/telegram-status Inspect connection, mode, queue, transport and diagnostics

Profile names use lowercase ASCII letters and digits (max 32 characters); default, main and active are reserved.

Environment variables
Area Variables
Bot token bootstrap TELEGRAM_BOT_TOKEN, TELEGRAM_BOT_KEY, TELEGRAM_TOKEN, TELEGRAM_KEY
HTTP proxy HTTP_PROXY, HTTPS_PROXY, NO_PROXY, plus NODE_USE_ENV_PROXY=1 or Node --use-env-proxy
Network family PI_TELEGRAM_NETWORK_FAMILY = auto, ipv4, ipv6 or ipv4-fallback
Agent data root PI_CODING_AGENT_DIR
Inbound file limit PI_TELEGRAM_INBOUND_FILE_MAX_BYTES, TELEGRAM_MAX_FILE_SIZE_BYTES
Outbound attachment limit PI_TELEGRAM_OUTBOUND_ATTACHMENT_MAX_BYTES, TELEGRAM_MAX_ATTACHMENT_SIZE_BYTES

Defaults: config in ~/.pi/agent, inbound temp files in ~/.pi/agent/tmp/telegram, and assistant: { rendering: "rich", draftPreviews: false }.

How it works

flowchart LR
    TG["Telegram<br/>private DM · Threaded Mode"] -->|"getUpdates"| POLL
    subgraph OMP["omp instance (extension)"]
        POLL["polling + updates<br/>pairing · routing"] --> Q["turns + queue<br/>control · priority · default"]
        Q -->|"sendUserMessage"| AG["agent session<br/>(currently active)"]
        AG -->|"lifecycle events"| OUT["previews · rich replies<br/>files · voice · buttons"]
    end
    OUT -->|"Bot API"| TG
    POLL <-->|"local bus<br/>Unix socket / named pipe"| F["follower omp instances<br/>(Threaded Mode)"]

The core loop is: Telegram message → Telegram turn → queue or active dispatch → agent lifecycle → streaming preview / native active status → final Rich Markdown reply → optional files, voice, buttons or callback actions. Exactly one instance owns getUpdates per bot; in Threaded Mode followers are visible processes the operator started and ran /telegram-connect in — Telegram never launches hidden omp processes.

Layout and public entrypoints
Path Role
index.ts Composition root: wires live ports, session state, transport adapters and lifecycle hooks
lib/*.ts Flat domain modules (queue, polling, locks, bus, menus, rendering, delivery…) forming an acyclic import graph
api/*.ts Public companion-extension entrypoints: inbound, outbound, delivery, activity, updates, commands, sections, status, voice, keyboard
docs/ Architecture and contract documentation
tests/*.test.ts Domain regressions run with node --test

State: ~/.pi/agent/telegram.json (config), ~/.pi/agent/locks.json (polling ownership) and profile-scoped redacted logs*.jsonl under tmp/telegram (never model context).

Documentation: Architecture · Public API · Delivery · Activity · Inbound · Outbound · Voice · Sections · Updates · Multi-Instance Bus · Locks · UI Style · Callback Namespaces · Command Templates — index in docs/README.md.

Limitations

  • Telegram is a companion surface around a live runtime, not a second runtime: no hidden omp processes, no PTY or fake terminal, no raw TTY input, no session replacement without an official extension API, and non-owner users cannot control the bridge.
  • In Threaded Mode, threadless messages sent from the All tab are not routed as prompts once bound threads exist; use a bound thread tab.
  • Package metadata declares the extension only under omp.extensions (the pi block was removed in 572967c); install this fork through omp, and use upstream @llblab/pi-telegram for plain Pi.
  • Open work is tracked in BACKLOG.md (promoted-follower reload evidence, native Windows Threaded Mode follow-ups, evidence-backed Telegram client and Rich Markdown quirks).

Development

npm ci
npm run typecheck     # tsc --noEmit
npm test              # node --experimental-strip-types --test tests/*.test.ts
npm run audit         # npm audit
npm run pack:check    # npm pack --dry-run
npm run validate      # all of the above

Engineering conventions: AGENTS.md. Completed delivery history: CHANGELOG.md.

CI/CD

  • .github/workflows/validate.yml — on every push and pull request: Node 24, npm ci, npm run validate.
  • .github/workflows/release.yml — on tags v*.*.*: checks that the tag matches package.json's version, extracts that version's section from CHANGELOG.md into the release notes, and creates the release with gh release create (a GitHub CLI call). The extraction expects a ## <version> heading; the fork's entry currently sits under ## Unreleased as a ### heading, so a tag would fail that check until the section is promoted.

Credits and notices

  • MIT licensed (LICENSE): copyright Evandro Fonseca Junior (evandrodevbr) and llblab.
  • Built on llblab/pi-telegram, itself a fork of badlogic/pi-telegram; runs inside Oh My Pi and talks to the Telegram Bot API.
  • Unofficial project, not affiliated with Telegram or the Oh My Pi maintainers.