151 lines
9.8 KiB
Markdown
151 lines
9.8 KiB
Markdown
<div align="center">
|
|
|
|
<img src="assets/readme/hero.svg" width="100%" alt="oh-my-pi-telegram: drive a live omp session from a private Telegram chat, with /start, the /compact, /next and /stop menu and prompts sent from the phone">
|
|
|
|

|
|

|
|

|
|

|
|
|
|
[Issues](https://git.evandro.dev.br/evandro/oh-my-pi-telegram/issues) · [Docs](docs/README.md) · [Changelog](CHANGELOG.md) · [Backlog](BACKLOG.md)
|
|
|
|
</div>
|
|
|
|

|
|
|
|
## What it is
|
|
|
|
oh-my-pi-telegram is an [Oh My Pi](https://github.com/can1357/oh-my-pi) (`omp`) extension that turns a private chat with your own Telegram bot into a companion for the session running on your machine. From the phone you send prompts, files and voice notes, queue and steer turns, switch the model or thinking level, and receive streamed previews and the final answer.
|
|
|
|
It is a fork of [`@llblab/[email protected]`](https://github.com/llblab/pi-telegram/tree/v0.22.0) (SHA `afe09c5`), repackaged as `@evandrodevbr/oh-my-pi-telegram` and declared as an `omp` extension.
|
|
|
|
| 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. |
|
|
| Rich replies | Rich Markdown (default) or legacy Markdown-to-HTML for final answers; optional live draft previews; native `...typing` status while the agent works. |
|
|
| Files and voice | Inbound files land in `<agent dir>/tmp/telegram` (50 MiB default limit); `telegram_attach` returns artifacts as real files; inbound voice goes through command templates or STT handlers; outbound voice through `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 | Independent bots from one agent directory, with isolated polling, diagnostics and bus transport. |
|
|
|
|
## Why use it
|
|
|
|
It is a runtime adapter, not a remote terminal. A Telegram prompt is a normal model turn in the session that is active right now and inherits its post-compaction context, so token cost is not proportional only to the new mobile message.
|
|
|
|
Why this fork and not upstream: `@llblab/[email protected]` targets the Pi extension platform (`@earendil-works/pi-*`), and `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`, with no code changes or shims.
|
|
3. Declares the extension through an `omp` block in `package.json` (extensions, display name, `compatibleWith: >=16.5.2`); the old `pi` block was removed in `572967c`.
|
|
|
|
Do not use it if you need a real terminal from the phone: there are no hidden `omp` processes, no PTY and no raw TTY input. 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. For plain Pi, use upstream `@llblab/pi-telegram`.
|
|
|
|
## How it works
|
|
|
|
- The active `omp` instance owns `getUpdates` polling for one bot. You start it with `/telegram-connect`; Telegram never launches hidden `omp` processes.
|
|
- Each Telegram message becomes a turn: it goes to the queue or is dispatched to the active session, then streams back as a preview with the native typing status and ends as a final Rich Markdown reply, optionally with files, voice, buttons or callback actions.
|
|
- In Threaded Mode, follower instances talk to the leader over a local bus (Unix socket or named pipe) and get their own Telegram thread.
|
|
- Code layout: `index.ts` is the composition root, `lib/*.ts` are flat domain modules (queue, polling, locks, bus, menus, rendering, delivery), `api/*.ts` are the public entry points for companion extensions, and `docs/` holds the architecture and contract documents.
|
|
|
|
## Quickstart
|
|
|
|
Requires `omp` >= 16.5.2 (`package.json` → `omp.compatibleWith`) and Node.js >= 22.19.0 (`engines.node`).
|
|
|
|
```bash
|
|
# From git (this repository)
|
|
omp plugin install https://git.evandro.dev.br/evandro/oh-my-pi-telegram.git
|
|
|
|
# From a local checkout (development)
|
|
omp plugin link /path/to/oh-my-pi-telegram
|
|
```
|
|
|
|
The npm package `@evandrodevbr/oh-my-pi-telegram` is not published yet. Restart (or reload) `omp` so the extension loads, then:
|
|
|
|
1. Create a bot with [@BotFather](https://t.me/BotFather) (`/newbot`) and copy the token.
|
|
2. In `omp`, run `/telegram-setup` and paste the token.
|
|
3. Run `/telegram-connect` to start 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 is `<agent dir>/telegram.json`. The agent directory is `PI_CODING_AGENT_DIR` when set, `~/.omp/agent` when the process is `omp`, and `~/.pi/agent` otherwise (`lib/paths.ts`).
|
|
|
|
## Usage
|
|
|
|
<details>
|
|
<summary>Commands</summary>
|
|
|
|
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.
|
|
|
|
</details>
|
|
|
|
<details>
|
|
<summary>Environment variables</summary>
|
|
|
|
| Area | Variables |
|
|
|---|---|
|
|
| Bot token bootstrap | `TELEGRAM_BOT_TOKEN`, `TELEGRAM_BOT_KEY`, `TELEGRAM_TOKEN`, `TELEGRAM_KEY` |
|
|
| Network family | `PI_TELEGRAM_NETWORK_FAMILY` = `auto`, `ipv4`, `ipv6` or `ipv4-fallback` (default) |
|
|
| 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: inbound temp files in `<agent dir>/tmp/telegram`, and `assistant: { rendering: "rich", draftPreviews: false }`.
|
|
|
|
</details>
|
|
|
|
Full reference: [architecture](docs/architecture.md), [public API](docs/public-api.md), [delivery](docs/delivery.md), [inbound](docs/inbound.md), [outbound](docs/outbound.md), [voice](docs/voice.md), [multi-instance bus](docs/multi-instance-bus.md) and the rest in the [docs index](docs/README.md).
|
|
|
|
## Project status
|
|
|
|
Fork release `0.22.0-evandro.1`. Per [`CHANGELOG.md`](CHANGELOG.md), the fork re-ran the upstream gates: typecheck, 1,229 of 1,230 tests passing with one platform-only skip, `npm audit` with 0 vulnerabilities and a clean `npm pack --dry-run`. CI (`.github/workflows/validate.yml`) runs `npm ci` and `npm run validate` on Ubuntu with Node 24 for every push and pull request.
|
|
|
|
- A design spec for an `omp` status-bar segment ([`docs/superpowers/specs/`](docs/superpowers/specs/2026-07-15-telegram-omp-status-design.md)) needs a new `omp` core API and is not implemented here.
|
|
- In Threaded Mode, threadless messages sent from the `All` tab are not routed as prompts once bound threads exist; use a bound thread tab.
|
|
- `release.yml` needs a `## <version>` heading in `CHANGELOG.md`; the fork entry sits under `## Unreleased` as a `###` heading, so a tag fails that check until the section is promoted.
|
|
- Open work (promoted-follower reload evidence, native Windows Threaded Mode follow-ups, Telegram client and Rich Markdown quirks) is tracked in [`BACKLOG.md`](BACKLOG.md).
|
|
|
|
Development:
|
|
|
|
```bash
|
|
npm ci
|
|
npm run validate # typecheck + test + audit + pack:check
|
|
```
|
|
|
|
Engineering conventions are in [`AGENTS.md`](AGENTS.md).
|
|
|
|
## License
|
|
|
|
MIT, see [`LICENSE`](LICENSE): copyright Evandro Fonseca Junior (evandrodevbr), llblab and Mario Zechner (badlogic). Built on [llblab/pi-telegram](https://github.com/llblab/pi-telegram), itself a fork of [badlogic/pi-telegram](https://github.com/badlogic/pi-telegram); runs inside [Oh My Pi](https://github.com/can1357/oh-my-pi) and talks to the Telegram Bot API. Unofficial project, not affiliated with Telegram or the Oh My Pi maintainers.
|
|
|
|
---
|
|
|
|
<div align="center">
|
|
<sub>Made by <a href="https://evandro.dev.br">Evandro Fonseca Junior</a> · <a href="https://git.evandro.dev.br/evandro">git.evandro.dev.br</a></sub>
|
|
</div>
|