@llblab/pi-telegram 0.18.5 → 0.19.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/AGENTS.md +5 -4
- package/BACKLOG.md +5 -10
- package/CHANGELOG.md +23 -0
- package/README.md +176 -226
- package/docs/architecture.md +3 -3
- package/docs/multi-instance-bus.md +23 -2
- package/index.ts +35 -3
- package/lib/bindings.ts +3 -14
- package/lib/bus-follower.ts +26 -7
- package/lib/bus-leader.ts +152 -27
- package/lib/bus.ts +44 -0
- package/lib/config.ts +22 -0
- package/lib/menu-settings.ts +88 -0
- package/lib/routing.ts +5 -11
- package/lib/runtime.ts +23 -7
- package/lib/status.ts +2 -2
- package/lib/threads.ts +56 -2
- package/lib/updates.ts +44 -3
- package/package.json +2 -2
- /package/{screenshot.png → banner.png} +0 -0
package/README.md
CHANGED
|
@@ -1,25 +1,15 @@
|
|
|
1
1
|
# pi-telegram
|
|
2
2
|
|
|
3
|
-

|
|
4
4
|
|
|
5
|
-
**Telegram
|
|
5
|
+
**A Telegram companion hub for live Pi sessions.**
|
|
6
6
|
|
|
7
|
-
`pi-telegram` turns a private Telegram DM into a
|
|
7
|
+
`pi-telegram` turns a private Telegram DM into a mobile operator surface for Pi. It accepts prompts, queues work, streams readable previews, delivers final replies and files, exposes safe controls, and lets companion extensions add Telegram-native capabilities without owning a second bot loop.
|
|
8
8
|
|
|
9
|
-
|
|
9
|
+
It is a **runtime adapter**, not a remote terminal. Start or supervise work in the Pi TUI, then continue from Telegram while away from the keyboard. The bridge preserves Pi session semantics instead of pretending Telegram is a PTY, shell, or process launcher. That boundary is the product: Telegram gets safe runtime handles, not raw terminal power.
|
|
10
10
|
|
|
11
11
|
This repository is an actively maintained fork of [`badlogic/pi-telegram`](https://github.com/badlogic/pi-telegram). It started from upstream commit [`cb34008`](https://github.com/badlogic/pi-telegram/commit/cb34008460b6c1ca036d92322f69d87f626be0fc) and has since diverged substantially.
|
|
12
12
|
|
|
13
|
-
## What this gives you
|
|
14
|
-
|
|
15
|
-
- **Mobile supervision**: continue a live Pi session from Telegram without turning Telegram into a fake terminal.
|
|
16
|
-
- **Telegram-native controls**: menus, settings, queue controls, native active status, Rich Markdown replies, drafts, buttons, voice, files, and artifacts.
|
|
17
|
-
- **Safe runtime mapping**: Telegram turns map into Pi lifecycle, queueing, model switching, compaction, previews, final replies, and ownership rules.
|
|
18
|
-
- **Optional Threaded Mode**: one leader and visible follower Pi processes can share one bot through named Telegram threads.
|
|
19
|
-
- **Extension platform**: companion extensions can add Telegram-native commands, sections, status rows, update handlers, handlers, and voice providers without owning polling.
|
|
20
|
-
|
|
21
|
-
Use this README for the product shape. Follow the docs for exact contracts.
|
|
22
|
-
|
|
23
13
|
## Install
|
|
24
14
|
|
|
25
15
|
From npm:
|
|
@@ -34,24 +24,24 @@ From git:
|
|
|
34
24
|
pi install git:github.com/llblab/pi-telegram
|
|
35
25
|
```
|
|
36
26
|
|
|
37
|
-
##
|
|
27
|
+
## Quick Start
|
|
38
28
|
|
|
39
29
|
### 1. Create a Telegram bot
|
|
40
30
|
|
|
41
|
-
1. Open [@BotFather](https://t.me/BotFather)
|
|
42
|
-
2. Run `/newbot
|
|
43
|
-
3. Pick a name and username
|
|
44
|
-
4. Copy the bot token
|
|
31
|
+
1. Open [@BotFather](https://t.me/BotFather).
|
|
32
|
+
2. Run `/newbot`.
|
|
33
|
+
3. Pick a name and username.
|
|
34
|
+
4. Copy the bot token.
|
|
45
35
|
|
|
46
|
-
### 2. Configure
|
|
36
|
+
### 2. Configure Pi
|
|
47
37
|
|
|
48
|
-
|
|
38
|
+
Run this inside Pi:
|
|
49
39
|
|
|
50
40
|
```bash
|
|
51
41
|
/telegram-setup
|
|
52
42
|
```
|
|
53
43
|
|
|
54
|
-
Paste
|
|
44
|
+
Paste the bot token. If `~/.pi/agent/telegram.json` already contains a saved token, setup offers it as the default. If no saved token exists, setup can prefill from `TELEGRAM_BOT_TOKEN`, `TELEGRAM_BOT_KEY`, `TELEGRAM_TOKEN`, or `TELEGRAM_KEY`.
|
|
55
45
|
|
|
56
46
|
### 3. Connect this Pi session
|
|
57
47
|
|
|
@@ -59,262 +49,222 @@ Paste your bot token when prompted. If a bot token is already saved in `~/.pi/ag
|
|
|
59
49
|
/telegram-connect
|
|
60
50
|
```
|
|
61
51
|
|
|
62
|
-
The
|
|
52
|
+
The connected Pi instance owns Telegram polling. In classic mode this is a singleton lock. When Telegram private-chat Threaded Mode is available, one live instance becomes the leader and later visible Pi instances register as followers.
|
|
63
53
|
|
|
64
54
|
### 4. Pair your Telegram account
|
|
65
55
|
|
|
66
|
-
|
|
67
|
-
2. Send `/start`
|
|
68
|
-
|
|
69
|
-
The first user to message the bot becomes the exclusive owner of the adapter. Messages from other users are ignored.
|
|
70
|
-
|
|
71
|
-
### Environment-only configuration
|
|
72
|
-
|
|
73
|
-
Most day-to-day controls live in the Telegram menu or Pi commands. A few important runtime knobs intentionally stay in environment variables because they affect bootstrap, networking, or transport limits before a menu can help:
|
|
74
|
-
|
|
75
|
-
- **Bot token bootstrap**: `/telegram-setup` can prefill from `TELEGRAM_BOT_TOKEN`, `TELEGRAM_BOT_KEY`, `TELEGRAM_TOKEN`, or `TELEGRAM_KEY` when no token is already saved.
|
|
76
|
-
- **HTTP/HTTPS proxy**: native `fetch` can use `HTTP_PROXY`, `HTTPS_PROXY`, and `NO_PROXY` when Node's environment proxy mode is enabled. Use `NODE_USE_ENV_PROXY=1` or start Node with `--use-env-proxy`. SOCKS5 is not part of the zero-dependency core. If you need it, run a local HTTP-to-SOCKS bridge or system tunnel and point `HTTP_PROXY` / `HTTPS_PROXY` at the HTTP endpoint.
|
|
77
|
-
- **Telegram network family**: `PI_TELEGRAM_NETWORK_FAMILY=auto|ipv4|ipv6|ipv4-fallback` controls Bot API transport only. The default is `ipv4-fallback`: try native `fetch` first, then retry transport-level failures through IPv4-only HTTPS. Use `auto` to force native `fetch` only, or `ipv4`/`ipv6` to force a family.
|
|
78
|
-
- **Agent data root / temp location**: `PI_CODING_AGENT_DIR` changes the base agent directory used for `telegram.json`, locks, generated outbound-handler artifacts, and Telegram temp files. When unset, the adapter uses `~/.pi/agent`, so inbound Telegram files land in `~/.pi/agent/tmp/telegram`.
|
|
79
|
-
- **Inbound file limit**: `PI_TELEGRAM_INBOUND_FILE_MAX_BYTES` or `TELEGRAM_MAX_FILE_SIZE_BYTES` changes the default 50 MiB Telegram download limit.
|
|
80
|
-
- **Outbound attachment limit**: `PI_TELEGRAM_OUTBOUND_ATTACHMENT_MAX_BYTES` or `TELEGRAM_MAX_ATTACHMENT_SIZE_BYTES` changes the default 50 MiB `telegram_attach` delivery limit.
|
|
81
|
-
|
|
82
|
-
Assistant Markdown is delivered through Telegram's native Rich Message API. There is no `telegram.json` rendering toggle: final replies use `sendRichMessage`, and streaming previews use `sendRichMessageDraft` when Telegram drafts are available.
|
|
83
|
-
|
|
84
|
-
Long-running Telegram turns use Telegram's native active status as the activity indicator: technically Bot API `sendChatAction(typing)`, presented in product language as `...active` even when Telegram clients render it as typing dots. Active status is the only automatic in-chat work signal before the final reply.
|
|
85
|
-
|
|
86
|
-
Set these variables before launching Pi. Some transport defaults (notably Telegram temp directory and inbound/outbound byte-limit constants) are intentionally captured when the extension modules load, while setup-token defaults and agent-dir lookups used by config/locks are read through their runtime helpers.
|
|
87
|
-
|
|
88
|
-
## Use
|
|
89
|
-
|
|
90
|
-
Once paired, chat with your bot in Telegram. Text, images, files, replies, edits, media groups, and configured handler output are forwarded into Pi as Telegram-originated turns.
|
|
91
|
-
|
|
92
|
-
What it feels like:
|
|
93
|
-
|
|
94
|
-
- Start work in the terminal, walk away, and keep supervising the same live Pi session from Telegram.
|
|
95
|
-
- Open `/start` and get a Telegram control panel for the running Pi session: status, prompt templates, model, thinking, settings, and queue.
|
|
96
|
-
- Fire off three tasks while Pi is busy. They become visible queue items instead of terminal noise.
|
|
97
|
-
- Open Queue from the menu, inspect waiting work, delete stale prompts, or move important work forward.
|
|
98
|
-
- Switch models from Telegram mid-run; the adapter schedules a safe continuation instead of tearing state apart.
|
|
99
|
-
- Send a voice note; a configured inbound handler or registered STT provider transcribes it; Pi answers in the same chat.
|
|
100
|
-
- Drop a screenshot and ask, "what is broken here?" The image payload reaches Pi with the local file context.
|
|
101
|
-
- Ask for a generated file; when Pi calls `telegram_attach`, the artifact returns with the active Telegram reply or is sent directly to the paired/default chat from local work.
|
|
102
|
-
|
|
103
|
-
### Telegram controls
|
|
104
|
-
|
|
105
|
-
Use these inside the Telegram DM with your bot. The main entrypoint is `/start`: it opens the operator menu and exposes many of the important agent controls that can be safely adapted through Pi's extension APIs. The bot does not forward arbitrary terminal slash commands or emulate TUI-only session controls.
|
|
106
|
-
|
|
107
|
-
- **`/start`**: Pair the first Telegram user when needed, register bot commands, and open the inline application menu with command help, prompt-template commands, status rows, model controls, thinking controls, settings, and queue controls.
|
|
108
|
-
- **`/compact`**: Ask for inline confirmation, then start session compaction when the session is idle; Telegram shows the native active indicator while manual or automatic compaction is running.
|
|
109
|
-
- **`/next`**: Dispatch the next queued turn, aborting Pi first if needed.
|
|
110
|
-
- **`/continue`**: Enqueue a priority `continue` prompt.
|
|
111
|
-
- **`/abort`**: Abort the active run without touching the queue. Abort-history applies only to Telegram-owned active turns; later local prompts do not make the next Telegram prompt absorb older queue items.
|
|
112
|
-
- **`/stop`**: Abort the active run and clear waiting Telegram queue items.
|
|
113
|
-
|
|
114
|
-
Hidden compatibility shortcuts: `/help` and `/status` open the main application menu, `/model` opens model controls, `/thinking` opens reasoning controls, `/queue` opens queue controls, and `/settings` opens bridge settings.
|
|
115
|
-
|
|
116
|
-
Prompt-template commands are discovered from Pi prompt templates, mapped to Telegram-safe aliases (`fix-tests.md` becomes `/fix_tests`), shown in `/start`, and expanded before queueing.
|
|
117
|
-
|
|
118
|
-
### Pi commands
|
|
119
|
-
|
|
120
|
-
Run these inside Pi, not Telegram:
|
|
121
|
-
|
|
122
|
-
- **`/telegram-setup`**: Configure or update the Telegram bot token.
|
|
123
|
-
- **`/telegram-connect`**: Start polling Telegram updates in the current Pi session and acquire the singleton lock.
|
|
124
|
-
- **`/telegram-disconnect`**: Stop polling in the current Pi session and release the singleton lock.
|
|
125
|
-
- **`/telegram-status`**: Inspect adapter status, connection, polling, execution, queue, and recent redacted runtime/API failure events.
|
|
126
|
-
|
|
127
|
-
### Files and artifacts
|
|
56
|
+
Open the bot DM and send:
|
|
128
57
|
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
### Telegram Threaded Mode and multi-instance bus
|
|
134
|
-
|
|
135
|
-
Telegram private-chat Threaded Mode is the switch. Classic single-DM polling is the base mode. When Telegram reports private-chat threads are available for the bot, the adapter enables the local leader/follower bus automatically; when threads are unavailable or later disabled, it uses classic single-DM polling as the ordinary private-bot mode.
|
|
136
|
-
|
|
137
|
-
Only the leader calls `getUpdates`; followers authenticate to the local bus and route allowlisted, target-scoped Telegram work through the leader. When private-chat threads are available, they become the UI targets:
|
|
138
|
-
|
|
139
|
-
- The leader owns one thread;
|
|
140
|
-
- Each explicitly connected follower gets one visible thread;
|
|
141
|
-
- Telegram never launches hidden Pi follower processes;
|
|
142
|
-
- New thread names are assigned by the bridge from a compact curated palette, while existing human names are preserved;
|
|
143
|
-
- Unknown owner-created threads preserve the original prompt and offer a target-thread chooser instead of spawning work invisibly;
|
|
144
|
-
- Stale follower tabs receive compact lifecycle notices before cleanup when the leader can prove ownership.
|
|
145
|
-
|
|
146
|
-
Thread input is still authorized by `allowedUserId`. There is no separate public `telegram.json` switch for the bus: Telegram capability detection is the runtime source of truth. Native Windows Threaded Mode smoke remains tracked in `BACKLOG.md`; the intended transport is the same local bus over Windows named pipes instead of Unix sockets.
|
|
147
|
-
|
|
148
|
-
## Core features
|
|
149
|
-
|
|
150
|
-
### Operator menu and controls
|
|
151
|
-
|
|
152
|
-
The inline application menu is the primary operator surface. It exposes status, prompt-template commands, companion-extension Telegram commands, model selection, thinking level selection, settings, and queue inspection/mutation: a Telegram-shaped subset of the important handles normally available from the CLI. A typical control loop stays inside Telegram: open `/start`, inspect status, jump into Queue, delete stale work, switch model, return to the main menu, and keep the Pi session running without touching the terminal.
|
|
153
|
-
|
|
154
|
-
### Queue runtime
|
|
155
|
-
|
|
156
|
-
Messages sent while Pi is busy enter the prompt queue and are processed in order. Control actions and model-switch continuation turns use higher-priority lanes. Queue processing and reply delivery stay local to the Pi instance that accepted the work, even if `/telegram-connect` later moves elsewhere.
|
|
157
|
-
|
|
158
|
-
The menu is the primary way to inspect and mutate the queue. Reactions are an extra shortcut when Telegram delivers `message_reaction` updates for the chat. The same rules apply to text, voice, files, images, and media groups:
|
|
58
|
+
```text
|
|
59
|
+
/start
|
|
60
|
+
```
|
|
159
61
|
|
|
160
|
-
|
|
161
|
-
|
|
62
|
+
The first Telegram user to message the bot becomes the allowed owner. Other users are ignored.
|
|
63
|
+
|
|
64
|
+
## What It Feels Like
|
|
65
|
+
|
|
66
|
+
- Start a task in the terminal, walk away, and keep supervising it from your phone.
|
|
67
|
+
- Send another prompt while Pi is busy; it becomes a queued Telegram turn instead of interrupting the active run.
|
|
68
|
+
- Open `/start` to inspect status, model, thinking, settings, prompt templates, and queue controls.
|
|
69
|
+
- Send voice, images, files, replies, edits, or media groups; the bridge turns them into Pi context.
|
|
70
|
+
- Ask for an artifact; `telegram_attach` returns it through the active reply or direct Telegram delivery.
|
|
71
|
+
- In Threaded Mode, run multiple visible Pi instances through one bot, each with its own Telegram thread.
|
|
72
|
+
|
|
73
|
+
## Product Model
|
|
74
|
+
|
|
75
|
+
| Lens | What `pi-telegram` owns |
|
|
76
|
+
| ----------------------- | -------------------------------------------------------------------------------------------------- |
|
|
77
|
+
| Operator companion | A phone-width control surface for a live Pi session |
|
|
78
|
+
| Runtime adapter | Telegram turns mapped into Pi lifecycle, queueing, previews, final replies, and artifacts |
|
|
79
|
+
| Telegram UI harness | Menus, settings, callbacks, Rich Markdown, drafts, active status, buttons, voice, and files |
|
|
80
|
+
| Multi-instance organism | One leader plus explicit visible followers routed through Telegram private-chat threads |
|
|
81
|
+
| Extension platform | Commands, sections, status rows, update handlers, inbound/outbound handlers, and voice providers |
|
|
82
|
+
| Safety boundary | No hidden Pi processes, no fake terminal, no PTY tricks, no arbitrary TUI slash-command forwarding |
|
|
83
|
+
|
|
84
|
+
## Feature Showcase
|
|
85
|
+
|
|
86
|
+
`pi-telegram` is intentionally broad: it is a Telegram-shaped runtime surface, not only a message relay. This catalogue keeps the practical feature surface visible while detailed contracts stay in `/docs`.
|
|
87
|
+
|
|
88
|
+
| Surface | What you can do | Why it matters |
|
|
89
|
+
| -------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------- |
|
|
90
|
+
| Prompt intake | Send text, replies, edits, images, files, albums, voice notes, and handler output into Pi. | Telegram becomes a real mobile input surface with file/context references, not just a text tunnel. |
|
|
91
|
+
| Queue control | Inspect waiting turns, delete stale work, promote important prompts, continue, abort, stop, or force the next queued item. | Long Pi tasks keep running while new mobile prompts stay visible and controllable instead of interrupting or disappearing. |
|
|
92
|
+
| Operator menu | Use `/start` for status, prompt templates, model, thinking, settings, queue, extension sections, and diagnostics. | The bot is an operator panel, not a command cheat sheet. |
|
|
93
|
+
| Prompt templates | Run Pi prompt templates as Telegram-safe commands such as `/fix_tests`. | Reusable local workflows become phone-accessible without exposing arbitrary terminal commands. |
|
|
94
|
+
| Model and thinking | Switch model or reasoning level from Telegram through safe continuation flows. | Mobile control can adjust execution strategy without tearing down the current session. |
|
|
95
|
+
| Compaction | Confirm `/compact`, show native active status during compaction, and preserve Telegram-owned turn semantics. | Context maintenance is visible and safe from the phone. |
|
|
96
|
+
| Streaming previews | Show native active status and, when enabled, Rich Markdown drafts while the agent is still working. | The operator can see progress without making draft rendering the baseline. |
|
|
97
|
+
| Final Rich Markdown | Deliver complete assistant/guest model replies through Telegram Rich Message APIs with safe splitting. | Meaningful model answers stay readable on narrow mobile screens without forcing generic HTML conversion. |
|
|
98
|
+
| Bridge UI rendering | Render tool rows, reasoning/technical steps, menus, queue controls, status, settings, diagnostics, and sections through explicit Telegram HTML/plain UI. | Harness-owned surfaces remain operationally predictable and visually distinct from model-authored answers. |
|
|
99
|
+
| Inbound files | Download inbound files to the Pi agent temp directory with size limits. | Screenshots, PDFs, datasets, and artifacts enter Pi as inspectable local files. |
|
|
100
|
+
| Outbound artifacts | Return generated files through `telegram_attach` during active turns or explicit direct delivery. | Agents send real artifacts as files, not pasted blobs. |
|
|
101
|
+
| Voice input | Route audio through configured command-template handlers, programmatic handlers, or STT providers. | Voice notes become usable prompt context. |
|
|
102
|
+
| Voice output | Use `telegram_voice`, reply modes, configured voice handlers, and TTS providers. | Replies can become Telegram voice messages when the workflow calls for it. |
|
|
103
|
+
| Buttons | Turn top-level `telegram_button` comments into inline buttons. | Assistant-authored choices become native Telegram interactions. |
|
|
104
|
+
| Callback routing | Route known callbacks to the owner extension and unknown callbacks back into Pi. | Companion extensions can build UI without polling Telegram themselves. |
|
|
105
|
+
| Threaded Mode | Run one leader plus visible follower Pi instances through named private-chat threads. | One bot can host a local multi-instance Pi organism without hidden process spawning. |
|
|
106
|
+
| Reroute and restore | Preserve unknown threads and offer explicit target choices. | Telegram client state can be repaired without silently deleting or hijacking prompts. |
|
|
107
|
+
| Extension sections | Add menu sections, commands, status rows, settings, callbacks, and delivery helpers from companion extensions. | `pi-telegram` becomes a platform surface for other Pi extensions. |
|
|
108
|
+
| Runtime diagnostics | Use `/telegram-status` and recent runtime events for connection, role, queue, transport, and failure evidence. | Debugging lives in the operator surface instead of hidden logs only. |
|
|
109
|
+
| Safety and ownership | Pair one owner, lock transport, scope targets, and reject fake terminal behavior. | Remote access remains explicit, bounded, and understandable. |
|
|
110
|
+
|
|
111
|
+
## Core Loop
|
|
112
|
+
|
|
113
|
+
```text
|
|
114
|
+
Telegram message
|
|
115
|
+
-> Telegram turn
|
|
116
|
+
-> queue or active dispatch
|
|
117
|
+
-> Pi agent lifecycle
|
|
118
|
+
-> streaming preview / native active status
|
|
119
|
+
-> final Rich Markdown reply
|
|
120
|
+
-> optional files, voice, buttons, or callback actions
|
|
121
|
+
```
|
|
162
122
|
|
|
163
|
-
|
|
123
|
+
The bridge keeps Telegram responsive without stealing Pi's runtime model. Queueing, model changes, compaction, aborts, final delivery, and direct artifact sends all stay scoped to the Pi instance that accepted the work.
|
|
164
124
|
|
|
165
|
-
|
|
125
|
+
## Telegram Controls
|
|
166
126
|
|
|
167
|
-
|
|
127
|
+
Use these in the bot DM.
|
|
168
128
|
|
|
169
|
-
|
|
129
|
+
| Command | Purpose |
|
|
130
|
+
| ----------- | ------------------------------------------------------- |
|
|
131
|
+
| `/start` | Pair when needed and open the main operator menu |
|
|
132
|
+
| `/compact` | Confirm and run session compaction when safe |
|
|
133
|
+
| `/next` | Dispatch the next queued turn, aborting first if needed |
|
|
134
|
+
| `/continue` | Enqueue a priority continuation prompt |
|
|
135
|
+
| `/abort` | Abort the active run while preserving the queue |
|
|
136
|
+
| `/stop` | Abort the active run and clear waiting Telegram turns |
|
|
170
137
|
|
|
171
|
-
|
|
138
|
+
Hidden compatibility shortcuts: `/help`, `/status`, `/model`, `/thinking`, `/queue`, and `/settings` jump into the same menu system.
|
|
172
139
|
|
|
173
|
-
|
|
140
|
+
## Pi Commands
|
|
174
141
|
|
|
175
|
-
|
|
142
|
+
Run these inside Pi.
|
|
176
143
|
|
|
177
|
-
|
|
144
|
+
| Command | Purpose |
|
|
145
|
+
| ---------------------- | ------------------------------------------------------------------ |
|
|
146
|
+
| `/telegram-setup` | Save or update the bot token |
|
|
147
|
+
| `/telegram-connect` | Start polling and acquire Telegram transport ownership |
|
|
148
|
+
| `/telegram-disconnect` | Stop polling and release ownership |
|
|
149
|
+
| `/telegram-status` | Inspect connection, mode, queue, transport, and recent diagnostics |
|
|
178
150
|
|
|
179
|
-
|
|
180
|
-
{
|
|
181
|
-
"inboundHandlers": [
|
|
182
|
-
{
|
|
183
|
-
"type": "text",
|
|
184
|
-
"template": "/path/to/translate --lang {lang=en} --text \"{text}\""
|
|
185
|
-
},
|
|
186
|
-
{
|
|
187
|
-
"type": "voice",
|
|
188
|
-
"template": [
|
|
189
|
-
"/path/to/stt --file {file} --lang {lang=ru}",
|
|
190
|
-
"/path/to/translate-stdin --lang {lang=en}"
|
|
191
|
-
]
|
|
192
|
-
},
|
|
193
|
-
{
|
|
194
|
-
"mime": "audio/*",
|
|
195
|
-
"template": [
|
|
196
|
-
"/path/to/stt-fallback --file {file} --lang {lang=ru}",
|
|
197
|
-
"/path/to/translate-stdin --lang {lang=en}"
|
|
198
|
-
]
|
|
199
|
-
}
|
|
200
|
-
]
|
|
201
|
-
}
|
|
202
|
-
```
|
|
151
|
+
## Main Surfaces
|
|
203
152
|
|
|
204
|
-
###
|
|
153
|
+
### Operator Menu
|
|
205
154
|
|
|
206
|
-
|
|
155
|
+
`/start` opens the Telegram-native control panel: status, prompt-template commands, model selection, thinking level, settings, queue controls, and extension sections. It is the primary Telegram UI; reaction shortcuts are secondary queue affordances.
|
|
207
156
|
|
|
208
|
-
|
|
157
|
+
### Queue Runtime
|
|
209
158
|
|
|
210
|
-
|
|
211
|
-
Full technical answer stays readable as text.
|
|
159
|
+
Messages sent while Pi is busy become queued turns. Priority lanes support control actions and model-switch continuations. Queue controls let you inspect, delete, promote, and dispatch work from Telegram without touching the terminal.
|
|
212
160
|
|
|
213
|
-
|
|
214
|
-
Text to synthesize as a Telegram voice message.
|
|
215
|
-
-->
|
|
161
|
+
### Native Rich Markdown
|
|
216
162
|
|
|
217
|
-
|
|
218
|
-
List the main risks first.
|
|
219
|
-
-->
|
|
220
|
-
```
|
|
163
|
+
Rich Markdown is the model-answer membrane. Complete assistant and guest model replies use Telegram's native Rich Message APIs, while tool-call rows, reasoning/thinking blocks, menus, status rows, queue controls, settings, diagnostics, and other harness-owned surfaces use explicit Telegram HTML/plain rendering. This keeps meaningful model-authored answers visually distinct from bridge-owned operational UI. Streaming previews may use rich-message drafts when enabled; final replies persist through `sendRichMessage`.
|
|
221
164
|
|
|
222
|
-
|
|
165
|
+
### Files And Artifacts
|
|
223
166
|
|
|
224
|
-
|
|
167
|
+
Inbound files land under `<agent-dir>/tmp/telegram` and default to a 50 MiB limit. `telegram_attach` is the canonical outbound file path. During Telegram-originated turns it attaches to the active reply; during explicit local/TUI delivery it can send to the paired/default chat or routed Threaded Mode target.
|
|
225
168
|
|
|
226
|
-
### Voice
|
|
169
|
+
### Voice And Media
|
|
227
170
|
|
|
228
|
-
|
|
171
|
+
Voice notes, audio, images, PDFs, and other media can pass through configured inbound handlers, programmatic handlers, or registered STT providers. Outbound voice can use configured `outboundHandlers` or registered TTS providers; `pi-telegram` owns reply policy and Telegram transport, while providers own synthesis.
|
|
229
172
|
|
|
230
|
-
|
|
231
|
-
- `manual`: agent-authored `<!-- telegram_voice -->` markup is required for voice replies; no automatic conversion. Unlike `hidden`, this explicit mode adds `[voice] reply mode: manual` context.
|
|
232
|
-
- `mirror`: when the user sends a voice message, the next reply is converted to voice and text preview is suppressed. Text-originated turns stay on the normal/manual text path, so agent-authored `<!-- telegram_voice -->` markup still works explicitly.
|
|
233
|
-
- `always`: every reply is converted to voice and text preview is suppressed.
|
|
173
|
+
### Buttons And Callbacks
|
|
234
174
|
|
|
235
|
-
|
|
175
|
+
Assistant replies can include top-level hidden `telegram_button` comments. The bridge strips the comments from visible text, renders inline buttons, and routes callbacks back into Pi as queued prompts or extension-owned callback actions.
|
|
236
176
|
|
|
237
|
-
|
|
177
|
+
### Threaded Mode And Multi-Instance Bus
|
|
238
178
|
|
|
239
|
-
|
|
179
|
+
Classic private DM mode is the base product mode. When Telegram private-chat Threaded Mode is available, the bridge enables a local leader/follower bus automatically:
|
|
240
180
|
|
|
241
|
-
|
|
181
|
+
- One live leader owns `getUpdates`.
|
|
182
|
+
- Followers are visible Pi processes started by the operator.
|
|
183
|
+
- Each connected instance gets a Telegram thread target.
|
|
184
|
+
- Unknown threads are preserved and offered explicit reroute/restore choices.
|
|
185
|
+
- Telegram never launches hidden Pi processes.
|
|
242
186
|
|
|
243
|
-
|
|
187
|
+
| Mode | Best for | Runtime shape |
|
|
188
|
+
| ------------- | -------------------------------------------------------- | ----------------------------------------------------------------------------- |
|
|
189
|
+
| Classic DM | One live Pi session controlled from one private bot chat | One polling owner, one queue/runtime surface |
|
|
190
|
+
| Threaded Mode | Several visible Pi terminals sharing one bot | One leader owns transport; followers route through named private-chat threads |
|
|
244
191
|
|
|
245
|
-
|
|
192
|
+
## Environment Configuration
|
|
246
193
|
|
|
247
|
-
|
|
194
|
+
Most controls live in Pi commands or the Telegram menu. Environment variables remain for bootstrap and transport boundaries:
|
|
248
195
|
|
|
249
|
-
|
|
196
|
+
| Area | Variables |
|
|
197
|
+
| ------------------------- | ---------------------------------------------------------------------------------------------- |
|
|
198
|
+
| Bot token bootstrap | `TELEGRAM_BOT_TOKEN`, `TELEGRAM_BOT_KEY`, `TELEGRAM_TOKEN`, `TELEGRAM_KEY` |
|
|
199
|
+
| HTTP proxy | `HTTP_PROXY`, `HTTPS_PROXY`, `NO_PROXY`, plus `NODE_USE_ENV_PROXY=1` or Node `--use-env-proxy` |
|
|
200
|
+
| Telegram network family | `PI_TELEGRAM_NETWORK_FAMILY`=auto | ipv4 | ipv6 | ipv4-fallback` |
|
|
201
|
+
| Agent data root | `PI_CODING_AGENT_DIR` |
|
|
202
|
+
| Inbound file limit | `PI_TELEGRAM_INBOUND_FILE_MAX_BYTES`, `TELEGRAM_MAX_FILE_SIZE_BYTES` |
|
|
203
|
+
| Outbound attachment limit | `PI_TELEGRAM_OUTBOUND_ATTACHMENT_MAX_BYTES`, `TELEGRAM_MAX_ATTACHMENT_SIZE_BYTES` |
|
|
250
204
|
|
|
251
|
-
|
|
205
|
+
Defaults are chosen for ordinary private-bot use: saved config in `~/.pi/agent`, inbound temp files in `~/.pi/agent/tmp/telegram`, native Rich Markdown replies, and native Telegram active status for long-running turns.
|
|
252
206
|
|
|
253
|
-
|
|
207
|
+
## Extension Platform
|
|
254
208
|
|
|
255
|
-
|
|
209
|
+
Companion extensions can integrate with Telegram without owning polling or transport:
|
|
256
210
|
|
|
257
|
-
|
|
211
|
+
- Register Telegram slash commands.
|
|
212
|
+
- Add menu sections and settings surfaces.
|
|
213
|
+
- Add compact status rows.
|
|
214
|
+
- Handle update/callback namespaces.
|
|
215
|
+
- Provide inbound preprocessing handlers.
|
|
216
|
+
- Provide outbound voice synthesis.
|
|
217
|
+
- Use direct delivery helpers for explicit local/TUI sends.
|
|
258
218
|
|
|
259
|
-
|
|
219
|
+
Stable public entrypoints are documented in [Public API](./docs/public-api.md), [Extension Sections](./docs/sections.md), [Inbound Handlers](./docs/inbound.md), [Outbound Handlers](./docs/outbound.md), [Updates](./docs/updates.md), and [Voice Integration](./docs/voice.md).
|
|
260
220
|
|
|
261
|
-
|
|
262
|
-
{
|
|
263
|
-
"time": {
|
|
264
|
-
"injectionMode": "interval",
|
|
265
|
-
"interval": 3600000
|
|
266
|
-
}
|
|
267
|
-
}
|
|
268
|
-
```
|
|
221
|
+
## Safety Boundaries
|
|
269
222
|
|
|
270
|
-
|
|
223
|
+
`pi-telegram` intentionally does not:
|
|
271
224
|
|
|
272
|
-
|
|
225
|
+
- Spawn hidden Pi follower processes.
|
|
226
|
+
- Pretend Telegram is a terminal or PTY.
|
|
227
|
+
- Forward arbitrary Telegram slash commands into the Pi TUI.
|
|
228
|
+
- Inject raw TTY input or terminal-control sequences.
|
|
229
|
+
- Replace Pi session lifecycle without an official Pi API.
|
|
230
|
+
- Let non-owner Telegram users control the bridge.
|
|
273
231
|
|
|
274
|
-
|
|
275
|
-
- [Open Backlog](./BACKLOG.md): planned work and known follow-ups.
|
|
276
|
-
- [Changelog](./CHANGELOG.md): completed delivery history.
|
|
277
|
-
- [Documentation Index](./docs/README.md): technical docs hub.
|
|
278
|
-
- [Architecture](./docs/architecture.md): runtime and subsystem overview.
|
|
279
|
-
- [Public API](./docs/public-api.md): stable commands, config, package entrypoints, assistant markup, and extension APIs.
|
|
280
|
-
- [Inbound Handlers](./docs/inbound.md): Telegram → Pi preprocessing.
|
|
281
|
-
- [Outbound Handlers](./docs/outbound.md): final text, voice, and artifact pipelines.
|
|
282
|
-
- [Command Templates](./docs/command-templates.md): portable command-template contract.
|
|
283
|
-
- [Callback Namespaces](./docs/callback-namespaces.md): callback interop for layered extensions.
|
|
284
|
-
- [Updates](./docs/updates.md): shared update interception.
|
|
285
|
-
- [Extension Sections](./docs/sections.md): Telegram extension sections platform for loading extensions that register UI surfaces.
|
|
286
|
-
- [Voice Integration](./docs/voice.md): voice reply policies, transparent interception, and provider extension API.
|
|
287
|
-
- [Locks](./docs/locks.md): singleton polling ownership.
|
|
288
|
-
- [UI Style](./docs/ui-style.md): inline button, toggle, tab, option-list, card, and dialog style guide.
|
|
232
|
+
Telegram is a companion surface around a live Pi runtime, not a second runtime.
|
|
289
233
|
|
|
290
|
-
##
|
|
234
|
+
## Documentation Map
|
|
291
235
|
|
|
292
|
-
-
|
|
293
|
-
-
|
|
294
|
-
-
|
|
236
|
+
- [Architecture](./docs/architecture.md) — runtime, domains, queue, transport, and Threaded Mode overview.
|
|
237
|
+
- [Public API](./docs/public-api.md) — package entrypoints and stable companion-extension contracts.
|
|
238
|
+
- [Inbound Handlers](./docs/inbound.md) — Telegram-to-Pi preprocessing pipelines.
|
|
239
|
+
- [Outbound Handlers](./docs/outbound.md) — final text/voice/file transformation and delivery.
|
|
240
|
+
- [Voice Integration](./docs/voice.md) — STT/TTS provider model and reply policies.
|
|
241
|
+
- [Extension Sections](./docs/sections.md) — Telegram-native companion UI surfaces.
|
|
242
|
+
- [Updates](./docs/updates.md) — update handler registry and callback interop.
|
|
243
|
+
- [Multi-Instance Bus](./docs/multi-instance-bus.md) — leader/follower routing in Threaded Mode.
|
|
244
|
+
- [Locks](./docs/locks.md) — singleton ownership and shared lock conventions.
|
|
245
|
+
- [UI Style](./docs/ui-style.md) — menu, emoji, labels, dialogs, and inline keyboard standards.
|
|
246
|
+
- [Callback Namespaces](./docs/callback-namespaces.md) — callback ownership and routing.
|
|
247
|
+
- [Command Templates](./docs/command-templates.md) — handler command-template conventions.
|
|
295
248
|
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
Third-party extensions that integrate with `pi-telegram`:
|
|
299
|
-
|
|
300
|
-
- [`pi-codex-usage`](https://github.com/llblab/pi-codex-usage) — Compact Codex subscription quota/status widget for the Pi statusline and the inline menu status text opened by `/start`.
|
|
301
|
-
|
|
302
|
-
```bash
|
|
303
|
-
pi install npm:@llblab/pi-codex-usage
|
|
304
|
-
```
|
|
249
|
+
The docs index lives at [docs/README.md](./docs/README.md).
|
|
305
250
|
|
|
306
|
-
|
|
251
|
+
## Development
|
|
307
252
|
|
|
308
253
|
```bash
|
|
309
|
-
|
|
254
|
+
npm run typecheck
|
|
255
|
+
npm test
|
|
256
|
+
npm run audit
|
|
257
|
+
npm run pack:check
|
|
310
258
|
```
|
|
311
259
|
|
|
312
|
-
|
|
260
|
+
Full validation:
|
|
313
261
|
|
|
314
262
|
```bash
|
|
315
|
-
|
|
263
|
+
npm run validate
|
|
316
264
|
```
|
|
317
265
|
|
|
318
|
-
|
|
266
|
+
Project context:
|
|
319
267
|
|
|
320
|
-
|
|
268
|
+
- [AGENTS.md](./AGENTS.md) — engineering and runtime conventions.
|
|
269
|
+
- [BACKLOG.md](./BACKLOG.md) — release-relevant open work.
|
|
270
|
+
- [CHANGELOG.md](./CHANGELOG.md) — completed delivery history.
|
package/docs/architecture.md
CHANGED
|
@@ -223,7 +223,7 @@ During active Telegram-owned turns, assistant message start/update hooks re-arm
|
|
|
223
223
|
|
|
224
224
|
### Rendering And Delivery
|
|
225
225
|
|
|
226
|
-
|
|
226
|
+
Rich Markdown is the model-answer membrane. Complete assistant replies send final Markdown directly as `InputRichMessage.markdown` through `sendRichMessage`, and guest replies use native Rich Markdown through `InputRichMessageContent` in `answerGuestQuery` results. Tool-call rows, reasoning/thinking blocks, menus, status rows, queue controls, settings, diagnostics, and other harness-owned surfaces stay on explicit Telegram HTML/plain rendering. Streaming previews may use `sendRichMessageDraft` when enabled and when draft delivery succeeds. The bridge still strips top-level assistant action comments before delivery and may split output only for Telegram transport limits.
|
|
227
227
|
|
|
228
228
|
Assistant delivery guarantees:
|
|
229
229
|
|
|
@@ -231,12 +231,12 @@ Assistant delivery guarantees:
|
|
|
231
231
|
- Before native Rich Markdown delivery, the bridge normalizes known Bot-API-fragile source forms without changing visible meaning, including space-after-marker blockquotes and dollar-prefixed ticker atoms that Telegram may otherwise treat as unterminated math.
|
|
232
232
|
- Quoted rich replies use Telegram `rich_message` blocks as the prompt-context source when available, so `[reply]` context receives rendered plain text instead of raw `InputRichMessage.markdown` fallback text.
|
|
233
233
|
- Long native Markdown replies are split only at Telegram Rich Message transport limits; oversized fenced code, display-math, and fully wrapped inline-formatting blocks are rewrapped per chunk so persisted Rich Markdown chunks remain structurally valid.
|
|
234
|
-
-
|
|
234
|
+
- When enabled, streaming previews pass structurally closed assistant Markdown prefixes through to `sendRichMessageDraft` with ownership checks, voice suppression, and serialized flushes. Unclosed inline spans, links, fenced code, comments, and display-math blocks are held back until a safe boundary exists. Draft failures are recorded and the failing frame is skipped instead of degrading to raw plain-message previews, because partial Markdown can be invalid while the final message remains valid.
|
|
235
235
|
- Preview flushes are serialized so older edits cannot race newer drafts; final delivery waits for active draft flushes and does not perform a post-final draft-clear call.
|
|
236
236
|
|
|
237
237
|
UI/compat rendering guarantees:
|
|
238
238
|
|
|
239
|
-
- Bridge-owned UI surfaces such as commands, menus, status messages, queue controls, and interactive sections use Telegram HTML/plain rendering helpers by default. These texts are authored for
|
|
239
|
+
- Bridge-owned UI surfaces such as tool rows, reasoning/thinking blocks, commands, menus, status messages, queue controls, diagnostics, settings, and interactive sections use Telegram HTML/plain rendering helpers by default. These texts are authored for operational UI rather than model output, so explicit HTML/plain markup remains clearer, safer, and easier to maintain.
|
|
240
240
|
- In those UI/compat surfaces, real code blocks stay literal and escaped, supported absolute links stay clickable, unsupported links degrade safely, tables use compact monospace rendering with grapheme/display-width accounting, and list/quote/heading spacing stays Telegram-safe.
|
|
241
241
|
|
|
242
242
|
Final delivery attaches reply metadata only where requested. Reply parameters apply only to the first chunk of split messages; continuation chunks are adjacent normal messages. Media-group turns reply to the representative message id.
|