Skip to content

Latest commit

 

History

History
1147 lines (775 loc) · 28.8 KB

File metadata and controls

1147 lines (775 loc) · 28.8 KB
title Command Reference

Command Reference

This is the detailed reference for Telegram commands supported by Incursa Codex Telegram.

Use README.md for first setup and usage.md for day-to-day workflows.

Syntax Rules

  1. Commands are case-insensitive.
  2. Arguments are separated by whitespace unless a command says otherwise.
  3. Session IDs can be abbreviated if the prefix is unambiguous.
  4. Project selectors can be a list number, project key, project name prefix, or full path.
  5. Private chats, trusted group roots, and forum topics can auto-route plain text to the active session.
  6. Use /send <text> when Telegram privacy mode or an unsupported chat type prevents normal auto-routing.
  7. Attachments are forwarded to Codex when they are attached to a routed message.
  8. Voice notes are transcribed first, then either captured into an input bundle or sent to the active session according to TelegramInput:DefaultCaptureMode.
  9. Groups and forum topics require an allowed user plus either AllowedChatIds or /trust from an allowed user in that chat.

Quick Workflow

/doctor
/project add C:\src\your-repo
/new setup-check
Summarize this repository and tell me the next safest setup check to run.
/tail 80

Use a Unix path on Linux/macOS:

/project add /home/you/src/your-repo

Commands

/help

Shows the built-in command summary and navigation buttons.

Syntax:

/help

Expected behavior:

  1. Replies with the supported command list.
  2. Adds navigation buttons for Sessions, Projects, and Help.

/whoami

Shows the Telegram identifiers needed for configuration and troubleshooting.

Syntax:

/whoami

Expected behavior:

  1. Shows Telegram user ID.
  2. Shows chat ID.
  3. Shows topic thread ID when sent inside a forum topic.
  4. Works before the user allowlist is configured so first-time setup can discover IDs.

Do not show /whoami in a public video unless you are comfortable exposing the IDs.

/version

Shows the app version for the currently running Telegram process.

Syntax:

/version

Expected behavior:

  1. Shows the Incursa Codex Telegram assembly version.
  2. Helps confirm whether Telegram is talking to the binary you just installed or an older process.

/trust

Trusts the current group or forum chat for allowlisted users without copying a chat ID into configuration.

Syntax:

/trust
/trust chat
/trust remove

Expected behavior:

  1. Works only for users already listed in TelegramBot:AllowedUserIds.
  2. In a private chat, explains that no chat trust entry is required.
  3. In a group or forum topic, stores the current chat ID in local Telegram state.
  4. Allows future commands, callbacks, topic workflows, audio, and attachments from allowlisted users in that chat.
  5. Allows the trusted chat root and each forum topic to keep separate active project/session state.
  6. /trust remove removes Telegram-granted trust for the current chat. If the chat is also listed in TelegramBot:AllowedChatIds, configuration still allows it.

/doctor

Explains the current conversation, routing, project, session, workspace, queue state, and next recommended action.

Aliases:

/diag
/diagnostics

Syntax:

/doctor

Expected behavior:

  1. Shows whether the user and chat are allowed.
  2. Shows whether plain text can auto-route.
  3. Shows known project/session counts and current selections.
  4. Shows workspace roots and process directory.
  5. Shows outbound queue counts.
  6. Ends with a concrete next action.

Use this before changing configuration blindly.

/debug

Shows or changes the Telegram debug preamble mode.

Syntax:

/debug
/debug status
/debug on
/debug off
/debug reset

Expected behavior:

  1. /debug or /debug status shows the effective setting, runtime override, and configuration default.
  2. /debug on starts prefixing Telegram text messages with diagnostic metadata.
  3. /debug off disables the runtime override.
  4. /debug reset clears the runtime override and returns to TelegramBot:Outbound:DebugPreambleEnabled.
  5. Preambles include source, chat/topic, session, turn, and active-turn fields when known.

Use this when investigating whether foreground replies, queued work, and live Codex turn output are interleaving.

Trace controls are also available through /debug trace ...:

/debug trace status
/debug trace on
/debug trace off
/debug trace latest

/debug trace on enables local JSONL trace-file writes for this process. In-memory turn diagnostics are still collected for recent turns even when file tracing is off.

Structured interface capture is available through /debug capture ...:

