feat(messages): forward batches and auto-preserve albums#129
Merged
chigwell merged 4 commits intoMay 22, 2026
Conversation
`forward_message` now accepts `Union[int, List[int]]` for `message_id`. When given a list, Telethon's `forward_messages` preserves Telegram album grouping (messages sharing a `grouped_id`) in the destination chat, which was impossible with the previous single-int signature. `list_messages` and `get_message_context` now include `grouped_id` in each record when present, so callers can detect album membership and forward all parts atomically. Motivated by an agent use case: forwarding multi-photo posts (3+ photos with a caption) produced one detached photo at a time. Without `grouped_id` exposure there was no way to discover sibling messages, and without list-id forward there was no way to preserve the album.
…ance
Small models hosting the MCP client often pick the simpler branch of
`Union[int, List[int]]` and fall back to looping single-int forwards,
defeating the album-grouping preservation added in the previous commit.
Two changes to nudge them toward the correct path:
1. `forward_message`: rewrite the docstring as a directive ("USE A LIST
WHENEVER FORWARDING >1 MESSAGE") with an Args block FastMCP parses
for per-parameter descriptions. The model now sees the rule front and
center in the tool description, not buried in a paragraph.
2. New tool `forward_messages` (plural) with a pure `List[int]` signature
— no Union, no anyOf in the resulting JSON Schema. A list-only schema
is unambiguous: the model has no "int branch" to fall back on.
Backward-compatible: `forward_message` still accepts both `int` and
`List[int]`.
Smaller MCP-client models reliably fail to check grouped_id before
forwarding and end up calling forward_message with the album anchor id
only — delivering one detached photo instead of the full post. Skill
prompts and tool-description directives don't move the needle on this.
Move the smarts server-side: when forward_message receives a single
int and the target message has a grouped_id, fetch a small window of
nearby ids (albums are allocated contiguously), filter siblings with
the same grouped_id, and forward them all in one Telethon call. The
destination receives the full grouped album intact.
Adds expand_album: bool = True so callers can opt out for the rare
case of forwarding exactly one item out of an album. List inputs are
left untouched — they remain the explicit batch path.
Net effect: the agent can be naive ("forward this post") and the
server still delivers the album correctly. Result message now states
when an expansion happened so the user is aware.
Owner
|
Hey @samplec0de, thank you for the contribution! Could I please ask you to fix the |
b332f2e to
dfc12ec
Compare
chigwell
approved these changes
May 22, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Three related changes to make forwarding work well in agent / MCP-client use:
forward_messageacceptsUnion[int, List[int]]. Passing a list of ids in a single call lets Telethon'sforward_messagespreserve Telegram album grouping (messages sharinggrouped_idarrive as one grouped album, not detached items).list_messagesandget_message_contextincludegrouped_idin each record when the message is part of an album. Callers can detect album membership programmatically (it was not exposed before).New
forward_messagestool (plural) with a pureList[int]signature, plus server-side album auto-expansion inforward_message: when called with a single int and the target message has agrouped_id, the server now fetches a small contiguous window of neighbour ids, filters siblings sharing the samegrouped_id, and forwards them all in one Telethon call. Anexpand_album: bool = Trueflag lets callers opt out for the rare case of forwarding one specific item out of an album.Motivation
When driven by a small MCP-client model (e.g.
gpt-oss-20bin LM Studio), the upstream behavior reliably broke for multi-photo channel posts: the model would callforward_messagewith the album's anchor id only and the destination received one detached photo. Tool-description directives and skill prompts did not move the needle.The two failure modes addressed:
grouped_idexposure, a client cannot tell that a message is part of a group, so it cannot construct the list even if the tool accepted one.The server-side auto-expand path (3) means the most common case ("forward this post") works correctly without any client intelligence at all.
Backward compatibility
forward_message(message_id=<int>, ...)— same call signature, but now expands albums by default. Opt out withexpand_album=Falseto restore the previous one-message behavior.forward_message(message_id=<list>, ...)— new capability, no behavior change for any existing caller.forward_messagesis new; no conflict.grouped_idinlist_messages/get_message_contextis an additive field that only appears when non-null; existing consumers ignoring unknown keys are unaffected.Commits
aaa4f28feat(messages): forward list of ids and expose grouped_id095d00bfeat(messages): add forward_messages (batch) tool and strengthen guidance85a8f39feat(forward_message): auto-expand albums on single-int forwardsTesting notes
Verified end-to-end against a real personal account: forwarding a 3-photo post from a public channel via the auto-expand path delivers one grouped album with the original "Forwarded from <source>" header to the destination, matching the result of forwarding the same post manually from the Telegram client.
Happy to split into separate PRs or rework the API surface if that fits the project direction better.