





















@@ -4,6 +4,7 @@ import {
44clearPluginInteractiveHandlers,
55registerPluginInteractiveHandler,
66} from "openclaw/plugin-sdk/plugin-runtime";
7+import type { MsgContext } from "openclaw/plugin-sdk/reply-runtime";
78import { loadSessionStore } from "openclaw/plugin-sdk/session-store-runtime";
89import { mockPinnedHostnameResolution } from "openclaw/plugin-sdk/test-env";
910import { afterAll, beforeAll, beforeEach, describe, expect, it, vi } from "vitest";
@@ -84,7 +85,7 @@ async function loadInboundContextContract() {
84858586type MockCallSource = {
8687mock: {
87-calls: ArrayLike<ReadonlyArray<unknown>>;
88+calls: ReadonlyArray<ReadonlyArray<unknown>>;
8889};
8990};
9091@@ -101,13 +102,22 @@ function requireArray(value: unknown, label: string): unknown[] {
101102}
102103103104function mockArg(source: MockCallSource, callIndex: number, argIndex: number, label: string) {
104-const call = source.mock.calls[callIndex];
105+const call = source.mock.calls.at(callIndex);
105106if (!call) {
106107throw new Error(`expected mock call: ${label}`);
107108}
108109return call[argIndex];
109110}
110111112+function mockMsgContextArg(
113+source: MockCallSource,
114+callIndex: number,
115+argIndex: number,
116+label: string,
117+): MsgContext {
118+return mockArg(source, callIndex, argIndex, label) as MsgContext;
119+}
120+111121function execApprovalCall(index = 0) {
112122return requireRecord(
113123mockArg(resolveExecApprovalSpy as unknown as MockCallSource, index, 0, "exec approval call"),
@@ -553,7 +563,7 @@ describe("createTelegramBot", () => {
553563});
554564555565expect(editMessageReplyMarkupSpy).toHaveBeenCalledTimes(1);
556-const [chatId, messageId, replyMarkup] = editMessageReplyMarkupSpy.mock.calls[0] ?? [];
566+const [chatId, messageId, replyMarkup] = editMessageReplyMarkupSpy.mock.calls.at(0) ?? [];
557567expect(chatId).toBe(1234);
558568expect(messageId).toBe(21);
559569expect(replyMarkup).toEqual({ reply_markup: { inline_keyboard: [] } });
@@ -988,7 +998,7 @@ describe("createTelegramBot", () => {
988998expect(listCall.cfg).toBeTypeOf("object");
989999expect(listCall.agentIds).toEqual(["main"]);
9901000expect(editMessageTextSpy).toHaveBeenCalledTimes(1);
991-const [chatId, messageId, text, params] = editMessageTextSpy.mock.calls[0] ?? [];
1001+const [chatId, messageId, text, params] = editMessageTextSpy.mock.calls.at(0) ?? [];
9921002expect(chatId).toBe(1234);
9931003expect(messageId).toBe(12);
9941004expect(String(text)).toContain(`${INFO_EMOJI} Commands (2/`);
@@ -1143,10 +1153,10 @@ describe("createTelegramBot", () => {
1143115311441154expect(replySpy).not.toHaveBeenCalled();
11451155expect(editMessageTextSpy).toHaveBeenCalledTimes(1);
1146-expect(editMessageTextSpy.mock.calls[0]?.[2]).toContain(
1156+expect(editMessageTextSpy.mock.calls.at(0)?.[2]).toContain(
11471157`${CHECK_MARK_EMOJI} Model reset to default`,
11481158);
1149-expect(editMessageTextSpy.mock.calls[0]?.[2]).toContain(
1159+expect(editMessageTextSpy.mock.calls.at(0)?.[2]).toContain(
11501160"Session selection cleared. Runtime unchanged. New replies use the agent's configured default.",
11511161);
11521162@@ -1219,7 +1229,7 @@ describe("createTelegramBot", () => {
1219122912201230expect(replySpy).not.toHaveBeenCalled();
12211231expect(editMessageTextSpy).toHaveBeenCalledTimes(1);
1222-const [, , , params] = editMessageTextSpy.mock.calls[0] ?? [];
1232+const [, , , params] = editMessageTextSpy.mock.calls.at(0) ?? [];
12231233const inlineKeyboard = (
12241234params as {
12251235reply_markup?: {
@@ -1293,10 +1303,10 @@ describe("createTelegramBot", () => {
1293130312941304expect(replySpy).not.toHaveBeenCalled();
12951305expect(editMessageTextSpy).toHaveBeenCalledTimes(1);
1296-expect(editMessageTextSpy.mock.calls[0]?.[2]).toContain(
1306+expect(editMessageTextSpy.mock.calls.at(0)?.[2]).toContain(
12971307`${CHECK_MARK_EMOJI} Model reset to default`,
12981308);
1299-expect(editMessageTextSpy.mock.calls[0]?.[2]).toContain(
1309+expect(editMessageTextSpy.mock.calls.at(0)?.[2]).toContain(
13001310"Session selection cleared. Runtime unchanged. New replies use the agent's configured default.",
13011311);
13021312@@ -1368,7 +1378,7 @@ describe("createTelegramBot", () => {
1368137813691379expect(replySpy).not.toHaveBeenCalled();
13701380expect(editMessageTextSpy).toHaveBeenCalledTimes(1);
1371-const editCall = editMessageTextSpy.mock.calls[0];
1381+const editCall = editMessageTextSpy.mock.calls.at(0);
13721382expect(editCall?.[0]).toBe(1234);
13731383expect(editCall?.[1]).toBe(17);
13741384expect(editCall?.[2]).toBe(
@@ -1523,7 +1533,7 @@ describe("createTelegramBot", () => {
1523153315241534expect(replySpy).not.toHaveBeenCalled();
15251535expect(editMessageTextSpy).toHaveBeenCalledTimes(1);
1526-expect(editMessageTextSpy.mock.calls[0]?.[2]).toContain(
1536+expect(editMessageTextSpy.mock.calls.at(0)?.[2]).toContain(
15271537'Could not resolve model "shared-model".',
15281538);
15291539expect(answerCallbackQuerySpy).toHaveBeenCalledWith("cbq-model-compact-2");
@@ -1568,7 +1578,7 @@ describe("createTelegramBot", () => {
15681578});
1569157915701580expect(replySpy).toHaveBeenCalledTimes(1);
1571-const payload = replySpy.mock.calls[0][0];
1581+const payload = mockMsgContextArg(replySpy as unknown as MockCallSource, 0, 0, "replySpy call");
15721582const { expectChannelInboundContextContract: expectInboundContextContract } =
15731583await loadInboundContextContract();
15741584const { escapeRegExp, formatEnvelopeTimestamp } = await loadEnvelopeTimestampHelpers();
@@ -1659,7 +1669,7 @@ describe("createTelegramBot", () => {
16591669});
1660167016611671expect(replySpy).toHaveBeenCalledTimes(1);
1662-const payload = replySpy.mock.calls[0][0];
1672+const payload = mockMsgContextArg(replySpy as unknown as MockCallSource, 0, 0, "replySpy call");
16631673const [conversationContext] = requireArray(
16641674payload.UntrustedStructuredContext,
16651675"structured context",
@@ -1762,7 +1772,7 @@ describe("createTelegramBot", () => {
17621772});
1763177317641774expect(replySpy).toHaveBeenCalledTimes(1);
1765-const payload = replySpy.mock.calls[0][0];
1775+const payload = mockMsgContextArg(replySpy as unknown as MockCallSource, 0, 0, "replySpy call");
17661776const [conversationContext] = requireArray(
17671777payload.UntrustedStructuredContext,
17681778"structured context",
@@ -1807,7 +1817,7 @@ describe("createTelegramBot", () => {
18071817});
1808181818091819expect(replySpy).toHaveBeenCalledTimes(1);
1810-const payload = replySpy.mock.calls[0][0];
1820+const payload = mockMsgContextArg(replySpy as unknown as MockCallSource, 0, 0, "replySpy call");
18111821expect(payload.Body).toContain("[Reply chain - nearest first]");
18121822expect(payload.Body).toContain("[1. Ada id:9001]");
18131823expect(payload.Body).toContain('"summarize this"');
@@ -1845,7 +1855,7 @@ describe("createTelegramBot", () => {
18451855});
1846185618471857expect(replySpy).toHaveBeenCalledTimes(1);
1848-const payload = replySpy.mock.calls[0][0];
1858+const payload = mockMsgContextArg(replySpy as unknown as MockCallSource, 0, 0, "replySpy call");
18491859expect(payload.Body).toContain("[Reply chain - nearest first]");
18501860expect(payload.Body).toContain("[1. Ada id:9001]");
18511861expect(payload.Body).not.toContain("PK");
@@ -1900,7 +1910,12 @@ describe("createTelegramBot", () => {
19001910}
1901191119021912expect(replySpy).toHaveBeenCalledTimes(1);
1903-const payload = replySpy.mock.calls[0][0] as {
1913+const payload = mockMsgContextArg(
1914+replySpy as unknown as MockCallSource,
1915+0,
1916+0,
1917+"replySpy call",
1918+) as {
19041919MediaPath?: string;
19051920MediaPaths?: string[];
19061921ReplyToBody?: string;
@@ -1990,7 +2005,12 @@ describe("createTelegramBot", () => {
19902005}
1991200619922007expect(replySpy).toHaveBeenCalledTimes(1);
1993-const payload = replySpy.mock.calls[0][0] as {
2008+const payload = mockMsgContextArg(
2009+replySpy as unknown as MockCallSource,
2010+0,
2011+0,
2012+"replySpy call",
2013+) as {
19942014ReplyChain?: Array<{
19952015messageId?: string;
19962016body?: string;
@@ -2178,7 +2198,7 @@ describe("createTelegramBot", () => {
21782198});
2179219921802200expect(replySpy).toHaveBeenCalledTimes(1);
2181-const payload = replySpy.mock.calls[0][0];
2201+const payload = mockMsgContextArg(replySpy as unknown as MockCallSource, 0, 0, "replySpy call");
21822202expect(payload.Body).toContain("[Reply chain - nearest first]");
21832203expect(payload.Body).toContain("[1. unknown sender]");
21842204expect(payload.Body).toContain('"summarize this"');
@@ -2214,7 +2234,7 @@ describe("createTelegramBot", () => {
22142234});
2215223522162236expect(replySpy).toHaveBeenCalledTimes(1);
2217-const payload = replySpy.mock.calls[0][0];
2237+const payload = mockMsgContextArg(replySpy as unknown as MockCallSource, 0, 0, "replySpy call");
22182238expect(payload.Body).toContain("[Reply chain - nearest first]");
22192239expect(payload.Body).toContain("[1. Ada id:9002]");
22202240expect(payload.Body).toContain('"summarize this"');
@@ -2262,7 +2282,7 @@ describe("createTelegramBot", () => {
22622282});
2263228322642284expect(replySpy).toHaveBeenCalledTimes(1);
2265-const payload = replySpy.mock.calls[0][0];
2285+const payload = mockMsgContextArg(replySpy as unknown as MockCallSource, 0, 0, "replySpy call");
22662286expect(payload.ReplyToForwardedFrom).toBe("Bob Smith (@bobsmith)");
22672287expect(payload.ReplyToForwardedFromType).toBe("user");
22682288expect(payload.ReplyToForwardedFromId).toBe("999");
@@ -2325,7 +2345,7 @@ describe("createTelegramBot", () => {
23252345});
2326234623272347expect(replySpy).toHaveBeenCalledTimes(1);
2328-const payload = replySpy.mock.calls[0][0];
2348+const payload = mockMsgContextArg(replySpy as unknown as MockCallSource, 0, 0, "replySpy call");
23292349expect(payload.ReplyToId).toBe("9003");
23302350expect(payload.ReplyToBody).toBe("forwarded text");
23312351expect(payload.ReplyToSender).toBe("Ada");
@@ -2365,7 +2385,7 @@ describe("createTelegramBot", () => {
23652385});
2366238623672387expect(replySpy).toHaveBeenCalledTimes(1);
2368-const payload = replySpy.mock.calls[0][0];
2388+const payload = mockMsgContextArg(replySpy as unknown as MockCallSource, 0, 0, "replySpy call");
23692389expect(payload.WasMentioned).toBe(true);
23702390});
23712391@@ -2837,7 +2857,7 @@ describe("createTelegramBot", () => {
28372857});
2838285828392859expect(replySpy).toHaveBeenCalledTimes(1);
2840-const payload = replySpy.mock.calls[0][0];
2860+const payload = mockMsgContextArg(replySpy as unknown as MockCallSource, 0, 0, "replySpy call");
28412861expect(payload.CommandTargetSessionKey).toBe("agent:main:main");
28422862});
28432863@@ -3019,7 +3039,7 @@ describe("createTelegramBot", () => {
30193039});
3020304030213041expect(enqueueSystemEventSpy).toHaveBeenCalledTimes(1);
3022-expect(enqueueSystemEventSpy.mock.calls[0]?.[0]).toBe(
3042+expect(enqueueSystemEventSpy.mock.calls.at(0)?.[0]).toBe(
30233043`Telegram reaction added: ${THUMBS_UP_EMOJI} by Ada (@ada_bot) on msg 42`,
30243044);
30253045expect(String(systemEventOptions().contextKey)).toContain("telegram:reaction:add:1234:42:9");
@@ -3247,10 +3267,10 @@ describe("createTelegramBot", () => {
32473267});
3248326832493269expect(enqueueSystemEventSpy).toHaveBeenCalledTimes(1);
3250-expect(enqueueSystemEventSpy.mock.calls[0]?.[0]).toBe(
3270+expect(enqueueSystemEventSpy.mock.calls.at(0)?.[0]).toBe(
32513271`Telegram reaction added: ${PARTY_EMOJI} by Ada on msg 99`,
32523272);
3253-expect(enqueueSystemEventSpy.mock.calls[0]?.[1]).toBeTypeOf("object");
3273+expect(enqueueSystemEventSpy.mock.calls.at(0)?.[1]).toBeTypeOf("object");
32543274});
3255327532563276it("skips reaction in own mode when message is not sent by bot", async () => {
@@ -3444,7 +3464,7 @@ describe("createTelegramBot", () => {
34443464});
3445346534463466expect(enqueueSystemEventSpy).toHaveBeenCalledTimes(1);
3447-expect(enqueueSystemEventSpy.mock.calls[0]?.[0]).toBe(
3467+expect(enqueueSystemEventSpy.mock.calls.at(0)?.[0]).toBe(
34483468`Telegram reaction added: ${FIRE_EMOJI} by Bob (@bob_user) on msg 100`,
34493469);
34503470expect(String(systemEventOptions().sessionKey)).toContain("telegram:group:5678:topic:1");
@@ -3480,7 +3500,7 @@ describe("createTelegramBot", () => {
34803500});
3481350134823502expect(enqueueSystemEventSpy).toHaveBeenCalledTimes(1);
3483-expect(enqueueSystemEventSpy.mock.calls[0]?.[0]).toBe(
3503+expect(enqueueSystemEventSpy.mock.calls.at(0)?.[0]).toBe(
34843504`Telegram reaction added: ${EYES_EMOJI} by Bob on msg 101`,
34853505);
34863506expect(String(systemEventOptions().sessionKey)).toContain("telegram:group:5678:topic:1");
@@ -3515,13 +3535,13 @@ describe("createTelegramBot", () => {
35153535});
3516353635173537expect(enqueueSystemEventSpy).toHaveBeenCalledTimes(1);
3518-expect(enqueueSystemEventSpy.mock.calls[0]?.[0]).toBe(
3538+expect(enqueueSystemEventSpy.mock.calls.at(0)?.[0]).toBe(
35193539`Telegram reaction added: ${HEART_EMOJI} by Charlie on msg 200`,
35203540);
35213541expect(String(systemEventOptions().sessionKey)).toContain("telegram:group:9999");
35223542expect(String(systemEventOptions().contextKey)).toContain("telegram:reaction:add:9999:200:11");
35233543// Verify session key does NOT contain :topic:
3524-const eventOptions = enqueueSystemEventSpy.mock.calls[0]?.[1] as {
3544+const eventOptions = enqueueSystemEventSpy.mock.calls.at(0)?.[1] as {
35253545sessionKey?: string;
35263546};
35273547const sessionKey = eventOptions.sessionKey ?? "";
此内容由惯性聚合(RSS阅读器)自动聚合整理,仅供阅读参考。 原文来自 — 版权归原作者所有。