@@ -23,21 +23,24 @@ type Model interface {
2323
2424// messageModel implements Model
2525type messageModel struct {
26- message * types.Message
26+ message * types.Message
27+ previous * types.Message
28+
2729 width int
2830 height int
2931 focused bool
3032 spinner spinner.Spinner
3133}
3234
3335// New creates a new message view
34- func New (msg * types.Message ) * messageModel {
36+ func New (msg , previous * types.Message ) * messageModel {
3537 return & messageModel {
36- message : msg ,
37- width : 80 , // Default width
38- height : 1 , // Will be calculated
39- focused : false ,
40- spinner : spinner .New (spinner .ModeBoth ),
38+ message : msg ,
39+ previous : previous ,
40+ width : 80 , // Default width
41+ height : 1 , // Will be calculated
42+ focused : false ,
43+ spinner : spinner .New (spinner .ModeBoth ),
4144 }
4245}
4346
@@ -77,31 +80,39 @@ func (mv *messageModel) Render(width int) string {
7780 case types .MessageTypeSpinner :
7881 return mv .spinner .View ()
7982 case types .MessageTypeUser :
80- return styles .UserMessageBorderStyle .Width (width - 1 ).Render (msg .Content )
83+ return styles .UserMessageStyle .Width (width - 1 ).Render (msg .Content )
8184 case types .MessageTypeAssistant :
8285 if msg .Content == "" {
8386 return mv .spinner .View ()
8487 }
8588
86- rendered , err := markdown .NewRenderer (width ).Render (msg .Content )
89+ rendered , err := markdown .NewRenderer (width - styles . AssistantMessageStyle . GetPaddingLeft () ).Render (msg .Content )
8790 if err != nil {
88- return senderPrefix (msg .Sender ) + msg .Content
91+ rendered = msg .Content
92+ } else {
93+ rendered = strings .TrimRight (rendered , "\n \r \t " )
94+ }
95+
96+ if mv .previous != nil && mv .previous .Type == msg .Type && mv .previous .Sender == msg .Sender {
97+ return styles .AssistantMessageStyle .Render (rendered )
8998 }
9099
91- return senderPrefix (msg .Sender ) + strings . TrimRight (rendered , " \n \r \t " )
100+ return mv . senderPrefix (msg .Sender ) + styles . AssistantMessageStyle . Render (rendered )
92101 case types .MessageTypeAssistantReasoning :
93102 if msg .Content == "" {
94103 return mv .spinner .View ()
95104 }
96- // Render through the markdown renderer to ensure proper wrapping to width
105+
97106 rendered , err := markdown .NewRenderer (width ).Render (msg .Content )
98107 if err != nil {
99- text := "Thinking: " + senderPrefix (msg .Sender ) + msg .Content
108+ text := "Thinking: " + mv . senderPrefix (msg .Sender ) + msg .Content
100109 return styles .MutedStyle .Italic (true ).Render (text )
101110 }
111+
102112 // Strip ANSI from inner rendering so muted style fully applies
103113 clean := stripANSI (strings .TrimRight (rendered , "\n \r \t " ))
104- thinkingText := "Thinking: " + senderPrefix (msg .Sender ) + clean
114+ thinkingText := "Thinking: " + mv .senderPrefix (msg .Sender ) + clean
115+
105116 return styles .MutedStyle .Italic (true ).Render (thinkingText )
106117 case types .MessageTypeShellOutput :
107118 if rendered , err := markdown .NewRenderer (width ).Render (fmt .Sprintf ("```console\n %s\n ```" , msg .Content )); err == nil {
@@ -111,19 +122,19 @@ func (mv *messageModel) Render(width int) string {
111122 case types .MessageTypeCancelled :
112123 return styles .WarningStyle .Render ("⚠ stream cancelled ⚠" )
113124 case types .MessageTypeWelcome :
114- return styles .WelcomeMessageBorderStyle .Width (width - 1 ).Render (strings .TrimRight (msg .Content , "\n \r \t " ))
125+ return styles .WelcomeMessageStyle .Width (width - 1 ).Render (strings .TrimRight (msg .Content , "\n \r \t " ))
115126 case types .MessageTypeError :
116127 return styles .ErrorMessageStyle .Width (width - 1 ).Render (msg .Content )
117128 default :
118129 return msg .Content
119130 }
120131}
121132
122- func senderPrefix (sender string ) string {
133+ func ( mv * messageModel ) senderPrefix (sender string ) string {
123134 if sender == "" {
124135 return ""
125136 }
126- return styles .AgentBadgeStyle .Render ("[" + sender + "] " ) + "\n \n "
137+ return styles .AgentBadgeStyle .Render (sender + " ▶ " ) + "\n \n "
127138}
128139
129140// Height calculates the height needed for this message view
0 commit comments