Skip to content

Commit 1470b43

Browse files
committed
fix(telegram): rotate previews after visible tool output
1 parent dd643b5 commit 1470b43

2 files changed

Lines changed: 12 additions & 7 deletions

File tree

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ Docs: https://docs.openclaw.ai
1111
- Voice Call/realtime: add opt-in OpenClaw agent voice context capsules and consult-cadence guidance so Gemini/OpenAI realtime calls can sound like the configured agent without consulting the full agent on every ordinary turn. Thanks @scoootscooob.
1212
- Docker/Gateway: harden the gateway container by dropping `NET_RAW` and `NET_ADMIN` capabilities and enabling `no-new-privileges` in the bundled `docker-compose.yml`. Thanks @VintageAyu.
1313
- Telegram: accept plugin-owned numeric forum-topic targets in the agent message tool and keep reply-dispatch provider chunks behind a real stable runtime alias during in-place package updates. Fixes #77137. Thanks @richardmqq.
14+
- Telegram/streaming: keep draft preview rotation from reusing a pre-tool assistant preview after visible tool or media output lands between compaction replay and the next assistant message. Thanks @vincentkoc.
1415
- Channels/WhatsApp: support explicit WhatsApp Channel/Newsletter `@newsletter` outbound message targets with channel session metadata instead of DM routing. Fixes #13417; carries forward the narrow outbound target idea from #13424. Thanks @vincentkoc and @agentz-manfred.
1516
- TTS/telephony: honor provider voice/model overrides in telephony synthesis providers so Google Meet agent speech logs match the backend that actually produced the audio. Thanks @vincentkoc.
1617
- Voice Call/realtime: bound the paced Twilio audio queue and close overloaded realtime streams before provider audio can pile up behind the websocket backpressure guard. Thanks @vincentkoc.

extensions/telegram/src/bot-message-dispatch.ts

Lines changed: 11 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -555,6 +555,7 @@ export const dispatchTelegramMessage = async ({
555555
let splitReasoningOnNextStream = false;
556556
let skipNextAnswerMessageStartRotation = false;
557557
let pendingCompactionReplayBoundary = false;
558+
let discardAnswerPreviewOnNextRotation = false;
558559
let draftLaneEventQueue = Promise.resolve();
559560
const reasoningStepState = createTelegramReasoningStepState();
560561
const enqueueDraftLaneEvent = (task: () => Promise<void>): Promise<void> => {
@@ -600,6 +601,7 @@ export const dispatchTelegramMessage = async ({
600601
const materializedId = await answerLane.stream?.materialize?.();
601602
const previewMessageId = materializedId ?? answerLane.stream?.messageId();
602603
if (
604+
!discardAnswerPreviewOnNextRotation &&
603605
typeof previewMessageId === "number" &&
604606
activePreviewLifecycleByLane.answer === "transient"
605607
) {
@@ -613,6 +615,7 @@ export const dispatchTelegramMessage = async ({
613615
answerLane.stream?.forceNewMessage();
614616
didForceNewMessage = true;
615617
}
618+
discardAnswerPreviewOnNextRotation = false;
616619
resetDraftLaneState(answerLane);
617620
answerLaneHasAssistantContent = false;
618621
if (didForceNewMessage) {
@@ -967,11 +970,12 @@ export const dispatchTelegramMessage = async ({
967970
if (isDispatchSuperseded()) {
968971
return;
969972
}
970-
const clearPendingCompactionReplayBoundaryOnVisibleBoundary = (
971-
didDeliver: boolean,
972-
) => {
973+
const markVisibleNonPreviewBoundary = (didDeliver: boolean) => {
973974
if (didDeliver && info.kind !== "final") {
974975
pendingCompactionReplayBoundary = false;
976+
if (answerLane.hasStreamedMessage) {
977+
discardAnswerPreviewOnNextRotation = true;
978+
}
975979
}
976980
};
977981
if (payload.isError === true) {
@@ -1047,6 +1051,8 @@ export const dispatchTelegramMessage = async ({
10471051
});
10481052
if (info.kind === "final") {
10491053
emitPreviewFinalizedHook(result);
1054+
} else if (segment.lane === "answer" && result.kind === "sent") {
1055+
markVisibleNonPreviewBoundary(true);
10501056
}
10511057
if (segment.lane === "reasoning") {
10521058
if (result.kind !== "skipped") {
@@ -1069,7 +1075,7 @@ export const dispatchTelegramMessage = async ({
10691075
if (reply.hasMedia) {
10701076
const payloadWithoutSuppressedReasoning =
10711077
typeof payload.text === "string" ? { ...payload, text: "" } : payload;
1072-
clearPendingCompactionReplayBoundaryOnVisibleBoundary(
1078+
markVisibleNonPreviewBoundary(
10731079
await sendPayload(payloadWithoutSuppressedReasoning),
10741080
);
10751081
}
@@ -1093,9 +1099,7 @@ export const dispatchTelegramMessage = async ({
10931099
}
10941100
return;
10951101
}
1096-
clearPendingCompactionReplayBoundaryOnVisibleBoundary(
1097-
await sendPayload(payload),
1098-
);
1102+
markVisibleNonPreviewBoundary(await sendPayload(payload));
10991103
if (info.kind === "final") {
11001104
await flushBufferedFinalAnswer();
11011105
pendingCompactionReplayBoundary = false;

0 commit comments

Comments
 (0)