/debug capture status
/debug capture on
/debug capture off
/debug capture full on
/debug capture full on 30m
/debug capture full off
/debug capture latest
/debug capture <traceId>

Expected behavior:

  1. /debug capture on enables metadata capture: Telegram/Codex ids, event kinds, counts, text lengths, attachment metadata, local paths, routing decisions, queue/chunk counts, statuses, and errors.
  2. /debug capture full on enables full capture for a bounded TTL. Full capture writes redacted message bodies, Codex input text, Codex event bodies, final responses, and outbound Telegram chunk text to local trace files.
  3. /debug capture full off returns to metadata capture while trace writing remains enabled.
  4. /debug capture off disables trace-file capture for this process. Recent in-memory diagnostics remain available.
  5. Trace files are written as JSONL under TelegramDebugTrace:TraceDirectory when set; otherwise under the configured data root in telegram-traces/yyyyMMdd/<traceId>.jsonl.
  6. Secret-looking values such as authorization headers, tokens, API keys, cookies, and bot tokens are redacted before trace files are written.
  7. Full capture is intentionally visible in status output so it is not left on accidentally.
  8. Attachment file copies are only written when full capture is enabled and TelegramDebugTrace:CaptureAttachmentCopies is true. Copies are placed beside the trace file under telegram-traces/yyyyMMdd/<traceId>.attachments/, and the JSONL event records the copied paths.

/trace

Shows local trace and turn-delivery diagnostics.

Syntax:

/trace
/trace latest
/trace <traceId>
/trace status
/trace on
/trace off
/trace reset

Expected behavior:

  1. /trace latest shows the newest in-memory trace diagnostics.
  2. /trace on and /trace off control trace-file writing for the current process.
  3. Diagnostics distinguish Telegram input receipt, bundling, queueing, steering, Codex send/plan requests, actual Codex turn start, Codex terminal events, and Telegram outbound delivery.
  4. Diagnostics show Codex event counts, assistant-output character counts, queued outbound characters, sent chunks, pending chunks, compaction, rate limits, timeouts, and last Telegram API/send errors.
  5. /debug capture latest and /debug capture <traceId> reuse the same diagnostics view.

/output

Shows or changes the Telegram output presentation mode.

Syntax:

/output mode
/output mode compact
/output mode verbose
/output mode live
/output mode final
/output mode reset

Expected behavior:

  1. /output mode shows the effective mode and whether it came from configuration or a runtime override.
  2. compact sends final output durably and publishes sparse still-working pulses while active work is otherwise quiet.
  3. verbose sends progress and update events as durable Telegram messages according to the normal filters.
  4. live uses an editable live turn card for progress/update events while final output remains durable Telegram history.
  5. final suppresses normal progress/update chatter and sends final output, errors, approval requests, and artifacts.
  6. reset clears the runtime override and returns to TelegramOutput:PresentationMode.
  7. The same choices are available from the Output Mode button on session cards.

/turn

Shows operational turn history retained by the bot.

Syntax:

/turn updates [sessionId] [turnId]
/turn progress [sessionId] [turnId]
/turn full [sessionId] [turnId]
/turn final [sessionId] [turnId]

Expected behavior:

  1. updates shows user-facing normalized events and omits low-value progress noise.
  2. progress shows retained progress history when progress capture is enabled or summarized.
  3. full shows all retained operational events for the turn.
  4. final shows retained final-response events.
  5. The Show Updates, Show Progress, Show Full Turn, and Final buttons use the same operational history path for the selected session.
  6. Use the slash form with an explicit turnId when inspecting an older turn; button payloads stay compact for Telegram callback limits.
  7. Operational history is not full debug capture. Use /debug capture full on when raw Telegram/Codex interface traffic is needed.

/projects

Lists known local project directories.

Syntax:

/projects

Expected behavior:

  1. Lists projects stored in local state.
  2. Marks the active project for this Telegram conversation.
  3. Adds Use buttons when projects are available.

/project add <path>

Adds a local directory to the project catalog and selects it for the current conversation.

Syntax:

/project add <absolute directory path>

Examples:

/project add C:\src\my-repo
/project add /home/you/src/my-repo

Expected behavior:

  1. Validates that the directory is under an allowed workspace root.
  2. Adds the normalized path to local project state.
  3. Selects the project for the current private chat, group, or topic.
  4. Rejects paths outside configured workspace roots.

