#21276: fix(telegram): stabilize partial finalization and MEDIA dedupe (AI-assisted)
channel: telegram
size: S
Cluster:
Telegram Streaming Enhancements
## Summary
- Problem: Telegram `streamMode: partial` finalization could regress/overwrite expected final behavior, and MEDIA path variants (e.g. `file://` vs local path) could be treated as different entries.
- Why it matters: Users can see unstable final message behavior and duplicate/incorrect media handling in Telegram.
- What changed: Stabilized partial-to-final ordering in Telegram draft flow, normalized MEDIA path variants for dedupe, and added/updated focused tests.
- What did NOT change (scope boundary): No provider/model behavior changes outside Telegram/media payload handling.
## Change Type (select all)
- [x] Bug fix
- [ ] Feature
- [ ] Refactor
- [ ] Docs
- [ ] Security hardening
- [ ] Chore/infra
## Scope (select all touched areas)
- [ ] Gateway / orchestration
- [ ] Skills / tool execution
- [ ] Auth / tokens
- [ ] Memory / storage
- [x] Integrations
- [ ] API / contracts
- [ ] UI / DX
- [ ] CI/CD / infra
## Linked Issue/PR
- Closes #18780
- Related #18784
## User-visible / Behavior Changes
- Telegram partial streaming finalization is more stable and less likely to regress at finalization boundary.
- MEDIA path variants (`file://...` vs equivalent local path) are deduped consistently.
## Security Impact (required)
- New permissions/capabilities? (`No`)
- Secrets/tokens handling changed? (`No`)
- New/changed network calls? (`No`)
- Command/tool execution surface changed? (`No`)
- Data access scope changed? (`No`)
- If any `Yes`, explain risk + mitigation: `N/A`
## Repro + Verification
### Environment
- OS: macOS (local dev)
- Runtime/container: Node.js + pnpm
- Model/provider: N/A (unit tests)
- Integration/channel (if any): Telegram
- Relevant config (redacted): standard local config; no new config required
### Steps
1. Run Telegram partial-stream test paths and MEDIA payload dedupe tests.
2. Compare behavior for partial/final ordering and path-variant dedupe.
3. Confirm no regressions in targeted suites.
### Expected
- Stable finalization ordering in partial stream mode.
- Equivalent MEDIA paths dedupe to one logical entry.
### Actual
- Verified via passing targeted tests after patch.
## Evidence
- [x] Failing test/log before + passing after
- [ ] Trace/log snippets
- [ ] Screenshot/recording
- [ ] Perf numbers (if relevant)
## Human Verification (required)
- Verified scenarios: targeted Telegram draft-stream, dispatch, and payload dedupe tests.
- Edge cases checked: regressive partial snapshots, file/path variant dedupe.
- What you did **not** verify: full live Telegram E2E against production bot.
## Compatibility / Migration
- Backward compatible? (`Yes`)
- Config/env changes? (`No`)
- Migration needed? (`No`)
- If yes, exact upgrade steps: `N/A`
## Failure Recovery (if this breaks)
- How to disable/revert this change quickly: revert this PR commits.
- Files/config to restore: Telegram draft/payload files touched in this PR.
- Known bad symptoms reviewers should watch for: duplicate media outputs or partial/final ordering regressions.
## Risks and Mitigations
- Risk: Over-dedup in unusual path edge cases.
- Mitigation: path-variant tests added/updated; scope limited to MEDIA dedupe logic.
<!-- greptile_comment -->
<h3>Greptile Summary</h3>
Stabilizes Telegram partial finalization ordering and normalizes MEDIA path variants for deduplication. The changes address two key issues: (1) partial-to-final message ordering regressions, and (2) `file://` vs local path variants being treated as different media entries.
**Key changes:**
- Added `normalizeMediaForDedupe` function in `reply-payloads.ts` that strips `file://` prefix to normalize path variants for consistent deduplication
- Added tests for cross-variant MEDIA deduplication (`file:///tmp/photo.jpg` vs `/tmp/photo.jpg`)
- Added test coverage for draft stream finalization edge cases (message ID available after stop)
- Added tests for partial mode behavior (no force new message on assistant restart or reasoning end)
**Issues found:**
- Two duplicate test names in `bot-message-dispatch.test.ts` that will cause test framework issues (lines 418 and 504)
<h3>Confidence Score: 3/5</h3>
- safe to merge after fixing duplicate test names
- core logic changes are focused and well-tested, but duplicate test names will cause test execution issues that must be resolved before merge
- src/telegram/bot-message-dispatch.test.ts requires removing duplicate tests before merge
<sub>Last reviewed commit: 5ac94b4</sub>
<!-- greptile_other_comments_section -->
<!-- /greptile_comment -->
Most Similar PRs
#19399: telegram: fix MEDIA false positives and partial final drop
by HOYALIM · 2026-02-17
85.3%
#19479: fix(telegram): skip redundant final edit in partial streaming mode
by v8hid · 2026-02-17
82.2%
#17953: fix(telegram): prevent silent message loss and duplicate messages i...
by zuyan9 · 2026-02-16
81.4%
#19673: fix(telegram): avoid starting streaming replies with only 1-2 words
by emanuelst · 2026-02-18
80.8%
#16321: Fix #12767: suppress HEARTBEAT_OK leakage in Telegram DM replies
by tdjackey · 2026-02-14
79.8%
#15985: fix(telegram): defer buffer deletion until processing succeeds
by coygeek · 2026-02-14
79.2%
#20735: fix: skip auto-attaching tool MEDIA: paths already sent via message t…
by anillBhoi · 2026-02-19
78.6%
#14794: fix: parse inline MEDIA: tokens in agent replies
by explainanalyze · 2026-02-12
78.4%
#7261: fix(telegram): preserve DM topic thread id for outbound media
by ViffyGwaanl · 2026-02-02
78.3%
#22434: feat(telegram): support sending original quality images
by godenjan · 2026-02-21
78.2%