@@ -564,6 +564,107 @@ func TestModeCommand(t *testing.T) {
564564 }
565565}
566566
567+ // TestEnhanceMode_SendsNarratedMessages tests that enhance mode sends
568+ // new narrated messages per tool_call (no edits, no cleanup, silent tool_result).
569+ func TestEnhanceMode_SendsNarratedMessages (t * testing.T ) {
570+ bot := newMockBot ()
571+
572+ chatID := int64 (123 )
573+ messageID := 1
574+ isEnhance := true
575+
576+ // Simulate the narrator for enhance mode
577+ type narrateMsg struct {}
578+ var progressMsgID int
579+ if isEnhance {
580+ msg , _ := bot .SendMessage (chatID , "🤔 Looking into that..." ,
581+ & telegram.SendOpts {ReplyToMessageID : messageID })
582+ if msg != nil {
583+ progressMsgID = msg .ID
584+ }
585+ }
586+
587+ // Simulate enhance-mode tool handler
588+ toolHandler := func (event string , name string , data string ) {
589+ if ! isEnhance {
590+ return
591+ }
592+ switch event {
593+ case "tool_call" :
594+ msg := narratorToolCallMessage (name , data )
595+ if msg != "" {
596+ bot .SendMessage (chatID , msg ,
597+ & telegram.SendOpts {ParseMode : telegram .ParseModeMarkdownV2 })
598+ }
599+ case "tool_result" :
600+ // silent in enhance mode
601+ }
602+ }
603+
604+ // Fire events: one iteration with reasoning + 2 tool calls
605+ toolHandler ("tool_call" , "read_file" , `{"path":"/etc/hostname"}` )
606+ toolHandler ("tool_result" , "read_file" , `{"content":"my-host"}` )
607+ toolHandler ("tool_call" , "shell" , `{"command":"go test ./..."}` )
608+ toolHandler ("tool_result" , "shell" , `{"output":"PASS","exit_code":0}` )
609+
610+ calls := bot .recorded ()
611+ t .Logf ("Enhance mode sequence (%d calls):" , len (calls ))
612+ for i , c := range calls {
613+ t .Logf (" %d. %s %q (msgID=%d)" , i + 1 , c .Method , truncateStr (c .Text , 60 ), c .MsgID )
614+ }
615+
616+ // Expected: 3 sendMessages (thinking node + 2 narrated tool_call)
617+ // No edits, no deletes
618+ if len (calls ) != 3 {
619+ t .Fatalf ("expected 3 calls (thinking node + 2 narrated), got %d" , len (calls ))
620+ }
621+
622+ // Call 1: thinking node
623+ if calls [0 ].Method != "sendMessage" || ! strings .Contains (calls [0 ].Text , "🤔" ) {
624+ t .Errorf ("call 1: expected sendMessage with thinking node, got %s %q" , calls [0 ].Method , calls [0 ].Text )
625+ }
626+
627+ // Call 2: narrated read_file
628+ if calls [1 ].Method != "sendMessage" || ! strings .Contains (calls [1 ].Text , "📖" ) {
629+ t .Errorf ("call 2: expected sendMessage with narrated read_file, got %s %q" , calls [1 ].Method , calls [1 ].Text )
630+ }
631+
632+ // Call 3: narrated shell
633+ if calls [2 ].Method != "sendMessage" || ! strings .Contains (calls [2 ].Text , "⚙️" ) {
634+ t .Errorf ("call 3: expected sendMessage with narrated shell, got %s %q" , calls [2 ].Method , calls [2 ].Text )
635+ }
636+
637+ // No editMessageText
638+ for _ , c := range calls {
639+ if c .Method == "editMessageText" {
640+ t .Errorf ("unexpected editMessageText in enhance mode: %q" , c .Text )
641+ }
642+ }
643+
644+ // No deleteMessage
645+ for _ , c := range calls {
646+ if c .Method == "deleteMessage" {
647+ t .Errorf ("unexpected deleteMessage in enhance mode (msgID=%d)" , c .MsgID )
648+ }
649+ }
650+
651+ // Verify progressMsgID is NOT deleted (it was stored but defer cleanup
652+ // skipped it because isEngaging=false)
653+ _ = progressMsgID
654+ }
655+
656+ // narratorToolCallMessage replicates the narrator's ToolCallMessage for tests.
657+ func narratorToolCallMessage (name , args string ) string {
658+ switch name {
659+ case "read_file" :
660+ return "📖 Reading `hostname`..."
661+ case "shell" :
662+ return "⚙️ Running `go test ./...`..."
663+ default :
664+ return "🔧 Working on `" + name + "`..."
665+ }
666+ }
667+
567668// truncateStr truncates a string for display in test logs.
568669func truncateStr (s string , n int ) string {
569670 if len (s ) <= n {
0 commit comments