@llblab/pi-kit 0.36.3 → 0.37.1
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/CHANGELOG.md +10 -0
- package/README.md +2 -2
- package/node_modules/@llblab/pi-telegram/AGENTS.md +4 -4
- package/node_modules/@llblab/pi-telegram/BACKLOG.md +9 -11
- package/node_modules/@llblab/pi-telegram/CHANGELOG.md +19 -0
- package/node_modules/@llblab/pi-telegram/dist/lib/bindings.d.ts +2 -1
- package/node_modules/@llblab/pi-telegram/dist/lib/bindings.js +2 -1
- package/node_modules/@llblab/pi-telegram/dist/lib/commands.d.ts +5 -6
- package/node_modules/@llblab/pi-telegram/dist/lib/commands.js +36 -35
- package/node_modules/@llblab/pi-telegram/dist/lib/extension.js +2 -3
- package/node_modules/@llblab/pi-telegram/dist/lib/outbound-buttons.js +20 -18
- package/node_modules/@llblab/pi-telegram/dist/lib/outbound-markup.d.ts +6 -6
- package/node_modules/@llblab/pi-telegram/dist/lib/outbound-markup.js +23 -65
- package/node_modules/@llblab/pi-telegram/dist/lib/outbound.js +3 -3
- package/node_modules/@llblab/pi-telegram/dist/lib/prompts.d.ts +1 -1
- package/node_modules/@llblab/pi-telegram/dist/lib/prompts.js +1 -1
- package/node_modules/@llblab/pi-telegram/dist/lib/runtime.d.ts +1 -0
- package/node_modules/@llblab/pi-telegram/dist/lib/runtime.js +1 -0
- package/node_modules/@llblab/pi-telegram/dist/lib/telegram-api.d.ts +4 -2
- package/node_modules/@llblab/pi-telegram/dist/lib/telegram-api.js +29 -20
- package/node_modules/@llblab/pi-telegram/dist/package.json +1 -1
- package/node_modules/@llblab/pi-telegram/dist/skills/telegram-bridge/SKILL.md +5 -5
- package/node_modules/@llblab/pi-telegram/docs/architecture.md +6 -6
- package/node_modules/@llblab/pi-telegram/docs/compact-matrix-literal.md +1 -1
- package/node_modules/@llblab/pi-telegram/docs/generative-apps.md +1 -1
- package/node_modules/@llblab/pi-telegram/docs/multi-instance-bus.md +1 -1
- package/node_modules/@llblab/pi-telegram/docs/outbound.md +8 -8
- package/node_modules/@llblab/pi-telegram/docs/public-api.md +5 -3
- package/node_modules/@llblab/pi-telegram/lib/bindings.ts +4 -0
- package/node_modules/@llblab/pi-telegram/lib/commands.ts +53 -43
- package/node_modules/@llblab/pi-telegram/lib/extension.ts +1 -3
- package/node_modules/@llblab/pi-telegram/lib/outbound-buttons.ts +17 -15
- package/node_modules/@llblab/pi-telegram/lib/outbound-markup.ts +28 -68
- package/node_modules/@llblab/pi-telegram/lib/outbound.ts +3 -3
- package/node_modules/@llblab/pi-telegram/lib/prompts.ts +1 -1
- package/node_modules/@llblab/pi-telegram/lib/runtime.ts +2 -1
- package/node_modules/@llblab/pi-telegram/lib/telegram-api.ts +31 -18
- package/node_modules/@llblab/pi-telegram/package.json +1 -1
- package/node_modules/@llblab/pi-telegram/skills/telegram-bridge/SKILL.md +5 -5
- package/package.json +2 -2
package/CHANGELOG.md
CHANGED
|
@@ -2,6 +2,16 @@
|
|
|
2
2
|
|
|
3
3
|
All notable changes to `@llblab/pi-kit` are documented here.
|
|
4
4
|
|
|
5
|
+
## 0.37.1: Bundled Package Updates (2026-10-26)
|
|
6
|
+
|
|
7
|
+
- `Exact pins`: `@llblab/pi-telegram` 0.58.1 → 0.58.3.
|
|
8
|
+
- `Packaging`: Synchronizes the lockfile, bundle aliases and README inventory. Package membership and resource order remain unchanged; packed validation does not certify extension safety or installed-client behavior.
|
|
9
|
+
|
|
10
|
+
## 0.37.0: Bundled Package Updates (2026-10-25)
|
|
11
|
+
|
|
12
|
+
- `Exact pins`: `@llblab/pi-telegram` 0.57.11 → 0.58.1.
|
|
13
|
+
- `Packaging`: Synchronizes the lockfile, bundle aliases and README inventory. Package membership and resource order remain unchanged; packed validation does not certify extension safety or installed-client behavior.
|
|
14
|
+
|
|
5
15
|
## 0.36.3: Bundled Package Updates (2026-10-24)
|
|
6
16
|
|
|
7
17
|
- `Exact pins`: `@llblab/pi-telegram` 0.57.7 → 0.57.11.
|
package/README.md
CHANGED
|
@@ -18,7 +18,7 @@ Package links lead to the owning repositories for usage, documentation, issues,
|
|
|
18
18
|
| [`@llblab/pi-codex-usage`](https://github.com/llblab/pi-codex-usage) | `0.13.2` | OpenAI/legacy Codex subscription quota and Business credit status, with persistent priority Fast toggle mirrored in Telegram |
|
|
19
19
|
| [`@llblab/pi-grow-loop`](https://github.com/llblab/pi-grow-loop) | `0.9.0` | Visible continuation scheduling and bounded worker Skills through compiled, manifest-owned resources |
|
|
20
20
|
| [`@llblab/pi-state-flow`](https://github.com/llblab/pi-state-flow) | `0.26.5` | Scoped context/memory compiler with step-independent current memory, stable Passive/Active modes and visible blocked-state status |
|
|
21
|
-
| [`@llblab/pi-telegram`](https://github.com/llblab/pi-telegram) | `0.
|
|
21
|
+
| [`@llblab/pi-telegram`](https://github.com/llblab/pi-telegram) | `0.58.3` | Telegram companion with per-prompt Steer, queued controls, Reroute/Restore, recoverable connections, previews, follower Threads, files, and voice |
|
|
22
22
|
| [`@llblab/skills`](https://github.com/llblab/skills) | `1.15.0` | Portable workflows for engineering, review, design, context maintenance, and other focused tasks |
|
|
23
23
|
|
|
24
24
|
Versions are exact by design. An upstream release does not change an installed kit until this repository explicitly advances the dependency and publishes a new kit version. Runtime defects and package-specific feature requests belong in the linked repository; package selection and kit installation issues belong here.
|
|
@@ -27,7 +27,7 @@ Versions are exact by design. An upstream release does not change an installed k
|
|
|
27
27
|
|
|
28
28
|
Requires **Pi 1.0.0+** and **Node.js 22.19.0+**. State Flow requires its canonical checkpoint/tail storage format and does not convert unsupported stores in place. Preserve existing stores and consult the [owning package's storage guidance](https://github.com/llblab/pi-state-flow/blob/v0.26.5/docs/usage.md#moving-a-store-and-supported-formats) before changing installations.
|
|
29
29
|
|
|
30
|
-
From
|
|
30
|
+
From NPM:
|
|
31
31
|
|
|
32
32
|
```bash
|
|
33
33
|
pi install npm:@llblab/pi-kit
|
|
@@ -107,9 +107,9 @@ Use the relevant local skill before non-trivial work in its domain. Keep skill o
|
|
|
107
107
|
- A model selection from an authorized Telegram target may stop and continue any interruptible active agent run in that same Pi session, including local/TUI work. Queue the synthetic control-lane continuation before aborting; when no Telegram prompt owns the run, bind continuation and reply ownership to the exact model-menu chat/Thread/message. Delay abort until every active tool execution settles, and clear both selection and fallback target on cancellation, agent start, settlement, or session replacement.
|
|
108
108
|
- Telegram extension side effects must not hold Pi's core lifecycle hostage after semantic completion. Preserve ordering in extension-owned background work, record failures, and fence target/profile/transport/session authority.
|
|
109
109
|
- In Threaded Mode, All is service/input-only. New output, previews, typing and routing UI require a concrete Thread; neither implicit fallback nor explicit aggregate delivery may write to All. Unavailable routing authority retains input without an All notice or silent settlement. Classic DM and explicit channel/business destinations remain separate; historical All output is not auto-cleaned.
|
|
110
|
-
- Complete assistant/guest model answers use Telegram-native Rich Markdown. Harness-owned menus, status, diagnostics, thinking, and tool evidence remain explicit HTML/plain or their documented native surface. Before Telegram preview or final delivery, strip every assistant-authored HTML comment regardless of Markdown position
|
|
110
|
+
- Complete assistant/guest model answers use Telegram-native Rich Markdown. Harness-owned menus, status, diagnostics, thinking, and tool evidence remain explicit HTML/plain or their documented native surface. Before Telegram preview or final delivery, strip every assistant-authored HTML comment regardless of Markdown position and recognize complete action comments by their delimiters and payload, independent of surrounding Markdown; a comment-only result sends no text message. Preserve literal code outside comments and structurally safe chunking; never split invalid markup.
|
|
111
111
|
- `preview` owns streaming lifecycle only, not assistant rendering. Finalization waits for the captured generation's preceding preview work, never later drafts blocked by that publication, and must not issue pre/post-final draft-clear calls that create transient Telegram draft UI. Reset/invalidation detaches predecessor dependencies; late settlements cannot mutate replacement state. Turns that already answer as one atomic reply (voice replies, Guest Mode queries) never stream previews.
|
|
112
|
-
- Native `sendChatAction(typing)` is the automatic activity signal for unsettled agent and compaction work while Telegram transport is authorized. Extension-owned blocking UI prompts pause it and completion resumes it while either work owner remains active. Compaction may stop only a typing loop it actually started; it must preserve a pre-existing agent-owned loop. Refresh only the assigned Thread on a conservative three-second cadence; do not mirror typing to aggregate `All` and multiply shared-chat flood pressure. Typing is best-effort presence only, never a Thread-existence or message-delivery probe: a failed exact-target action remains a structured diagnostic and must not replace a healthy connected/leader/follower status with `error`. Do not invent extra in-chat work indicators or emit activity for startup/connect/reload/recovery alone.
|
|
112
|
+
- Native `sendChatAction(typing)` is the automatic activity signal for unsettled agent and compaction work while Telegram transport is authorized. Extension-owned blocking UI prompts pause it and completion resumes it while either work owner remains active. Compaction may stop only a typing loop it actually started; it must preserve a pre-existing agent-owned loop. Refresh only the assigned Thread on a conservative three-second cadence; do not mirror typing to aggregate `All` and multiply shared-chat flood pressure. One Thread's pending action must not suppress another Thread's activity. Typing is best-effort presence only, never a Thread-existence or message-delivery probe: a failed exact-target action remains a structured diagnostic and must not replace a healthy connected/leader/follower status with `error`. Do not invent extra in-chat work indicators or emit activity for startup/connect/reload/recovery alone.
|
|
113
113
|
- Public activity handlers and connected companion delivery are asynchronous, target-bound, generation-fenced surfaces. Connected companion projection has no independent opt-out: disconnect or authority loss is its boundary. Token deltas, hidden reasoning, unknown sources, and stale authority never enter public projection.
|
|
114
114
|
- Profiles hold only bot identity and the paired owner; Settings-menu preferences live in shared top-level config. Thread display (`threads.displayMode`) defaults to the Letters strategy, with Names, Directory Snake, and Directory Title as the other automatic choices; Names projects the generated dictionary name for the slot. Unsupported retained display keys resolve to Letters without rewriting persisted configuration. A durable manual Thread display name retained on its Workspace binding overrides any automatic projection until exact reset; keep generated/recovery identity separate from manual and acknowledged display fields. After leader startup, automatic display contraction waits one follower-staleness window so election and follower re-registration cannot briefly remove and restore an acknowledged same-cwd suffix; stop/start generation cancels stale reconciliation. UI labels, emoji semantics, navigation, settings controls, callback namespaces, voice behavior, command templates, and assistant markup follow the linked `/docs` contracts. Generated human-readable action labels use `emoji + space + text`; emoji-free action text is only a reasoned no-semantic-marker fallback. State/value controls follow the [button control hierarchy](./docs/ui-style.md#button-control-hierarchy), not the action-label grammar. Non-spatial generated controls default to top-level vertical cells, with nested rows reserved for unmistakably compact peers. Do not restate other evolving UI details here.
|
|
115
115
|
|
|
@@ -134,7 +134,7 @@ The detailed map is canonical in [`docs/architecture.md`](./docs/architecture.md
|
|
|
134
134
|
- Command templates remain compact and shell-free. Use string leaves or ordered `template` arrays; shell operators are not an execution contract. Examples use portable executable placeholders, never machine-local paths.
|
|
135
135
|
- `telegram_attach` is the canonical file path and `telegram_message` the direct Markdown text/buttons path. Both require current direct or registered-follower authority and must not replace the normal active-turn reply.
|
|
136
136
|
- Inbound handlers transform text/media before queueing; outbound handlers precede programmatic/provider fallbacks. Public contracts and ordering live in `docs/inbound.md`, `docs/outbound.md`, and `docs/public-api.md`.
|
|
137
|
-
- Pi integration uses public hooks and APIs. Telegram `/new` is scheduled against the exact durable update, dispatched only after that update is removed from the journal, and then routed through the
|
|
137
|
+
- Pi integration uses public hooks and APIs. Telegram `/new` is scheduled against the exact durable update, dispatched only after that update is removed from the journal, and then routed through the `/telegram-connect --internal new <token>` Pi gateway via `pi.sendUserMessage(..., { expandPromptTemplates: true })`; the internal branch never enters profile activation or connection/recovery, only a runtime-armed one-use typed action may execute, manual invocation reports that the action cannot be run manually, and the handler receives the real `ExtensionCommandContext` before calling `ctx.newSession()`. Before replacement, CAS-publish one exact expiring handoff in the profile target snapshot. `workspace-thread` successors re-key the matching Workspace binding; `classic-chat` successors preserve Profile/CWD/session/chat continuity without creating a binding or invoking topic APIs. Both atomically claim the intent before one terminal result, and the old `withSession` path never publishes the same success. A registered follower cannot persist leader-owned state: its Workspace Thread intent is published and claimed by the leader over capability-gated exact-generation bus RPC after leader-side binding validation, and records its source runtime instance so only that follower lineage may re-key or claim it. Never replace the session while inbound authority is unsettled, store stale command contexts, accept an expired or mismatched handoff, inject terminal input, spawn a shadow Pi process, or mutate session files.
|
|
138
138
|
|
|
139
139
|
## 7. Engineering Conventions
|
|
140
140
|
|
|
@@ -145,7 +145,7 @@ The detailed map is canonical in [`docs/architecture.md`](./docs/architecture.md
|
|
|
145
145
|
- Treat every meaningful `lib/extension.ts` edit as a composition-pressure check, but keep one-off live adapter wiring there when extraction would only hide cross-domain state.
|
|
146
146
|
- Follow [`docs/ui-style.md`](./docs/ui-style.md) for interface copy, emoji, buttons, menus, and dialogs. Update the registry before assigning a new UI emoji meaning. Standalone notices use one fully bold emoji-led sentence with a terminal period; menu or chooser headings use the same hierarchy with a terminal colon. Material names may add nested italic emphasis without breaking the outer bold span. Callback toasts are fleeting plain text with no emoji and no terminal sentence period (question/exclamation marks and ellipses remain), written in that final form at their call site; no delivery boundary rewrites punctuation, and navigation taps answer silently. In-chat notices and explicit raw API payloads keep their punctuation.
|
|
147
147
|
- Markdown lists never contain blank lines between adjacent items; list items are not paragraphs. Use blank lines only between paragraphs or independently separated blocks. Markdown tables use compact source formatting with `---` separator cells and one surrounding space per cell. Preserve vendored references unchanged.
|
|
148
|
-
- Treat Windows filesystem, named-pipe, lock, heartbeat, and atomic-rename reports as high-signal evidence; reduce them to regressions or explicit platform caveats.
|
|
148
|
+
- Treat Windows filesystem, named-pipe, lock, heartbeat, and atomic-rename reports as high-signal evidence; reduce them to regressions or explicit platform caveats. Process fixtures must distinguish bounded startup from post-readiness natural exit: arm the exit guard only after the declared checkpoint, retain a separate total cap, and ensure extra startup allowance cannot hide retained post-readiness handles.
|
|
149
149
|
- Route significant runtime failures through the redacted recent-event recorder. Keep the compact TUI status at generic `error`; details belong in diagnostics.
|
|
150
150
|
|
|
151
151
|
## 8. Work Protocol
|
|
@@ -2,21 +2,19 @@
|
|
|
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
|
-
## 0.57.11 publication checkpoint
|
|
6
|
-
|
|
7
|
-
- [ ] Validate and publish only the pre-publication follower reply-target fix through the protected dev-to-main release path. Require fresh Ubuntu, Windows and both macOS shard checks before merge, exact candidate/merged-tree equality, one immutable version tag and the repository-owned release workflow.
|
|
8
|
-
- [ ] Confirm the published GitHub Release and public npm version, tag/gitHead identity, release notes and packed runtime/skills before closing this checkpoint. Keep post-refusal recovery and disposable-tab live acceptance open; do not reload the running session.
|
|
9
|
-
|
|
10
5
|
## Disposable Thread live acceptance
|
|
11
6
|
|
|
12
7
|
- [ ] After separate operator authorization, use disposable Telegram tabs to check leader Settings review/Back, one confirmed cleanup of an inactive slotless binding, preservation of its replacement letter holder, and visible outcome/recovery copy. Native filesystem and injected-transport tests do not prove live Telegram/client or native Windows acceptance. Never use production history as the disposable fixture.
|
|
13
8
|
- [ ] On separately authorized disposable routing tabs, verify pending-choice protection, Cancel after the view becomes unavailable, expiry notice in the owned leader Thread and no duplicate deletion after an unknown outcome. Local native journal/API-decoder fixtures are not live client acceptance.
|
|
14
9
|
|
|
15
|
-
##
|
|
10
|
+
## Typing authority during Telegram turns
|
|
11
|
+
|
|
12
|
+
Live report on package 0.58.2 and Pi 1.4.0: every Telegram turn logged `sendChatAction: Telegram API call authority is unavailable` in a connected, long-lived session. The reporter's leader/follower role and refusal stage are not yet known. Prompt-cache acceptance is complete; this is a separate typing-indicator investigation.
|
|
16
13
|
|
|
17
|
-
The
|
|
14
|
+
The native expired-loop diagnostic case is corrected: real typing loop/starter, direct API runtime and API client regressions cover mocked HTTP 200 after stop/same-target replacement, with unchanged session generation and transport epoch. A process-local ended-loop observation suppresses only the corresponding typed authority diagnostic; the request still rejects, active-owner refusals remain visible, and no callback crosses IPC. Real-client regressions retain the original HTTP/network failure when authority expires during error handling; a native follower caller rejects a delayed ACK after its local owner ends, without replay. Direct/follower and Classic/Threaded paths remain distinct from live acceptance. This does not establish the cause of the reporter's live failure or prove client typing.
|
|
18
15
|
|
|
19
|
-
- [ ]
|
|
16
|
+
- [ ] Correlate the live report with the corrected native case using only redacted leader/follower role, timing around loop end/replacement and refusal-stage evidence if available. Do not infer transport loss or widen authority from the error string alone; isolate any distinct current-owner refusal before another runtime change.
|
|
17
|
+
- [ ] After separately approved live validation, confirm client typing and absence of expired-loop API noise across Telegram turns and loop replacement. Preserve exact Thread targeting, independent Thread requests, best-effort presence and no unhealthy-status escalation; local native fixtures are not live acceptance.
|
|
20
18
|
|
|
21
19
|
## Stuck forwarded command after Thread re-creation
|
|
22
20
|
|
|
@@ -38,10 +36,10 @@ A target-scoped reply refusal cannot prove that a command made no prior effects.
|
|
|
38
36
|
- [ ] Route an input that arrives in a tab bound to nothing through a fresh temporary routing tab (the All flow) instead of publishing the chooser in the orphan, deleting the orphan with it once nothing unspent remains. Needs its own durable-metadata design.
|
|
39
37
|
- [ ] Live acceptance on disposable tabs only: Cancel on an orphan tab deletes it; a second unspent input keeps it until the last Cancel; a plain `std::map` option button is delivered as an ordinary prompt.
|
|
40
38
|
|
|
41
|
-
##
|
|
39
|
+
## Passive-child cold-import follow-up
|
|
42
40
|
|
|
43
|
-
The 0.57.8 tag validation failed `Child process sharing the agent dir does not poll while parent owns Telegram lock` even when that file ran alone: `Child process did not exit. stdout= stderr=` at its existing child deadline. The other seven process tests and the identical pre-merge tree passed. That historical failure has no child-stage trace, so cold import, startup and a retained runtime handle remain competing explanations. Bounded diagnostic sampling is exhausted; passing traces showed imports up to 4.37 seconds against the five-second non-Windows child budget and natural exit within 8–14 ms after the event-loop checkpoint. These traces do not identify the original cause.
|
|
44
|
-
- [ ]
|
|
41
|
+
The 0.57.8 tag validation failed `Child process sharing the agent dir does not poll while parent owns Telegram lock` even when that file ran alone: `Child process did not exit. stdout= stderr=` at its existing child deadline. The other seven process tests and the identical pre-merge tree passed. That historical failure has no child-stage trace, so cold import, startup and a retained runtime handle remain competing explanations. Bounded diagnostic sampling is exhausted; passing traces showed imports up to 4.37 seconds against the five-second non-Windows child budget and natural exit within 8–14 ms after the event-loop checkpoint. These traces do not identify the original cause. A later main-validation recurrence stopped after `eval` and `import-start`, with parent-clock `elapsedMs=5009` and no import-complete checkpoint. That trace locates this recurrence before import completion, not in natural exit or a retained post-checkpoint handle; the slow dependency/startup cause remains unknown. The minor release's independent tag-owned validation passed the same committed tree, which does not erase that historical failed main check. The initial hotfix candidate then showed the same pre-import-completion state on Ubuntu at `elapsedMs=5026`; the recurrence is not macOS-only. Slow dependency/startup cost remains unexplained, separate from the fixture's corrected startup/exit observation contract.
|
|
42
|
+
- [ ] On a genuinely failing cold-import trace under the phase-owned fixture, isolate dependency/startup cost using its actual overall/exit deadline and stage evidence before changing runtime imports or budgets. Preserve natural-exit/no-poll assertions and job budgets. Do not spend unchanged-head diagnostic samples or infer runner contention or the historical cause from passing runs.
|
|
45
43
|
|
|
46
44
|
## Windows Workspace-gate fixture timeout
|
|
47
45
|
|
|
@@ -4,6 +4,25 @@
|
|
|
4
4
|
|
|
5
5
|
## Unreleased
|
|
6
6
|
|
|
7
|
+
## 0.58.3: Typing Cancellation Diagnostics
|
|
8
|
+
|
|
9
|
+
- `Typing diagnostics`: Ended typing loops no longer log cancellation-only authority refusals as API failures. Real HTTP/network failures retain their provenance and diagnostics even if authority expires before settlement. Requests remain rejected and single-attempt; callbacks stay local. Native late-success/failure and follower-ACK regressions cover this case, not the cause of the live report.
|
|
10
|
+
- `Prompt-cache acceptance`: Reporter-provided live Anthropic captures and connected-session measurements confirm the released fix across tool changes, resume, local/Telegram switches and reconnect, with no new thinking drops in the tested runs. The remaining live-confirmation gate is closed; connected wire capture and broader model/cache-expiry coverage remain outside this evidence. Already-lost thinking is not reconstructed.
|
|
11
|
+
|
|
12
|
+
## 0.58.2: Flexible Assistant Action Markup
|
|
13
|
+
|
|
14
|
+
- `HTML actions`: Complete button/voice comments activate by their delimiters and accepted payload regardless of whitespace or surrounding Markdown, including code fences. Adjacent same-line comments are independent; unfinished comments do not activate. Escape the opening delimiter as `<!--` for literal examples.
|
|
15
|
+
- `In-body buttons`: Fenced `telegram_button` blocks tolerate horizontal indentation, whitespace before the exact name, and three or more backticks or tildes. Closures require the same marker and at least the opening length on a separate line. Enclosing fenced examples remain literal; incomplete blocks, malformed JSON/CML and invalid rows still register no callbacks.
|
|
16
|
+
|
|
17
|
+
## 0.58.1: Independent Thread Typing
|
|
18
|
+
|
|
19
|
+
- `Typing`: A pending activity request in one Thread no longer silently suppresses another Thread's typing. Exact chat/Thread/action calls still coalesce with their own minimum interval, while real Telegram 429 cooldowns remain shared across the chat, including late failures after a faster peer completes. Authority checks, one-attempt typing and bounded gate storage remain intact.
|
|
20
|
+
- `Process validation`: Passive-child checks distinguish cold startup from natural exit: a 15-second total cap retains the existing Windows bound, while a separate five-second guard starts after the event-loop checkpoint on every platform. Regressions reject both a missing checkpoint and retained post-checkpoint work; no polling assertions, natural-exit requirement or job budgets are weakened.
|
|
21
|
+
|
|
22
|
+
## 0.58.0: Unified Connect Gateway
|
|
23
|
+
|
|
24
|
+
- `Pi commands`: Removes the standalone `/telegram-internal` gateway. Runtime-armed session replacement now dispatches `/telegram-connect --internal new <token>` after exact durable update completion. Internal calls bypass profile activation and connection/recovery; malformed, unarmed and replayed calls fail closed. `internal` remains a valid profile name.
|
|
25
|
+
|
|
7
26
|
## 0.57.11: Follower Reply Target
|
|
8
27
|
|
|
9
28
|
- `Follower command replies`: Status/model/settings and text replies from an admitted follower command select its acknowledged Thread before publication, not the old input Thread. A changed Thread drops the reply anchor; delivery, menu state and ownership use one destination. The journaled original and explicit selected-menu grants stay intact; no refused-send recovery, handler replay or proxy widening is added.
|
|
@@ -201,6 +201,7 @@ export declare function createTelegramLiveTargetWorkObserver<TContext>(deps: {
|
|
|
201
201
|
}, ctx: TContext) => TelegramBusLiveRebindWorkState;
|
|
202
202
|
interface TelegramCommandsAndToolsBindingDeps {
|
|
203
203
|
pi: Pi.ExtensionAPI;
|
|
204
|
+
handleInternalAction: Commands.TelegramSessionActionRuntime["handleInternalAction"];
|
|
204
205
|
agentDir: string;
|
|
205
206
|
configStore: Config.TelegramConfigStore;
|
|
206
207
|
persistConfig: (config?: Config.TelegramConfig) => Promise<void>;
|
|
@@ -241,7 +242,7 @@ interface TelegramCommandsAndToolsBindingDeps {
|
|
|
241
242
|
connectionIntent: NonNullable<Commands.TelegramBridgeCommandRegistrationDeps["connectionIntent"]>;
|
|
242
243
|
recordRuntimeEvent: TelegramRuntimeEventRecorder;
|
|
243
244
|
}
|
|
244
|
-
export declare function registerTelegramCommandsAndTools({ pi, agentDir, configStore, persistConfig, setup, activeTurnRuntime, lockedPollingRuntime, stopPolling, getDisconnectThreadName, onTransportChanged, getStatusLines, buttonActionStore, sendMarkdownReply, sendChannelMarkdownMessage, sendChannelMediaMessage, listChannelPosts, mutateChannelPost, callMultipart, getDefaultChatId, getDefaultTarget, resolveAgentTarget, routeAgentMessage, canSendDirect, setGenerativeAppLiveSurfaceRuntime, recordRuntimeEvent, updateStatus, isContextCurrent, getSessionGeneration, connectionIntent, }: TelegramCommandsAndToolsBindingDeps): void;
|
|
245
|
+
export declare function registerTelegramCommandsAndTools({ pi, handleInternalAction, agentDir, configStore, persistConfig, setup, activeTurnRuntime, lockedPollingRuntime, stopPolling, getDisconnectThreadName, onTransportChanged, getStatusLines, buttonActionStore, sendMarkdownReply, sendChannelMarkdownMessage, sendChannelMediaMessage, listChannelPosts, mutateChannelPost, callMultipart, getDefaultChatId, getDefaultTarget, resolveAgentTarget, routeAgentMessage, canSendDirect, setGenerativeAppLiveSurfaceRuntime, recordRuntimeEvent, updateStatus, isContextCurrent, getSessionGeneration, connectionIntent, }: TelegramCommandsAndToolsBindingDeps): void;
|
|
245
246
|
interface TelegramLifecycleBindingDeps {
|
|
246
247
|
pi: Pi.ExtensionAPI;
|
|
247
248
|
publicationRuntime: TelegramBridgePublicationRuntime;
|
|
@@ -497,7 +497,7 @@ export function createTelegramLiveTargetWorkObserver(deps) {
|
|
|
497
497
|
};
|
|
498
498
|
};
|
|
499
499
|
}
|
|
500
|
-
export function registerTelegramCommandsAndTools({ pi, agentDir, configStore, persistConfig, setup, activeTurnRuntime, lockedPollingRuntime, stopPolling, getDisconnectThreadName, onTransportChanged, getStatusLines, buttonActionStore, sendMarkdownReply, sendChannelMarkdownMessage, sendChannelMediaMessage, listChannelPosts, mutateChannelPost, callMultipart, getDefaultChatId, getDefaultTarget, resolveAgentTarget, routeAgentMessage, canSendDirect, setGenerativeAppLiveSurfaceRuntime, recordRuntimeEvent, updateStatus, isContextCurrent, getSessionGeneration, connectionIntent, }) {
|
|
500
|
+
export function registerTelegramCommandsAndTools({ pi, handleInternalAction, agentDir, configStore, persistConfig, setup, activeTurnRuntime, lockedPollingRuntime, stopPolling, getDisconnectThreadName, onTransportChanged, getStatusLines, buttonActionStore, sendMarkdownReply, sendChannelMarkdownMessage, sendChannelMediaMessage, listChannelPosts, mutateChannelPost, callMultipart, getDefaultChatId, getDefaultTarget, resolveAgentTarget, routeAgentMessage, canSendDirect, setGenerativeAppLiveSurfaceRuntime, recordRuntimeEvent, updateStatus, isContextCurrent, getSessionGeneration, connectionIntent, }) {
|
|
501
501
|
GenerativeApps.registerTelegramBindTool(pi, {
|
|
502
502
|
agentDir,
|
|
503
503
|
getActiveProfileName: configStore.getActiveProfileName,
|
|
@@ -551,6 +551,7 @@ export function registerTelegramCommandsAndTools({ pi, agentDir, configStore, pe
|
|
|
551
551
|
}, { deliverAs: "nextTurn" });
|
|
552
552
|
};
|
|
553
553
|
Commands.registerTelegramBridgeCommands(pi, {
|
|
554
|
+
handleInternalAction,
|
|
554
555
|
promptForConfig: async (ctx, profileName) => {
|
|
555
556
|
const nextProfileName = profileName ?? undefined;
|
|
556
557
|
if (profileName && !Config.isValidTelegramProfileName(profileName)) {
|
|
@@ -166,6 +166,7 @@ export interface TelegramBridgeCommandStartPollingResult {
|
|
|
166
166
|
owner?: string;
|
|
167
167
|
}
|
|
168
168
|
export interface TelegramBridgeCommandRegistrationDeps {
|
|
169
|
+
handleInternalAction?: TelegramSessionActionRuntime["handleInternalAction"];
|
|
169
170
|
promptForConfig: (ctx: ExtensionCommandContext, profileName?: string) => Promise<void>;
|
|
170
171
|
getStatusLines: (options?: TelegramBridgeStatusLineOptions) => string[];
|
|
171
172
|
reloadConfig: () => Promise<void>;
|
|
@@ -661,11 +662,10 @@ export declare function createTelegramCommandHandler<TMessage extends TelegramCo
|
|
|
661
662
|
prepareSelectedMenuCommand(command: ParsedTelegramCommand, messages: readonly TMessage[], ctx: TContext, admission: TelegramSelectedCommandAdmission): (() => Promise<boolean>) | undefined;
|
|
662
663
|
};
|
|
663
664
|
export declare function createTelegramCommandOrPromptDispatcher<TMessage, TContext>(deps: TelegramCommandOrPromptDispatcherDeps<TMessage, TContext>): (messages: TMessage[], ctx: TContext) => Promise<void>;
|
|
664
|
-
export declare const
|
|
665
|
-
export declare const
|
|
666
|
-
export declare const TELEGRAM_INTERNAL_MANUAL_USE_MESSAGE = "This internal Telegram
|
|
665
|
+
export declare const TELEGRAM_CONNECT_COMMAND_NAME = "telegram-connect";
|
|
666
|
+
export declare const TELEGRAM_INTERNAL_COMMAND_FLAG = "--internal";
|
|
667
|
+
export declare const TELEGRAM_INTERNAL_MANUAL_USE_MESSAGE = "This internal Telegram action cannot be run manually.";
|
|
667
668
|
export interface TelegramSessionActionRuntimeDeps {
|
|
668
|
-
registerCommand: Pi.ExtensionAPI["registerCommand"];
|
|
669
669
|
sendUserMessage: Pi.ExtensionAPI["sendUserMessage"];
|
|
670
670
|
notifyResult: (target: {
|
|
671
671
|
chatId: number;
|
|
@@ -697,7 +697,6 @@ export interface TelegramSessionReplacementSettlementDeps {
|
|
|
697
697
|
}
|
|
698
698
|
export declare function settleTelegramSessionReplacement(deps: TelegramSessionReplacementSettlementDeps): Promise<"none" | "settled" | "expired" | "failed" | "stale">;
|
|
699
699
|
export interface TelegramSessionActionAssemblyDeps {
|
|
700
|
-
registerCommand: Pi.ExtensionAPI["registerCommand"];
|
|
701
700
|
sendUserMessage: Pi.ExtensionAPI["sendUserMessage"];
|
|
702
701
|
store: {
|
|
703
702
|
load: () => Promise<void>;
|
|
@@ -753,7 +752,7 @@ export declare function createTelegramSessionActionAssembly(deps: TelegramSessio
|
|
|
753
752
|
};
|
|
754
753
|
};
|
|
755
754
|
export interface TelegramSessionActionRuntime {
|
|
756
|
-
|
|
755
|
+
handleInternalAction: (args: string, ctx: Pi.ExtensionCommandContext) => Promise<void>;
|
|
757
756
|
scheduleAfterUpdate: (updateId: number, target: {
|
|
758
757
|
chatId: number;
|
|
759
758
|
threadId?: number;
|
|
@@ -405,6 +405,7 @@ function formatTelegramTakeoverPrompt(ctx, owner) {
|
|
|
405
405
|
return `${action}\n\n${from} ${source}\n${to} ${ctx.cwd}`;
|
|
406
406
|
}
|
|
407
407
|
export function registerTelegramBridgeCommands(pi, deps) {
|
|
408
|
+
const handleInternalAction = deps.handleInternalAction;
|
|
408
409
|
pi.registerCommand("telegram-setup", {
|
|
409
410
|
description: "<profile> — Configure Telegram bot token",
|
|
410
411
|
handler: async (args, ctx) => {
|
|
@@ -418,9 +419,19 @@ export function registerTelegramBridgeCommands(pi, deps) {
|
|
|
418
419
|
ctx.ui.notify(deps.getStatusLines({ verbose }).join("\n"), "info");
|
|
419
420
|
},
|
|
420
421
|
});
|
|
421
|
-
pi.registerCommand(
|
|
422
|
+
pi.registerCommand(TELEGRAM_CONNECT_COMMAND_NAME, {
|
|
422
423
|
description: "<profile> — Start Telegram bridge",
|
|
423
424
|
handler: async (args, ctx) => {
|
|
425
|
+
const words = args.trim().split(/\s+/);
|
|
426
|
+
// Service dispatch never inherits profile activation or explicit-connect recovery authority.
|
|
427
|
+
if (words.some(word => word.toLowerCase().startsWith(TELEGRAM_INTERNAL_COMMAND_FLAG))) {
|
|
428
|
+
if (words[0] !== TELEGRAM_INTERNAL_COMMAND_FLAG || !handleInternalAction) {
|
|
429
|
+
ctx.ui.notify(TELEGRAM_INTERNAL_MANUAL_USE_MESSAGE, "warning");
|
|
430
|
+
return;
|
|
431
|
+
}
|
|
432
|
+
await handleInternalAction(words.slice(1).join(" "), ctx);
|
|
433
|
+
return;
|
|
434
|
+
}
|
|
424
435
|
const sessionGeneration = deps.getSessionGeneration?.();
|
|
425
436
|
let intentId;
|
|
426
437
|
// Pi context getters throw after replacement; check plain intent/generation first.
|
|
@@ -2415,9 +2426,9 @@ async function handleTelegramCommandRuntime(commandName, message, ctx, deps, com
|
|
|
2415
2426
|
},
|
|
2416
2427
|
}, commandArgs);
|
|
2417
2428
|
}
|
|
2418
|
-
export const
|
|
2419
|
-
export const
|
|
2420
|
-
export const TELEGRAM_INTERNAL_MANUAL_USE_MESSAGE = "This internal Telegram
|
|
2429
|
+
export const TELEGRAM_CONNECT_COMMAND_NAME = "telegram-connect";
|
|
2430
|
+
export const TELEGRAM_INTERNAL_COMMAND_FLAG = "--internal";
|
|
2431
|
+
export const TELEGRAM_INTERNAL_MANUAL_USE_MESSAGE = "This internal Telegram action cannot be run manually.";
|
|
2421
2432
|
function delayTelegramSessionAction(delayMs) {
|
|
2422
2433
|
return new Promise((resolve) => setTimeout(resolve, delayMs));
|
|
2423
2434
|
}
|
|
@@ -2487,7 +2498,6 @@ export function createTelegramSessionActionAssembly(deps) {
|
|
|
2487
2498
|
report(new Error("Telegram new-session result delivery failed."));
|
|
2488
2499
|
};
|
|
2489
2500
|
const action = createTelegramSessionActionRuntime({
|
|
2490
|
-
registerCommand: deps.registerCommand,
|
|
2491
2501
|
sendUserMessage: deps.sendUserMessage,
|
|
2492
2502
|
notifyResult(target, result) {
|
|
2493
2503
|
return sendTerminalResult(target, result);
|
|
@@ -2585,7 +2595,6 @@ export function createTelegramSessionActionRuntime(deps) {
|
|
|
2585
2595
|
let pendingUpdateId;
|
|
2586
2596
|
let pendingTarget;
|
|
2587
2597
|
let pendingAction;
|
|
2588
|
-
let registered = false;
|
|
2589
2598
|
const reportFailure = (error) => {
|
|
2590
2599
|
try {
|
|
2591
2600
|
deps.recordRuntimeEvent?.("new-session", error);
|
|
@@ -2595,35 +2604,29 @@ export function createTelegramSessionActionRuntime(deps) {
|
|
|
2595
2604
|
}
|
|
2596
2605
|
};
|
|
2597
2606
|
return {
|
|
2598
|
-
|
|
2599
|
-
|
|
2607
|
+
async handleInternalAction(args, ctx) {
|
|
2608
|
+
const action = pendingAction;
|
|
2609
|
+
const [operation, token, ...extra] = args.trim().split(/\s+/);
|
|
2610
|
+
if (!action || operation !== "new" ||
|
|
2611
|
+
token !== action.token || extra.length !== 0) {
|
|
2612
|
+
ctx.ui.notify(TELEGRAM_INTERNAL_MANUAL_USE_MESSAGE, "warning");
|
|
2600
2613
|
return;
|
|
2601
|
-
|
|
2602
|
-
|
|
2603
|
-
|
|
2604
|
-
|
|
2605
|
-
|
|
2606
|
-
|
|
2607
|
-
ctx.
|
|
2608
|
-
|
|
2614
|
+
}
|
|
2615
|
+
pendingAction = undefined;
|
|
2616
|
+
switch (action.kind) {
|
|
2617
|
+
case "replace-session":
|
|
2618
|
+
try {
|
|
2619
|
+
await deps.prepareReplacement?.(ctx, action.updateId, action.target);
|
|
2620
|
+
const result = await ctx.newSession();
|
|
2621
|
+
if (result.cancelled)
|
|
2622
|
+
await deps.notifyResult(action.target, "cancelled");
|
|
2609
2623
|
}
|
|
2610
|
-
|
|
2611
|
-
|
|
2612
|
-
|
|
2613
|
-
try {
|
|
2614
|
-
await deps.prepareReplacement?.(ctx, action.updateId, action.target);
|
|
2615
|
-
const result = await ctx.newSession();
|
|
2616
|
-
if (result.cancelled)
|
|
2617
|
-
await deps.notifyResult(action.target, "cancelled");
|
|
2618
|
-
}
|
|
2619
|
-
catch (error) {
|
|
2620
|
-
reportFailure(error);
|
|
2621
|
-
await deps.notifyResult(action.target, "failure");
|
|
2622
|
-
}
|
|
2623
|
-
return;
|
|
2624
|
+
catch (error) {
|
|
2625
|
+
reportFailure(error);
|
|
2626
|
+
await deps.notifyResult(action.target, "failure");
|
|
2624
2627
|
}
|
|
2625
|
-
|
|
2626
|
-
}
|
|
2628
|
+
return;
|
|
2629
|
+
}
|
|
2627
2630
|
},
|
|
2628
2631
|
scheduleAfterUpdate(updateId, target) {
|
|
2629
2632
|
if (pendingUpdateId !== undefined || pendingAction !== undefined)
|
|
@@ -2643,9 +2646,7 @@ export function createTelegramSessionActionRuntime(deps) {
|
|
|
2643
2646
|
const token = randomUUID();
|
|
2644
2647
|
pendingAction = { kind: "replace-session", token, updateId, target };
|
|
2645
2648
|
void Promise.resolve()
|
|
2646
|
-
.then(() => deps.sendUserMessage(`/${
|
|
2647
|
-
expandPromptTemplates: true,
|
|
2648
|
-
}))
|
|
2649
|
+
.then(() => deps.sendUserMessage(`/${TELEGRAM_CONNECT_COMMAND_NAME} ${TELEGRAM_INTERNAL_COMMAND_FLAG} new ${token}`, { expandPromptTemplates: true }))
|
|
2649
2650
|
.catch((error) => {
|
|
2650
2651
|
pendingAction = undefined;
|
|
2651
2652
|
reportFailure(error);
|
|
@@ -80,7 +80,7 @@ const telegramBusProtocolIdentity = Bus.createTelegramCurrentBusProtocolIdentity
|
|
|
80
80
|
export default function (pi) {
|
|
81
81
|
Skills.registerTelegramSkillDiscovery(pi);
|
|
82
82
|
const piRuntime = Pi.createExtensionApiRuntimePorts(pi);
|
|
83
|
-
const { getActiveTools, getCommands, getThinkingLevel, sendUserMessage,
|
|
83
|
+
const { getActiveTools, getCommands, getThinkingLevel, sendUserMessage, setActiveTools, setModel, setThinkingLevel, } = piRuntime;
|
|
84
84
|
const bridgeRuntime = Runtime.createTelegramBridgeRuntime();
|
|
85
85
|
const runtimeDiagnostics = Logging.createTelegramRuntimeDiagnosticsRuntime({
|
|
86
86
|
sharedFile: true,
|
|
@@ -242,7 +242,6 @@ export default function (pi) {
|
|
|
242
242
|
captureAuthority: captureTelegramStateAuthority,
|
|
243
243
|
});
|
|
244
244
|
const sessionActionAssembly = Commands.createTelegramSessionActionAssembly({
|
|
245
|
-
registerCommand,
|
|
246
245
|
sendUserMessage,
|
|
247
246
|
store: threadStore,
|
|
248
247
|
getProfileName: configStore.getActiveProfileName,
|
|
@@ -2293,9 +2292,9 @@ export default function (pi) {
|
|
|
2293
2292
|
}
|
|
2294
2293
|
},
|
|
2295
2294
|
}.reset);
|
|
2296
|
-
sessionActionsRuntime.register();
|
|
2297
2295
|
Bindings.registerTelegramCommandsAndTools({
|
|
2298
2296
|
pi,
|
|
2297
|
+
handleInternalAction: sessionActionsRuntime.handleInternalAction,
|
|
2299
2298
|
agentDir: Paths.resolveAgentDir(),
|
|
2300
2299
|
configStore,
|
|
2301
2300
|
persistConfig: persistTelegramConfigWithSync,
|
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
* Owns assistant-authored telegram_button extraction, button action storage, callback handling, and prompt-turn construction
|
|
5
5
|
*/
|
|
6
6
|
import { randomUUID } from "node:crypto";
|
|
7
|
-
import { getTelegramActionString as getTelegramButtonString, parseTelegramActionPayloadRows, parseTelegramButtonPayloadRows, replaceTelegramButtonFences,
|
|
7
|
+
import { getTelegramActionString as getTelegramButtonString, parseTelegramActionPayloadRows, parseTelegramButtonPayloadRows, replaceTelegramButtonFences, replaceTelegramHtmlComments, } from "./outbound-markup.js";
|
|
8
8
|
import { truncateTelegramQueueSummary, } from "./queue.js";
|
|
9
9
|
const TELEGRAM_BUTTON_CALLBACK_PREFIX = "tgbtn";
|
|
10
10
|
const TELEGRAM_BUTTON_ACTION_TTL_MS = 24 * 60 * 60 * 1000;
|
|
@@ -117,7 +117,23 @@ export function planTelegramButtonReply(markdown, deps) {
|
|
|
117
117
|
}),
|
|
118
118
|
}));
|
|
119
119
|
};
|
|
120
|
-
const
|
|
120
|
+
const footerKeyboard = [];
|
|
121
|
+
const stripped = replaceTelegramHtmlComments(markdown, (comment) => {
|
|
122
|
+
const command = "telegram_button";
|
|
123
|
+
const normalizedContent = comment.content
|
|
124
|
+
.replace(/^\s+/, "")
|
|
125
|
+
.replace(/^!/, "");
|
|
126
|
+
if (!normalizedContent.startsWith(command))
|
|
127
|
+
return comment.raw;
|
|
128
|
+
const payloadRows = parseTelegramActionPayloadRows(comment, command);
|
|
129
|
+
if (!payloadRows)
|
|
130
|
+
return "";
|
|
131
|
+
const rows = buildRows(payloadRows, false);
|
|
132
|
+
if (rows)
|
|
133
|
+
footerKeyboard.push(...rows);
|
|
134
|
+
return "";
|
|
135
|
+
});
|
|
136
|
+
const withRichButtons = replaceTelegramButtonFences(stripped, (payload, closed) => {
|
|
121
137
|
if (!closed)
|
|
122
138
|
return "";
|
|
123
139
|
const payloadRows = parseTelegramButtonPayloadRows(payload);
|
|
@@ -133,22 +149,8 @@ export function planTelegramButtonReply(markdown, deps) {
|
|
|
133
149
|
}
|
|
134
150
|
return `\n${rows.map(renderTelegramRichButtonRow).join("\n\n")}\n`;
|
|
135
151
|
});
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
const normalizedContent = comment.content
|
|
139
|
-
.replace(/^\s+/, "")
|
|
140
|
-
.replace(/^!/, "");
|
|
141
|
-
if (!normalizedContent.startsWith(command))
|
|
142
|
-
return comment.raw;
|
|
143
|
-
const payloadRows = parseTelegramActionPayloadRows(comment, command);
|
|
144
|
-
if (!payloadRows)
|
|
145
|
-
return "";
|
|
146
|
-
const rows = buildRows(payloadRows, false);
|
|
147
|
-
if (rows)
|
|
148
|
-
keyboard.push(...rows);
|
|
149
|
-
return "";
|
|
150
|
-
});
|
|
151
|
-
const visibleMarkdown = normalizeMarkdownAfterButtonExtraction(stripped);
|
|
152
|
+
keyboard.push(...footerKeyboard);
|
|
153
|
+
const visibleMarkdown = normalizeMarkdownAfterButtonExtraction(withRichButtons);
|
|
152
154
|
return {
|
|
153
155
|
markdown: keyboard.length > 0 && !visibleMarkdown
|
|
154
156
|
? DEFAULT_TELEGRAM_BUTTON_REPLY_MARKDOWN
|
|
@@ -1,22 +1,22 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Telegram outbound markup parsing helpers
|
|
3
3
|
* Zones: telegram outbound, assistant markup
|
|
4
|
-
* Owns
|
|
4
|
+
* Owns delimiter-based assistant action comment extraction, attribute parsing, and markup stripping shared by voice and outbound delivery
|
|
5
5
|
*/
|
|
6
|
-
export interface
|
|
6
|
+
export interface TelegramHtmlComment {
|
|
7
7
|
raw: string;
|
|
8
8
|
content: string;
|
|
9
9
|
start: number;
|
|
10
10
|
end: number;
|
|
11
11
|
}
|
|
12
|
-
export declare function
|
|
13
|
-
comments:
|
|
12
|
+
export declare function collectTelegramHtmlComments(markdown: string): {
|
|
13
|
+
comments: TelegramHtmlComment[];
|
|
14
14
|
openCommentStart?: number;
|
|
15
15
|
};
|
|
16
16
|
export declare function replaceTelegramButtonFences(markdown: string, replace: (payload: string, closed: boolean) => string): string;
|
|
17
|
-
export declare function
|
|
17
|
+
export declare function replaceTelegramHtmlComments(markdown: string, replacer: (comment: TelegramHtmlComment) => string): string;
|
|
18
18
|
export declare function parseTelegramButtonPayloadRows(source: string): Record<string, unknown>[][] | undefined;
|
|
19
|
-
export declare function parseTelegramActionPayloadRows(comment:
|
|
19
|
+
export declare function parseTelegramActionPayloadRows(comment: TelegramHtmlComment, command: string): Record<string, unknown>[][] | undefined;
|
|
20
20
|
export declare function stripTelegramCommentMarkupForPreview(markdown: string): string;
|
|
21
21
|
export declare function stripTelegramCommentMarkupForDelivery(markdown: string): string;
|
|
22
22
|
export interface TelegramVoiceReplyItem {
|