/project <number|name|path>

Selects an existing project.

Syntax:

/project <number>
/project <name>
/project <absolute path>

Examples:

/project 1
/project codex-telegram
/project C:\src\my-repo

Expected behavior:

  1. Selects a matching known project.
  2. Rejects ambiguous names and asks for a clearer selector.
  3. Stores the selection for the current conversation.

/project current

Shows the active project for the current conversation.

Syntax:

/project current

Expected behavior:

  1. Shows project name/key/path when a project is selected.
  2. Gives selection guidance when no project is active.

/new [name]

Creates and selects a new Codex session in the active project.

Syntax:

/new
/new <session name>

Example:

/new release-readiness

Expected behavior:

  1. Requires an active project.
  2. Creates a Codex session with the supplied name, or an auto-generated project-based name when omitted.
  3. Selects it for the current conversation.
  4. Starts following live output for that session.
  5. Includes a compact Rate limits line when Codex account data is available quickly.

Plain Text Message

In a private chat, trusted group root, or forum topic, a normal message continues the active session.

Example:

Review the README and tell me the top three setup gaps. Do not edit files.

Expected behavior:

  1. Uses the selected session when one exists.
  2. Creates a project-based default session if no session is selected.
  3. Sends attachments with the prompt when attachments are present.
  4. With the default TelegramInput:DefaultCaptureMode of BundleAlways, creates or updates an editable input bundle before starting Codex.
  5. If an operator chooses ImmediateText, very long plain-text messages still open an input bundle before a turn starts, which keeps Telegram-split prompts together.
  6. The input bundle card shows only the current useful actions, such as Send now, Queue next, Steer current turn, Add more, Clear, and Cancel.
  7. If TelegramInput:AutoDispatchAfterSeconds is greater than 0, an open bundle is automatically sent or queued after that many idle seconds with no new captured input.
  8. Telegram albums/media groups are debounced by TelegramInput:MediaGroupDebounceMilliseconds and forwarded as one inbound bundle candidate with all collected media.
  9. Slash commands remain available as fallbacks.

Cards are the live mobile control surface. Editing a session or input-bundle card does not replace the durable Telegram message history: assistant output is still delivered as normal Telegram messages after a bundle is sent, queued, or steered.

/send <text>

Sends text to the active session.

Syntax:

/send <text>

Example:

/send summarize the current repository state

Expected behavior:

  1. Routes text to the active session or creates one when allowed.
  2. Useful when Telegram privacy mode or an unsupported chat type prevents normal auto-routing.
  3. Keeps immediate send behavior for command fallback use; normal non-command input is captured into an input bundle by default and can be changed with TelegramInput:DefaultCaptureMode.

/steer <text>

Adds guidance to an active turn.

Syntax:

/steer <text>

Example:

/steer focus on the failing test first

Expected behavior:

  1. Requires an active selected session.
  2. Sends steering text to the currently active Codex turn.
  3. Replies with an error if there is no live turn to steer.
  4. If Codex does not accept the steer request quickly, posts a durable pending message and later reports success or failure.

Use /send for normal new work. Use /steer only while Codex is already working. Steering text is sent immediately and cannot be edited after the bot hands it to Codex; edit queued text first with /queue edit <id> <new text>.

/queue

Shows queued prompts submitted by you for the current Telegram conversation.

Syntax:

/queue
/queued

Expected behavior:

  1. Lists queued prompts in FIFO order for the current private chat, group root, or forum topic.
  2. Shows the target session, queued age, short queue item ID, prompt preview, and attachment count.
  3. Adds Send now, Edit, and Delete buttons for each listed item.
  4. Keeps the list conversation-scoped by default so queued text from other chats or topics is not shown accidentally.

/queue all

Shows your queued prompts across Telegram conversations.

Syntax:

/queue all

Expected behavior:

  1. Lists queued prompts submitted by your Telegram user ID across conversations.
  2. Adds the conversation label for each queued item.
  3. Uses the same Send now, Edit, and Delete buttons.

/queue edit <id> <new text>

Replaces the text for one queued prompt.

Syntax:

/queue edit <id> <new text>

Example:

/queue edit a1b2c3d4 focus only on the failing Linux startup path

