diff --git a/CHANGELOG.md b/CHANGELOG.md index 4a5a29d..477771d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,7 @@ ## Current +- `[Queue UI]` Marked liked high-priority queued Telegram turns with `⬆` in the pi status-bar queue preview. Impact: operators can now distinguish reaction-promoted turns from normal queued prompts at a glance. - `[Docs]` Added short responsibility header comments to every project `.ts` file. Impact: file boundaries are easier to understand while navigating the growing `/lib` split. - `[Naming]` Renamed extracted domain modules and mirrored regression suites to use repo-scoped bare domain filenames such as `api.ts`, `queue.ts`, and `queue.test.ts` instead of repeating `telegram-*` in every path. Impact: the internal topology is easier to scan and stays aligned with the repository-level Telegram scope. - `[Controls]` Expanded Telegram session controls with a richer `/status` view, inline model selection, and thinking-level controls, and fixed the callback-selection path so idle model and thinking picks apply immediately instead of only becoming visible after a later Telegram interaction. Impact: more bridge configuration can be managed directly from Telegram with more predictable immediate feedback. diff --git a/README.md b/README.md index c04fe41..99067c3 100644 --- a/README.md +++ b/README.md @@ -24,7 +24,7 @@ Compared to upstream commit `cb34008`, this fork significantly extends and harde - Markdown and reply rendering improvements, with richer formatting support, narrow-client-friendly table/list rendering, quote compatibility fixes, and multiple fixes for incorrect Telegram rendering and chunking edge cases - Streaming, attachment, and delivery workflow hardening, including more robust preview updates and file handling - General runtime polish, bug fixes, and refactors across pairing, command handling, and Telegram session behavior -- Cleaner internal domain layout, with flat `/lib/*.ts` modules and mirrored `/tests/*.test.ts` suites that use repo-scoped domain names instead of redundant `telegram-*` filename prefixes +- Cleaner internal domain layout, with flat `/lib/*.ts` modules and mirrored `/tests/*.test.ts` suites that use repo-scoped domain names In short: this fork is no longer just a repackaged copy of upstream; it is a feature-expanded and bug-fixed Telegram frontend for pi. @@ -162,9 +162,11 @@ If you send more Telegram messages while pi is busy, they are queued and process The pi status bar shows queued Telegram turns as compact previews, for example: ```text -+3: [summarize this image…, write a shell script…, 📎 2 attachments] ++3: [⬆ write a shell script…, summarize this image…, 📎 2 attachments] ``` +Priority turns promoted with 👍 are marked with `⬆` in that queue preview. + Each preview is limited to at most 4 words or 32 characters. ### Reprioritize or discard queued messages diff --git a/docs/architecture.md b/docs/architecture.md index 8625578..189aa88 100644 --- a/docs/architecture.md +++ b/docs/architecture.md @@ -68,7 +68,7 @@ Queued items now use two explicit dimensions: - `kind`: prompt vs control - `queueLane`: control vs priority vs default -This lets synthetic control actions and Telegram prompts share one stable ordering model while still rendering distinctly in status output. +This lets synthetic control actions and Telegram prompts share one stable ordering model while still rendering distinctly in status output. In the pi status bar queue preview, priority prompts are marked with `⬆` while control items keep their own control-specific summary markers such as `⚡`. A dispatched prompt remains in the queue until `agent_start` consumes it. That keeps the active Telegram turn bound correctly for previews, attachments, abort handling, and final reply delivery. diff --git a/lib/queue.ts b/lib/queue.ts index 76f4c2b..1a65c57 100644 --- a/lib/queue.ts +++ b/lib/queue.ts @@ -189,6 +189,13 @@ export function consumeDispatchedTelegramPrompt( return { activeTurn: nextItem, remainingItems: items.slice(1) }; } +function formatTelegramQueueItemStatusSummary(item: TelegramQueueItem): string { + if (item.queueLane === "priority") { + return `⬆ ${item.statusSummary}`; + } + return item.statusSummary; +} + export function formatQueuedTelegramItemsStatus( items: TelegramQueueItem[], ): string { @@ -196,7 +203,7 @@ export function formatQueuedTelegramItemsStatus( const previewCount = 4; const summaries = items .slice(0, previewCount) - .map((item) => item.statusSummary) + .map(formatTelegramQueueItemStatusSummary) .filter(Boolean); if (summaries.length === 0) return ` +${items.length}`; const suffix = items.length > summaries.length ? ", …" : ""; diff --git a/package.json b/package.json index 2e23513..f91d74a 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@llblab/pi-telegram", - "version": "0.2.6", + "version": "0.2.7", "private": false, "description": "Better Telegram DM bridge extension for pi", "type": "module", @@ -29,7 +29,8 @@ "pi": { "extensions": [ "./index.ts" - ] + ], + "image": "https://github.com/llblab/pi-telegram/raw/main/screenshot.png" }, "peerDependencies": { "@mariozechner/pi-ai": "*", diff --git a/screenshot.png b/screenshot.png index a02750e..ae1573c 100644 Binary files a/screenshot.png and b/screenshot.png differ diff --git a/tests/queue.test.ts b/tests/queue.test.ts index df55e39..9bab282 100644 --- a/tests/queue.test.ts +++ b/tests/queue.test.ts @@ -16,6 +16,7 @@ import { buildTelegramSessionStartState, executeTelegramControlItemRuntime, executeTelegramQueueDispatchPlan, + formatQueuedTelegramItemsStatus, getNextTelegramToolExecutionCount, shouldStartTelegramPolling, } from "../lib/queue.ts"; @@ -169,6 +170,57 @@ test("Queue mutation helpers apply and clear prompt priority without touching co assert.equal(cleared.items[1]?.queueLane, "control"); }); +test("Queued status formatting marks priority prompts in the pi status bar", () => { + const queueItemType = undefined as + | Parameters[0][number] + | undefined; + const priorityPrompt: typeof queueItemType = { + kind: "prompt", + chatId: 1, + replyToMessageId: 1, + sourceMessageIds: [11], + queueOrder: 4, + queueLane: "priority", + laneOrder: 0, + queuedAttachments: [], + content: [{ type: "text", text: "prompt" }], + historyText: "prompt history", + statusSummary: "prompt", + }; + const defaultPrompt: typeof queueItemType = { + kind: "prompt", + chatId: 1, + replyToMessageId: 2, + sourceMessageIds: [12], + queueOrder: 5, + queueLane: "default", + laneOrder: 5, + queuedAttachments: [], + content: [{ type: "text", text: "default" }], + historyText: "default history", + statusSummary: "default", + }; + const controlItem: typeof queueItemType = { + kind: "control", + controlType: "status", + chatId: 1, + replyToMessageId: 3, + queueOrder: 6, + queueLane: "control", + laneOrder: 0, + statusSummary: "⚡ status", + execute: async () => {}, + }; + assert.equal( + formatQueuedTelegramItemsStatus([ + controlItem, + priorityPrompt, + defaultPrompt, + ]), + " +3: [⚡ status, ⬆ prompt, default]", + ); +}); + test("History partition keeps control items queued and extracts prompt items", () => { const queueItemType = undefined as | Parameters<