← Back to PRs

#13278: feat(telegram): full sticker support — thumbnail fallback, set indexing, vision, cache

by thebtf open 2026-02-10 08:40 View on GitHub →
channel: telegram agents size: XL
## Summary Unlock the existing sticker pipeline for **all** sticker types (video, animated, static). Currently, `resolveMedia()` drops `is_animated` (TGS) and `is_video` (WEBM) stickers — which covers 90%+ of modern Telegram sticker packs. The cache stays empty, `sticker-search` returns nothing, and agents can't build sticker vocabulary. ### What this PR does - **Thumbnail fallback** — download `sticker.thumbnail` (static WEBP/JPEG ~320px, present on all types) instead of the full WEBM/TGS. Enables vision description for video and animated stickers. - **Sticker set indexing** — on first encounter with a sticker, pre-index the entire set (configurable limit, default 20) via fire-and-forget. Builds vocabulary exponentially faster. - **Cache TTL & eviction** — configurable TTL (default 90 days) and max entries (default 5000) with LRU eviction. - **Custom emoji vision** — resolve `custom_emoji` entities in messages via vision API, annotate text with `[emoji: description]`. Gated behind `customEmojiVision` (default: false). - **Vision model resolution** — remove hardcoded `VISION_PROVIDERS` list. New order: explicit `stickerVisionModel` config → agent's default model → catalog scan → auto-resolver. - **Sticker action hints** — add per-action usage hints to `message` tool description so agents understand `sticker-search` and `sticker` workflows. - **ReplyPayload stickerId** — extend `ReplyPayload` with optional `stickerId` for native sticker delivery. ### Config options (all in `channels.telegram`) | Option | Type | Default | Description | |--------|------|---------|-------------| | `stickerVisionModel` | `string` | agent's model | Explicit vision model (`provider/model`) | | `stickerSetIndexing` | `boolean` | `true` | Pre-index sticker sets on first encounter | | `stickerSetIndexLimit` | `number` | `20` | Max stickers to describe per set | | `stickerCacheTtlDays` | `number` | `90` | Cache entry TTL in days | | `stickerCacheMaxEntries` | `number` | `5000` | Max cache entries (LRU eviction) | | `customEmojiVision` | `boolean` | `false` | Enable vision for custom emoji | ### Files changed | Area | Files | Change | |------|-------|--------| | Core | `sticker-cache.ts` | Set indexing, cache eviction, vision model resolution | | Core | `bot/delivery.ts` | Thumbnail fallback for video/animated stickers | | Core | `bot-message-dispatch.ts` | Wire visionModel through dispatch, trigger set indexing | | New | `custom-emoji.ts` | Custom emoji resolution via vision API | | Schema | `types.telegram.ts`, `zod-schema.providers-core.ts` | Config types + Zod validation | | UX | `message-tool.ts` | ACTION_HINTS for sticker/sticker-search | | Types | `bot/types.ts`, `auto-reply/types.ts` | isVideo/isAnimated, stickerId | ## Test plan - [x] 47 test cases: thumbnail fallback, set indexing, cache eviction, custom emoji, sticker search - [x] Build passes (`npm run build`) - [x] Manual: send video sticker to bot → vision + cache → sticker-search returns it → agent sends it back - [ ] CI <!-- greptile_comment --> <h2>Greptile Overview</h2> <h3>Greptile Summary</h3> This PR expands Telegram sticker support to cover animated/video stickers by downloading static thumbnails for vision, adds a sticker cache with TTL/max-entry eviction, and introduces optional custom emoji vision annotation. It also adds fire-and-forget sticker set indexing to build sticker vocabulary faster, threads a `stickerVisionModel` override into dispatch, and extends reply payloads with `stickerId` so agents can send cached stickers back natively. Key integration points are `src/telegram/bot/delivery.ts` (sticker media resolution + thumbnail fallback), `src/telegram/bot-message-dispatch.ts` (vision description + caching + set indexing + emoji annotation), and `src/telegram/sticker-cache.ts` (persistence + eviction + model resolution + set indexing). <h3>Confidence Score: 3/5</h3> - This PR is close to mergeable but has correctness issues in the sticker pipeline around cached/pathless cases. - Core functionality is well-scoped and tests were added, but current gating/return-shape in sticker media resolution and dispatch can cause cached stickers to be skipped (especially when thumbnail download fails) and can prevent cached descriptions from being applied for non-vision models. These are user-visible behavior regressions for sticker handling in certain scenarios. - src/telegram/bot/delivery.ts, src/telegram/bot-message-dispatch.ts <!-- greptile_other_comments_section --> <sub>(5/5) You can turn off certain types of comments like style [here](https://app.greptile.com/review/github)!</sub> <!-- /greptile_comment --> --- ## Validation - [x] `pnpm build` — passes - [x] `pnpm check` — passes - [x] `pnpm test` — 47 test cases pass ## Contribution checklist - [x] **Focused scope**: Full sticker support (thumbnail fallback, set indexing, vision, cache) - [x] **What + why**: described above - [x] **AI-assisted**: Yes, Claude Code was used for implementation and iterative development. Testing level: fully tested (47 tests + manual)

Most Similar PRs