@llblab/pi-telegram 0.11.2 → 0.12.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 +15 -11
- package/BACKLOG.md +0 -10
- package/CHANGELOG.md +18 -0
- package/README.md +18 -14
- package/api/inbound.ts +14 -0
- package/api/keyboard.ts +10 -0
- package/api/outbound.ts +11 -0
- package/api/sections.ts +17 -0
- package/api/updates.ts +11 -0
- package/api/voice.ts +24 -0
- package/docs/README.md +7 -5
- package/docs/architecture.md +160 -225
- package/docs/callback-namespaces.md +3 -3
- package/docs/{inbound-handlers.md → inbound.md} +13 -10
- package/docs/locks.md +3 -3
- package/docs/{outbound-handlers.md → outbound.md} +13 -10
- package/docs/public-api.md +266 -0
- package/docs/{extension-sections.md → sections.md} +31 -27
- package/docs/ui-style.md +165 -0
- package/docs/{external-handlers.md → updates.md} +33 -31
- package/docs/voice.md +17 -14
- package/index.ts +84 -238
- package/lib/bindings.ts +301 -0
- package/lib/commands.ts +114 -1
- package/lib/config.ts +43 -2
- package/lib/{inbound-handlers.ts → inbound.ts} +5 -4
- package/lib/lifecycle.ts +41 -6
- package/lib/menu-model.ts +3 -3
- package/lib/menu-queue.ts +1 -1
- package/lib/menu-settings.ts +21 -10
- package/lib/menu-status.ts +1 -1
- package/lib/menu.ts +1 -1
- package/lib/{outbound-handlers.ts → outbound.ts} +21 -11
- package/lib/polling.ts +4 -3
- package/lib/preview.ts +1 -1
- package/lib/routing.ts +44 -3
- package/lib/{extension-sections.ts → sections.ts} +37 -8
- package/lib/updates.ts +121 -1
- package/lib/voice.ts +33 -14
- package/package.json +11 -1
- package/lib/external-handlers.ts +0 -166
package/AGENTS.md
CHANGED
|
@@ -24,10 +24,12 @@
|
|
|
24
24
|
## 3. Project Topology
|
|
25
25
|
|
|
26
26
|
- `/index.ts`: Main extension entrypoint and runtime composition layer for the bridge
|
|
27
|
-
- `/
|
|
28
|
-
- `/
|
|
27
|
+
- `/api/*.ts`: Public package entrypoint membranes. Export only stable companion-extension symbols documented in `/docs/public-api.md`; keep runtime helpers in `/lib` package-private.
|
|
28
|
+
- `/lib/*.ts`: Flat domain modules for reusable runtime logic. Favor domain files such as queueing/runtime, replies, polling, updates, outbound-attachments, commands, lifecycle hooks, prompts, prompt-templates, pi SDK adapter/bindings, Telegram API, config, turns, media, setup, rendering, app menu, menu-model, menu-thinking, menu-queue, status/model-resolution support, and other cohesive bridge subsystems; use `shared` only when a type or constant truly spans multiple domains
|
|
29
|
+
- `/tests/*.test.ts`: Domain-mirrored regression suites that follow the same flat naming as `/lib` plus public package-boundary regressions for `/api`
|
|
29
30
|
- `/docs/README.md`: Documentation index for technical project docs
|
|
30
31
|
- `/docs/architecture.md`: Runtime and subsystem overview for the bridge
|
|
32
|
+
- `/docs/public-api.md`: Stable public API map for commands, config, assistant markup, extension APIs, package entrypoints, and compatibility boundaries
|
|
31
33
|
- `/README.md`: User-facing project entry point. Keep its rhythm as install → connect → use → core features → docs, with vivid examples that explain the runtime adapter/operator-console model without duplicating full docs.
|
|
32
34
|
- `/AGENTS.md`: Durable engineering and runtime conventions
|
|
33
35
|
- `/BACKLOG.md`: Canonical open work
|
|
@@ -106,11 +108,11 @@
|
|
|
106
108
|
The canonical detailed ownership map lives in [`docs/architecture.md`](./docs/architecture.md). Keep this section as a compact agent-facing index, not a second copy of the full map.
|
|
107
109
|
|
|
108
110
|
- Scheduling and lifecycle: `queue`, `runtime`, `lifecycle`, `locks`
|
|
109
|
-
- Telegram transport and inbound flow: `api`, `polling`, `updates`, `routing`, `media`, `turns`, `inbound
|
|
110
|
-
- Response surfaces: `preview`, `replies`, `rendering`, `keyboard`, `outbound-attachments`, `outbound
|
|
111
|
+
- Telegram transport and inbound flow: `api`, `polling`, `updates`, `routing`, `media`, `turns`, `inbound`, `config`, `setup`
|
|
112
|
+
- Response surfaces: `preview`, `replies`, `rendering`, `keyboard`, `outbound-attachments`, `outbound`, `voice`, `status`
|
|
111
113
|
- Controls and application menu UI: `commands`, `menu`, `menu-model`, `menu-thinking`, `menu-status`, `menu-queue`, `model`, `prompts`
|
|
112
|
-
- Extension platform: `
|
|
113
|
-
- Pi SDK boundary: `pi` owns direct pi imports and bound extension API ports
|
|
114
|
+
- Extension platform: `sections` owns section registry, token mapping, callback dispatch, context building, and its globalThis bridge; `voice` owns the voice-provider registry and its globalThis bridge
|
|
115
|
+
- Pi SDK boundary: `pi` owns direct pi imports and bound extension API ports; `bindings` owns pi-facing command/tool/lifecycle registration wiring extracted from the entrypoint
|
|
114
116
|
|
|
115
117
|
## 6.4 Entrypoint And Import Boundaries
|
|
116
118
|
|
|
@@ -142,11 +144,13 @@ The canonical detailed ownership map lives in [`docs/architecture.md`](./docs/ar
|
|
|
142
144
|
- Command help plus prompt-template commands and status/model/thinking/queue controls are driven through `/start`'s Telegram inline application menu and callback queries; the Queue button shows the queued-item count, model-menu scope/pagination controls stay at the top under Main menu, the model pagination indicator opens a compact page picker, and thinking-menu text stays a compact heading because the current level is marked by button state; `/status`, `/model`, `/thinking`, and `/queue` are hidden compatibility shortcuts
|
|
143
145
|
- Shared inline-keyboard structure belongs to `keyboard`; application-control button labels, callback data, and callback behavior stay in `menu`/`menu-model`/`menu-thinking`/`menu-status`/`menu-queue` while core queue mechanics stay in `queue`
|
|
144
146
|
- Telegram `/settings` options should open nested detail submenus by default: checkbox options show a description plus Back, `on`, and `off`; list options show Back plus selectable values. One-shot actions such as syncing may run directly without a submenu when there is no meaningful choice or description step.
|
|
147
|
+
- Inline UI labels and dialogs follow [`docs/ui-style.md`](./docs/ui-style.md): action buttons use emoji plus capitalized action text, state & navigation buttons show state and lead to a submenu, first-level submenus start with `⬆️ Main menu` while deeper submenus start with `⬆️ Back`, boolean toggles use Capitalized horizontal `On`/`Off` with green active `On`, yellow active `Off`, and black inactive dots, tabs use capitalized labels with purple default-state and yellow elevated-state active dots and black inactive dots, vertical option lists mark only the current value green, and confirmation dialogs use a single bold text-only question with emoji on buttons only.
|
|
145
148
|
- Inbound text/media may be transformed through configured `inboundHandlers` before queueing; legacy `attachmentHandlers` are deprecated compatibility aliases appended after `inboundHandlers`; outbound files must flow through `telegram_attach`
|
|
146
149
|
- Long Telegram text split recovery belongs to `text-groups`: keep it conservative, short-debounced, same chat/user/message-id contiguous, and gated by near-limit human text so normal rapid follow-ups and slash commands stay separate
|
|
147
|
-
- Public
|
|
150
|
+
- Public API boundaries live in [`docs/public-api.md`](./docs/public-api.md): companion extensions must use public API domain subpaths such as `@llblab/pi-telegram/sections`, `/voice`, `/inbound`, `/outbound`, and `/updates`; `0.12.0` intentionally removes the published `@llblab/pi-telegram/lib/*.ts` compatibility wildcard
|
|
151
|
+
- Public handler API matrix: low-level buses use `registerTelegramUpdateHandler(handler)`, `registerTelegramInboundHandler(kind, handler)`, and `registerTelegramOutboundHandler(kind, handler)` without ids; high-level surfaces use stable identity (`registerTelegramSection({ id, ... })`, `registerTelegramVoiceTranscriptionProvider(provider, { id })`, and `registerTelegramVoiceSynthesisProvider(provider, { id })`). Inbound handlers and command-backed outbound handlers use command templates as the standard config contract; built-in outbound buttons use inline keyboards plus callback routing because no polling command execution is needed
|
|
148
152
|
- Telegram prompt-template commands are discovered from π slash commands with `source: "prompt"`; π template names are mapped to Bot API-compatible aliases (`fix-tests` → `/fix_tests`), aliases that conflict with built-in bridge commands or hidden shortcuts are not displayed, prompt-template aliases stay out of the Telegram bot command menu, and the bridge expands template files before queueing because extension-originated `sendUserMessage()` bypasses π's interactive template expansion
|
|
149
|
-
- Unknown callback data not owned by pi-telegram prefixes (`tgbtn:`, `menu:`, `model:`, `thinking:`, `status:`, `queue:`, `section:`, `settings:`) may be forwarded as `[callback] <data>` after built-in handlers decline it;
|
|
153
|
+
- Unknown callback data not owned by pi-telegram prefixes (`compact:`, `tgbtn:`, `menu:`, `model:`, `thinking:`, `status:`, `queue:`, `section:`, `settings:`) may be forwarded as `[callback] <data>` after built-in handlers decline it; update-handler extensions should follow `docs/callback-namespaces.md` and must not poll the same bot independently
|
|
150
154
|
- Command templates stay compact and shell-free: no `command` field, no shell execution, inline defaults are allowed as `{name=default}`, `template` may be a string or an ordered composition array, only `args`/`defaults` inherit into leaves, top-level `timeout` wraps composed sequences, stdout pipes to the next step's stdin by default, and multi-step work should use `template: [...]` rather than provider-specific fields; `pipe` is only a legacy local alias
|
|
151
155
|
- Command-template documentation examples should use portable executable placeholders such as `/path/to/stt` and `/path/to/tts`, not host-local skill paths or machine-specific install locations
|
|
152
156
|
|
|
@@ -155,15 +159,15 @@ The canonical detailed ownership map lives in [`docs/architecture.md`](./docs/ar
|
|
|
155
159
|
- `Section identity`: use the same identity-key rules as the Extension Locks Standard (`package.json/name` → canonical id); no separate `owner` field
|
|
156
160
|
- `Token mapping`: Telegram's 64-byte `callback_data` limit forces compact numeric tokens (`section:0:action:payload`). Section authors never hand-roll `section:` strings — use `ctx.callbackData(action, payload?)`
|
|
157
161
|
- `Navigation hierarchy`: Back buttons are auto-prepended by `ctx.edit()` / `ctx.open()`. Root views use `⬆️ Main menu` → `menu:back`. Nested views from `handleCallback` use `⬆️ Back` → `section:<token>:open`. Settings views use `⬆️ Back` → `settings:list`
|
|
158
|
-
- `Context ports`: sections receive `TelegramSectionContext` / `TelegramSectionCallbackContext` with `answerCallback`, `edit`, `open`, `enqueuePrompt`, and `callbackData`. No filesystem access, no raw bot clients, no second
|
|
162
|
+
- `Context ports`: sections receive `TelegramSectionContext` / `TelegramSectionCallbackContext` with `answerCallback`, `edit`, `open`, `enqueuePrompt`, and `callbackData`. No filesystem access, no raw bot clients, no second polling loop
|
|
159
163
|
- `Settings indicators`: use `settings.getLabel()` for dynamic status rows in the Settings submenu (e.g., `🟢`/`⚫️` based on internal state). Called on every Settings list render
|
|
160
164
|
- `Handler fallback`: `section.handleCallback` runs first; if it returns `"pass"` and `settings.handleCallback` exists, the settings handler runs with a fresh context carrying `backCallback="settings:list"`
|
|
161
|
-
- `Stale tokens`: unknown or unregistered tokens answer the callback with a short popup. Section errors are caught and surfaced as popup text — no unhandled exceptions leak to
|
|
165
|
+
- `Stale tokens`: unknown or unregistered tokens answer the callback with a short popup. Section errors are caught and surfaced as popup text — no unhandled exceptions leak to polling
|
|
162
166
|
- `Load order`: `pi-telegram` must load first (sets `globalThis.__piTelegramSectionRegistry__`). Consumer extensions load second. The typed import is the preferred path; the `globalThis` bridge exists for load-order tolerance
|
|
163
167
|
- `Shutdown`: call `pi.on("shutdown", () => unregister())` in the extension's default export
|
|
164
168
|
- `Section separators`: extension-injected main-menu rows appear before the **⚙️ Settings** row. Extension settings rows appear before built-in Proactive push controls
|
|
165
169
|
- `Model button format`: use `provider/ModelId` format (e.g., `anthropic/claude-sonnet-4-5`) across model menu buttons and status row. The compact `provider/id` form is canonical
|
|
166
|
-
- `Section domain ownership`: `lib/
|
|
170
|
+
- `Section domain ownership`: `lib/sections.ts` owns the registry, token mapping, callback dispatch, and context building. `lib/menu.ts` dispatches `section:` callbacks before built-in handling. `lib/menu-status.ts` injects section rows. `lib/menu-settings.ts` injects settings rows and passes `sectionRegistry` through callback deps
|
|
167
171
|
- `Callback routing order`: button actions → queue menu → settings menu → section callbacks → built-in menu handling → `[callback]` fallback. Settings menu callbacks always pass `sectionRegistry` to `updateTelegramSettingsMenuMessage` and `handleTelegramSettingsMenuCallbackAction`
|
|
168
172
|
|
|
169
173
|
## 9. Pre-Task Preparation Protocol
|
package/BACKLOG.md
CHANGED
|
@@ -1,13 +1,3 @@
|
|
|
1
1
|
# Project Backlog
|
|
2
2
|
|
|
3
3
|
## Open Work
|
|
4
|
-
|
|
5
|
-
- [ ] Adapt `pi-xai-voice` to the finalized voice-provider contract.
|
|
6
|
-
- Priority: High after `0.11.0` lands.
|
|
7
|
-
- Idea: Update provider imports to `@llblab/pi-telegram/lib/voice.ts`, persist `voice.replyMode` to the same `telegram.json` location pi-telegram reads, return `transcriptText` only when the provider's transcript toggle is enabled, and rely on provider-owned OGG/Opus conversion.
|
|
8
|
-
- Exit: `pi-xai-voice` works against `pi-telegram@0.11.x` without direct `globalThis` access or fork-local import resolution.
|
|
9
|
-
|
|
10
|
-
- [ ] Explore always-available outbound Telegram tools for queued artifacts and controls.
|
|
11
|
-
- Priority: Low.
|
|
12
|
-
- Idea: Provide tools such as `telegram_attach_file` and `telegram_attach_button` that can be called outside an active Telegram turn, using the paired chat/session as the delivery target when safe.
|
|
13
|
-
- Exit: Design note defines active-turn versus ambient delivery semantics, safety constraints, failure modes, and whether the current `telegram_attach` contract should stay turn-scoped or gain an ambient companion.
|
package/CHANGELOG.md
CHANGED
|
@@ -2,6 +2,24 @@
|
|
|
2
2
|
|
|
3
3
|
## Unreleased
|
|
4
4
|
|
|
5
|
+
- Nothing yet.
|
|
6
|
+
|
|
7
|
+
## 0.12.0: Public API Membranes, Telegram UX Safety, And Extension Interop
|
|
8
|
+
|
|
9
|
+
- `[Typing Status]` Auto-compaction now starts and stops the native Telegram `typing` keepalive like manual `/compact`, including timeout and shutdown cleanup. Active Telegram turns also re-arm typing on assistant message start/update events so transient provider/model errors cannot permanently leave a continuing run without Telegram activity feedback.
|
|
10
|
+
- `[Compaction Safety]` Telegram `/compact` now opens an inline confirmation dialog before manual compaction starts, protecting the operator from accidental taps near `/start`. The dialog follows the dedicated UI style guide: a bold text-only question with emoji only on the explicit `Yes, compact` and `No` buttons. Confirming edits the dialog directly to `Compaction started.` instead of showing a separate `Compaction confirmed.` step.
|
|
11
|
+
- `[Docs]` Added `docs/ui-style.md` as the focused style guide for inline buttons, toggles, tabs, option lists, cards, and dialogs.
|
|
12
|
+
- `[Docs]` Restructured `docs/architecture.md` into a clearer architectural map with runtime topology, domain ownership, core flows, extension surfaces, and operational behavior while pushing detailed UI/callback rules toward focused standards.
|
|
13
|
+
- `[Breaking API]` Bumped package version to `0.12.0` and renamed the public implementation domains to `lib/sections.ts`, `lib/updates.ts`, `lib/inbound.ts`, and `lib/outbound.ts`. Package exports now expose only the stable public API domains (`/sections`, `/updates`, `/inbound`, `/outbound`, `/voice`, `/keyboard`) and no longer expose the compatibility `./lib/*.ts` wildcard.
|
|
14
|
+
- `[Architecture]` Folded the public update-handler interop surface into `updates` and renamed the internal long-poll loop module back to `polling`, giving the pair concise one-word domains: `updates` for update contracts/classification/handler registry and `polling` for the `getUpdates` runtime. Entrypoint extraction now lives in `bindings`, a concrete pi-facing command/tool/lifecycle wiring boundary rather than a new product domain.
|
|
15
|
+
- `[Tests]` Added an architecture invariant and package self-import regressions that pin the `0.12.0` package exports to stable `/api` membranes with exact runtime export shapes and prevent accidental restoration of the removed `./lib/*.ts` wildcard.
|
|
16
|
+
- `[Docs]` Added `docs/public-api.md` as the public API map for commands, config, assistant markup, extension APIs, callback ownership, and public/internal stability boundaries.
|
|
17
|
+
- `[API]` Hardened Telegram Extension Sections by rejecting duplicate section ids and validating `ctx.callbackData()` against Telegram's 64-byte callback-data limit.
|
|
18
|
+
- `[API]` Added `registerTelegramUpdateHandler()` as the matrix-aligned low-level update bus name.
|
|
19
|
+
- `[API]` Documented the public low/high-level registration matrix: low-level buses (`updates`, `inbound`, `outbound`) intentionally have no ids, while high-level sections and voice providers use stable ids in new integrations.
|
|
20
|
+
- `[Settings UI]` Refined control conventions: boolean toggles use Capitalized horizontal `On`/`Off` with green active `On`, yellow active `Off`, and black inactive markers; state/navigation rows use Capitalized status values; horizontal tabs use capitalized labels with purple default-state and yellow elevated-state active markers; vertical option lists keep only the current value marked green; submenu navigation distinguishes `⬆️ Main menu` from deeper `⬆️ Back` rows; confirmation actions use explicit `Yes, ...` labels such as `🗜 Yes, compact`; added State & Navigation Buttons section to the style guide for buttons that show state and lead to a submenu.
|
|
21
|
+
- `[Config]` Time Injection Hidden mode now removes `time.injectionMode` from `telegram.json` instead of persisting `"hidden"`, matching Voice Reply Hidden semantics: missing key = default hidden state.
|
|
22
|
+
|
|
5
23
|
## 0.11.2: Queue Continuation, Compaction Safety, And Settings Polish
|
|
6
24
|
|
|
7
25
|
- `[Time Context]` Renamed the disabled time injection mode from `off` to `hidden` in Settings and config defaults, matching voice reply mode semantics where no prompt-context line is injected. Legacy `off` callbacks/config values are still treated as hidden.
|
package/README.md
CHANGED
|
@@ -85,7 +85,7 @@ What it feels like:
|
|
|
85
85
|
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 normally live in the CLI, adapted for Telegram.
|
|
86
86
|
|
|
87
87
|
- **`/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.
|
|
88
|
-
- **`/compact`**:
|
|
88
|
+
- **`/compact`**: Ask for inline confirmation, then start session compaction when the session is idle; Telegram shows the native typing indicator while manual or automatic compaction is running.
|
|
89
89
|
- **`/next`**: Dispatch the next queued turn, aborting π first if needed.
|
|
90
90
|
- **`/continue`**: Enqueue a priority `continue` prompt.
|
|
91
91
|
- **`/abort`**: Abort the active run without touching the queue.
|
|
@@ -199,11 +199,11 @@ If `telegram.json` explicitly sets a valid `voice.replyMode`, prompts include co
|
|
|
199
199
|
|
|
200
200
|
In `mirror` and `always` modes, the bridge transparently intercepts agent text responses and routes them through the outbound voice pipeline. Configured `outboundHandlers` with `type: "voice"` run first in their configured order; zero-config registered synthesis providers run after them as progressive fallbacks. If several synthesis providers are installed, they are tried in registration order and the first one that returns a valid `.ogg`/`.opus` artifact handles the reply; `undefined`, errors, or invalid output fall through to the next provider. If every voice generator fails, the bridge falls back to sending the text reply instead.
|
|
201
201
|
|
|
202
|
-
Voice synthesis provider extensions (e.g. `pi-xai-voice`) register a TTS backend at runtime:
|
|
202
|
+
Voice synthesis provider extensions (e.g. `pi-xai-voice`) register a TTS backend at runtime through public API domain subpaths:
|
|
203
203
|
|
|
204
204
|
```typescript
|
|
205
|
-
import { registerTelegramVoiceSynthesisProvider } from "@llblab/pi-telegram/
|
|
206
|
-
import { recordTelegramRuntimeEvent } from "@llblab/pi-telegram/
|
|
205
|
+
import { registerTelegramVoiceSynthesisProvider } from "@llblab/pi-telegram/voice";
|
|
206
|
+
import { recordTelegramRuntimeEvent } from "@llblab/pi-telegram/outbound";
|
|
207
207
|
|
|
208
208
|
// Return path only (backward compatible)
|
|
209
209
|
const dispose = registerTelegramVoiceSynthesisProvider(
|
|
@@ -211,6 +211,7 @@ const dispose = registerTelegramVoiceSynthesisProvider(
|
|
|
211
211
|
const path = await myTTS(text, { language: lang });
|
|
212
212
|
return path; // must be .ogg or .opus
|
|
213
213
|
},
|
|
214
|
+
{ id: "pi-xai-voice/tts" },
|
|
214
215
|
);
|
|
215
216
|
|
|
216
217
|
// Return path + transcript caption
|
|
@@ -220,6 +221,7 @@ const dispose2 = registerTelegramVoiceSynthesisProvider(
|
|
|
220
221
|
const path = await myTTS(rewritten, { language: lang });
|
|
221
222
|
return { audioPath: path, transcriptText: text };
|
|
222
223
|
},
|
|
224
|
+
{ id: "pi-xai-voice/tts-with-transcript" },
|
|
223
225
|
);
|
|
224
226
|
|
|
225
227
|
// Surface diagnostics in /telegram-status
|
|
@@ -229,17 +231,17 @@ recordTelegramRuntimeEvent("xai-voice", new Error("TTS complete"), {
|
|
|
229
231
|
});
|
|
230
232
|
```
|
|
231
233
|
|
|
232
|
-
Multiple synthesis providers can be registered;
|
|
234
|
+
Multiple synthesis providers can be registered; stable provider registrations pass a durable `id`, while omitted ids remain a compatibility path for older providers. The bridge tries configured `type: "voice"` handlers first, then programmatic handlers, then registered synthesis providers in registration order until one succeeds. Providers and handlers receive the text to synthesize and optional `lang`/`rate` hints from `<!-- telegram_voice -->` markup or the automatic interception path. Voice delivery must produce `.ogg` or `.opus` files.
|
|
233
235
|
|
|
234
236
|
### Extension interop
|
|
235
237
|
|
|
236
|
-
Unknown inline-button callbacks are forwarded to π as `[callback] <data>` when they do not belong to pi-telegram, so other extensions can namespace and handle Telegram buttons without polling the bot themselves. Layered extensions that need synchronous update handling can register a
|
|
238
|
+
Unknown inline-button callbacks are forwarded to π as `[callback] <data>` when they do not belong to pi-telegram, so other extensions can namespace and handle Telegram buttons without polling the bot themselves. Layered extensions that need synchronous update handling can register a handler on the shared update registry.
|
|
237
239
|
|
|
238
240
|
### Extension Sections
|
|
239
241
|
|
|
240
|
-
Ordinary pi extensions can register structured UI sections that appear in the main Telegram menu and Settings submenu without owning a second
|
|
242
|
+
Ordinary pi extensions can register structured UI sections that appear in the main Telegram menu and Settings submenu without owning a second polling loop. Each section gets a narrow typed context with `edit`, `open`, `enqueuePrompt`, `answerCallback`, and `callbackData()` — enough to build interactive Telegram-native surfaces while `pi-telegram` owns transport, callback routing, navigation hierarchy, and diagnostics.
|
|
241
243
|
|
|
242
|
-
Import `registerTelegramSection()` from `@llblab/pi-telegram/
|
|
244
|
+
Import `registerTelegramSection()` from `@llblab/pi-telegram/sections` and return a disposer on shutdown. Sections can send interactive messages directly into the chat via `ctx.open()` — confirmation dialogs, approve/deny gates, and multi-step forms live outside the menu hierarchy while callbacks route through the same typed handler. See [`@llblab/pi-telegram-extension-demo`](https://github.com/llblab/pi-telegram-extension-demo) for a working reference and the [Extension Sections Standard](./docs/sections.md) for the full contract.
|
|
243
245
|
|
|
244
246
|
### Proactive push
|
|
245
247
|
|
|
@@ -267,14 +269,16 @@ Modes are `hidden`, `always`, and `interval`. `hidden` means no time line is add
|
|
|
267
269
|
- [Changelog](./CHANGELOG.md): completed delivery history.
|
|
268
270
|
- [Documentation Index](./docs/README.md): technical docs hub.
|
|
269
271
|
- [Architecture](./docs/architecture.md): runtime and subsystem overview.
|
|
270
|
-
- [
|
|
271
|
-
- [
|
|
272
|
-
- [
|
|
272
|
+
- [Public API](./docs/public-api.md): stable commands, config, package entrypoints, assistant markup, and extension APIs.
|
|
273
|
+
- [Inbound Handlers](./docs/inbound.md): Telegram → π preprocessing.
|
|
274
|
+
- [Outbound Handlers](./docs/outbound.md): final text, voice, and artifact pipelines.
|
|
273
275
|
- [Command Templates](./docs/command-templates.md): portable command-template contract.
|
|
274
276
|
- [Callback Namespaces](./docs/callback-namespaces.md): callback interop for layered extensions.
|
|
275
|
-
- [
|
|
276
|
-
- [Extension Sections](./docs/
|
|
277
|
+
- [Updates](./docs/updates.md): shared update interception.
|
|
278
|
+
- [Extension Sections](./docs/sections.md): Telegram extension sections platform for loading extensions that register UI surfaces.
|
|
279
|
+
- [Voice Integration](./docs/voice.md): voice reply policies, transparent interception, and provider extension API.
|
|
277
280
|
- [Locks](./docs/locks.md): singleton polling ownership.
|
|
281
|
+
- [UI Style](./docs/ui-style.md): inline button, toggle, tab, option-list, card, and dialog style guide.
|
|
278
282
|
|
|
279
283
|
## Notes
|
|
280
284
|
|
|
@@ -292,7 +296,7 @@ Third-party extensions that integrate with `pi-telegram`:
|
|
|
292
296
|
pi install npm:pi-telegram-tool-status
|
|
293
297
|
```
|
|
294
298
|
|
|
295
|
-
- [`pi-xai-voice`](https://github.com/luxus/pi-xai-voice) — xAI
|
|
299
|
+
- [`pi-xai-voice`](https://github.com/luxus/pi-xai-voice) — Companion extension that adds xAI-powered TTS for voice reply policies and `telegram_voice` markup.
|
|
296
300
|
|
|
297
301
|
```bash
|
|
298
302
|
pi install npm:pi-xai-voice
|
package/api/inbound.ts
ADDED
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Public Telegram inbound API
|
|
3
|
+
* Zones: package boundary, companion extension interop
|
|
4
|
+
* Exposes the stable programmatic inbound handler surface while keeping handler runtime internals package-private
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
export {
|
|
8
|
+
registerTelegramInboundHandler,
|
|
9
|
+
type TelegramInboundHandlerFile,
|
|
10
|
+
type TelegramInboundHandlerOutput,
|
|
11
|
+
type TelegramInboundProgrammaticHandler,
|
|
12
|
+
type TelegramInboundProgrammaticHandlerInput,
|
|
13
|
+
type TelegramInboundProgrammaticHandlerResult,
|
|
14
|
+
} from "../lib/inbound.ts";
|
package/api/keyboard.ts
ADDED
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Public Telegram keyboard API
|
|
3
|
+
* Zones: package boundary, companion extension interop
|
|
4
|
+
* Exposes shared inline-keyboard structural types without runtime exports
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
export type {
|
|
8
|
+
TelegramInlineKeyboardButton,
|
|
9
|
+
TelegramInlineKeyboardMarkup,
|
|
10
|
+
} from "../lib/keyboard.ts";
|
package/api/outbound.ts
ADDED
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Public Telegram outbound API
|
|
3
|
+
* Zones: package boundary, companion extension interop
|
|
4
|
+
* Exposes stable outbound handler and diagnostics surfaces while keeping delivery internals package-private
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
export {
|
|
8
|
+
recordTelegramRuntimeEvent,
|
|
9
|
+
registerTelegramOutboundHandler,
|
|
10
|
+
type TelegramOutboundProgrammaticHandler,
|
|
11
|
+
} from "../lib/outbound.ts";
|
package/api/sections.ts
ADDED
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Public Telegram sections API
|
|
3
|
+
* Zones: package boundary, companion extension interop
|
|
4
|
+
* Exposes the stable managed Telegram menu-section surface while keeping registry internals package-private
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
export {
|
|
8
|
+
getTelegramSectionDiagnostics,
|
|
9
|
+
registerTelegramSection,
|
|
10
|
+
type TelegramSectionCallbackContext,
|
|
11
|
+
type TelegramSectionCallbackResult,
|
|
12
|
+
type TelegramSectionContext,
|
|
13
|
+
type TelegramSectionDiagnostic,
|
|
14
|
+
type TelegramSectionRegistration,
|
|
15
|
+
type TelegramSectionSettingsRegistration,
|
|
16
|
+
type TelegramSectionView,
|
|
17
|
+
} from "../lib/sections.ts";
|
package/api/updates.ts
ADDED
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Public Telegram updates API
|
|
3
|
+
* Zones: package boundary, companion extension interop
|
|
4
|
+
* Exposes the stable raw-update handler surface while keeping update routing internals package-private
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
export {
|
|
8
|
+
registerTelegramUpdateHandler,
|
|
9
|
+
type TelegramUpdateHandler,
|
|
10
|
+
type TelegramUpdateHandlerVerdict,
|
|
11
|
+
} from "../lib/updates.ts";
|
package/api/voice.ts
ADDED
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Public Telegram voice API
|
|
3
|
+
* Zones: package boundary, companion extension interop
|
|
4
|
+
* Exposes the stable STT/TTS provider surface and voice policy helpers
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
export {
|
|
8
|
+
TELEGRAM_VOICE_REPLY_MODES,
|
|
9
|
+
computeVoicePromptContribution,
|
|
10
|
+
computeVoiceTurnFlags,
|
|
11
|
+
getTelegramVoiceReplyMode,
|
|
12
|
+
getTelegramVoiceSendTranscript,
|
|
13
|
+
isVoiceTurn,
|
|
14
|
+
registerTelegramVoiceSynthesisProvider,
|
|
15
|
+
registerTelegramVoiceTranscriptionProvider,
|
|
16
|
+
shouldSuppressPreviewForVoice,
|
|
17
|
+
type TelegramVoiceReplyMode,
|
|
18
|
+
type TelegramVoiceSynthesisProvider,
|
|
19
|
+
type TelegramVoiceSynthesisProviderResult,
|
|
20
|
+
type TelegramVoiceTranscriptionFile,
|
|
21
|
+
type TelegramVoiceTranscriptionProvider,
|
|
22
|
+
type TelegramVoiceTranscriptionProviderResult,
|
|
23
|
+
type TelegramVoiceTurnView,
|
|
24
|
+
} from "../lib/voice.ts";
|
package/docs/README.md
CHANGED
|
@@ -5,11 +5,13 @@ Living index of project documentation in `/docs`.
|
|
|
5
5
|
## Documents
|
|
6
6
|
|
|
7
7
|
- [architecture.md](./architecture.md) — Overview of the Telegram bridge runtime, queueing model, rendering pipeline, and interactive controls
|
|
8
|
+
- [public-api.md](./public-api.md) — Stable public API map: package entrypoints, commands, config, assistant markup, extension APIs, and compatibility boundaries
|
|
8
9
|
- [command-templates.md](./command-templates.md) — Portable command-template standard core
|
|
9
|
-
- [inbound
|
|
10
|
-
- [outbound
|
|
10
|
+
- [inbound.md](./inbound.md) — Local `pi-telegram` inbound text/media handler bus, programmatic inbound handlers, registered STT provider fallbacks, legacy `attachmentHandlers` compatibility, placeholders, and fallbacks
|
|
11
|
+
- [outbound.md](./outbound.md) — Local `pi-telegram` outbound-handler config, text/voice/button behavior, voice synthesis provider fallback priority, artifact outputs, and callback routing
|
|
12
|
+
- [callback-namespaces.md](./callback-namespaces.md) — Shared Telegram `callback_data` namespace standard for layered extensions
|
|
13
|
+
- [updates.md](./updates.md) — Update classification and runtime handler registry that lets layered extensions observe and consume Telegram updates without owning their own polling connection
|
|
14
|
+
- [sections.md](./sections.md) — Telegram Extension Sections Standard: registration contract, context ports, callback routing, navigation hierarchy, and demo reference for pi extensions that want Telegram UI surfaces
|
|
11
15
|
- [voice.md](./voice.md) — Voice integration guide: detection, reply policy, STT/TTS provider registration, provider-owned conversion, and transparent interception
|
|
12
16
|
- [locks.md](./locks.md) — Shared `locks.json` standard for singleton extension ownership
|
|
13
|
-
- [
|
|
14
|
-
- [external-handlers.md](./external-handlers.md) — Runtime interceptor registry that lets layered extensions observe and consume Telegram updates without owning their own polling connection
|
|
15
|
-
- [extension-sections.md](./extension-sections.md) — Telegram Extension Sections Standard: registration contract, context ports, callback routing, navigation hierarchy, and demo reference for pi extensions that want Telegram UI surfaces
|
|
17
|
+
- [ui-style.md](./ui-style.md) — Inline UI style guide for buttons, toggles, tabs, option lists, cards, and dialogs
|