@@ -3866,13 +3866,7 @@ describe("dispatchReplyFromConfig", () => {
38663866 } ) ;
38673867
38683868 expect ( result . sourceReplyDeliveryMode ) . toBe ( "message_tool_only" ) ;
3869- expect ( onCommandOutput ) . toHaveBeenCalledWith ( {
3870- phase : "end" ,
3871- title : "Exec" ,
3872- name : "exec" ,
3873- status : "failed" ,
3874- exitCode : 1 ,
3875- } ) ;
3869+ expect ( onCommandOutput ) . not . toHaveBeenCalled ( ) ;
38763870 expect ( dispatcher . sendToolResult ) . not . toHaveBeenCalled ( ) ;
38773871 expect ( dispatcher . sendFinalReply ) . not . toHaveBeenCalled ( ) ;
38783872 } ) ;
@@ -3886,6 +3880,7 @@ describe("dispatchReplyFromConfig", () => {
38863880 verboseLevel : "on" ,
38873881 } ;
38883882 const onCommandOutput = vi . fn ( ) ;
3883+ const onToolResult = vi . fn ( ) ;
38893884 const cfg = emptyConfig ;
38903885 const dispatcher = createDispatcher ( ) ;
38913886 const ctx = buildTestCtx ( {
@@ -3922,17 +3917,13 @@ describe("dispatchReplyFromConfig", () => {
39223917 sourceReplyDeliveryMode : "message_tool_only" ,
39233918 allowProgressCallbacksWhenSourceDeliverySuppressed : true ,
39243919 onCommandOutput,
3920+ onToolResult,
39253921 } ,
39263922 } ) ;
39273923
39283924 expect ( result . sourceReplyDeliveryMode ) . toBe ( "message_tool_only" ) ;
3929- expect ( onCommandOutput ) . toHaveBeenCalledWith ( {
3930- phase : "end" ,
3931- title : "Exec" ,
3932- name : "exec" ,
3933- status : "failed" ,
3934- exitCode : 2 ,
3935- } ) ;
3925+ expect ( onCommandOutput ) . not . toHaveBeenCalled ( ) ;
3926+ expect ( onToolResult ) . not . toHaveBeenCalled ( ) ;
39363927 expect ( dispatcher . sendToolResult ) . not . toHaveBeenCalled ( ) ;
39373928 expect ( dispatcher . sendFinalReply ) . not . toHaveBeenCalled ( ) ;
39383929 } ) ;
@@ -4024,7 +4015,7 @@ describe("dispatchReplyFromConfig", () => {
40244015 expect ( dispatcher . sendFinalReply ) . not . toHaveBeenCalled ( ) ;
40254016 } ) ;
40264017
4027- it ( "suppresses terminal tool-error fallbacks when regular verbose progress is visible " , async ( ) => {
4018+ it ( "keeps terminal tool-error fallbacks available when regular verbose failed command progress is hidden " , async ( ) => {
40284019 setNoAbort ( ) ;
40294020 sessionStoreMocks . currentEntry = {
40304021 sessionId : "s1" ,
@@ -4060,18 +4051,13 @@ describe("dispatchReplyFromConfig", () => {
40604051 replyOptions : { onCommandOutput } ,
40614052 } ) ;
40624053
4063- expect ( onCommandOutput ) . toHaveBeenCalledWith ( {
4064- phase : "end" ,
4065- name : "exec" ,
4066- status : "failed" ,
4067- exitCode : 1 ,
4068- } ) ;
4054+ expect ( onCommandOutput ) . not . toHaveBeenCalled ( ) ;
40694055 expect ( receivedOptions ?. suppressToolErrorWarnings ) . toBeUndefined ( ) ;
4070- expect ( receivedOptions ?. shouldSuppressToolErrorWarnings ?.( ) ) . toBe ( true ) ;
4056+ expect ( receivedOptions ?. shouldSuppressToolErrorWarnings ?.( ) ) . toBeUndefined ( ) ;
40714057 expect ( dispatcher . sendFinalReply ) . toHaveBeenCalledWith ( { text : "done" } ) ;
40724058 } ) ;
40734059
4074- it ( "suppresses terminal tool-error fallbacks in group sessions when verbose progress is visible " , async ( ) => {
4060+ it ( "keeps terminal tool-error fallbacks available when regular verbose failed item progress is hidden " , async ( ) => {
40754061 setNoAbort ( ) ;
40764062 sessionStoreMocks . currentEntry = {
40774063 sessionId : "s1" ,
@@ -4109,14 +4095,56 @@ describe("dispatchReplyFromConfig", () => {
41094095 replyOptions : { onItemEvent } ,
41104096 } ) ;
41114097
4112- expect ( onItemEvent ) . toHaveBeenCalledWith ( {
4113- itemId : "item-1" ,
4114- kind : "tool" ,
4098+ expect ( onItemEvent ) . not . toHaveBeenCalled ( ) ;
4099+ expect ( receivedOptions ?. suppressToolErrorWarnings ) . toBeUndefined ( ) ;
4100+ expect ( receivedOptions ?. shouldSuppressToolErrorWarnings ?.( ) ) . toBeUndefined ( ) ;
4101+ expect ( dispatcher . sendFinalReply ) . toHaveBeenCalledWith ( { text : "done" } ) ;
4102+ } ) ;
4103+
4104+ it ( "keeps full verbose failed command progress visible" , async ( ) => {
4105+ setNoAbort ( ) ;
4106+ sessionStoreMocks . currentEntry = {
4107+ sessionId : "s1" ,
4108+ updatedAt : 0 ,
4109+ sendPolicy : "allow" ,
4110+ verboseLevel : "full" ,
4111+ } ;
4112+ const dispatcher = createDispatcher ( ) ;
4113+ const onCommandOutput = vi . fn ( ) ;
4114+ const ctx = buildTestCtx ( {
4115+ Provider : "telegram" ,
4116+ ChatType : "direct" ,
4117+ SessionKey : "agent:main:telegram:direct:U1" ,
4118+ } ) ;
4119+ let receivedOptions : GetReplyOptions | undefined ;
4120+ const replyResolver = vi . fn ( async ( _ctx : MsgContext , opts ?: GetReplyOptions ) => {
4121+ receivedOptions = opts ;
4122+ expect ( opts ?. shouldSuppressToolErrorWarnings ?.( ) ) . toBeUndefined ( ) ;
4123+ await opts ?. onCommandOutput ?.( {
4124+ phase : "end" ,
4125+ name : "exec" ,
4126+ status : "failed" ,
4127+ exitCode : 1 ,
4128+ } ) ;
4129+ return { text : "done" } satisfies ReplyPayload ;
4130+ } ) ;
4131+
4132+ await dispatchReplyFromConfig ( {
4133+ ctx,
4134+ cfg : emptyConfig ,
4135+ dispatcher,
4136+ replyResolver,
4137+ replyOptions : { onCommandOutput } ,
4138+ } ) ;
4139+
4140+ expect ( onCommandOutput ) . toHaveBeenCalledWith ( {
4141+ phase : "end" ,
41154142 name : "exec" ,
41164143 status : "failed" ,
4144+ exitCode : 1 ,
41174145 } ) ;
41184146 expect ( receivedOptions ?. suppressToolErrorWarnings ) . toBeUndefined ( ) ;
4119- expect ( receivedOptions ?. shouldSuppressToolErrorWarnings ?.( ) ) . toBe ( true ) ;
4147+ expect ( receivedOptions ?. shouldSuppressToolErrorWarnings ?.( ) ) . toBeUndefined ( ) ;
41204148 expect ( dispatcher . sendFinalReply ) . toHaveBeenCalledWith ( { text : "done" } ) ;
41214149 } ) ;
41224150
0 commit comments