44 clearPluginInteractiveHandlers ,
55 registerPluginInteractiveHandler ,
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() {
8485
8586type MockCallSource = {
8687 mock : {
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}
102103
103104function mockArg ( source : MockCallSource , callIndex : number , argIndex : number , label : string ) {
104- const call = source . mock . calls [ callIndex ] ;
105+ const call = source . mock . calls . at ( callIndex ) ;
105106 if ( ! call ) {
106107 throw new Error ( `expected mock call: ${ label } ` ) ;
107108 }
108109 return call [ argIndex ] ;
109110}
110111
112+ 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 ) {
112122 return requireRecord (
113123 mockArg ( resolveExecApprovalSpy as unknown as MockCallSource , index , 0 , "exec approval call" ) ,
@@ -553,7 +563,7 @@ describe("createTelegramBot", () => {
553563 } ) ;
554564
555565 expect ( editMessageReplyMarkupSpy ) . toHaveBeenCalledTimes ( 1 ) ;
556- const [ chatId , messageId , replyMarkup ] = editMessageReplyMarkupSpy . mock . calls [ 0 ] ?? [ ] ;
566+ const [ chatId , messageId , replyMarkup ] = editMessageReplyMarkupSpy . mock . calls . at ( 0 ) ?? [ ] ;
557567 expect ( chatId ) . toBe ( 1234 ) ;
558568 expect ( messageId ) . toBe ( 21 ) ;
559569 expect ( replyMarkup ) . toEqual ( { reply_markup : { inline_keyboard : [ ] } } ) ;
@@ -988,7 +998,7 @@ describe("createTelegramBot", () => {
988998 expect ( listCall . cfg ) . toBeTypeOf ( "object" ) ;
989999 expect ( listCall . agentIds ) . toEqual ( [ "main" ] ) ;
9901000 expect ( editMessageTextSpy ) . toHaveBeenCalledTimes ( 1 ) ;
991- const [ chatId , messageId , text , params ] = editMessageTextSpy . mock . calls [ 0 ] ?? [ ] ;
1001+ const [ chatId , messageId , text , params ] = editMessageTextSpy . mock . calls . at ( 0 ) ?? [ ] ;
9921002 expect ( chatId ) . toBe ( 1234 ) ;
9931003 expect ( messageId ) . toBe ( 12 ) ;
9941004 expect ( String ( text ) ) . toContain ( `${ INFO_EMOJI } Commands (2/` ) ;
@@ -1143,10 +1153,10 @@ describe("createTelegramBot", () => {
11431153
11441154 expect ( replySpy ) . not . toHaveBeenCalled ( ) ;
11451155 expect ( 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", () => {
12191229
12201230 expect ( replySpy ) . not . toHaveBeenCalled ( ) ;
12211231 expect ( editMessageTextSpy ) . toHaveBeenCalledTimes ( 1 ) ;
1222- const [ , , , params ] = editMessageTextSpy . mock . calls [ 0 ] ?? [ ] ;
1232+ const [ , , , params ] = editMessageTextSpy . mock . calls . at ( 0 ) ?? [ ] ;
12231233 const inlineKeyboard = (
12241234 params as {
12251235 reply_markup ?: {
@@ -1293,10 +1303,10 @@ describe("createTelegramBot", () => {
12931303
12941304 expect ( replySpy ) . not . toHaveBeenCalled ( ) ;
12951305 expect ( 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", () => {
13681378
13691379 expect ( replySpy ) . not . toHaveBeenCalled ( ) ;
13701380 expect ( editMessageTextSpy ) . toHaveBeenCalledTimes ( 1 ) ;
1371- const editCall = editMessageTextSpy . mock . calls [ 0 ] ;
1381+ const editCall = editMessageTextSpy . mock . calls . at ( 0 ) ;
13721382 expect ( editCall ?. [ 0 ] ) . toBe ( 1234 ) ;
13731383 expect ( editCall ?. [ 1 ] ) . toBe ( 17 ) ;
13741384 expect ( editCall ?. [ 2 ] ) . toBe (
@@ -1523,7 +1533,7 @@ describe("createTelegramBot", () => {
15231533
15241534 expect ( replySpy ) . not . toHaveBeenCalled ( ) ;
15251535 expect ( 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 ) ;
15291539 expect ( answerCallbackQuerySpy ) . toHaveBeenCalledWith ( "cbq-model-compact-2" ) ;
@@ -1568,7 +1578,7 @@ describe("createTelegramBot", () => {
15681578 } ) ;
15691579
15701580 expect ( replySpy ) . toHaveBeenCalledTimes ( 1 ) ;
1571- const payload = replySpy . mock . calls [ 0 ] [ 0 ] ;
1581+ const payload = mockMsgContextArg ( replySpy as unknown as MockCallSource , 0 , 0 , "replySpy call" ) ;
15721582 const { expectChannelInboundContextContract : expectInboundContextContract } =
15731583 await loadInboundContextContract ( ) ;
15741584 const { escapeRegExp, formatEnvelopeTimestamp } = await loadEnvelopeTimestampHelpers ( ) ;
@@ -1659,7 +1669,7 @@ describe("createTelegramBot", () => {
16591669 } ) ;
16601670
16611671 expect ( replySpy ) . toHaveBeenCalledTimes ( 1 ) ;
1662- const payload = replySpy . mock . calls [ 0 ] [ 0 ] ;
1672+ const payload = mockMsgContextArg ( replySpy as unknown as MockCallSource , 0 , 0 , "replySpy call" ) ;
16631673 const [ conversationContext ] = requireArray (
16641674 payload . UntrustedStructuredContext ,
16651675 "structured context" ,
@@ -1762,7 +1772,7 @@ describe("createTelegramBot", () => {
17621772 } ) ;
17631773
17641774 expect ( replySpy ) . toHaveBeenCalledTimes ( 1 ) ;
1765- const payload = replySpy . mock . calls [ 0 ] [ 0 ] ;
1775+ const payload = mockMsgContextArg ( replySpy as unknown as MockCallSource , 0 , 0 , "replySpy call" ) ;
17661776 const [ conversationContext ] = requireArray (
17671777 payload . UntrustedStructuredContext ,
17681778 "structured context" ,
@@ -1807,7 +1817,7 @@ describe("createTelegramBot", () => {
18071817 } ) ;
18081818
18091819 expect ( replySpy ) . toHaveBeenCalledTimes ( 1 ) ;
1810- const payload = replySpy . mock . calls [ 0 ] [ 0 ] ;
1820+ const payload = mockMsgContextArg ( replySpy as unknown as MockCallSource , 0 , 0 , "replySpy call" ) ;
18111821 expect ( payload . Body ) . toContain ( "[Reply chain - nearest first]" ) ;
18121822 expect ( payload . Body ) . toContain ( "[1. Ada id:9001]" ) ;
18131823 expect ( payload . Body ) . toContain ( '"summarize this"' ) ;
@@ -1845,7 +1855,7 @@ describe("createTelegramBot", () => {
18451855 } ) ;
18461856
18471857 expect ( replySpy ) . toHaveBeenCalledTimes ( 1 ) ;
1848- const payload = replySpy . mock . calls [ 0 ] [ 0 ] ;
1858+ const payload = mockMsgContextArg ( replySpy as unknown as MockCallSource , 0 , 0 , "replySpy call" ) ;
18491859 expect ( payload . Body ) . toContain ( "[Reply chain - nearest first]" ) ;
18501860 expect ( payload . Body ) . toContain ( "[1. Ada id:9001]" ) ;
18511861 expect ( payload . Body ) . not . toContain ( "PK" ) ;
@@ -1900,7 +1910,12 @@ describe("createTelegramBot", () => {
19001910 }
19011911
19021912 expect ( 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 {
19041919 MediaPath ?: string ;
19051920 MediaPaths ?: string [ ] ;
19061921 ReplyToBody ?: string ;
@@ -1990,7 +2005,12 @@ describe("createTelegramBot", () => {
19902005 }
19912006
19922007 expect ( 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 {
19942014 ReplyChain ?: Array < {
19952015 messageId ?: string ;
19962016 body ?: string ;
@@ -2178,7 +2198,7 @@ describe("createTelegramBot", () => {
21782198 } ) ;
21792199
21802200 expect ( replySpy ) . toHaveBeenCalledTimes ( 1 ) ;
2181- const payload = replySpy . mock . calls [ 0 ] [ 0 ] ;
2201+ const payload = mockMsgContextArg ( replySpy as unknown as MockCallSource , 0 , 0 , "replySpy call" ) ;
21822202 expect ( payload . Body ) . toContain ( "[Reply chain - nearest first]" ) ;
21832203 expect ( payload . Body ) . toContain ( "[1. unknown sender]" ) ;
21842204 expect ( payload . Body ) . toContain ( '"summarize this"' ) ;
@@ -2214,7 +2234,7 @@ describe("createTelegramBot", () => {
22142234 } ) ;
22152235
22162236 expect ( replySpy ) . toHaveBeenCalledTimes ( 1 ) ;
2217- const payload = replySpy . mock . calls [ 0 ] [ 0 ] ;
2237+ const payload = mockMsgContextArg ( replySpy as unknown as MockCallSource , 0 , 0 , "replySpy call" ) ;
22182238 expect ( payload . Body ) . toContain ( "[Reply chain - nearest first]" ) ;
22192239 expect ( payload . Body ) . toContain ( "[1. Ada id:9002]" ) ;
22202240 expect ( payload . Body ) . toContain ( '"summarize this"' ) ;
@@ -2262,7 +2282,7 @@ describe("createTelegramBot", () => {
22622282 } ) ;
22632283
22642284 expect ( replySpy ) . toHaveBeenCalledTimes ( 1 ) ;
2265- const payload = replySpy . mock . calls [ 0 ] [ 0 ] ;
2285+ const payload = mockMsgContextArg ( replySpy as unknown as MockCallSource , 0 , 0 , "replySpy call" ) ;
22662286 expect ( payload . ReplyToForwardedFrom ) . toBe ( "Bob Smith (@bobsmith)" ) ;
22672287 expect ( payload . ReplyToForwardedFromType ) . toBe ( "user" ) ;
22682288 expect ( payload . ReplyToForwardedFromId ) . toBe ( "999" ) ;
@@ -2325,7 +2345,7 @@ describe("createTelegramBot", () => {
23252345 } ) ;
23262346
23272347 expect ( replySpy ) . toHaveBeenCalledTimes ( 1 ) ;
2328- const payload = replySpy . mock . calls [ 0 ] [ 0 ] ;
2348+ const payload = mockMsgContextArg ( replySpy as unknown as MockCallSource , 0 , 0 , "replySpy call" ) ;
23292349 expect ( payload . ReplyToId ) . toBe ( "9003" ) ;
23302350 expect ( payload . ReplyToBody ) . toBe ( "forwarded text" ) ;
23312351 expect ( payload . ReplyToSender ) . toBe ( "Ada" ) ;
@@ -2365,7 +2385,7 @@ describe("createTelegramBot", () => {
23652385 } ) ;
23662386
23672387 expect ( replySpy ) . toHaveBeenCalledTimes ( 1 ) ;
2368- const payload = replySpy . mock . calls [ 0 ] [ 0 ] ;
2388+ const payload = mockMsgContextArg ( replySpy as unknown as MockCallSource , 0 , 0 , "replySpy call" ) ;
23692389 expect ( payload . WasMentioned ) . toBe ( true ) ;
23702390 } ) ;
23712391
@@ -2837,7 +2857,7 @@ describe("createTelegramBot", () => {
28372857 } ) ;
28382858
28392859 expect ( replySpy ) . toHaveBeenCalledTimes ( 1 ) ;
2840- const payload = replySpy . mock . calls [ 0 ] [ 0 ] ;
2860+ const payload = mockMsgContextArg ( replySpy as unknown as MockCallSource , 0 , 0 , "replySpy call" ) ;
28412861 expect ( payload . CommandTargetSessionKey ) . toBe ( "agent:main:main" ) ;
28422862 } ) ;
28432863
@@ -3019,7 +3039,7 @@ describe("createTelegramBot", () => {
30193039 } ) ;
30203040
30213041 expect ( 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 ) ;
30253045 expect ( String ( systemEventOptions ( ) . contextKey ) ) . toContain ( "telegram:reaction:add:1234:42:9" ) ;
@@ -3247,10 +3267,10 @@ describe("createTelegramBot", () => {
32473267 } ) ;
32483268
32493269 expect ( 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 } ) ;
32553275
32563276 it ( "skips reaction in own mode when message is not sent by bot" , async ( ) => {
@@ -3444,7 +3464,7 @@ describe("createTelegramBot", () => {
34443464 } ) ;
34453465
34463466 expect ( 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 ) ;
34503470 expect ( String ( systemEventOptions ( ) . sessionKey ) ) . toContain ( "telegram:group:5678:topic:1" ) ;
@@ -3480,7 +3500,7 @@ describe("createTelegramBot", () => {
34803500 } ) ;
34813501
34823502 expect ( 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 ) ;
34863506 expect ( String ( systemEventOptions ( ) . sessionKey ) ) . toContain ( "telegram:group:5678:topic:1" ) ;
@@ -3515,13 +3535,13 @@ describe("createTelegramBot", () => {
35153535 } ) ;
35163536
35173537 expect ( 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 ) ;
35213541 expect ( String ( systemEventOptions ( ) . sessionKey ) ) . toContain ( "telegram:group:9999" ) ;
35223542 expect ( 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 {
35253545 sessionKey ?: string ;
35263546 } ;
35273547 const sessionKey = eventOptions . sessionKey ?? "" ;
0 commit comments