on main help sign in
chore: improve agent tool ui
fa408c5Kujtim Hoxha
internal/tui/components/chat/chat.go+10−1
@@ -118,7 +118,7 @@ func (m *messageListCmp) View() string {
118// handleChildSession handles messages from child sessions (agent tools).
118// handleChildSession handles messages from child sessions (agent tools).
119func (m *messageListCmp) handleChildSession(event pubsub.Event[message.Message]) tea.Cmd {
119func (m *messageListCmp) handleChildSession(event pubsub.Event[message.Message]) tea.Cmd {
120 var cmds []tea.Cmd
120 var cmds []tea.Cmd
121− if len(event.Payload.ToolCalls()) == 0 {
121+ if len(event.Payload.ToolCalls()) == 0 && len(event.Payload.ToolResults()) == 0 {
122 return nil
122 return nil
123 }
123 }
124 items := m.listCmp.Items()
124 items := m.listCmp.Items()
@@ -158,6 +158,15 @@ func (m *messageListCmp) handleChildSession(event pubsub.Event[message.Message])
158 )
158 )
159 }
159 }
160 }
160 }
161+ for _, tr := range event.Payload.ToolResults() {
162+ for nestedInx, nestedTC := range nestedToolCalls {
163+ if nestedTC.GetToolCall().ID == tr.ToolCallID {
164+ nestedToolCalls[nestedInx].SetToolResult(tr)
165+ break
166+ }
167+ }
168+ }
169+
161 toolCall.SetNestedToolCalls(nestedToolCalls)
170 toolCall.SetNestedToolCalls(nestedToolCalls)
162 m.listCmp.UpdateItem(
171 m.listCmp.UpdateItem(
163 toolCallInx,
172 toolCallInx,
internal/tui/components/chat/messages/renderer.go+14−3
@@ -112,10 +112,21 @@ func (br baseRenderer) unmarshalParams(input string, target any) error {
112}
112}
113
113
114// makeHeader builds the tool call header with status icon and parameters for a nested tool call.
114// makeHeader builds the tool call header with status icon and parameters for a nested tool call.
115−func (br baseRenderer) makeNestedHeader(_ *toolCallCmp, tool string, width int, params ...string) string {
115+func (br baseRenderer) makeNestedHeader(v *toolCallCmp, tool string, width int, params ...string) string {
116 t := styles.CurrentTheme()
116 t := styles.CurrentTheme()
117+ icon := t.S().Base.Foreground(t.GreenDark).Render(styles.ToolPending)
118+ if v.result.ToolCallID != "" {
119+ if v.result.IsError {
120+ icon = t.S().Base.Foreground(t.RedDark).Render(styles.ToolError)
121+ } else {
122+ icon = t.S().Base.Foreground(t.Green).Render(styles.ToolSuccess)
123+ }
124+ } else if v.cancelled {
125+ icon = t.S().Muted.Render(styles.ToolPending)
126+ }
117 tool = t.S().Base.Foreground(t.FgHalfMuted).Render(tool) + " "
127 tool = t.S().Base.Foreground(t.FgHalfMuted).Render(tool) + " "
128+ prefix := fmt.Sprintf("%s %s ", icon, tool)
118− return tool + renderParamList(true, width-lipgloss.Width(tool), params...)
129+ return prefix + renderParamList(true, width-lipgloss.Width(tool), params...)
119}
130}
120
131
121// makeHeader builds "<Tool>: param (key=value)" and truncates as needed.
132// makeHeader builds "<Tool>: param (key=value)" and truncates as needed.
@@ -542,7 +553,7 @@ func (tr agentRenderer) Render(v *toolCallCmp) string {
542
553
543 if v.result.ToolCallID == "" {
554 if v.result.ToolCallID == "" {
544 v.spinning = true
555 v.spinning = true
545− parts = append(parts, v.anim.View())
556+ parts = append(parts, "", v.anim.View())
546 } else {
557 } else {
547 v.spinning = false
558 v.spinning = false
548 }
559 }
internal/tui/components/chat/messages/tool.go+2−2
@@ -219,11 +219,11 @@ func (m *toolCallCmp) SetIsNested(isNested bool) {
219// renderPending displays the tool name with a loading animation for pending tool calls
219// renderPending displays the tool name with a loading animation for pending tool calls
220func (m *toolCallCmp) renderPending() string {
220func (m *toolCallCmp) renderPending() string {
221 t := styles.CurrentTheme()
221 t := styles.CurrentTheme()
222+ icon := t.S().Base.Foreground(t.GreenDark).Render(styles.ToolPending)
222 if m.isNested {
223 if m.isNested {
223 tool := t.S().Base.Foreground(t.FgHalfMuted).Render(prettifyToolName(m.call.Name))
224 tool := t.S().Base.Foreground(t.FgHalfMuted).Render(prettifyToolName(m.call.Name))
224− return fmt.Sprintf("%s %s", tool, m.anim.View())
225+ return fmt.Sprintf("%s %s %s", icon, tool, m.anim.View())
225 }
226 }
226− icon := t.S().Base.Foreground(t.GreenDark).Render(styles.ToolPending)
227 tool := t.S().Base.Foreground(t.Blue).Render(prettifyToolName(m.call.Name))
227 tool := t.S().Base.Foreground(t.Blue).Render(prettifyToolName(m.call.Name))
228 return fmt.Sprintf("%s %s %s", icon, tool, m.anim.View())
228 return fmt.Sprintf("%s %s %s", icon, tool, m.anim.View())
229}
229}