Skip to main content

tgkit

Delivery toolkit on top of aiogram 3.30+.

  • Telegram-safe markdown: escape/format LLM output for parse_mode=MarkdownV2, split at the 4096 UTF-16 limit, truncate captions after escaping.
  • Rate-limit-aware sends: every send/edit absorbs retry after in place; formatting rejections degrade to plain text, never silently.
  • Degradation ladder: Rich Message → MarkdownV2 → plain. DeliveryOutcome tells you which tier landed and why the others did not.
  • Rich Messages (Bot API 10.x): 32k-char GFM documents, ![alt](/abs/path) embeds lifted into inline media, spill and rejections reported.
  • Streamed agent turns: Turn renders one in-flight reply (answer + activity + status), streams it as a draft in private chats or paced edits in groups, then persists it as a durable Rich Message with a collapsed Activity Log.

tgkit knows nothing about your agent framework, STT provider or vision model. Those are injected.

Install

uv add tgkit

Python ≥ 3.12. Hard deps: aiogram>=3.30, pillow>=11.

Send text

from aiogram import Bot
from tgkit import send_text, with_retry

bot = Bot(token="...")

async def main() -> None:
    outcome = await with_retry(send_text, bot, chat_id=123, text="# Hello\n\n| a | b |\n|---|---|\n| 1 | 2 |")
    print(outcome.tier)          # "rich" | "markdownv2" | "plain"
    print(outcome.message_id)    # last message produced
    if outcome.degraded:
        print(outcome.error_chain)

send_text walks the ladder itself; with_retry adds the outer retry-after policy for the whole call.

Stream an agent turn

Supply an Event Classifier: (event, activity_limit) -> (kind, payload) where kind is "text" (payload: str), "activity" (payload: (activity_id, line)) or "ignored". tgkit never interprets your events.

from tgkit import EventKind, Turn

def classify(event: object, activity_limit: int) -> tuple[EventKind, object]:
    match event:
        case {"type": "text", "delta": delta}:
            return "text", delta
        case {"type": "tool", "id": tool_id, "name": name}:
            return "activity", (tool_id, f"🔧 {name}")
    return "ignored", None

async def run(bot, chat_id: int, agent) -> None:
    turn = await Turn.create(bot, chat_id, classify_event=classify)
    async for event in agent.stream():
        await turn.notify(event)
    await turn.persist()          # final Rich Message + Activity Log

Turn.notify raises RuntimeError when no classifier was given; append_answer / add_activity work without one.

Transcribe a voice note

Supply a Transcriber: async (bytes) -> str.

from tgkit.voice import transcribe_voice_text

async def whisper(audio: bytes) -> str:
    ...  # your STT call

text = await transcribe_voice_text(bot, message.voice, transcribe=whisper)

Empty transcripts and transcriber failures raise TelegramVoiceTranscriptionError.

More

Development

uv sync --all-groups
just check     # ruff format --check, ruff check, pytest

MIT © 2026 RoCry

Metadata

Release files for tgkit 0.1.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for tgkit 0.1.0
File Size Uploaded
tgkit-0.1.0.tar.gz 130.2 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for tgkit 0.1.0
File Interpreter ABI Platform
tgkit-0.1.0-py3-none-any.whl Python 3 none any Details

Total release size: 183.8 kB

Release files / tgkit-0.1.0.tar.gz

Download URL tgkit-0.1.0.tar.gz
Size 130.2 kB
Tags Source
SHA-256 checksum
How to use checksums
d8d0fa4d15a22a3ec7cf1cda64dc8a13db8c648e0beef94171bd5cedcc4bd6ad
BLAKE2b-256 checksum
How to use checksums
15d3c6f1492eb057fe15201610ab316c245149c864911e03f708fa55d482b9a2
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Sep 7, 2026.

Transparency log

Release files / tgkit-0.1.0-py3-none-any.whl

Download URL tgkit-0.1.0-py3-none-any.whl
Size 53.6 kB
Tags Python 3
SHA-256 checksum
How to use checksums
e666c0f61c3f275850bd248f9247eb0fb5b32ccb28f756757ebcec43d905f95d
BLAKE2b-256 checksum
How to use checksums
76fec23e31fdd26301538045634b7b7aacefea235d57f22b5223fbabdf9b84f2
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Sep 7, 2026.

Transparency log

Release history Release notifications | RSS feed

This release

0.1.0 This release

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page