Expected behavior:

  1. Accepts a full queue item ID, an unambiguous prefix, or the current conversation list number.
  2. Replaces queued text while preserving any queued attachments.
  3. Rejects unknown, ambiguous, or already-drained items without changing the queue.

/queue delete <id>

Deletes one queued prompt.

Syntax:

/queue delete <id>

Expected behavior:

  1. Accepts a full queue item ID, an unambiguous prefix, or the current conversation list number.
  2. Removes only that queued prompt.
  3. Deletes temporary attachment files owned by that queued prompt.
  4. Leaves other queued prompts and session-level state untouched.

/queue send <id>

Removes one queued prompt and sends it as steering input to the active turn.

Syntax:

/queue send <id>
/queue now <id>
/queue steer <id>

Expected behavior:

  1. Accepts a full queue item ID, an unambiguous prefix, or the current conversation list number.
  2. Removes the queued prompt before attempting to steer the active turn.
  3. Sends text and preserved attachments through the active-turn steering path.
  4. Requeues the item if steering fails, including when no active turn is running.
  5. If Codex does not accept the steer request quickly, posts a durable pending message and later reports success or requeues on failure.
  6. Deletes temporary attachment files only after steering succeeds or after the target session is gone.

/sessions

Lists active and Telegram-managed sessions.

Syntax:

/sessions

Expected behavior:

  1. Lists active and recently managed sessions.
  2. Marks the active session with *.
  3. Shows status and relative last activity.
  4. Adds Use buttons for listed sessions.

/sessions all [count]

Shows recent Codex history, including older idle sessions.

Syntax:

/sessions all
/sessions all <count>

Examples:

/sessions all
/sessions all 20

Expected behavior:

  1. Includes older idle history.
  2. Clamps the count to the supported range.
  3. Adds Use buttons for listed sessions.

/use <sessionId>

Selects an existing session for the current conversation.

Syntax:

/use <sessionId>

Example:

/use 019df8e5

Expected behavior:

  1. Accepts a full session ID or unambiguous prefix.
  2. Selects the session for this conversation.
  3. Starts following live output for that session.
  4. Rejects unknown or ambiguous IDs.

/status [sessionId]

Shows session status.

Syntax:

/status
/status <sessionId>

Expected behavior:

  1. Defaults to the active session.
  2. Renders a concise snapshot with active state, current activity, elapsed time when active, queued prompt count, pending Telegram delivery when relevant, output mode, model, and last activity.
  3. Keeps trace IDs, working directories, detailed delivery counters, and closeout bodies out of the default snapshot; use /debug, /trace, /outbound, or /turn when you need that detail.
  4. Includes a compact Rate limits line with five-hour and weekly block percentages and reset times when Codex account data is available.
  5. Shows the last turn closeout when the current process has observed one, including missing-final-response warnings for streamed assistant text.
  6. Includes buttons for Send/Add Input, Steer, Queue, Refresh, Tail/History, Debug/Trace, Model, Thinking, and Stop/Cancel.

/usage

Shows Codex account usage reported by the local Codex app-server.

Syntax:

/usage

Expected behavior:

  1. Reads Codex account rate-limit data from the local Codex app-server.
  2. Shows remaining percentage for the five-hour block.
  3. Shows remaining percentage for the weekly block.
  4. Shows reset timing and local reset time when Codex reports reset timestamps.
  5. Fails with clear setup text if the local Codex executable is missing or the app-server does not expose account usage.

/tail [count]

Shows recent output for the active session.

Syntax:

/tail
/tail <count>

Examples:

/tail
/tail 80

Expected behavior:

  1. Defaults to the active session.
  2. Defaults to 40 recent lines when no count is supplied.
  3. Starts following live output for the session.
  4. Adds a session button when applicable.
  5. Includes recent in-process session events when transcript output alone does not explain the latest turn state.

/tail <sessionId> [count]

Shows recent output for a specific session.

Syntax:

/tail <sessionId>
/tail <sessionId> <count>

Example:

/tail 019df8e5 120

Expected behavior:

  1. Resolves the full session ID or unambiguous prefix.
  2. Shows recent output for that session.
  3. Starts following live output for that session in the current conversation.

/model

Shows model settings and model-selection buttons for the active session.

Syntax:

/model

