|
8 | 8 | tea "github.com/charmbracelet/bubbletea/v2" |
9 | 9 | "github.com/charmbracelet/lipgloss/v2" |
10 | 10 | "github.com/opencode-ai/opencode/internal/app" |
11 | | - "github.com/opencode-ai/opencode/internal/logging" |
| 11 | + "github.com/opencode-ai/opencode/internal/llm/agent" |
12 | 12 | "github.com/opencode-ai/opencode/internal/message" |
13 | 13 | "github.com/opencode-ai/opencode/internal/pubsub" |
14 | 14 | "github.com/opencode-ai/opencode/internal/session" |
@@ -106,26 +106,71 @@ func (m *messageListCmp) View() string { |
106 | 106 | } |
107 | 107 |
|
108 | 108 | // handleChildSession handles messages from child sessions (agent tools). |
109 | | -// TODO: update the agent tool message with the changes |
110 | | -func (m *messageListCmp) handleChildSession(event pubsub.Event[message.Message]) { |
111 | | - // Implementation pending |
| 109 | +func (m *messageListCmp) handleChildSession(event pubsub.Event[message.Message]) tea.Cmd { |
| 110 | + var cmds []tea.Cmd |
| 111 | + if len(event.Payload.ToolCalls()) == 0 { |
| 112 | + return nil |
| 113 | + } |
| 114 | + items := m.listCmp.Items() |
| 115 | + toolCallInx := NotFound |
| 116 | + var toolCall messages.ToolCallCmp |
| 117 | + for i := len(items) - 1; i >= 0; i-- { |
| 118 | + if msg, ok := items[i].(messages.ToolCallCmp); ok { |
| 119 | + if msg.GetToolCall().ID == event.Payload.SessionID { |
| 120 | + toolCallInx = i |
| 121 | + toolCall = msg |
| 122 | + } |
| 123 | + } |
| 124 | + } |
| 125 | + if toolCallInx == NotFound { |
| 126 | + return nil |
| 127 | + } |
| 128 | + nestedToolCalls := toolCall.GetNestedToolCalls() |
| 129 | + for _, tc := range event.Payload.ToolCalls() { |
| 130 | + found := false |
| 131 | + for existingInx, existingTC := range nestedToolCalls { |
| 132 | + if existingTC.GetToolCall().ID == tc.ID { |
| 133 | + nestedToolCalls[existingInx].SetToolCall(tc) |
| 134 | + found = true |
| 135 | + break |
| 136 | + } |
| 137 | + } |
| 138 | + if !found { |
| 139 | + nestedCall := messages.NewToolCallCmp( |
| 140 | + event.Payload.ID, |
| 141 | + tc, |
| 142 | + messages.WithToolCallNested(true), |
| 143 | + ) |
| 144 | + cmds = append(cmds, nestedCall.Init()) |
| 145 | + nestedToolCalls = append( |
| 146 | + nestedToolCalls, |
| 147 | + nestedCall, |
| 148 | + ) |
| 149 | + } |
| 150 | + } |
| 151 | + toolCall.SetNestedToolCalls(nestedToolCalls) |
| 152 | + m.listCmp.UpdateItem( |
| 153 | + toolCallInx, |
| 154 | + toolCall, |
| 155 | + ) |
| 156 | + return tea.Batch(cmds...) |
112 | 157 | } |
113 | 158 |
|
114 | 159 | // handleMessageEvent processes different types of message events (created/updated). |
115 | 160 | func (m *messageListCmp) handleMessageEvent(event pubsub.Event[message.Message]) tea.Cmd { |
116 | 161 | switch event.Type { |
117 | 162 | case pubsub.CreatedEvent: |
118 | 163 | if event.Payload.SessionID != m.session.ID { |
119 | | - m.handleChildSession(event) |
120 | | - return nil |
| 164 | + return m.handleChildSession(event) |
121 | 165 | } |
122 | | - |
123 | 166 | if m.messageExists(event.Payload.ID) { |
124 | 167 | return nil |
125 | 168 | } |
126 | | - |
127 | 169 | return m.handleNewMessage(event.Payload) |
128 | 170 | case pubsub.UpdatedEvent: |
| 171 | + if event.Payload.SessionID != m.session.ID { |
| 172 | + return m.handleChildSession(event) |
| 173 | + } |
129 | 174 | return m.handleUpdateAssistantMessage(event.Payload) |
130 | 175 | } |
131 | 176 | return nil |
@@ -196,8 +241,6 @@ func (m *messageListCmp) handleUpdateAssistantMessage(msg message.Message) tea.C |
196 | 241 | // Find existing assistant message and tool calls for this message |
197 | 242 | assistantIndex, existingToolCalls := m.findAssistantMessageAndToolCalls(items, msg.ID) |
198 | 243 |
|
199 | | - logging.Info("Update Assistant Message", "msg", msg, "assistantMessageInx", assistantIndex, "toolCalls", existingToolCalls) |
200 | | - |
201 | 244 | // Handle assistant message content |
202 | 245 | if cmd := m.updateAssistantMessageContent(msg, assistantIndex); cmd != nil { |
203 | 246 | cmds = append(cmds, cmd) |
@@ -389,6 +432,19 @@ func (m *messageListCmp) convertAssistantMessage(msg message.Message, toolResult |
389 | 432 | for _, tc := range msg.ToolCalls() { |
390 | 433 | options := m.buildToolCallOptions(tc, msg, toolResultMap) |
391 | 434 | uiMessages = append(uiMessages, messages.NewToolCallCmp(msg.ID, tc, options...)) |
| 435 | + // If this tool call is the agent tool, fetch nested tool calls |
| 436 | + if tc.Name == agent.AgentToolName { |
| 437 | + nestedMessages, _ := m.app.Messages.List(context.Background(), tc.ID) |
| 438 | + nestedUIMessages := m.convertMessagesToUI(nestedMessages, make(map[string]message.ToolResult)) |
| 439 | + nestedToolCalls := make([]messages.ToolCallCmp, 0, len(nestedUIMessages)) |
| 440 | + for _, nestedMsg := range nestedUIMessages { |
| 441 | + if toolCall, ok := nestedMsg.(messages.ToolCallCmp); ok { |
| 442 | + toolCall.SetIsNested(true) |
| 443 | + nestedToolCalls = append(nestedToolCalls, toolCall) |
| 444 | + } |
| 445 | + } |
| 446 | + uiMessages[len(uiMessages)-1].(messages.ToolCallCmp).SetNestedToolCalls(nestedToolCalls) |
| 447 | + } |
392 | 448 | } |
393 | 449 |
|
394 | 450 | return uiMessages |
|
0 commit comments