@@ -3504,6 +3504,40 @@ describe("dispatchTelegramMessage draft streaming", () => {
35043504 expect ( sendMessageTelegram ) . not . toHaveBeenCalled ( ) ;
35053505 } ) ;
35063506
3507+ it ( "does not send failure fallback when source delivery is message-tool-only and reply lane is non-silently skipped" , async ( ) => {
3508+ setupDraftStreams ( { answerMessageId : 2001 , reasoningMessageId : 3001 } ) ;
3509+ // Simulate a group turn where config sets message_tool delivery (not a room_event), the
3510+ // message tool sends the visible reply, and the main reply lane is skipped as "empty".
3511+ dispatchReplyWithBufferedBlockDispatcher . mockImplementation ( async ( { dispatcherOptions } ) => {
3512+ dispatcherOptions . onSkip ?.( { text : "" , isError : false } , { kind : "final" , reason : "empty" } ) ;
3513+ return {
3514+ queuedFinal : false ,
3515+ counts : { block : 0 , final : 0 , tool : 0 } ,
3516+ sourceReplyDeliveryMode : "message_tool_only" ,
3517+ } ;
3518+ } ) ;
3519+
3520+ await dispatchWithContext ( {
3521+ context : createContext ( {
3522+ isGroup : true ,
3523+ ctxPayload : {
3524+ SessionKey : "agent:main:telegram:group:-100456" ,
3525+ ChatType : "group" ,
3526+ } as unknown as TelegramMessageContext [ "ctxPayload" ] ,
3527+ msg : {
3528+ chat : { id : - 100456 , type : "supergroup" } ,
3529+ message_id : 789 ,
3530+ } as unknown as TelegramMessageContext [ "msg" ] ,
3531+ chatId : - 100456 ,
3532+ threadSpec : { id : undefined , scope : "none" } ,
3533+ } ) ,
3534+ } ) ;
3535+
3536+ expect ( deliverReplies ) . not . toHaveBeenCalled ( ) ;
3537+ expect ( editMessageTelegram ) . not . toHaveBeenCalled ( ) ;
3538+ expect ( sendMessageTelegram ) . not . toHaveBeenCalled ( ) ;
3539+ } ) ;
3540+
35073541 it ( "runs ambient room events as tool-only invisible turns" , async ( ) => {
35083542 const historyKey = "telegram:group:-100123" ;
35093543 const groupHistories = new Map ( [
0 commit comments