on main help sign in
refactor(chat): rename GetMessageItems to ExtractMessageItems and GetToolRenderer to ToolRenderer
2cccd51Ayman Bagabas
internal/ui/chat/messages.go+9−24
@@ -151,12 +151,12 @@ func cappedMessageWidth(availableWidth int) int {
151 return min(availableWidth-messageLeftPaddingTotal, maxTextWidth)
151 return min(availableWidth-messageLeftPaddingTotal, maxTextWidth)
152}
152}
153
153
154−// GetMessageItems extracts [MessageItem]s from a [message.Message]. It returns
154+// ExtractMessageItems extracts [MessageItem]s from a [message.Message]. It
155−// all parts of the message as [MessageItem]s.
155+// returns all parts of the message as [MessageItem]s.
156//
156//
157// For assistant messages with tool calls, pass a toolResults map to link results.
157// For assistant messages with tool calls, pass a toolResults map to link results.
158// Use BuildToolResultMap to create this map from all messages in a session.
158// Use BuildToolResultMap to create this map from all messages in a session.
159−func GetMessageItems(sty *styles.Styles, msg *message.Message, toolResults map[string]message.ToolResult) []MessageItem {
159+func ExtractMessageItems(sty *styles.Styles, msg *message.Message, toolResults map[string]message.ToolResult) []MessageItem {
160 switch msg.Role {
160 switch msg.Role {
161 case message.User:
161 case message.User:
162 return []MessageItem{NewUserMessageItem(sty, msg)}
162 return []MessageItem{NewUserMessageItem(sty, msg)}
@@ -170,7 +170,7 @@ func GetMessageItems(sty *styles.Styles, msg *message.Message, toolResults map[s
170 if tr, ok := toolResults[tc.ID]; ok {
170 if tr, ok := toolResults[tc.ID]; ok {
171 result = &tr
171 result = &tr
172 }
172 }
173− items = append(items, GetToolMessageItem(
173+ items = append(items, NewToolMessageItem(
174 sty,
174 sty,
175 tc,
175 tc,
176 result,
176 result,
@@ -182,30 +182,15 @@ func GetMessageItems(sty *styles.Styles, msg *message.Message, toolResults map[s
182 return []MessageItem{}
182 return []MessageItem{}
183}
183}
184
184
185−// GetToolRenderer returns the appropriate ToolRenderFunc for a given tool call.
185+// ToolRenderer returns the appropriate [ToolRenderFunc] for a given tool call.
186// this should be used for nested tools as well.
186// this should be used for nested tools as well.
187−func GetToolRenderer(tc message.ToolCall) ToolRenderFunc {
187+func ToolRenderer(tc message.ToolCall) ToolRenderFunc {
188− renderFunc := DefaultToolRenderer
189 switch tc.Name {
188 switch tc.Name {
190 case tools.BashToolName:
189 case tools.BashToolName:
191− renderFunc = BashToolRenderer
190+ return BashToolRenderer
191+ default:
192+ return DefaultToolRenderer
192 }
193 }
193− return renderFunc
194−}
195−
196−// GetToolMessageItem creates a MessageItem for a tool call and its result.
197−func GetToolMessageItem(sty *styles.Styles, tc message.ToolCall, result *message.ToolResult, canceled bool) MessageItem {
198− // we only do full width for diffs (as far as I know)
199− cappedWidth := tc.Name != tools.EditToolName && tc.Name != tools.MultiEditToolName
200−
201− return NewToolMessageItem(
202− sty,
203− GetToolRenderer(tc),
204− tc,
205− result,
206− canceled,
207− cappedWidth,
208− )
209}
194}
210
195
211// shouldRenderAssistantMessage determines if an assistant message should be rendered
196// shouldRenderAssistantMessage determines if an assistant message should be rendered
internal/ui/chat/tools.go+4−3
@@ -6,6 +6,7 @@ import (
6
6
7 tea "charm.land/bubbletea/v2"
7 tea "charm.land/bubbletea/v2"
8 "charm.land/lipgloss/v2"
8 "charm.land/lipgloss/v2"
9+ "github.com/charmbracelet/crush/internal/agent/tools"
9 "github.com/charmbracelet/crush/internal/message"
10 "github.com/charmbracelet/crush/internal/message"
10 "github.com/charmbracelet/crush/internal/ui/anim"
11 "github.com/charmbracelet/crush/internal/ui/anim"
11 "github.com/charmbracelet/crush/internal/ui/styles"
12 "github.com/charmbracelet/crush/internal/ui/styles"
@@ -91,18 +92,18 @@ type ToolMessageItem struct {
91// NewToolMessageItem creates a new tool message item with the given renderFunc.
92// NewToolMessageItem creates a new tool message item with the given renderFunc.
92func NewToolMessageItem(
93func NewToolMessageItem(
93 sty *styles.Styles,
94 sty *styles.Styles,
94− renderFunc ToolRenderFunc,
95 toolCall message.ToolCall,
95 toolCall message.ToolCall,
96 result *message.ToolResult,
96 result *message.ToolResult,
97 canceled bool,
97 canceled bool,
98− hasCappedWidth bool,
99) *ToolMessageItem {
98) *ToolMessageItem {
99+ // we only do full width for diffs (as far as I know)
100+ hasCappedWidth := toolCall.Name != tools.EditToolName && toolCall.Name != tools.MultiEditToolName
100 t := &ToolMessageItem{
101 t := &ToolMessageItem{
101 highlightableMessageItem: defaultHighlighter(sty),
102 highlightableMessageItem: defaultHighlighter(sty),
102 cachedMessageItem: &cachedMessageItem{},
103 cachedMessageItem: &cachedMessageItem{},
103 focusableMessageItem: &focusableMessageItem{},
104 focusableMessageItem: &focusableMessageItem{},
104 sty: sty,
105 sty: sty,
105− renderFunc: renderFunc,
106+ renderFunc: ToolRenderer(toolCall),
106 toolCall: toolCall,
107 toolCall: toolCall,
107 result: result,
108 result: result,
108 canceled: canceled,
109 canceled: canceled,
internal/ui/model/chat.go+2−2
@@ -245,8 +245,8 @@ func (m *Chat) ClearMessages() {
245 m.ClearMouse()
245 m.ClearMouse()
246}
246}
247
247
248−// GetMessageItem returns the message item at the given id.
248+// MessageItem returns the message item with the given ID, or nil if not found.
249−func (m *Chat) GetMessageItem(id string) chat.MessageItem {
249+func (m *Chat) MessageItem(id string) chat.MessageItem {
250 idx, ok := m.idInxMap[id]
250 idx, ok := m.idInxMap[id]
251 if !ok {
251 if !ok {
252 return nil
252 return nil
internal/ui/model/ui.go+6−6
@@ -380,7 +380,7 @@ func (m *UI) setSessionMessages(msgs []message.Message) tea.Cmd {
380 // Add messages to chat with linked tool results
380 // Add messages to chat with linked tool results
381 items := make([]chat.MessageItem, 0, len(msgs)*2)
381 items := make([]chat.MessageItem, 0, len(msgs)*2)
382 for _, msg := range msgPtrs {
382 for _, msg := range msgPtrs {
383− items = append(items, chat.GetMessageItems(m.com.Styles, msg, toolResultMap)...)
383+ items = append(items, chat.ExtractMessageItems(m.com.Styles, msg, toolResultMap)...)
384 }
384 }
385
385
386 // If the user switches between sessions while the agent is working we want
386 // If the user switches between sessions while the agent is working we want
@@ -407,7 +407,7 @@ func (m *UI) appendSessionMessage(msg message.Message) tea.Cmd {
407 var cmds []tea.Cmd
407 var cmds []tea.Cmd
408 switch msg.Role {
408 switch msg.Role {
409 case message.User, message.Assistant:
409 case message.User, message.Assistant:
410− items := chat.GetMessageItems(m.com.Styles, &msg, nil)
410+ items := chat.ExtractMessageItems(m.com.Styles, &msg, nil)
411 for _, item := range items {
411 for _, item := range items {
412 if animatable, ok := item.(chat.Animatable); ok {
412 if animatable, ok := item.(chat.Animatable); ok {
413 if cmd := animatable.StartAnimation(); cmd != nil {
413 if cmd := animatable.StartAnimation(); cmd != nil {
@@ -421,7 +421,7 @@ func (m *UI) appendSessionMessage(msg message.Message) tea.Cmd {
421 }
421 }
422 case message.Tool:
422 case message.Tool:
423 for _, tr := range msg.ToolResults() {
423 for _, tr := range msg.ToolResults() {
424− toolItem := m.chat.GetMessageItem(tr.ToolCallID)
424+ toolItem := m.chat.MessageItem(tr.ToolCallID)
425 if toolItem == nil {
425 if toolItem == nil {
426 // we should have an item!
426 // we should have an item!
427 continue
427 continue
@@ -439,7 +439,7 @@ func (m *UI) appendSessionMessage(msg message.Message) tea.Cmd {
439// that is why we need to handle creating/updating each tool call message too
439// that is why we need to handle creating/updating each tool call message too
440func (m *UI) updateSessionMessage(msg message.Message) tea.Cmd {
440func (m *UI) updateSessionMessage(msg message.Message) tea.Cmd {
441 var cmds []tea.Cmd
441 var cmds []tea.Cmd
442− existingItem := m.chat.GetMessageItem(msg.ID)
442+ existingItem := m.chat.MessageItem(msg.ID)
443 if existingItem == nil || msg.Role != message.Assistant {
443 if existingItem == nil || msg.Role != message.Assistant {
444 return nil
444 return nil
445 }
445 }
@@ -450,7 +450,7 @@ func (m *UI) updateSessionMessage(msg message.Message) tea.Cmd {
450
450
451 var items []chat.MessageItem
451 var items []chat.MessageItem
452 for _, tc := range msg.ToolCalls() {
452 for _, tc := range msg.ToolCalls() {
453− existingToolItem := m.chat.GetMessageItem(tc.ID)
453+ existingToolItem := m.chat.MessageItem(tc.ID)
454 if toolItem, ok := existingToolItem.(*chat.ToolMessageItem); ok {
454 if toolItem, ok := existingToolItem.(*chat.ToolMessageItem); ok {
455 existingToolCall := toolItem.ToolCall()
455 existingToolCall := toolItem.ToolCall()
456 // only update if finished state changed or input changed
456 // only update if finished state changed or input changed
@@ -460,7 +460,7 @@ func (m *UI) updateSessionMessage(msg message.Message) tea.Cmd {
460 }
460 }
461 }
461 }
462 if existingToolItem == nil {
462 if existingToolItem == nil {
463− items = append(items, chat.GetToolMessageItem(m.com.Styles, tc, nil, false))
463+ items = append(items, chat.NewToolMessageItem(m.com.Styles, tc, nil, false))
464 }
464 }
465 }
465 }
466
466