fix: stabilize Telegram draft boundaries and suppress NO_REPLY lead leaks (#33169)

* fix: stabilize telegram draft stream message boundaries

* fix: suppress NO_REPLY lead-fragment leaks

* fix: keep underscore guard for non-NO_REPLY prefixes

* fix: skip assistant-start rotation only after real lane rotation

* fix: preserve finalized state when pre-rotation does not force

* fix: reset finalized preview state on message-start boundary

* fix: document Telegram draft boundary + NO_REPLY reliability updates (#33169) (thanks @obviyus)
This commit is contained in:
Ayaan Zaidi
2026-03-03 22:49:33 +05:30
committed by GitHub
parent a7a9a3d3c8
commit 3d998828b9
8 changed files with 212 additions and 137 deletions

View File

@@ -8,7 +8,6 @@ export type DraftLaneState = {
stream: TelegramDraftStream | undefined;
lastPartialText: string;
hasStreamedMessage: boolean;
previewRevisionBaseline: number;
};
export type ArchivedPreview = {
@@ -329,43 +328,6 @@ export function createLaneTextDeliverer(params: CreateLaneTextDelivererParams) {
!hasMedia && text.length > 0 && text.length <= params.draftMaxChars && !payload.isError;
if (infoKind === "final") {
const hasPreviewButtons = Boolean(previewButtons?.some((row) => row.length > 0));
const canFinalizeDraftPreviewDirectly =
isDraftPreviewLane(lane) &&
lane.hasStreamedMessage &&
canEditViaPreview &&
!hasPreviewButtons;
let draftPreviewStopped = false;
if (canFinalizeDraftPreviewDirectly) {
const previewRevisionBeforeFlush = lane.stream?.previewRevision?.() ?? 0;
const finalTextSnapshot = text.trimEnd();
const hasEmittedPreviewInCurrentLane =
previewRevisionBeforeFlush > lane.previewRevisionBaseline;
const deliveredPreviewTextBeforeFinal = lane.stream?.lastDeliveredText?.() ?? "";
const finalTextAlreadyDelivered =
deliveredPreviewTextBeforeFinal === finalTextSnapshot && hasEmittedPreviewInCurrentLane;
const unchangedFinalText = text === lane.lastPartialText;
lane.stream?.update(text);
await params.flushDraftLane(lane);
await params.stopDraftLane(lane);
draftPreviewStopped = true;
const previewUpdated = (lane.stream?.previewRevision?.() ?? 0) > previewRevisionBeforeFlush;
const deliveredPreviewTextAfterFinal =
lane.stream?.lastDeliveredText?.() ?? deliveredPreviewTextBeforeFinal;
if (
(previewUpdated && deliveredPreviewTextAfterFinal === finalTextSnapshot) ||
(unchangedFinalText && finalTextAlreadyDelivered)
) {
lane.lastPartialText = text;
params.finalizedPreviewByLane[laneName] = true;
params.markDelivered();
return "preview-finalized";
}
params.log(
`telegram: ${laneName} draft final text not emitted; falling back to standard send`,
);
}
if (laneName === "answer") {
const archivedResult = await consumeArchivedAnswerPreviewForFinal({
lane,
@@ -378,7 +340,7 @@ export function createLaneTextDeliverer(params: CreateLaneTextDelivererParams) {
return archivedResult;
}
}
if (canEditViaPreview && !params.finalizedPreviewByLane[laneName] && !draftPreviewStopped) {
if (canEditViaPreview && !params.finalizedPreviewByLane[laneName]) {
await params.flushDraftLane(lane);
if (laneName === "answer") {
const archivedResultAfterFlush = await consumeArchivedAnswerPreviewForFinal({
@@ -410,9 +372,7 @@ export function createLaneTextDeliverer(params: CreateLaneTextDelivererParams) {
`telegram: preview final too long for edit (${text.length} > ${params.draftMaxChars}); falling back to standard send`,
);
}
if (!draftPreviewStopped) {
await params.stopDraftLane(lane);
}
await params.stopDraftLane(lane);
const delivered = await params.sendPayload(params.applyTextToPayload(payload, text));
return delivered ? "sent" : "skipped";
}