mirror of
https://github.com/openclaw/openclaw.git
synced 2026-05-10 04:52:43 +00:00
refactor(telegram): split lane preview target helpers
This commit is contained in:
@@ -101,27 +101,59 @@ type ConsumeArchivedAnswerPreviewParams = {
|
|||||||
canEditViaPreview: boolean;
|
canEditViaPreview: boolean;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
type PreviewUpdateContext = "final" | "update";
|
||||||
|
type RegressiveSkipMode = "always" | "existingOnly";
|
||||||
|
|
||||||
|
type ResolvePreviewTargetParams = {
|
||||||
|
lane: DraftLaneState;
|
||||||
|
previewMessageIdOverride?: number;
|
||||||
|
stopBeforeEdit: boolean;
|
||||||
|
context: PreviewUpdateContext;
|
||||||
|
};
|
||||||
|
|
||||||
|
type PreviewTargetResolution = {
|
||||||
|
hadPreviewMessage: boolean;
|
||||||
|
previewMessageId: number | undefined;
|
||||||
|
stopCreatesFirstPreview: boolean;
|
||||||
|
};
|
||||||
|
|
||||||
|
function shouldSkipRegressivePreviewUpdate(args: {
|
||||||
|
currentPreviewText: string | undefined;
|
||||||
|
text: string;
|
||||||
|
skipRegressive: RegressiveSkipMode;
|
||||||
|
hadPreviewMessage: boolean;
|
||||||
|
}): boolean {
|
||||||
|
const currentPreviewText = args.currentPreviewText;
|
||||||
|
if (currentPreviewText === undefined) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return (
|
||||||
|
currentPreviewText.startsWith(args.text) &&
|
||||||
|
args.text.length < currentPreviewText.length &&
|
||||||
|
(args.skipRegressive === "always" || args.hadPreviewMessage)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
function resolvePreviewTarget(params: ResolvePreviewTargetParams): PreviewTargetResolution {
|
||||||
|
const lanePreviewMessageId = params.lane.stream?.messageId();
|
||||||
|
const previewMessageId =
|
||||||
|
typeof params.previewMessageIdOverride === "number"
|
||||||
|
? params.previewMessageIdOverride
|
||||||
|
: lanePreviewMessageId;
|
||||||
|
const hadPreviewMessage =
|
||||||
|
typeof params.previewMessageIdOverride === "number" || typeof lanePreviewMessageId === "number";
|
||||||
|
return {
|
||||||
|
hadPreviewMessage,
|
||||||
|
previewMessageId: typeof previewMessageId === "number" ? previewMessageId : undefined,
|
||||||
|
stopCreatesFirstPreview:
|
||||||
|
params.stopBeforeEdit && !hadPreviewMessage && params.context === "final",
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
export function createLaneTextDeliverer(params: CreateLaneTextDelivererParams) {
|
export function createLaneTextDeliverer(params: CreateLaneTextDelivererParams) {
|
||||||
const getLanePreviewText = (lane: DraftLaneState) => lane.lastPartialText;
|
const getLanePreviewText = (lane: DraftLaneState) => lane.lastPartialText;
|
||||||
const isDraftPreviewLane = (lane: DraftLaneState) => lane.stream?.previewMode?.() === "draft";
|
const isDraftPreviewLane = (lane: DraftLaneState) => lane.stream?.previewMode?.() === "draft";
|
||||||
|
|
||||||
const shouldSkipRegressivePreviewUpdate = (args: {
|
|
||||||
currentPreviewText: string | undefined;
|
|
||||||
text: string;
|
|
||||||
skipRegressive: "always" | "existingOnly";
|
|
||||||
hadPreviewMessage: boolean;
|
|
||||||
}): boolean => {
|
|
||||||
const currentPreviewText = args.currentPreviewText;
|
|
||||||
if (currentPreviewText === undefined) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
return (
|
|
||||||
currentPreviewText.startsWith(args.text) &&
|
|
||||||
args.text.length < currentPreviewText.length &&
|
|
||||||
(args.skipRegressive === "always" || args.hadPreviewMessage)
|
|
||||||
);
|
|
||||||
};
|
|
||||||
|
|
||||||
const tryEditPreviewMessage = async (args: {
|
const tryEditPreviewMessage = async (args: {
|
||||||
laneName: LaneName;
|
laneName: LaneName;
|
||||||
messageId: number;
|
messageId: number;
|
||||||
@@ -186,6 +218,7 @@ export function createLaneTextDeliverer(params: CreateLaneTextDelivererParams) {
|
|||||||
const finalizePreview = (
|
const finalizePreview = (
|
||||||
previewMessageId: number,
|
previewMessageId: number,
|
||||||
treatEditFailureAsDelivered: boolean,
|
treatEditFailureAsDelivered: boolean,
|
||||||
|
hadPreviewMessage: boolean,
|
||||||
): boolean | Promise<boolean> => {
|
): boolean | Promise<boolean> => {
|
||||||
const currentPreviewText = previewTextSnapshot ?? getLanePreviewText(lane);
|
const currentPreviewText = previewTextSnapshot ?? getLanePreviewText(lane);
|
||||||
const shouldSkipRegressive = shouldSkipRegressivePreviewUpdate({
|
const shouldSkipRegressive = shouldSkipRegressivePreviewUpdate({
|
||||||
@@ -203,32 +236,44 @@ export function createLaneTextDeliverer(params: CreateLaneTextDelivererParams) {
|
|||||||
if (!lane.stream) {
|
if (!lane.stream) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
const lanePreviewMessageId = lane.stream.messageId();
|
const previewTargetBeforeStop = resolvePreviewTarget({
|
||||||
const hadPreviewMessage =
|
lane,
|
||||||
typeof previewMessageIdOverride === "number" || typeof lanePreviewMessageId === "number";
|
previewMessageIdOverride,
|
||||||
const stopCreatesFirstPreview = stopBeforeEdit && !hadPreviewMessage && context === "final";
|
stopBeforeEdit,
|
||||||
if (stopCreatesFirstPreview) {
|
context,
|
||||||
|
});
|
||||||
|
if (previewTargetBeforeStop.stopCreatesFirstPreview) {
|
||||||
// Final stop() can create the first visible preview message.
|
// Final stop() can create the first visible preview message.
|
||||||
// Prime pending text so the stop flush sends the final text snapshot.
|
// Prime pending text so the stop flush sends the final text snapshot.
|
||||||
lane.stream.update(text);
|
lane.stream.update(text);
|
||||||
await params.stopDraftLane(lane);
|
await params.stopDraftLane(lane);
|
||||||
const previewMessageId = lane.stream.messageId();
|
const previewTargetAfterStop = resolvePreviewTarget({
|
||||||
if (typeof previewMessageId !== "number") {
|
lane,
|
||||||
|
stopBeforeEdit: false,
|
||||||
|
context,
|
||||||
|
});
|
||||||
|
if (typeof previewTargetAfterStop.previewMessageId !== "number") {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
return finalizePreview(previewMessageId, true);
|
return finalizePreview(previewTargetAfterStop.previewMessageId, true, false);
|
||||||
}
|
}
|
||||||
if (stopBeforeEdit) {
|
if (stopBeforeEdit) {
|
||||||
await params.stopDraftLane(lane);
|
await params.stopDraftLane(lane);
|
||||||
}
|
}
|
||||||
const previewMessageId =
|
const previewTargetAfterStop = resolvePreviewTarget({
|
||||||
typeof previewMessageIdOverride === "number"
|
lane,
|
||||||
? previewMessageIdOverride
|
previewMessageIdOverride,
|
||||||
: lane.stream.messageId();
|
stopBeforeEdit: false,
|
||||||
if (typeof previewMessageId !== "number") {
|
context,
|
||||||
|
});
|
||||||
|
if (typeof previewTargetAfterStop.previewMessageId !== "number") {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
return finalizePreview(previewMessageId, false);
|
return finalizePreview(
|
||||||
|
previewTargetAfterStop.previewMessageId,
|
||||||
|
false,
|
||||||
|
previewTargetAfterStop.hadPreviewMessage,
|
||||||
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
const consumeArchivedAnswerPreviewForFinal = async ({
|
const consumeArchivedAnswerPreviewForFinal = async ({
|
||||||
|
|||||||
Reference in New Issue
Block a user