mirror of https://github.com/openclaw/openclaw.git
fix(telegram): only retain on sendMayHaveLanded when prior preview is visible
When no prior message exists (first preview creation), prefer fallback over silence — a duplicate is better than the user seeing nothing. Gate sendMayHaveLanded retention on lane.hasStreamedMessage.
This commit is contained in:
parent
7aa96de998
commit
8bfe7db27a
|
|
@ -365,13 +365,9 @@ export function createLaneTextDeliverer(params: CreateLaneTextDelivererParams) {
|
|||
context,
|
||||
});
|
||||
if (typeof previewTargetAfterStop.previewMessageId !== "number") {
|
||||
if (lane.stream?.sendMayHaveLanded?.()) {
|
||||
params.log(
|
||||
`telegram: ${laneName} preview send may have landed despite missing message id; keeping to avoid duplicate`,
|
||||
);
|
||||
params.markDelivered();
|
||||
return "retained";
|
||||
}
|
||||
// This is the first preview creation — no prior visible message exists.
|
||||
// Even if sendMayHaveLanded, prefer fallback over silence: a duplicate
|
||||
// is better than the user seeing nothing at all.
|
||||
return "fallback";
|
||||
}
|
||||
return finalizePreview(previewTargetAfterStop.previewMessageId, true, false);
|
||||
|
|
@ -386,7 +382,9 @@ export function createLaneTextDeliverer(params: CreateLaneTextDelivererParams) {
|
|||
context,
|
||||
});
|
||||
if (typeof previewTargetAfterStop.previewMessageId !== "number") {
|
||||
if (lane.stream?.sendMayHaveLanded?.()) {
|
||||
// Only retain when a prior preview is already visible to the user —
|
||||
// otherwise falling back is safer than silence.
|
||||
if (lane.hasStreamedMessage && lane.stream?.sendMayHaveLanded?.()) {
|
||||
params.log(
|
||||
`telegram: ${laneName} preview send may have landed despite missing message id; keeping to avoid duplicate`,
|
||||
);
|
||||
|
|
|
|||
|
|
@ -538,10 +538,10 @@ describe("createLaneTextDeliverer", () => {
|
|||
);
|
||||
});
|
||||
|
||||
it("retains preview when sendMayHaveLanded is true and no messageId", async () => {
|
||||
it("falls back when sendMayHaveLanded is true but no prior visible preview exists", async () => {
|
||||
const stream = createTestDraftStream();
|
||||
stream.sendMayHaveLanded.mockReturnValue(true);
|
||||
// No messageId → resolvePreviewTarget returns undefined
|
||||
// No messageId and no prior preview → nothing visible for user to see
|
||||
const harness = createHarness({ answerStream: stream });
|
||||
|
||||
const result = await harness.deliverLaneText({
|
||||
|
|
@ -551,6 +551,34 @@ describe("createLaneTextDeliverer", () => {
|
|||
infoKind: "final",
|
||||
});
|
||||
|
||||
// Prefer fallback (possible duplicate) over silence (no message at all)
|
||||
expect(result).toBe("sent");
|
||||
expect(harness.sendPayload).toHaveBeenCalledWith(
|
||||
expect.objectContaining({ text: "Hello final" }),
|
||||
);
|
||||
});
|
||||
|
||||
it("retains when sendMayHaveLanded is true and a prior preview was visible", async () => {
|
||||
// Stream has a messageId (visible preview) but loses it after stop
|
||||
const stream = createTestDraftStream({ messageId: 999 });
|
||||
stream.sendMayHaveLanded.mockReturnValue(true);
|
||||
const harness = createHarness({
|
||||
answerStream: stream,
|
||||
answerHasStreamedMessage: true,
|
||||
});
|
||||
// Simulate messageId lost after stop (e.g. forceNewMessage or timeout)
|
||||
harness.stopDraftLane.mockImplementation(async (lane: DraftLaneState) => {
|
||||
stream.setMessageId(undefined);
|
||||
await lane.stream?.stop();
|
||||
});
|
||||
|
||||
const result = await harness.deliverLaneText({
|
||||
laneName: "answer",
|
||||
text: "Hello final",
|
||||
payload: { text: "Hello final" },
|
||||
infoKind: "final",
|
||||
});
|
||||
|
||||
expect(result).toBe("preview-retained");
|
||||
expect(harness.sendPayload).not.toHaveBeenCalled();
|
||||
expect(harness.log).toHaveBeenCalledWith(
|
||||
|
|
|
|||
Loading…
Reference in New Issue