mirror of
https://github.com/openclaw/openclaw.git
synced 2026-07-01 01:23:33 +00:00
refactor(telegram): simplify album prompt selection
This commit is contained in:
@@ -245,6 +245,7 @@ export const registerTelegramHandlers = ({
|
||||
dispatchDedupeKeys: string[];
|
||||
spooledReplayParticipants: TelegramSpooledReplayDeferredParticipant[];
|
||||
};
|
||||
type PromptContextMessageSelection = ReadonlyMap<string, "include" | "exclude">;
|
||||
|
||||
const mediaGroupBuffer = new Map<string, BufferedMediaGroupEntry>();
|
||||
const mediaGroupProcessingByKey = new Map<string, Promise<void>>();
|
||||
@@ -950,8 +951,10 @@ export const registerTelegramHandlers = ({
|
||||
}
|
||||
|
||||
const allMedia: TelegramMediaRef[] = [];
|
||||
const promptContextMessageSelection = new Map<string, "include" | "exclude">();
|
||||
let skippedCount = 0;
|
||||
for (const { ctx, msg } of entry.messages) {
|
||||
const sourceMessageId = String(msg.message_id);
|
||||
let media;
|
||||
try {
|
||||
media = await resolveMedia({
|
||||
@@ -966,6 +969,7 @@ export const registerTelegramHandlers = ({
|
||||
runtime.log?.(
|
||||
warn(`media group: skipping photo that failed to fetch: ${String(mediaErr)}`),
|
||||
);
|
||||
promptContextMessageSelection.set(sourceMessageId, "exclude");
|
||||
skippedCount++;
|
||||
continue;
|
||||
}
|
||||
@@ -974,11 +978,11 @@ export const registerTelegramHandlers = ({
|
||||
path: media.path,
|
||||
contentType: media.contentType,
|
||||
stickerMetadata: media.stickerMetadata,
|
||||
...(typeof msg.message_id === "number"
|
||||
? { sourceMessageId: String(msg.message_id) }
|
||||
: {}),
|
||||
sourceMessageId,
|
||||
});
|
||||
promptContextMessageSelection.set(sourceMessageId, "include");
|
||||
} else {
|
||||
promptContextMessageSelection.set(sourceMessageId, "exclude");
|
||||
skippedCount++;
|
||||
}
|
||||
}
|
||||
@@ -1003,25 +1007,11 @@ export const registerTelegramHandlers = ({
|
||||
}).catch(() => {});
|
||||
}
|
||||
|
||||
// Only successfully downloaded album items have hydrated prompt media.
|
||||
// Skipped siblings still have raw telegram:file refs in the cache.
|
||||
const allAlbumMessageIds = entry.messages.flatMap(({ msg }) =>
|
||||
typeof msg.message_id === "number" ? [String(msg.message_id)] : [],
|
||||
);
|
||||
const hydratedAlbumMessageIds = allMedia.flatMap((media) =>
|
||||
media.sourceMessageId ? [media.sourceMessageId] : [],
|
||||
);
|
||||
const hydratedAlbumMessageIdSet = new Set(hydratedAlbumMessageIds);
|
||||
const skippedAlbumMessageIds = allAlbumMessageIds.filter(
|
||||
(messageId) => !hydratedAlbumMessageIdSet.has(messageId),
|
||||
);
|
||||
|
||||
const result = await processMessageWithReplyChain({
|
||||
ctx: primaryEntry.ctx,
|
||||
msg: primaryEntry.msg,
|
||||
allMedia,
|
||||
promptContextExtraMessageIds: hydratedAlbumMessageIds,
|
||||
promptContextExcludedMessageIds: skippedAlbumMessageIds,
|
||||
promptContextMessageSelection,
|
||||
storeAllowFrom: entry.storeAllowFrom,
|
||||
options: {
|
||||
...promptContextBoundaryOptions(entry.promptContextMinTimestampMs),
|
||||
@@ -1249,8 +1239,7 @@ export const registerTelegramHandlers = ({
|
||||
replyChainNodes: TelegramCachedMessageNode[],
|
||||
options?: TelegramMessageContextOptions,
|
||||
mediaByMessageId?: ReadonlyMap<string, TelegramMediaRef>,
|
||||
extraMessageIds?: readonly string[],
|
||||
excludedMessageIds?: readonly string[],
|
||||
selectedMessageIds?: PromptContextMessageSelection,
|
||||
): Promise<TelegramPromptContextEntry[]> => {
|
||||
const isGroup = msg.chat.type === "group" || msg.chat.type === "supergroup";
|
||||
const groupHistoryContextMode = isGroup
|
||||
@@ -1312,22 +1301,18 @@ export const registerTelegramHandlers = ({
|
||||
entry.node.messageId ? [[entry.node.messageId, entry] as const] : [],
|
||||
),
|
||||
);
|
||||
const excludedMessageIdSet = new Set(excludedMessageIds ?? []);
|
||||
for (const excludedMessageId of excludedMessageIdSet) {
|
||||
conversationContextById.delete(excludedMessageId);
|
||||
}
|
||||
for (const extraMessageId of new Set(extraMessageIds ?? [])) {
|
||||
if (
|
||||
extraMessageId === messageId ||
|
||||
excludedMessageIdSet.has(extraMessageId) ||
|
||||
conversationContextById.has(extraMessageId)
|
||||
) {
|
||||
for (const [selectedMessageId, selection] of selectedMessageIds ?? []) {
|
||||
if (selection === "exclude") {
|
||||
conversationContextById.delete(selectedMessageId);
|
||||
continue;
|
||||
}
|
||||
if (selectedMessageId === messageId || conversationContextById.has(selectedMessageId)) {
|
||||
continue;
|
||||
}
|
||||
const node = await messageCache.get({
|
||||
accountId,
|
||||
chatId: msg.chat.id,
|
||||
messageId: extraMessageId,
|
||||
messageId: selectedMessageId,
|
||||
});
|
||||
if (node?.messageId) {
|
||||
conversationContextById.set(node.messageId, { node });
|
||||
@@ -1419,8 +1404,7 @@ export const registerTelegramHandlers = ({
|
||||
ctx: TelegramContext;
|
||||
msg: Message;
|
||||
allMedia: TelegramMediaRef[];
|
||||
promptContextExtraMessageIds?: string[];
|
||||
promptContextExcludedMessageIds?: string[];
|
||||
promptContextMessageSelection?: PromptContextMessageSelection;
|
||||
storeAllowFrom: string[];
|
||||
options?: TelegramMessageContextOptions;
|
||||
dispatchDedupeKeys?: string[];
|
||||
@@ -1525,8 +1509,7 @@ export const registerTelegramHandlers = ({
|
||||
replyChainNodes,
|
||||
params.options,
|
||||
promptContextMediaByMessageId,
|
||||
params.promptContextExtraMessageIds,
|
||||
params.promptContextExcludedMessageIds,
|
||||
params.promptContextMessageSelection,
|
||||
);
|
||||
const result = await processMessage(
|
||||
params.ctx,
|
||||
@@ -2318,9 +2301,6 @@ export const registerTelegramHandlers = ({
|
||||
path: media.path,
|
||||
contentType: media.contentType,
|
||||
stickerMetadata: media.stickerMetadata,
|
||||
...(typeof msg.message_id === "number"
|
||||
? { sourceMessageId: String(msg.message_id) }
|
||||
: {}),
|
||||
},
|
||||
]
|
||||
: [];
|
||||
|
||||
@@ -16,8 +16,6 @@ export type TelegramMediaRef = {
|
||||
path: string;
|
||||
contentType?: string;
|
||||
stickerMetadata?: StickerMetadata;
|
||||
// Album flushes process one captioned primary message while sibling messages
|
||||
// remain in the prompt cache; keep their ids so context can hydrate each one.
|
||||
sourceMessageId?: string;
|
||||
};
|
||||
|
||||
|
||||
Reference in New Issue
Block a user