From 2cccd515a848a5df0d9dffea3c3f5f037752c07b Mon Sep 17 00:00:00 2001 From: Ayman Bagabas Date: Thu, 18 Dec 2025 13:24:59 -0500 Subject: [PATCH] refactor(chat): rename GetMessageItems to ExtractMessageItems and GetToolRenderer to ToolRenderer --- internal/ui/chat/messages.go | 33 +++++++++------------------------ internal/ui/chat/tools.go | 7 ++++--- internal/ui/model/chat.go | 4 ++-- internal/ui/model/ui.go | 12 ++++++------ 4 files changed, 21 insertions(+), 35 deletions(-) diff --git a/internal/ui/chat/messages.go b/internal/ui/chat/messages.go index 9bf977d2e2f6fbd960e57a7e5d77fedb28b5b54b..000847a192a106f45aa6836281e50bf89426f20f 100644 --- a/internal/ui/chat/messages.go +++ b/internal/ui/chat/messages.go @@ -151,12 +151,12 @@ func cappedMessageWidth(availableWidth int) int { return min(availableWidth-messageLeftPaddingTotal, maxTextWidth) } -// GetMessageItems extracts [MessageItem]s from a [message.Message]. It returns -// all parts of the message as [MessageItem]s. +// ExtractMessageItems extracts [MessageItem]s from a [message.Message]. It +// returns all parts of the message as [MessageItem]s. // // For assistant messages with tool calls, pass a toolResults map to link results. // Use BuildToolResultMap to create this map from all messages in a session. -func GetMessageItems(sty *styles.Styles, msg *message.Message, toolResults map[string]message.ToolResult) []MessageItem { +func ExtractMessageItems(sty *styles.Styles, msg *message.Message, toolResults map[string]message.ToolResult) []MessageItem { switch msg.Role { case message.User: return []MessageItem{NewUserMessageItem(sty, msg)} @@ -170,7 +170,7 @@ func GetMessageItems(sty *styles.Styles, msg *message.Message, toolResults map[s if tr, ok := toolResults[tc.ID]; ok { result = &tr } - items = append(items, GetToolMessageItem( + items = append(items, NewToolMessageItem( sty, tc, result, @@ -182,30 +182,15 @@ func GetMessageItems(sty *styles.Styles, msg *message.Message, toolResults map[s return []MessageItem{} } -// GetToolRenderer returns the appropriate ToolRenderFunc for a given tool call. +// ToolRenderer returns the appropriate [ToolRenderFunc] for a given tool call. // this should be used for nested tools as well. -func GetToolRenderer(tc message.ToolCall) ToolRenderFunc { - renderFunc := DefaultToolRenderer +func ToolRenderer(tc message.ToolCall) ToolRenderFunc { switch tc.Name { case tools.BashToolName: - renderFunc = BashToolRenderer + return BashToolRenderer + default: + return DefaultToolRenderer } - return renderFunc -} - -// GetToolMessageItem creates a MessageItem for a tool call and its result. -func GetToolMessageItem(sty *styles.Styles, tc message.ToolCall, result *message.ToolResult, canceled bool) MessageItem { - // we only do full width for diffs (as far as I know) - cappedWidth := tc.Name != tools.EditToolName && tc.Name != tools.MultiEditToolName - - return NewToolMessageItem( - sty, - GetToolRenderer(tc), - tc, - result, - canceled, - cappedWidth, - ) } // shouldRenderAssistantMessage determines if an assistant message should be rendered diff --git a/internal/ui/chat/tools.go b/internal/ui/chat/tools.go index 5d6987c604aac42090659dd35d3da77d9bfe9a2e..1847ac72287af31b7a0026c2ba60f85366a19e0a 100644 --- a/internal/ui/chat/tools.go +++ b/internal/ui/chat/tools.go @@ -6,6 +6,7 @@ import ( tea "charm.land/bubbletea/v2" "charm.land/lipgloss/v2" + "github.com/charmbracelet/crush/internal/agent/tools" "github.com/charmbracelet/crush/internal/message" "github.com/charmbracelet/crush/internal/ui/anim" "github.com/charmbracelet/crush/internal/ui/styles" @@ -91,18 +92,18 @@ type ToolMessageItem struct { // NewToolMessageItem creates a new tool message item with the given renderFunc. func NewToolMessageItem( sty *styles.Styles, - renderFunc ToolRenderFunc, toolCall message.ToolCall, result *message.ToolResult, canceled bool, - hasCappedWidth bool, ) *ToolMessageItem { + // we only do full width for diffs (as far as I know) + hasCappedWidth := toolCall.Name != tools.EditToolName && toolCall.Name != tools.MultiEditToolName t := &ToolMessageItem{ highlightableMessageItem: defaultHighlighter(sty), cachedMessageItem: &cachedMessageItem{}, focusableMessageItem: &focusableMessageItem{}, sty: sty, - renderFunc: renderFunc, + renderFunc: ToolRenderer(toolCall), toolCall: toolCall, result: result, canceled: canceled, diff --git a/internal/ui/model/chat.go b/internal/ui/model/chat.go index f506d469b6b90292af6373d20f2a296fa7d0ac6a..94a999cd75b5e3853cb173c2f287b0dfba3513f7 100644 --- a/internal/ui/model/chat.go +++ b/internal/ui/model/chat.go @@ -245,8 +245,8 @@ func (m *Chat) ClearMessages() { m.ClearMouse() } -// GetMessageItem returns the message item at the given id. -func (m *Chat) GetMessageItem(id string) chat.MessageItem { +// MessageItem returns the message item with the given ID, or nil if not found. +func (m *Chat) MessageItem(id string) chat.MessageItem { idx, ok := m.idInxMap[id] if !ok { return nil diff --git a/internal/ui/model/ui.go b/internal/ui/model/ui.go index 5fe8eeb3689a6a185c0e2cd6af7a1758120a5178..2dab87ba0de0eac8ed365938c7abc8395785c9b2 100644 --- a/internal/ui/model/ui.go +++ b/internal/ui/model/ui.go @@ -380,7 +380,7 @@ func (m *UI) setSessionMessages(msgs []message.Message) tea.Cmd { // Add messages to chat with linked tool results items := make([]chat.MessageItem, 0, len(msgs)*2) for _, msg := range msgPtrs { - items = append(items, chat.GetMessageItems(m.com.Styles, msg, toolResultMap)...) + items = append(items, chat.ExtractMessageItems(m.com.Styles, msg, toolResultMap)...) } // 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 { var cmds []tea.Cmd switch msg.Role { case message.User, message.Assistant: - items := chat.GetMessageItems(m.com.Styles, &msg, nil) + items := chat.ExtractMessageItems(m.com.Styles, &msg, nil) for _, item := range items { if animatable, ok := item.(chat.Animatable); ok { if cmd := animatable.StartAnimation(); cmd != nil { @@ -421,7 +421,7 @@ func (m *UI) appendSessionMessage(msg message.Message) tea.Cmd { } case message.Tool: for _, tr := range msg.ToolResults() { - toolItem := m.chat.GetMessageItem(tr.ToolCallID) + toolItem := m.chat.MessageItem(tr.ToolCallID) if toolItem == nil { // we should have an item! continue @@ -439,7 +439,7 @@ func (m *UI) appendSessionMessage(msg message.Message) tea.Cmd { // that is why we need to handle creating/updating each tool call message too func (m *UI) updateSessionMessage(msg message.Message) tea.Cmd { var cmds []tea.Cmd - existingItem := m.chat.GetMessageItem(msg.ID) + existingItem := m.chat.MessageItem(msg.ID) if existingItem == nil || msg.Role != message.Assistant { return nil } @@ -450,7 +450,7 @@ func (m *UI) updateSessionMessage(msg message.Message) tea.Cmd { var items []chat.MessageItem for _, tc := range msg.ToolCalls() { - existingToolItem := m.chat.GetMessageItem(tc.ID) + existingToolItem := m.chat.MessageItem(tc.ID) if toolItem, ok := existingToolItem.(*chat.ToolMessageItem); ok { existingToolCall := toolItem.ToolCall() // only update if finished state changed or input changed @@ -460,7 +460,7 @@ func (m *UI) updateSessionMessage(msg message.Message) tea.Cmd { } } if existingToolItem == nil { - items = append(items, chat.GetToolMessageItem(m.com.Styles, tc, nil, false)) + items = append(items, chat.NewToolMessageItem(m.com.Styles, tc, nil, false)) } }