@llblab/pi-telegram 0.45.11 → 0.47.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/BACKLOG.md +5 -1
- package/CHANGELOG.md +12 -0
- package/README.md +6 -6
- package/dist/api/activity.d.ts +6 -0
- package/dist/api/activity.js +6 -0
- package/dist/api/commands.d.ts +6 -0
- package/dist/api/commands.js +6 -0
- package/dist/api/delivery.d.ts +6 -0
- package/dist/api/delivery.js +6 -0
- package/dist/api/inbound.d.ts +6 -0
- package/dist/api/inbound.js +6 -0
- package/dist/api/keyboard.d.ts +6 -0
- package/dist/api/keyboard.js +6 -0
- package/dist/api/outbound.d.ts +6 -0
- package/dist/api/outbound.js +6 -0
- package/dist/api/sections.d.ts +7 -0
- package/dist/api/sections.js +6 -0
- package/dist/api/status.d.ts +6 -0
- package/dist/api/status.js +6 -0
- package/dist/api/updates.d.ts +6 -0
- package/dist/api/updates.js +6 -0
- package/dist/api/voice.d.ts +6 -0
- package/dist/api/voice.js +6 -0
- package/dist/index.d.ts +6 -0
- package/dist/index.js +6 -0
- package/dist/lib/activity-verbosity.d.ts +52 -0
- package/dist/lib/activity-verbosity.js +596 -0
- package/dist/lib/activity.d.ts +220 -0
- package/dist/lib/activity.js +574 -0
- package/dist/lib/agent-messages.d.ts +28 -0
- package/dist/lib/agent-messages.js +86 -0
- package/dist/lib/bindings.d.ts +250 -0
- package/dist/lib/bindings.js +936 -0
- package/dist/lib/bus-api.d.ts +18 -0
- package/dist/lib/bus-api.js +254 -0
- package/dist/lib/bus-follower.d.ts +464 -0
- package/dist/lib/bus-follower.js +1686 -0
- package/dist/lib/bus-leader.d.ts +292 -0
- package/dist/lib/bus-leader.js +2242 -0
- package/dist/lib/bus-transport.d.ts +64 -0
- package/dist/lib/bus-transport.js +140 -0
- package/dist/lib/bus.d.ts +518 -0
- package/dist/lib/bus.js +2055 -0
- package/dist/lib/channel-posts.d.ts +170 -0
- package/dist/lib/channel-posts.js +611 -0
- package/dist/lib/command-templates.d.ts +70 -0
- package/dist/lib/command-templates.js +744 -0
- package/dist/lib/commands.d.ts +541 -0
- package/dist/lib/commands.js +1155 -0
- package/dist/lib/config.d.ts +252 -0
- package/dist/lib/config.js +889 -0
- package/dist/lib/delivery.d.ts +163 -0
- package/dist/lib/delivery.js +542 -0
- package/dist/lib/extension.d.ts +7 -0
- package/dist/lib/extension.js +1608 -0
- package/dist/lib/generative-app-worker.mjs +104 -0
- package/dist/lib/generative-apps.d.ts +212 -0
- package/dist/lib/generative-apps.js +1006 -0
- package/dist/lib/inbound.d.ts +91 -0
- package/dist/lib/inbound.js +502 -0
- package/dist/lib/journal.d.ts +665 -0
- package/dist/lib/journal.js +3701 -0
- package/dist/lib/keyboard.d.ts +23 -0
- package/dist/lib/keyboard.js +37 -0
- package/dist/lib/lifecycle.d.ts +157 -0
- package/dist/lib/lifecycle.js +395 -0
- package/dist/lib/locks.d.ts +164 -0
- package/dist/lib/locks.js +1208 -0
- package/dist/lib/logging.d.ts +50 -0
- package/dist/lib/logging.js +274 -0
- package/dist/lib/media.d.ts +181 -0
- package/dist/lib/media.js +602 -0
- package/dist/lib/menu-model.d.ts +217 -0
- package/dist/lib/menu-model.js +663 -0
- package/dist/lib/menu-queue.d.ts +37 -0
- package/dist/lib/menu-queue.js +408 -0
- package/dist/lib/menu-settings.d.ts +116 -0
- package/dist/lib/menu-settings.js +595 -0
- package/dist/lib/menu-status.d.ts +32 -0
- package/dist/lib/menu-status.js +112 -0
- package/dist/lib/menu-thinking.d.ts +29 -0
- package/dist/lib/menu-thinking.js +82 -0
- package/dist/lib/menu.d.ts +171 -0
- package/dist/lib/menu.js +323 -0
- package/dist/lib/model.d.ts +127 -0
- package/dist/lib/model.js +409 -0
- package/dist/lib/outbound-attachments.d.ts +241 -0
- package/dist/lib/outbound-attachments.js +639 -0
- package/dist/lib/outbound-buttons.d.ts +69 -0
- package/dist/lib/outbound-buttons.js +248 -0
- package/dist/lib/outbound-markup.d.ts +42 -0
- package/dist/lib/outbound-markup.js +678 -0
- package/dist/lib/outbound-voice.d.ts +55 -0
- package/dist/lib/outbound-voice.js +152 -0
- package/dist/lib/outbound.d.ts +185 -0
- package/dist/lib/outbound.js +516 -0
- package/dist/lib/ownership.d.ts +77 -0
- package/dist/lib/ownership.js +174 -0
- package/dist/lib/paths.d.ts +40 -0
- package/dist/lib/paths.js +94 -0
- package/dist/lib/pi.d.ts +72 -0
- package/dist/lib/pi.js +121 -0
- package/dist/lib/polling.d.ts +351 -0
- package/dist/lib/polling.js +1196 -0
- package/dist/lib/preview.d.ts +192 -0
- package/dist/lib/preview.js +614 -0
- package/dist/lib/prompt-templates.d.ts +24 -0
- package/dist/lib/prompt-templates.js +118 -0
- package/dist/lib/prompts.d.ts +57 -0
- package/dist/lib/prompts.js +167 -0
- package/dist/lib/queue.d.ts +766 -0
- package/dist/lib/queue.js +1965 -0
- package/dist/lib/recovery.d.ts +86 -0
- package/dist/lib/recovery.js +285 -0
- package/dist/lib/rendering.d.ts +20 -0
- package/dist/lib/rendering.js +983 -0
- package/dist/lib/replies.d.ts +214 -0
- package/dist/lib/replies.js +737 -0
- package/dist/lib/routing.d.ts +207 -0
- package/dist/lib/routing.js +2282 -0
- package/dist/lib/runtime.d.ts +172 -0
- package/dist/lib/runtime.js +402 -0
- package/dist/lib/sections.d.ts +165 -0
- package/dist/lib/sections.js +327 -0
- package/dist/lib/setup.d.ts +82 -0
- package/dist/lib/setup.js +150 -0
- package/dist/lib/skills.d.ts +8 -0
- package/dist/lib/skills.js +12 -0
- package/dist/lib/status.d.ts +442 -0
- package/dist/lib/status.js +1006 -0
- package/dist/lib/sync.d.ts +179 -0
- package/dist/lib/sync.js +782 -0
- package/dist/lib/target.d.ts +20 -0
- package/dist/lib/target.js +27 -0
- package/dist/lib/telegram-api.d.ts +541 -0
- package/dist/lib/telegram-api.js +1159 -0
- package/dist/lib/text-groups.d.ts +89 -0
- package/dist/lib/text-groups.js +317 -0
- package/dist/lib/thread-cleanup-manager.d.ts +288 -0
- package/dist/lib/thread-cleanup-manager.js +560 -0
- package/dist/lib/thread-display.d.ts +46 -0
- package/dist/lib/thread-display.js +257 -0
- package/dist/lib/thread-naming.d.ts +46 -0
- package/dist/lib/thread-naming.js +78 -0
- package/dist/lib/thread-reconciler.d.ts +239 -0
- package/dist/lib/thread-reconciler.js +644 -0
- package/dist/lib/threads.d.ts +621 -0
- package/dist/lib/threads.js +3679 -0
- package/dist/lib/time-injection.d.ts +15 -0
- package/dist/lib/time-injection.js +56 -0
- package/dist/lib/turns.d.ts +109 -0
- package/dist/lib/turns.js +500 -0
- package/dist/lib/updates.d.ts +1290 -0
- package/dist/lib/updates.js +3634 -0
- package/dist/lib/voice.d.ts +117 -0
- package/dist/lib/voice.js +174 -0
- package/dist/lib/workspace-admission.d.ts +264 -0
- package/dist/lib/workspace-admission.js +1136 -0
- package/dist/lib/workspace-retirement.d.ts +219 -0
- package/dist/lib/workspace-retirement.js +587 -0
- package/dist/lib/workspace-slots.d.ts +30 -0
- package/dist/lib/workspace-slots.js +54 -0
- package/dist/package.json +126 -0
- package/dist/pi-telegram/index.js +1 -0
- package/dist/skills/generated-control-surface/SKILL.md +107 -0
- package/dist/skills/generated-control-surface/references/capability-adapters.md +27 -0
- package/dist/skills/generated-control-surface/references/layout-and-state.md +37 -0
- package/dist/skills/generative-apps/SKILL.md +115 -0
- package/dist/skills/show-me/SKILL.md +166 -0
- package/dist/skills/show-me/references/telegram-surfaces.md +43 -0
- package/dist/skills/telegram-bridge/SKILL.md +129 -0
- package/dist/skills/telegram-bridge/references/configuration.md +15 -0
- package/dist/skills/telegram-bridge/references/delivery-and-threads.md +27 -0
- package/dist/skills/telegram-bridge/references/diagnosis.md +18 -0
- package/docs/architecture.md +1 -1
- package/docs/compact-matrix-literal.md +10 -3
- package/docs/generative-apps.md +15 -13
- package/docs/multi-instance-bus.md +17 -3
- package/docs/outbound.md +1 -1
- package/docs/public-api.md +2 -2
- package/lib/bindings.ts +89 -6
- package/lib/bus-follower.ts +11 -3
- package/lib/bus-leader.ts +57 -20
- package/lib/bus.ts +12 -2
- package/lib/commands.ts +2 -2
- package/lib/config.ts +14 -7
- package/lib/delivery.ts +38 -6
- package/lib/extension.ts +26 -1
- package/lib/generative-apps.ts +379 -13
- package/lib/menu-settings.ts +21 -5
- package/lib/outbound-markup.ts +16 -7
- package/lib/pi.ts +4 -0
- package/lib/sync.ts +3 -0
- package/lib/telegram-api.ts +12 -1
- package/lib/thread-cleanup-manager.ts +36 -6
- package/lib/thread-display.ts +96 -18
- package/lib/threads.ts +150 -30
- package/package.json +56 -13
- package/scripts/build-dist.mjs +44 -0
- package/scripts/measure-bus.mjs +8 -1
- package/scripts/measure-workspace.mjs +8 -1
- package/skills/generative-apps/SKILL.md +1 -1
- package/skills/show-me/SKILL.md +1 -1
- package/skills/telegram-bridge/SKILL.md +1 -1
package/BACKLOG.md
CHANGED
|
@@ -2,6 +2,11 @@
|
|
|
2
2
|
|
|
3
3
|
_This file owns unresolved project work only. Completed behavior belongs in `CHANGELOG.md`; durable contracts belong in `AGENTS.md` and `/docs`._
|
|
4
4
|
|
|
5
|
+
- [ ] `Session-aware Thread binding` (`next minor`, primary outcome): Replace profile-scoped exact-`cwd` reuse as the sole Workspace identity with a durable composite of normalized exact `cwd` and Pi's stable public session identity. `/telegram-connect` must persist that session-to-Thread binding so reopening, resuming, or continuing the same Pi session automatically restores the same Telegram Thread and letter slot when the retained binding has not been validly displaced. Different sessions in one directory must receive distinct live slots, while the same session must not allocate a duplicate after process restart. Session number/name are bounded lookup or presentation aliases only, never routing authority. Preserve authenticated live-owner, accepted-work, displacement, retirement, and slot-pressure fences. This is the principal deliverable of the next minor release.
|
|
6
|
+
- [x] `Identity and migration contract`: [`docs/multi-instance-bus.md`](./docs/multi-instance-bus.md#approved-next-contract-session-aware-workspace-identity) now fixes the public session source, composite authority, binding-key derivation, lifecycle semantics, exact legacy `{ cwd, ∅ }` coexistence, fail-closed malformed present identity behavior, mixed-version fence, and non-ownership boundaries.
|
|
7
|
+
- [x] `Store and allocation foundation`: Session-qualified identity, persistence, independent same-cwd claims/slots, strict digest validation, cleanup and retirement snapshots, and exact legacy cwd-only coexistence are locally implemented. The former staged-adoption claim state and commit exceptions have been removed, so no latent mutation path can consume a cwd-only binding. Absence of session identity remains its own key across reload and stale status persistence; same-session restore retains its letter while another session cannot reuse it.
|
|
8
|
+
- [x] `Leader/follower lifecycle wiring`: Leader assembly now reads public `ctx.sessionManager.getSessionId()`, passes it through sync provisioning, and restores the matching session-qualified Workspace without creating a duplicate Thread; cwd-only legacy state remains an independent `{ cwd, ∅ }` identity and is never exposed through a session lookup. Authenticated follower registration now carries a strict bounded session ID over the bus, preserves it in the live registry, and passes it into leader-owned provisioning; fresh same-cwd follower sessions therefore commit distinct session-qualified bindings. Production follower assembly sources the value from the current Pi context, independently of process instance and session generation. Follower-to-leader promotion now resolves the exact current session binding and preserves its target, slot, generated name, and acknowledged display title through leader handoff. Startup restore and `/telegram-connect` share the session-bearing registration envelope and leader provisioner. Protocol v2 makes session identity mandatory for every cwd-scoped participant and rejects protocol-v1 0.45.x peers before provisioning; the supported upgrade path stops all instances, updates them together, then starts a fresh session-native leader. Session-aware stale-target replacement is now regression-covered: replacing session A updates only A's binding and leaves same-cwd session B untouched. Capability rejection is covered independently from the older durable-admission gate. Startup restore eligibility now checks the current session exactly and never treats a legacy cwd-only binding as that session, so neither a sibling nor `{ cwd, ∅ }` can make a fresh session auto-connect. Explicit `/telegram-connect`, restore-only registration, and reconnect handoff all use the same session-bearing registration runtime; focused tests cover restore-only and handoff transmission. The production integration harness now supplies a distinct stable `sessionManager.getSessionId()` per mocked context, and the lifecycle/cleanup integration regression passes with session-aware leader provisioning. Legacy `{ cwd, ∅ }` records remain readable but inert and independent: they are never adopted, migrated, or used for a v2 session. Full-suite closure is green: the bundled Show Me wording is compressed within its disclosure budget, integration contexts preserve one session manager across idle/active phases, and the complete test command passes.
|
|
9
|
+
- [ ] `Compatibility and acceptance` (`local-actionable` plus live gate, current): Exact lookup now treats both presence and absence of session ID symmetrically: `{ cwd, ∅ }` cannot match a session binding, and `{ cwd, session }` cannot match legacy. Focused store, follower, leader, and polling suites pass across coexistence, restore-only, same-session process replacement, follower reload/handoff, distinct same-cwd session allocation (the `/fork`/`/new` identity effect), promotion, session-isolated rename, stale-target replacement, malformed identity, and rolling-upgrade capability behavior. Full slot-pressure retirement now selects the oldest eligible exact binding across legacy and session-qualified identities and persists the victim's session component; protection and exact-intent fences remain unchanged. The Pi adapter now has explicit evidence that restart/reload/resume/continue-recent aliases do not influence authority: only the public stable session ID is read, while a forked ID remains distinct. Local acceptance is complete: generation-fenced stale ownership cannot mutate a replacement; target displacement is exact-session isolated; strict legacy and session-qualified snapshots coexist without aliasing or stale resurrection; protocol-v1 peers are explicitly rejected, while all protocol-v2 cwd participants use session-qualified identity. Update the current-contract docs only with locally validated behavior. Remaining gate: a separately operator-authorized live smoke for same-session restoration and two concurrent sessions in one directory.
|
|
5
10
|
- [ ] `Prompt enqueue hotfix` (`optional`, `operator-gated`): Optional nonblocking operator-authorized disposable-follower smoke: overlap delayed voice processing with turn completion and confirm one-time ordered consumption and truthful counts against the [queue contract](./docs/architecture.md#queue-and-dispatch-safety). Separately authorized supported recovery investigation remains open: prevention does not repair an already-wedged in-memory queue; establish the exact recovery path and preservation/discard consequences before mutation, otherwise report the blocker. No journal/ownership edits, replay of settled input, implicit queue clearing, or restart; live activation requires separate operator authorization.
|
|
6
11
|
- [ ] `Channel multimedia posts` (`0.45.1`, live-acceptance-gated): `telegram_message` channel delivery accepts one local `.jpg`/`.jpeg`/`.png`/`.webp` photo or `.mp4` video, uploads it through the multipart transport as `sendPhoto`/`sendVideo` with `text` as the HTML caption, validates kind and size (photo ≤ 10 MiB, video ≤ 50 MiB) plus ≤ 1024 visible caption characters before issuance, and rejects unsupported types and albums instead of downgrading them to links. The channel-post journal binds kind/file name/byte size/SHA-256 and caption, so duplicate requests and lost acknowledgements never re-upload; media-post edits replace the caption through `editMessageCaption`, and Markdown spoilers render as `<tg-spoiler>`. Live image publication passed on `@llb_log`. Regressions cover confirmed publication, duplicate requests, lost ACK, pre-issuance rejection, caption edits, and reconnect replacement. Remaining: operator-authorized disposable-channel acceptance of rejected upload, duplicate request, and caption edit.
|
|
7
12
|
- [ ] `Manual Thread naming` (`gated-but-preparable`, release priority): Local bot-owned `/name Name` and bare `/name` flows avoid model dispatch. One expiring exact-target input dialog immediately accepts the next valid name, always offers cancel, and offers **Reset to automatic** only while a manual override exists; duplicate/stale callbacks cannot repeat mutation. Durable manual override supersedes every automatic display mode, reset is leader/follower generation- and target-fenced, and Letters remains the default without rewriting recovery identity. Local review findings are remediated, including Bot-API-wait target-replacement regressions for leader/follower rename and reset. Remaining: disposable live acceptance for command-menu ordering, dialog, invalid input, duplicate callbacks, leader/follower rename and reset.
|
|
@@ -32,5 +37,4 @@ _This file owns unresolved project work only. Completed behavior belongs in `CHA
|
|
|
32
37
|
- [ ] Harden the implemented pre-queue `app::method` / strict-JSON bound-action route with revision capture for agent-mediated initial surfaces, profile/target authority, follower transport evidence, voice output delivery, and commit-unknown diagnostics while preserving generation-plus-revision stale-click rejection, fail-closed malformed/absent methods, ordinary model prompts, and native single-colon callbacks.
|
|
33
38
|
- [ ] Harden the implemented cross-process transition lock, dead-owner recovery, expected-generation/revision comparison, repaired partial-tail/current-state recovery, transactional `init` reset, and output-only methods with process-birth proof, bounded lock diagnostics, more interruption points, and explicit commit-unknown evidence.
|
|
34
39
|
- [ ] Complete the capability-owned Music Player adapter evidence beyond the successful real `ffplay` singleton install and no-model-turn bound `next`, `pause`, resume/`play`, and terminal `stop` Controls: exercise generated relative-volume controls over arbitrary absolute Actor percentages, `toggle`, `previous`, `status`, compatible singleton reuse, checkpoint restart, missing/terminal Run, unavailable backend, process timeout/cancellation/stream bounds, and redacted errors while keeping actor reality authoritative and rejecting generic remote-terminal methods.
|
|
35
|
-
- [ ] Extend the implemented new-message default plus opt-in `viewMode: "edit"` bound-action update into optional output-only `refresh` scheduling from `refreshAfterMs`, clamped to at least two seconds and serialized after prior completion; retain one latest logical view handle per app/profile/target, skip unchanged frame digests, honor Telegram retry/backoff, cancel on lifecycle replacement, stop and forget the handle on known deletion or message-not-found, and never recreate a deleted live view without a fresh user action.
|
|
36
40
|
- [ ] Cover CML and JSON equivalence, both mutually exclusive Tool shapes, direct agent-authored app discovery, install/copy and existing-app `init`, scalar/object/no-argument methods, agent-side diagnostic invocation, bounded CLI adaptation, refresh coalescing/rate limits/backoff/deletion, identity/path traversal, duplicate/overlapping prefixes, state recovery, handler failure, stale clicks, session replacement, follower routing, and the invariant that bound actions perform no model turn. `tests/generative-apps.test.ts` now covers scalar/object/no-argument argument shapes, throwing-method failure containment (state and journal untouched), and bounded argument/output/state/module limits before durable mutation; the remaining items stay open.
|
package/CHANGELOG.md
CHANGED
|
@@ -4,6 +4,18 @@
|
|
|
4
4
|
|
|
5
5
|
## Unreleased
|
|
6
6
|
|
|
7
|
+
## 0.47.0: Built runtime and live surfaces
|
|
8
|
+
|
|
9
|
+
- `Startup`: npm installs now load a compiled JavaScript extension from a nested `dist/pi-telegram` entrypoint while source checkouts retain `index.ts`. Stable public subpath exports ship compiled JavaScript plus declarations, packaged Skills follow the distributive root, and validation checks the built extension import.
|
|
10
|
+
- `Button authoring`: Native `telegram_button` fences now accept adjacent top-level JSON/CML objects without an outer array or commas as vertical singleton rows. Explicit outer matrices remain equivalent, nested arrays still own horizontal layout, and malformed sequences activate no controls.
|
|
11
|
+
- `Activity`: Native typing remains continuously re-armed during agent/message work, pauses only for local UI prompts, resumes for unsettled agent or compaction work, and retargets queued turns without leaking keepalive ticks across Threads; transport and session fences still suppress stale actions.
|
|
12
|
+
- `Live views`: Validated `refreshAfterMs` drives non-overlapping timers after hinted `telegram_bind` delivery. Refreshes and current-surface actions edit one generation-fenced Delivery handle through the Markdown/button planner across classic, leader, and follower targets; hints reschedule and omission closes. Retryable failures retain one frame; unavailable messages invalidate with a bounded diagnostic. Take, shutdown, and replacement fence late refreshes and cancel memory-only surfaces.
|
|
13
|
+
- `Thread display`: Adds explicit `directory-snake` and `directory-title` profile modes with shared Unicode-aware path tokenization, uppercase-abbreviation preservation, live Settings previews, initial/reconciled title projection, and negotiated peer capability fencing. Their slot suffixes now follow authenticated concurrent live same-directory ownership and disappear after disconnect or confirmed-dead pruning; dormant bindings and sticky legacy metadata are ignored. Retained `directories` stays unchanged.
|
|
14
|
+
|
|
15
|
+
## 0.46.0: Session-aware Workspace Threads
|
|
16
|
+
|
|
17
|
+
- `Session-aware Thread binding`: Workspace identity restored session-qualified bindings from Pi's stable public session identity, so reopening, resuming, or replacing a process reclaims the same Telegram Thread and letter while distinct sessions in one directory keep independent targets. Strict legacy cwd-only records remain inert and coexist safely; protocol v2 rejects mixed 0.45.x peers before provisioning, and exact-session cleanup, displacement, rename, promotion, and slot-pressure fences are preserved.
|
|
18
|
+
|
|
7
19
|
## 0.45.11: Consumer-owned companion semantics
|
|
8
20
|
|
|
9
21
|
- `Extension boundaries`: Removes consumer-specific state-scope emoji from the Telegram UI registry. The bridge continues to own generic Rich Message headings and inspection semantics, while companion extensions independently own their domain labels, composition rules, and presentation through the public section API.
|
package/README.md
CHANGED
|
@@ -6,7 +6,7 @@
|
|
|
6
6
|
|
|
7
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
|
-
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.
|
|
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. In Threaded Mode, a durable Workspace binding uses Pi's stable public session identity to restore the same Telegram Thread when that session resumes; live instance ownership and the exact Telegram target still authorize routing. The bridge preserves Pi session semantics instead of pretending Telegram is a PTY, shell, process launcher, or session browser. That boundary is the product: Telegram gets safe runtime handles, not raw terminal power.
|
|
10
10
|
|
|
11
11
|
Every completed intermediate commentary block from a Telegram-originated turn is delivered once as its own message before the existing final reply. While Telegram is connected, local, autonomous, and unclassified extension follow-up work also projects visible checkpoints and the final answer to the authorized Telegram target once and in order, preserving assistant-authored `telegram_button` comments as interactive prompt buttons. This connected companion projection is always active rather than configurable. Neither path mirrors local prompts, thinking, tool traffic, token deltas, or stale-generation work. The separate `Activity` setting defaults to `verbose` so new installations discover collapsed provider-exposed thinking and tool evidence immediately; operators can narrow it to one class or choose `quiet`. See [Outbound](docs/outbound.md#public-assistant-output) and the [configuration reference](docs/public-api.md#configuration-api).
|
|
12
12
|
|
|
@@ -55,7 +55,7 @@ Paste the bot token. If `~/.pi/agent/telegram.json` already contains a saved tok
|
|
|
55
55
|
/telegram-connect
|
|
56
56
|
```
|
|
57
57
|
|
|
58
|
-
The connected Pi instance owns Telegram polling. Use `/telegram-connect <profile>` to activate a named profile, and optionally append `as=Name` to name a fresh Workspace Thread. Each profile is a parallel bot runtime with isolated polling, diagnostics, Threaded Mode state, and local bus transport; the `default` profile keeps unsuffixed runtime paths. In classic mode each profile uses a singleton lock. When Telegram private-chat Threaded Mode is available, one live instance becomes the profile's leader and later visible Pi instances register as followers.
|
|
58
|
+
The connected Pi instance owns Telegram polling. Use `/telegram-connect <profile>` to activate a named profile, and optionally append `as=Name` to name a fresh Workspace Thread. Each profile is a parallel bot runtime with isolated polling, diagnostics, Threaded Mode state, and local bus transport; the `default` profile keeps unsuffixed runtime paths. In classic mode each profile uses a singleton lock. When Telegram private-chat Threaded Mode is available, one live instance becomes the profile's leader and later visible Pi instances register as followers. Reopening or resuming the same Pi session restores its remembered Thread at session startup; a distinct session in the same directory has its own binding and still requires explicit `/telegram-connect` when no remembered binding exists.
|
|
59
59
|
|
|
60
60
|
After an unclean computer shutdown, `/telegram-connect` detects truncated or structurally invalid temporary ownership/routing files, quarantines only the damaged files under `tmp/telegram/recovery/`, and retries once. A journal snapshot removed by older broad temp cleanup is rebuilt when its complete segment history proves an empty result, while a revisionless snapshot is repaired from the first surviving segment's exact predecessor when the reconstructed tail validates. Otherwise the snapshot and segments are quarantined as recovery evidence, a fresh journal is published, and startup continues with an informational diagnostic instead of requiring manual JSON repair. Unsupported journal versions block recovery without rewriting or quarantining the retained files; use a compatible runtime rather than deleting journals. Saved `telegram.json` configuration and runtime diagnostics remain intact. Recovery never replaces a verifiable live owner; if safe automatic recovery cannot complete, the command gives one explicit Pi-restart instruction instead of requiring deletion of the whole `tmp/` directory.
|
|
61
61
|
|
|
@@ -226,7 +226,7 @@ Voice notes, audio, images, PDFs, and other media can pass through configured in
|
|
|
226
226
|
|
|
227
227
|
### Buttons And Callbacks
|
|
228
228
|
|
|
229
|
-
Assistant replies can place controls between paragraphs using standalone triple-backtick `telegram_button` blocks, or keep them in the footer using top-level hidden `telegram_button` comments. Both wrappers accept singleton cells and mixed JSON/CML matrices. Native in-body rows allow up to eight buttons; HTML compatibility moves these rows to the footer. In-body clicks acknowledge without recoloring the Rich body, while footer selection styles remain unchanged. Hidden comments accept a JSON object, adaptive JSON/CML matrix, or positional Compact Matrix Literal (CML). One adaptive matrix may mix named JSON objects with positional CML cells; separators are optional and one trailing comma is tolerated, including inside JSON objects. Top-level cells become full-width rows while nested rows group one or more buttons horizontally without an artificial parser-level width cap;
|
|
229
|
+
Assistant replies can place controls between paragraphs using standalone triple-backtick `telegram_button` blocks, or keep them in the footer using top-level hidden `telegram_button` comments. Both wrappers accept singleton cells and mixed JSON/CML matrices. Native in-body rows allow up to eight buttons; HTML compatibility moves these rows to the footer. In-body clicks acknowledge without recoloring the Rich body, while footer selection styles remain unchanged. Hidden comments accept a JSON object, adaptive JSON/CML matrix, or positional Compact Matrix Literal (CML). One adaptive matrix may mix named JSON objects with positional CML cells; separators are optional and one trailing comma is tolerated, including inside JSON objects. Top-level cells become full-width rows while nested rows group one or more buttons horizontally without an artificial parser-level width cap; inside a fenced block, adjacent top-level JSON/CML objects may omit the outer array and commas. Generated surfaces default to five columns and use six to eight only for short position-bearing labels. CML uses `{value}`, `{label|prompt}`, `{|prompt}`, or the corresponding three-atom form with `selected_style` set to `primary`, `success`, or `danger`; omitting the first atom leaves the existing prompt-as-label fallback in charge, while the optional style still requires a non-empty prompt. A fourth atom adds disabled state: `{|Next||1}` or `{|Next||true}` disables, `0` or `false` enables (exact lowercase), and omission stays enabled; the third atom may be empty in this form. JSON uses boolean `disabled`. Disabled controls require no prompt or selected style: `{Next|||1}` shows only a label, while `{|||1}` is a blank disabled cell. Disabled controls remain visible without registering callbacks or invoking prompts/app methods. It trims atom boundaries, preserves non-structural text literally, and decodes only `\|`, `\}`, and `\\`. Prefer one matrix comment for multiple buttons. Buttons use `label` plus `prompt`, or the compact `value` key when both are identical. The bridge strips every assistant-authored HTML comment from Telegram previews and final replies regardless of Markdown position or owning extension, while only recognized top-level comments activate buttons or voice; comment-only output sends no text message and the Pi terminal transcript remains unchanged. It renders valid inline buttons and routes callbacks back into Pi as queued prompts or extension-owned callback actions. Button-only replies receive the standard `☑️ **Choose an option:**` heading as automatic visible fallback text. Once a generated prompt button is accepted, only that exact button switches to its optional `selected_style` (`primary` blue by default, `success` green, or `danger` red) without altering its agent-authored label or emoji; every style still queues the selected prompt.
|
|
230
230
|
|
|
231
231
|
### Threaded Mode And Multi-Instance Bus
|
|
232
232
|
|
|
@@ -236,16 +236,16 @@ Classic private DM mode is the base product mode. When Telegram private-chat Thr
|
|
|
236
236
|
- Followers are visible Pi processes started by the operator.
|
|
237
237
|
- Each connected instance gets a Telegram thread target.
|
|
238
238
|
- Queued work for a live follower transfers through authenticated exact-journal handoff rather than replaying under the transport owner.
|
|
239
|
-
-
|
|
239
|
+
- Reopening, resuming, or replacing the process for the same Pi session restores its remembered Thread; distinct sessions in one directory keep independent bindings and letter slots.
|
|
240
240
|
- Unknown threads are preserved and offered explicit reroute/restore choices.
|
|
241
241
|
- Telegram never launches hidden Pi processes.
|
|
242
242
|
|
|
243
|
-
In Threaded Mode, open Settings → **🧵 Thread display** to choose **Letters** (default), **Names**, or **
|
|
243
|
+
In Threaded Mode, open Settings → **🧵 Thread display** to choose **Letters** (default), **Names**, **directory-snake**, or **directory-title** for this bot profile; a retained **directories** value remains available as an unchanged legacy presentation. The Settings detail shows a bounded live preview computed from current Workspace bindings. Fresh tabs are created with the active mode's title instead of being visibly renamed afterward. Telegram tab titles, Pi terminal status, live Thread choosers/notices, prompt attribution, and named `telegram_message` targeting use the same acknowledged display name; target IDs and live registrations still own routing. Names shows the generated dictionary name chosen for the slot, such as `Anchor` for slot `A`; the directory formats produce `api_tools` or `Api Tools` and append `_a` or ` · A` only while two or more authenticated live instances share that exact directory. Dormant retained bindings do not keep those suffixes visible. `/name` sets a manual Thread display name; **Reset to automatic** restores the selected automatic projection. Switching preserves Thread IDs, slots, generated recovery identity, and queue ownership. Partial application reports an error and can be retried without recreating Threads.
|
|
244
244
|
|
|
245
245
|
| Mode | Best for | Runtime shape |
|
|
246
246
|
| --- | --- | --- |
|
|
247
247
|
| Classic DM | One running Pi instance and its active session controlled from one private bot chat | One polling owner, one queue/runtime surface |
|
|
248
|
-
| Threaded Mode | Several visible Pi
|
|
248
|
+
| Threaded Mode | Several visible Pi sessions sharing one bot | One leader owns transport; each private-chat Thread retains one session-qualified Workspace binding |
|
|
249
249
|
|
|
250
250
|
## Environment Configuration
|
|
251
251
|
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Public Telegram activity API
|
|
3
|
+
* Zones: package boundary, pi agent lifecycle, extension interop
|
|
4
|
+
* Exposes normalized non-blocking activity registration while keeping lifecycle wiring and dispatch internals package-private
|
|
5
|
+
*/
|
|
6
|
+
export { registerTelegramActivityHandler, type TelegramActivityContext, type TelegramActivityEnvelope, type TelegramActivityEvent, type TelegramActivityHandlerRegistration, type TelegramActivitySource, type TelegramActivityTarget, } from "../lib/activity.ts";
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Public Telegram activity API
|
|
3
|
+
* Zones: package boundary, pi agent lifecycle, extension interop
|
|
4
|
+
* Exposes normalized non-blocking activity registration while keeping lifecycle wiring and dispatch internals package-private
|
|
5
|
+
*/
|
|
6
|
+
export { registerTelegramActivityHandler, } from "../lib/activity.js";
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Public Telegram commands API
|
|
3
|
+
* Zones: package boundary, extension interop
|
|
4
|
+
* Exposes the stable Telegram slash-command registration surface while keeping registry internals package-private
|
|
5
|
+
*/
|
|
6
|
+
export { registerTelegramCommand, type TelegramExtensionCommandContext, type TelegramExtensionCommandRegistration, } from "../lib/commands.ts";
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Public Telegram delivery API
|
|
3
|
+
* Zones: package boundary, telegram delivery, extension interop
|
|
4
|
+
* Exposes target-aware operational view delivery while keeping transport and runtime binding internals package-private
|
|
5
|
+
*/
|
|
6
|
+
export { deleteTelegramView, editTelegramView, sendTelegramChatAction, sendTelegramView, type SendTelegramViewOptions, type TelegramDeliveryChatAction, type TelegramDeliveryFailureReason, type TelegramDeliveryHandle, type TelegramDeliveryParseMode, type TelegramDeliveryResult, type TelegramDeliveryScope, type TelegramDeliveryTarget, type TelegramDeliveryView, } from "../lib/delivery.ts";
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Public Telegram delivery API
|
|
3
|
+
* Zones: package boundary, telegram delivery, extension interop
|
|
4
|
+
* Exposes target-aware operational view delivery while keeping transport and runtime binding internals package-private
|
|
5
|
+
*/
|
|
6
|
+
export { deleteTelegramView, editTelegramView, sendTelegramChatAction, sendTelegramView, } from "../lib/delivery.js";
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Public Telegram inbound API
|
|
3
|
+
* Zones: package boundary, extension interop
|
|
4
|
+
* Exposes the stable programmatic inbound handler surface while keeping handler runtime internals package-private
|
|
5
|
+
*/
|
|
6
|
+
export { registerTelegramInboundHandler, type TelegramInboundHandlerFile, type TelegramInboundHandlerOutput, type TelegramInboundProgrammaticHandler, type TelegramInboundProgrammaticHandlerInput, type TelegramInboundProgrammaticHandlerResult, } from "../lib/inbound.ts";
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Public Telegram inbound API
|
|
3
|
+
* Zones: package boundary, extension interop
|
|
4
|
+
* Exposes the stable programmatic inbound handler surface while keeping handler runtime internals package-private
|
|
5
|
+
*/
|
|
6
|
+
export { registerTelegramInboundHandler, } from "../lib/inbound.js";
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Public Telegram keyboard API
|
|
3
|
+
* Zones: package boundary, extension interop
|
|
4
|
+
* Exposes shared inline-keyboard structural types without runtime exports
|
|
5
|
+
*/
|
|
6
|
+
export type { TelegramInlineKeyboardButton, TelegramInlineKeyboardButtonStyle, TelegramInlineKeyboardMarkup, } from "../lib/keyboard.ts";
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Public Telegram outbound API
|
|
3
|
+
* Zones: package boundary, extension interop
|
|
4
|
+
* Exposes stable outbound handler and diagnostics surfaces while keeping delivery internals package-private
|
|
5
|
+
*/
|
|
6
|
+
export { recordTelegramRuntimeEvent, registerTelegramOutboundHandler, type TelegramOutboundProgrammaticHandler, } from "../lib/outbound.ts";
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Public Telegram outbound API
|
|
3
|
+
* Zones: package boundary, extension interop
|
|
4
|
+
* Exposes stable outbound handler and diagnostics surfaces while keeping delivery internals package-private
|
|
5
|
+
*/
|
|
6
|
+
export { recordTelegramRuntimeEvent, registerTelegramOutboundHandler, } from "../lib/outbound.js";
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Public Telegram sections API
|
|
3
|
+
* Zones: package boundary, extension interop
|
|
4
|
+
* Exposes the stable managed Telegram menu-section surface while keeping registry internals package-private
|
|
5
|
+
*/
|
|
6
|
+
export type { TelegramInputRichBlock, TelegramInputRichMessage, TelegramRichText } from "../lib/telegram-api.ts";
|
|
7
|
+
export { getTelegramSectionDiagnostics, registerTelegramSection, type TelegramSectionCallbackContext, type TelegramSectionCallbackResult, type TelegramSectionContext, type TelegramSectionDiagnostic, type TelegramSectionRegistration, type TelegramSectionSettingsRegistration, type TelegramSectionView, } from "../lib/sections.ts";
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Public Telegram sections API
|
|
3
|
+
* Zones: package boundary, extension interop
|
|
4
|
+
* Exposes the stable managed Telegram menu-section surface while keeping registry internals package-private
|
|
5
|
+
*/
|
|
6
|
+
export { getTelegramSectionDiagnostics, registerTelegramSection, } from "../lib/sections.js";
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Public Telegram status API
|
|
3
|
+
* Zones: package boundary, extension interop
|
|
4
|
+
* Exposes compact status-menu line registration for extension consumers while keeping status rendering internals package-private
|
|
5
|
+
*/
|
|
6
|
+
export { registerTelegramStatusLineProvider, type TelegramStatusLineProvider, type TelegramStatusLineProviderContext, type TelegramStatusLineProviderResult, } from "../lib/status.ts";
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Public Telegram status API
|
|
3
|
+
* Zones: package boundary, extension interop
|
|
4
|
+
* Exposes compact status-menu line registration for extension consumers while keeping status rendering internals package-private
|
|
5
|
+
*/
|
|
6
|
+
export { registerTelegramStatusLineProvider, } from "../lib/status.js";
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Public Telegram updates API
|
|
3
|
+
* Zones: package boundary, extension interop
|
|
4
|
+
* Exposes the stable raw-update handler surface while keeping update routing internals package-private
|
|
5
|
+
*/
|
|
6
|
+
export { assertTelegramUpdateExecutionCurrent, carryTelegramUpdateExecutionFence, createTelegramUpdateExecutionFenceGuard, getTelegramUpdateExecutionFence, registerTelegramUpdateHandler, type TelegramUpdateExecutionFence, type TelegramUpdateHandler, type TelegramUpdateHandlerVerdict, } from "../lib/updates.ts";
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Public Telegram updates API
|
|
3
|
+
* Zones: package boundary, extension interop
|
|
4
|
+
* Exposes the stable raw-update handler surface while keeping update routing internals package-private
|
|
5
|
+
*/
|
|
6
|
+
export { assertTelegramUpdateExecutionCurrent, carryTelegramUpdateExecutionFence, createTelegramUpdateExecutionFenceGuard, getTelegramUpdateExecutionFence, registerTelegramUpdateHandler, } from "../lib/updates.js";
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Public Telegram voice API
|
|
3
|
+
* Zones: package boundary, extension interop
|
|
4
|
+
* Exposes the stable STT/TTS provider surface and voice policy helpers
|
|
5
|
+
*/
|
|
6
|
+
export { TELEGRAM_VOICE_REPLY_MODES, computeVoicePromptContribution, computeVoiceTurnFlags, getTelegramVoiceReplyMode, isVoiceTurn, registerTelegramVoiceSynthesisProvider, registerTelegramVoiceTranscriptionProvider, shouldSuppressPreviewForVoice, type TelegramVoiceReplyMode, type TelegramVoiceSynthesisProvider, type TelegramVoiceSynthesisProviderResult, type TelegramVoiceTranscriptionFile, type TelegramVoiceTranscriptionProvider, type TelegramVoiceTranscriptionProviderResult, type TelegramVoiceTurnView, } from "../lib/voice.ts";
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Public Telegram voice API
|
|
3
|
+
* Zones: package boundary, extension interop
|
|
4
|
+
* Exposes the stable STT/TTS provider surface and voice policy helpers
|
|
5
|
+
*/
|
|
6
|
+
export { TELEGRAM_VOICE_REPLY_MODES, computeVoicePromptContribution, computeVoiceTurnFlags, getTelegramVoiceReplyMode, isVoiceTurn, registerTelegramVoiceSynthesisProvider, registerTelegramVoiceTranscriptionProvider, shouldSuppressPreviewForVoice, } from "../lib/voice.js";
|
package/dist/index.d.ts
ADDED
package/dist/index.js
ADDED
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Bridge-owned Telegram activity verbosity projection
|
|
3
|
+
* Zones: telegram activity, rich rendering, operational delivery
|
|
4
|
+
* Owns persistent bounded thinking and tool disclosures; excludes activity normalization, assistant answer rendering, and transport authority policy
|
|
5
|
+
*/
|
|
6
|
+
import type { TelegramActivityEvent, TelegramActivityPublicationRuntime } from "./activity.ts";
|
|
7
|
+
import type { TelegramEditMessageTextBody, TelegramInputRichMessage, TelegramSendMessageBody, TelegramSendRichMessageBody, TelegramSentMessage } from "./telegram-api.ts";
|
|
8
|
+
import type { TelegramTarget } from "./target.ts";
|
|
9
|
+
export declare const TELEGRAM_ACTIVITY_DETAIL_MAX_CHARS = 1200;
|
|
10
|
+
export declare const TELEGRAM_ACTIVITY_MESSAGE_MAX_CHARS = 3900;
|
|
11
|
+
export declare const TELEGRAM_ACTIVITY_MESSAGE_MAX_TOOLS = 6;
|
|
12
|
+
export declare const TELEGRAM_REASONING_MESSAGE_MAX_FRAMES = 24;
|
|
13
|
+
export declare const TELEGRAM_REASONING_BUFFER_MAX_CHARS = 1200;
|
|
14
|
+
export declare const TELEGRAM_REASONING_MIN_INTERVAL_MS = 1200;
|
|
15
|
+
export declare const TELEGRAM_TOOL_UPDATE_MAX_ENTRIES = 4;
|
|
16
|
+
interface ToolActivity {
|
|
17
|
+
id: string;
|
|
18
|
+
name: string;
|
|
19
|
+
args: string;
|
|
20
|
+
updates: string[];
|
|
21
|
+
droppedUpdates: number;
|
|
22
|
+
result?: string;
|
|
23
|
+
isError?: boolean;
|
|
24
|
+
complete: boolean;
|
|
25
|
+
}
|
|
26
|
+
export declare function renderTelegramToolActivityHtml(tools: readonly ToolActivity[]): string;
|
|
27
|
+
export declare function renderTelegramToolActivityRichMessage(tools: readonly ToolActivity[]): TelegramInputRichMessage;
|
|
28
|
+
export declare function renderTelegramThinkingActivityHtml(text: string): string;
|
|
29
|
+
export interface TelegramActivityVerbosityRuntime {
|
|
30
|
+
accept: (event: TelegramActivityEvent) => void;
|
|
31
|
+
reset: () => void;
|
|
32
|
+
stop: () => void;
|
|
33
|
+
waitForIdle: () => Promise<void>;
|
|
34
|
+
}
|
|
35
|
+
export interface TelegramActivityVerbosityBinding extends TelegramActivityVerbosityRuntime {
|
|
36
|
+
bind: (runtime: TelegramActivityVerbosityRuntime) => void;
|
|
37
|
+
}
|
|
38
|
+
export declare function createTelegramActivityVerbosityBinding(): TelegramActivityVerbosityBinding;
|
|
39
|
+
export declare function createTelegramActivityVerbosityRuntime<TAuthority>(deps: {
|
|
40
|
+
enqueue?: TelegramActivityPublicationRuntime["enqueue"];
|
|
41
|
+
getActivityMode: () => "quiet" | "thinking" | "tools" | "verbose";
|
|
42
|
+
refreshActivityMode?: () => Promise<void>;
|
|
43
|
+
getNowMs?: () => number;
|
|
44
|
+
resolveTarget: (event: TelegramActivityEvent) => TelegramTarget | undefined;
|
|
45
|
+
captureAuthority: () => TAuthority;
|
|
46
|
+
isAuthorityActive: (authority: TAuthority) => boolean;
|
|
47
|
+
sendMessage: (body: TelegramSendMessageBody) => Promise<TelegramSentMessage>;
|
|
48
|
+
sendRichMessage: (body: TelegramSendRichMessageBody) => Promise<TelegramSentMessage>;
|
|
49
|
+
editMessageText: (body: TelegramEditMessageTextBody) => Promise<"edited" | "unchanged">;
|
|
50
|
+
recordFailure?: (operation: "config-refresh" | "reasoning-send" | "reasoning-edit" | "tool-send" | "tool-edit", event: TelegramActivityEvent, error: unknown) => void;
|
|
51
|
+
}): TelegramActivityVerbosityRuntime;
|
|
52
|
+
export {};
|