























@@ -88,6 +88,59 @@ export async function resolveTelegramMessageContextStorePath(params: {
8888});
8989}
909091+function replyTargetToChainEntry(replyTarget: TelegramReplyTarget): TelegramReplyChainEntry {
92+return {
93+ ...(replyTarget.id ? { messageId: replyTarget.id } : {}),
94+sender: replyTarget.sender,
95+ ...(replyTarget.senderId ? { senderId: replyTarget.senderId } : {}),
96+ ...(replyTarget.senderUsername ? { senderUsername: replyTarget.senderUsername } : {}),
97+ ...(replyTarget.body ? { body: replyTarget.body } : {}),
98+ ...(replyTarget.kind === "quote" ? { isQuote: true } : {}),
99+ ...(replyTarget.forwardedFrom?.from ? { forwardedFrom: replyTarget.forwardedFrom.from } : {}),
100+ ...(replyTarget.forwardedFrom?.fromId
101+ ? { forwardedFromId: replyTarget.forwardedFrom.fromId }
102+ : {}),
103+ ...(replyTarget.forwardedFrom?.fromUsername
104+ ? { forwardedFromUsername: replyTarget.forwardedFrom.fromUsername }
105+ : {}),
106+ ...(replyTarget.forwardedFrom?.date
107+ ? { forwardedDate: replyTarget.forwardedFrom.date * 1000 }
108+ : {}),
109+};
110+}
111+112+function stripReplyChainForwarded(entry: TelegramReplyChainEntry): TelegramReplyChainEntry {
113+const {
114+forwardedFrom: _forwardedFrom,
115+forwardedFromId: _forwardedFromId,
116+forwardedFromUsername: _forwardedFromUsername,
117+forwardedDate: _forwardedDate,
118+ ...withoutForwarded
119+} = entry;
120+return withoutForwarded;
121+}
122+123+function formatReplyChainEntry(entry: TelegramReplyChainEntry, index: number): string {
124+const labels = [
125+`${index + 1}. ${entry.sender ?? "unknown sender"}`,
126+entry.messageId ? `id:${entry.messageId}` : undefined,
127+entry.replyToId ? `reply_to:${entry.replyToId}` : undefined,
128+entry.timestamp ? new Date(entry.timestamp).toISOString() : undefined,
129+].filter(Boolean);
130+const bodyLines = [
131+entry.forwardedFrom
132+ ? `[Forwarded from ${entry.forwardedFrom}${
133+ entry.forwardedDate ? ` at ${new Date(entry.forwardedDate).toISOString()}` : ""
134+ }]`
135+ : undefined,
136+entry.isQuote && entry.body ? `"${entry.body}"` : entry.body,
137+entry.mediaType ? `<media:${entry.mediaType}>` : undefined,
138+entry.mediaPath ? `[media_path:${entry.mediaPath}]` : undefined,
139+entry.mediaRef ? `[media_ref:${entry.mediaRef}]` : undefined,
140+].filter(Boolean);
141+return `[${labels.join(" ")}]\n${bodyLines.join("\n")}`;
142+}
143+91144export async function buildTelegramInboundContextPayload(params: {
92145cfg: OpenClawConfig;
93146primaryCtx: TelegramContext;
@@ -228,105 +281,40 @@ export async function buildTelegramInboundContextPayload(params: {
228281forwardedFrom: visibleReplyForwardedFrom,
229282}
230283 : null;
231-const fallbackReplyChain: TelegramReplyChainEntry[] = visibleReplyTarget
232- ? [
233-{
234- ...(visibleReplyTarget.id ? { messageId: visibleReplyTarget.id } : {}),
235-sender: visibleReplyTarget.sender,
236- ...(visibleReplyTarget.senderId ? { senderId: visibleReplyTarget.senderId } : {}),
237- ...(visibleReplyTarget.senderUsername
238- ? { senderUsername: visibleReplyTarget.senderUsername }
239- : {}),
240- ...(visibleReplyTarget.body ? { body: visibleReplyTarget.body } : {}),
241- ...(visibleReplyTarget.kind === "quote" ? { isQuote: true } : {}),
242- ...(visibleReplyTarget.forwardedFrom?.from
243- ? { forwardedFrom: visibleReplyTarget.forwardedFrom.from }
244- : {}),
245- ...(visibleReplyTarget.forwardedFrom?.fromId
246- ? { forwardedFromId: visibleReplyTarget.forwardedFrom.fromId }
247- : {}),
248- ...(visibleReplyTarget.forwardedFrom?.fromUsername
249- ? { forwardedFromUsername: visibleReplyTarget.forwardedFrom.fromUsername }
250- : {}),
251- ...(visibleReplyTarget.forwardedFrom?.date
252- ? { forwardedDate: visibleReplyTarget.forwardedFrom.date * 1000 }
253- : {}),
254-},
255-]
256- : [];
257-const rawReplyChain = replyChain.length > 0 ? replyChain : fallbackReplyChain;
258-const replyChainWithVisibleTarget =
259-visibleReplyTarget && rawReplyChain[0]?.messageId === visibleReplyTarget.id
260- ? [
261-{
262- ...rawReplyChain[0],
263- ...(visibleReplyTarget.body ? { body: visibleReplyTarget.body } : {}),
264- ...(visibleReplyTarget.kind === "quote" ? { isQuote: true } : {}),
265- ...(visibleReplyTarget.forwardedFrom?.from
266- ? { forwardedFrom: visibleReplyTarget.forwardedFrom.from }
267- : {}),
268- ...(visibleReplyTarget.forwardedFrom?.fromId
269- ? { forwardedFromId: visibleReplyTarget.forwardedFrom.fromId }
270- : {}),
271- ...(visibleReplyTarget.forwardedFrom?.fromUsername
272- ? { forwardedFromUsername: visibleReplyTarget.forwardedFrom.fromUsername }
273- : {}),
274- ...(visibleReplyTarget.forwardedFrom?.date
275- ? { forwardedDate: visibleReplyTarget.forwardedFrom.date * 1000 }
276- : {}),
277-},
278- ...rawReplyChain.slice(1),
279-]
280- : rawReplyChain;
281-const visibleReplyChain = replyChainWithVisibleTarget
282-.filter((entry) =>
283-shouldIncludeGroupSupplementalContext({
284+const visibleReplyTargetEntry = visibleReplyTarget
285+ ? replyTargetToChainEntry(visibleReplyTarget)
286+ : undefined;
287+const visibleReplyTargetById = new Map<string, TelegramReplyChainEntry>(
288+visibleReplyTargetEntry?.messageId
289+ ? [[visibleReplyTargetEntry.messageId, visibleReplyTargetEntry]]
290+ : [],
291+);
292+const rawReplyChain =
293+replyChain.length > 0 ? replyChain : visibleReplyTargetEntry ? [visibleReplyTargetEntry] : [];
294+const visibleReplyChain = rawReplyChain.flatMap((entry) => {
295+const visibleEntry = {
296+ ...entry,
297+ ...(entry.messageId ? visibleReplyTargetById.get(entry.messageId) : undefined),
298+};
299+if (
300+!shouldIncludeGroupSupplementalContext({
284301kind: "quote",
285-senderId: entry.senderId,
286-senderUsername: entry.senderUsername,
287-}),
288-)
289-.map((entry) => {
290-const includeForwarded =
291-entry.forwardedFrom &&
292-shouldIncludeGroupSupplementalContext({
293-kind: "forwarded",
294-senderId: entry.forwardedFromId,
295-senderUsername: entry.forwardedFromUsername,
296-});
297-if (includeForwarded) {
298-return entry;
299-}
300-const {
301-forwardedFrom: _forwardedFrom,
302-forwardedFromId: _forwardedFromId,
303-forwardedFromUsername: _forwardedFromUsername,
304-forwardedDate: _forwardedDate,
305- ...withoutForwarded
306-} = entry;
307-return withoutForwarded;
308-});
302+senderId: visibleEntry.senderId,
303+senderUsername: visibleEntry.senderUsername,
304+})
305+) {
306+return [];
307+}
308+const includeForwarded =
309+visibleEntry.forwardedFrom &&
310+shouldIncludeGroupSupplementalContext({
311+kind: "forwarded",
312+senderId: visibleEntry.forwardedFromId,
313+senderUsername: visibleEntry.forwardedFromUsername,
314+});
315+return [includeForwarded ? visibleEntry : stripReplyChainForwarded(visibleEntry)];
316+});
309317const visibleForwardOrigin = includeForwardOrigin ? forwardOrigin : null;
310-const formatReplyChainEntry = (entry: TelegramReplyChainEntry, index: number) => {
311-const labels = [
312-`${index + 1}. ${entry.sender ?? "unknown sender"}`,
313-entry.messageId ? `id:${entry.messageId}` : undefined,
314-entry.replyToId ? `reply_to:${entry.replyToId}` : undefined,
315-entry.timestamp ? new Date(entry.timestamp).toISOString() : undefined,
316-].filter(Boolean);
317-const bodyLines = [
318-entry.forwardedFrom
319- ? `[Forwarded from ${entry.forwardedFrom}${
320- entry.forwardedDate ? ` at ${new Date(entry.forwardedDate).toISOString()}` : ""
321- }]`
322- : undefined,
323-entry.isQuote && entry.body ? `"${entry.body}"` : entry.body,
324-entry.mediaType ? `<media:${entry.mediaType}>` : undefined,
325-entry.mediaPath ? `[media_path:${entry.mediaPath}]` : undefined,
326-entry.mediaRef ? `[media_ref:${entry.mediaRef}]` : undefined,
327-].filter(Boolean);
328-return `[${labels.join(" ")}]\n${bodyLines.join("\n")}`;
329-};
330318const replySuffix =
331319visibleReplyChain.length > 0
332320 ? `\n\n[Reply chain - nearest first]\n${visibleReplyChain
此内容由惯性聚合(RSS阅读器)自动聚合整理,仅供阅读参考。 原文来自 — 版权归原作者所有。