mirror of
https://github.com/openclaw/openclaw.git
synced 2026-05-06 06:20:43 +00:00
fix(telegram): rotate previews after visible tool output
This commit is contained in:
@@ -11,6 +11,7 @@ Docs: https://docs.openclaw.ai
|
||||
- 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.
|
||||
- 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.
|
||||
- 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.
|
||||
- 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.
|
||||
- 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.
|
||||
- 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.
|
||||
- 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.
|
||||
|
||||
@@ -555,6 +555,7 @@ export const dispatchTelegramMessage = async ({
|
||||
let splitReasoningOnNextStream = false;
|
||||
let skipNextAnswerMessageStartRotation = false;
|
||||
let pendingCompactionReplayBoundary = false;
|
||||
let discardAnswerPreviewOnNextRotation = false;
|
||||
let draftLaneEventQueue = Promise.resolve();
|
||||
const reasoningStepState = createTelegramReasoningStepState();
|
||||
const enqueueDraftLaneEvent = (task: () => Promise<void>): Promise<void> => {
|
||||
@@ -600,6 +601,7 @@ export const dispatchTelegramMessage = async ({
|
||||
const materializedId = await answerLane.stream?.materialize?.();
|
||||
const previewMessageId = materializedId ?? answerLane.stream?.messageId();
|
||||
if (
|
||||
!discardAnswerPreviewOnNextRotation &&
|
||||
typeof previewMessageId === "number" &&
|
||||
activePreviewLifecycleByLane.answer === "transient"
|
||||
) {
|
||||
@@ -613,6 +615,7 @@ export const dispatchTelegramMessage = async ({
|
||||
answerLane.stream?.forceNewMessage();
|
||||
didForceNewMessage = true;
|
||||
}
|
||||
discardAnswerPreviewOnNextRotation = false;
|
||||
resetDraftLaneState(answerLane);
|
||||
answerLaneHasAssistantContent = false;
|
||||
if (didForceNewMessage) {
|
||||
@@ -967,11 +970,12 @@ export const dispatchTelegramMessage = async ({
|
||||
if (isDispatchSuperseded()) {
|
||||
return;
|
||||
}
|
||||
const clearPendingCompactionReplayBoundaryOnVisibleBoundary = (
|
||||
didDeliver: boolean,
|
||||
) => {
|
||||
const markVisibleNonPreviewBoundary = (didDeliver: boolean) => {
|
||||
if (didDeliver && info.kind !== "final") {
|
||||
pendingCompactionReplayBoundary = false;
|
||||
if (answerLane.hasStreamedMessage) {
|
||||
discardAnswerPreviewOnNextRotation = true;
|
||||
}
|
||||
}
|
||||
};
|
||||
if (payload.isError === true) {
|
||||
@@ -1047,6 +1051,8 @@ export const dispatchTelegramMessage = async ({
|
||||
});
|
||||
if (info.kind === "final") {
|
||||
emitPreviewFinalizedHook(result);
|
||||
} else if (segment.lane === "answer" && result.kind === "sent") {
|
||||
markVisibleNonPreviewBoundary(true);
|
||||
}
|
||||
if (segment.lane === "reasoning") {
|
||||
if (result.kind !== "skipped") {
|
||||
@@ -1069,7 +1075,7 @@ export const dispatchTelegramMessage = async ({
|
||||
if (reply.hasMedia) {
|
||||
const payloadWithoutSuppressedReasoning =
|
||||
typeof payload.text === "string" ? { ...payload, text: "" } : payload;
|
||||
clearPendingCompactionReplayBoundaryOnVisibleBoundary(
|
||||
markVisibleNonPreviewBoundary(
|
||||
await sendPayload(payloadWithoutSuppressedReasoning),
|
||||
);
|
||||
}
|
||||
@@ -1093,9 +1099,7 @@ export const dispatchTelegramMessage = async ({
|
||||
}
|
||||
return;
|
||||
}
|
||||
clearPendingCompactionReplayBoundaryOnVisibleBoundary(
|
||||
await sendPayload(payload),
|
||||
);
|
||||
markVisibleNonPreviewBoundary(await sendPayload(payload));
|
||||
if (info.kind === "final") {
|
||||
await flushBufferedFinalAnswer();
|
||||
pendingCompactionReplayBoundary = false;
|
||||
|
||||
Reference in New Issue
Block a user