Skip to content

Commit af02343

Browse files
authored
Merge pull request #1408 from rumpl/messages
Simpler code
2 parents 47a3fdc + b6422f7 commit af02343

File tree

2 files changed

+33
-45
lines changed

2 files changed

+33
-45
lines changed

pkg/tui/components/messages/messages.go

Lines changed: 32 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,6 @@ import (
1010
"charm.land/lipgloss/v2"
1111
"github.com/charmbracelet/x/ansi"
1212

13-
"github.com/docker/cagent/pkg/app"
1413
"github.com/docker/cagent/pkg/chat"
1514
"github.com/docker/cagent/pkg/runtime"
1615
"github.com/docker/cagent/pkg/session"
@@ -71,7 +70,6 @@ type model struct {
7170
views []layout.Model
7271
width int // Full width including scrollbar space
7372
height int
74-
app *app.App
7573

7674
// Height tracking system fields
7775
scrollOffset int // Current scroll position in lines
@@ -98,22 +96,17 @@ type model struct {
9896
}
9997

10098
// New creates a new message list component
101-
func New(a *app.App, sessionState *service.SessionState) Model {
102-
return &model{
103-
width: 120,
104-
height: 24,
105-
app: a,
106-
renderedItems: make(map[int]renderedItem),
107-
sessionState: sessionState,
108-
scrollbar: scrollbar.New(),
109-
selectedMessageIndex: -1,
110-
debugLayout: os.Getenv("CAGENT_EXPERIMENTAL_DEBUG_LAYOUT") == "1",
111-
}
99+
func New(sessionState *service.SessionState) Model {
100+
return newModel(120, 24, sessionState)
112101
}
113102

114103
// NewScrollableView creates a simple scrollable view for displaying messages in dialogs
115104
// This is a lightweight version that doesn't require app or session state management
116105
func NewScrollableView(width, height int, sessionState *service.SessionState) Model {
106+
return newModel(width, height, sessionState)
107+
}
108+
109+
func newModel(width, height int, sessionState *service.SessionState) *model {
117110
return &model{
118111
width: width,
119112
height: height,
@@ -260,9 +253,7 @@ func (m *model) handleMouseRelease(msg tea.MouseReleaseMsg) (layout.Model, tea.C
260253

261254
func (m *model) handleMouseWheel(msg tea.MouseWheelMsg) (layout.Model, tea.Cmd) {
262255
const mouseScrollAmount = 2
263-
buttonStr := msg.Button.String()
264-
265-
switch buttonStr {
256+
switch msg.Button.String() {
266257
case "wheelup":
267258
if m.scrollOffset > 0 {
268259
m.userHasScrolled = true
@@ -649,8 +640,8 @@ func (m *model) renderItem(index int, view layout.Model) renderedItem {
649640
msgView.SetSelected(isSelected)
650641
}
651642

652-
// Don't cache selected items since selection state can change
653-
if !isSelected && m.shouldCacheMessage(index) {
643+
shouldCache := !isSelected && m.shouldCacheMessage(index)
644+
if shouldCache {
654645
if cached, exists := m.renderedItems[index]; exists {
655646
return cached
656647
}
@@ -664,7 +655,7 @@ func (m *model) renderItem(index int, view layout.Model) renderedItem {
664655

665656
item := renderedItem{view: rendered, height: height}
666657

667-
if !isSelected && m.shouldCacheMessage(index) {
658+
if shouldCache {
668659
m.renderedItems[index] = item
669660
}
670661

@@ -794,7 +785,6 @@ func (m *model) addMessage(msg *types.Message) tea.Cmd {
794785
if initCmd := view.Init(); initCmd != nil {
795786
cmds = append(cmds, initCmd)
796787
}
797-
798788
if shouldAutoScroll {
799789
cmds = append(cmds, func() tea.Msg {
800790
m.scrollToBottom()
@@ -806,6 +796,12 @@ func (m *model) addMessage(msg *types.Message) tea.Cmd {
806796
}
807797

808798
func (m *model) LoadFromSession(sess *session.Session) tea.Cmd {
799+
appendSessionMessage := func(msg *types.Message, view layout.Model) {
800+
m.messages = append(m.messages, msg)
801+
m.views = append(m.views, view)
802+
m.sessionState.PreviousMessage = msg
803+
}
804+
809805
m.messages = nil
810806
m.views = nil
811807
m.renderedItems = make(map[int]renderedItem)
@@ -829,32 +825,24 @@ func (m *model) LoadFromSession(sess *session.Session) tea.Cmd {
829825
switch smsg.Message.Role {
830826
case chat.MessageRoleUser:
831827
msg := types.User(smsg.Message.Content)
832-
m.messages = append(m.messages, msg)
833-
m.views = append(m.views, m.createMessageView(msg))
834-
m.sessionState.PreviousMessage = msg
828+
appendSessionMessage(msg, m.createMessageView(msg))
835829
case chat.MessageRoleAssistant:
836830
// Reasoning content comes first (matches live stream order)
837831
if smsg.Message.ReasoningContent != "" {
838832
msg := types.Agent(types.MessageTypeAssistantReasoning, smsg.AgentName, smsg.Message.ReasoningContent)
839-
m.messages = append(m.messages, msg)
840-
m.views = append(m.views, m.createMessageView(msg))
841-
m.sessionState.PreviousMessage = msg
833+
appendSessionMessage(msg, m.createMessageView(msg))
842834
}
843835
for i, tc := range smsg.Message.ToolCalls {
844836
var toolDef tools.Tool
845837
if i < len(smsg.Message.ToolDefinitions) {
846838
toolDef = smsg.Message.ToolDefinitions[i]
847839
}
848840
msg := types.ToolCallMessage(smsg.AgentName, tc, toolDef, types.ToolStatusCompleted)
849-
m.messages = append(m.messages, msg)
850-
m.views = append(m.views, m.createToolCallView(msg))
851-
m.sessionState.PreviousMessage = msg
841+
appendSessionMessage(msg, m.createToolCallView(msg))
852842
}
853843
if smsg.Message.Content != "" {
854844
msg := types.Agent(types.MessageTypeAssistant, smsg.AgentName, smsg.Message.Content)
855-
m.messages = append(m.messages, msg)
856-
m.views = append(m.views, m.createMessageView(msg))
857-
m.sessionState.PreviousMessage = msg
845+
appendSessionMessage(msg, m.createMessageView(msg))
858846
}
859847
case chat.MessageRoleTool:
860848
continue
@@ -974,24 +962,24 @@ func (m *model) removeSpinner() {
974962
}
975963

976964
func (m *model) removePendingToolCallMessages() {
977-
var newMessages []*types.Message
978-
var newViews []layout.Model
965+
messages := make([]*types.Message, 0, len(m.messages))
966+
views := make([]layout.Model, 0, len(m.views))
979967

980968
for i, msg := range m.messages {
981-
shouldRemove := msg.Type == types.MessageTypeToolCall &&
982-
(msg.ToolStatus == types.ToolStatusPending || msg.ToolStatus == types.ToolStatusRunning)
969+
if msg.Type == types.MessageTypeToolCall &&
970+
(msg.ToolStatus == types.ToolStatusPending || msg.ToolStatus == types.ToolStatusRunning) {
971+
continue
972+
}
983973

984-
if !shouldRemove {
985-
newMessages = append(newMessages, msg)
986-
if i < len(m.views) {
987-
newViews = append(newViews, m.views[i])
988-
}
974+
messages = append(messages, msg)
975+
if i < len(m.views) {
976+
views = append(views, m.views[i])
989977
}
990978
}
991979

992-
if len(newMessages) != len(m.messages) {
993-
m.messages = newMessages
994-
m.views = newViews
980+
if len(messages) != len(m.messages) {
981+
m.messages = messages
982+
m.views = views
995983
m.invalidateAllItems()
996984
}
997985
}

pkg/tui/page/chat/chat.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -236,7 +236,7 @@ func New(a *app.App, sessionState *service.SessionState) Page {
236236

237237
p := &chatPage{
238238
sidebar: sidebar.New(sessionState),
239-
messages: messages.New(a, sessionState),
239+
messages: messages.New(sessionState),
240240
editor: editor.New(a, historyStore),
241241
spinner: spinner.New(spinner.ModeSpinnerOnly, styles.SpinnerDotsHighlightStyle),
242242
focusedPanel: PanelEditor,

0 commit comments

Comments
 (0)