Expected behavior:

  1. Shows current model and thinking effort.
  2. Includes a compact Rate limits line when Codex account data is available quickly.
  3. Shows available thinking efforts when known.
  4. Shows up to eight model buttons when available.
  5. Marks the selected model with [x].

/model [model] [thinking <effort>]

Changes model settings for the active session.

Syntax:

/model <model>
/model <model> thinking <effort>
/model thinking <effort>

Examples:

/model gpt-5.4
/model gpt-5.4 thinking high
/model thinking xhigh

Supported thinking values:

minimal
low
medium
high
xhigh

Expected behavior:

  1. Updates the selected session settings.
  2. Leaves unspecified values unchanged.
  3. Returns the updated model settings.
  4. Includes a compact Rate limits line when Codex account data is available quickly.
  5. Rejects invalid model or effort values reported by Codex.

/thinking

Shows thinking-effort buttons for the active session.

Syntax:

/thinking

Expected behavior:

  1. Shows current model and thinking effort.
  2. Shows available thinking-effort buttons when known.
  3. Marks the selected effort with [x].
  4. Controls the standard thinking effort for active turns; the bootstrap Codex runtime menu exposes a separate plan-mode thinking default.

/thinking <effort>

Changes the thinking effort for the active session.

Syntax:

/thinking <minimal|low|medium|high|xhigh>

Example:

/thinking high

Expected behavior:

  1. Updates only the thinking effort.
  2. Leaves the model unchanged.
  3. Returns the updated model settings.

/plan <request>

Asks Codex to plan and clarify before implementation for the active session.

Syntax:

/plan <request>

Example:

/plan review the current session flow and suggest the safest next implementation step

Expected behavior:

  1. Resolves the active session for the current conversation.
  2. Sends the request as a Plan mode turn rather than a normal send turn.
  3. Queues the request when the session is busy, using the same ordering rules as normal prompts.
  4. Starts the plan-mode flow so Codex can ask follow-up questions when needed.

/answer <answer>

Answers a pending Plan mode question for the active conversation.

Syntax:

/answer <answer>

Example:

/answer Use the faster implementation path and keep the bootstrap menu change minimal.

Expected behavior:

  1. Sends the answer to the pending Plan mode question for the active conversation.
  2. Replies that no Plan mode question is waiting if the conversation has nothing pending.
  3. Leaves the selected session unchanged.

/goal

Shows the current goal for the active session.

Syntax:

/goal
/goal show

Expected behavior:

  1. Resolves the active session for the current conversation.
  2. Shows the objective, status, optional token budget, tokens used, time used, and update age when a goal is set.
  3. Replies that no session goal is set when Codex has no goal for the thread.
  4. Replies with setup guidance when the connected Codex backend does not support thread goals.

/goal [objective]

Sets the goal objective for the active session.

Syntax:

/goal <objective>
/goal set <objective>
/goal set <objective> --budget <tokens>

Examples:

/goal get /goal working in the Telegram app
/goal set stabilize this branch --budget 12000

Expected behavior:

  1. Creates or replaces the active session goal.
  2. Sets goal status to active.
  3. Sends an optional token budget when provided.
  4. Returns the updated goal.

/goal clear|pause|resume|complete

Changes goal state for the active session.

Syntax:

/goal clear
/goal pause
/goal resume
/goal complete

Expected behavior:

  1. /goal clear removes the goal from the thread.
  2. /goal pause changes goal status to paused.
  3. /goal resume changes goal status to active.
  4. /goal complete changes goal status to complete.
  5. Returns the updated goal unless the goal was cleared.

Inline Model Control Phrase

Sets model/thinking and sends a prompt in one message.

Syntax:

Codex settings model <model> thinking <effort>: <prompt>

Example:

Codex settings model gpt-5.4 thinking high: inspect the release docs for gaps

Expected behavior:

  1. Parses the model/thinking directive.
  2. Updates the session settings.
  3. Sends the remaining prompt text to Codex.

/outbound

Shows outbound Telegram queue status.

Syntax:

/outbound
/outbound status

Expected behavior:

  1. Shows pending destinations, messages, chunks, and characters.
  2. Shows global backoff when Telegram rate limits are active.
  3. Shows pending output for the current chat.
  4. Use /trace latest when you need to know whether Codex finished, Telegram is still draining, output was compacted, or Telegram send failed.

Only status is implemented as an outbound subcommand.

/stop [sessionId]

Gracefully stops a session.

Syntax:

/stop
/stop <sessionId>

Expected behavior:

  1. Defaults to the active session.
  2. Requests a graceful stop.
  3. Clears pending queued prompts for that session.

/kill <sessionId> confirm

Hard-stops a session.

Syntax:

/kill <sessionId> confirm

Expected behavior:

  1. Requires explicit confirm.
  2. Resolves the full session ID or unambiguous prefix.
  3. Hard-stops the session.
  4. Clears pending queued prompts for that session.

Use /stop first unless a session is stuck.

/rename <sessionId> <new name>

Renames a session.

Syntax:

/rename <sessionId> <new name>

Example:

/rename 019df8e5 release demo

Expected behavior:

  1. Resolves the session ID.
  2. Updates the display name.
  3. Does not change transcript logs.

/forget <sessionId>

Hides a stopped or exited session from the managed list without deleting logs.

Syntax:

/forget <sessionId>

Expected behavior:

  1. Resolves the session ID.
  2. Removes it from the Telegram-managed session list.
  3. Does not delete transcript logs.

/restart confirm

Explains restart behavior for the standalone process.

Syntax:

/restart confirm

Expected behavior:

  1. Does not restart the process from Telegram.
  2. Explains that restart must be handled by the terminal, service manager, scheduled task, or container/runtime supervisor.

/topics

Lists topic/session bindings for the current chat.

Aliases:

/threads
/topic list
/topic ls

Expected behavior:

  1. Lists main-chat and forum-topic bindings known for the chat.
  2. Shows session summary, project name, and queued prompt count when present.
  3. Marks the current topic or chat root with *.

/topic current

Shows the current topic/session binding.

Syntax:

/topic current

Expected behavior:

  1. Shows topic thread ID.
  2. Shows active session status.
  3. Shows active project status when present.

/topic new <name> [| <path>]

Creates a new Telegram forum topic and matching Codex session.

Syntax:

/topic new <name>
/topic new <name> | <absolute directory path>

Examples:

/topic new release readiness
/topic new docs polish | C:\src\my-repo

Expected behavior:

  1. Works only in a forum-enabled supergroup.
  2. Requires the bot to have the topic-management rights Telegram requires.
  3. Uses the supplied path when provided and allowed.
  4. Otherwise uses the active project for the current conversation.
  5. Creates a Telegram topic and Codex session, then binds them together.

/topic attach [sessionId]

Binds the current forum topic to an existing Codex session.

Syntax:

/topic attach
/topic attach <sessionId>

Expected behavior:

  1. Must be run inside the forum topic to bind.
  2. With no session ID, tries the topic's current session first, then the user's private-chat active session.
  3. With a session ID, resolves the full ID or unambiguous prefix.
  4. Updates the topic's active session and project binding.

Attachments

Images and documents can be attached to a routed message.

Expected behavior:

  1. The file is downloaded to a temporary local path.
  2. If the input is captured into a bundle or queued for later, the attachment is copied under the configured local data root in telegram-attachments before the bundle/queue record is persisted.
  3. The attachment is forwarded to Codex with the prompt, bundle, queued prompt, or steering input when supported.
  4. Temporary source files are removed after durable copy or after processing when possible.
  5. If a persisted attachment is missing later, the bot reports the missing attachment instead of silently dropping it.

Voice Notes

Voice notes are transcribed before being sent to Codex.

Requirements:

  1. OpenAI:ApiKey or OPENAI_API_KEY.
  2. A transcription-capable OpenAI:Model.
  3. ffmpeg when transcoding is needed.
  4. Audio duration inside configured limits.

Suggested first voice prompt:

Please review the current project and tell me the three most important setup risks. Keep it concise and do not edit files.

Queueing And Delivery

If a prompt arrives while a session has an active turn, it is queued for that session.

Expected behavior:

  1. Queued prompts run in order.
  2. Separate sessions can progress independently.
  3. Telegram output is rate-limited but queued text items are sent as separate messages.
  4. Long individual outputs may still be split into multiple Telegram chunks.
  5. Assistant output is sent as durable Telegram messages/chunks, not by continuously editing the live status card.
  6. Completed turns append a standalone ~~ fin ~~ marker after final output.
  7. /tail, /history, and /trace are the authoritative paths when Telegram scrollback or edited cards are not enough.