diff options
| author | adamdottv <[email protected]> | 2025-05-29 15:37:06 -0500 |
|---|---|---|
| committer | adamdottv <[email protected]> | 2025-05-29 15:37:06 -0500 |
| commit | 0e31bbcd9322e1f667b87c88445a4f6effa1d934 (patch) | |
| tree | 428bbd368a197cb3e80523c629437d8cde86b092 /internal/tui/components | |
| parent | 913b3434d8243cc9681a3bf7520e7b027ec3853b (diff) | |
| download | opencode-0e31bbcd9322e1f667b87c88445a4f6effa1d934.tar.gz opencode-0e31bbcd9322e1f667b87c88445a4f6effa1d934.zip | |
wip: refactoring tui
Diffstat (limited to 'internal/tui/components')
| -rw-r--r-- | internal/tui/components/chat/chat.go | 4 | ||||
| -rw-r--r-- | internal/tui/components/chat/editor.go | 5 | ||||
| -rw-r--r-- | internal/tui/components/chat/message.go | 269 | ||||
| -rw-r--r-- | internal/tui/components/chat/messages.go | 71 | ||||
| -rw-r--r-- | internal/tui/components/dialog/filepicker.go | 5 |
5 files changed, 170 insertions, 184 deletions
diff --git a/internal/tui/components/chat/chat.go b/internal/tui/components/chat/chat.go index 7cd49ef6a..2fabea43d 100644 --- a/internal/tui/components/chat/chat.go +++ b/internal/tui/components/chat/chat.go @@ -7,7 +7,7 @@ import ( "github.com/charmbracelet/lipgloss" "github.com/charmbracelet/x/ansi" "github.com/sst/opencode/internal/config" - "github.com/sst/opencode/internal/message" + "github.com/sst/opencode/internal/tui/app" "github.com/sst/opencode/internal/tui/styles" "github.com/sst/opencode/internal/tui/theme" "github.com/sst/opencode/internal/version" @@ -15,7 +15,7 @@ import ( type SendMsg struct { Text string - Attachments []message.Attachment + Attachments []app.Attachment } func header(width int) string { diff --git a/internal/tui/components/chat/editor.go b/internal/tui/components/chat/editor.go index c3b06787e..6586f2020 100644 --- a/internal/tui/components/chat/editor.go +++ b/internal/tui/components/chat/editor.go @@ -13,7 +13,6 @@ import ( "github.com/charmbracelet/bubbles/textarea" tea "github.com/charmbracelet/bubbletea" "github.com/charmbracelet/lipgloss" - "github.com/sst/opencode/internal/message" "github.com/sst/opencode/internal/status" "github.com/sst/opencode/internal/tui/app" "github.com/sst/opencode/internal/tui/components/dialog" @@ -29,7 +28,7 @@ type editorCmp struct { height int app *app.App textarea textarea.Model - attachments []message.Attachment + attachments []app.Attachment deleteMode bool history []string historyIndex int @@ -233,7 +232,7 @@ func (m *editorCmp) Update(msg tea.Msg) (tea.Model, tea.Cmd) { } if len(imageBytes) != 0 { attachmentName := fmt.Sprintf("clipboard-image-%d", len(m.attachments)) - attachment := message.Attachment{FilePath: attachmentName, FileName: attachmentName, Content: imageBytes, MimeType: "image/png"} + attachment := app.Attachment{FilePath: attachmentName, FileName: attachmentName, Content: imageBytes, MimeType: "image/png"} m.attachments = append(m.attachments, attachment) } else { m.textarea.SetValue(m.textarea.Value() + text) diff --git a/internal/tui/components/chat/message.go b/internal/tui/components/chat/message.go index 9f8a9de64..c7b8234a0 100644 --- a/internal/tui/components/chat/message.go +++ b/internal/tui/components/chat/message.go @@ -8,7 +8,6 @@ import ( "github.com/charmbracelet/lipgloss" "github.com/charmbracelet/x/ansi" "github.com/sst/opencode/internal/config" - "github.com/sst/opencode/internal/message" "github.com/sst/opencode/internal/tui/styles" "github.com/sst/opencode/internal/tui/theme" "github.com/sst/opencode/pkg/client" @@ -244,17 +243,6 @@ func renderAssistantMessage( return strings.Join(messages, "\n\n") } -func findToolResponse(toolCallID string, futureMessages []message.Message) *message.ToolResult { - for _, msg := range futureMessages { - for _, result := range msg.ToolResults() { - if result.ToolCallID == toolCallID { - return &result - } - } - } - return nil -} - func renderToolName(name string) string { switch name { // case agent.AgentToolName: @@ -354,9 +342,9 @@ func removeWorkingDirPrefix(path string) string { return path } -func renderToolParams(paramWidth int, toolCall message.ToolCall) string { +func renderToolParams(paramWidth int, toolCall any) string { params := "" - switch toolCall.Name { + switch toolCall { // // case agent.AgentToolName: // // var params agent.AgentParams // // json.Unmarshal([]byte(toolCall.Input), ¶ms) @@ -445,9 +433,9 @@ func renderToolParams(paramWidth int, toolCall message.ToolCall) string { // var params tools.BatchParams // json.Unmarshal([]byte(toolCall.Input), ¶ms) // return renderParams(paramWidth, fmt.Sprintf("%d parallel calls", len(params.Calls))) - default: - input := strings.ReplaceAll(toolCall.Input, "\n", " ") - params = renderParams(paramWidth, input) + // default: + // input := strings.ReplaceAll(toolCall, "\n", " ") + // params = renderParams(paramWidth, input) } return params } @@ -460,21 +448,22 @@ func truncateHeight(content string, height int) string { return content } -func renderToolResponse(toolCall message.ToolCall, response message.ToolResult, width int) string { - t := theme.CurrentTheme() - baseStyle := styles.BaseStyle() - - if response.IsError { - errContent := fmt.Sprintf("Error: %s", strings.ReplaceAll(response.Content, "\n", " ")) - errContent = ansi.Truncate(errContent, width-1, "...") - return baseStyle. - Width(width). - Foreground(t.Error()). - Render(errContent) - } - - resultContent := truncateHeight(response.Content, maxResultHeight) - switch toolCall.Name { +func renderToolResponse(toolCall any, response any, width int) string { + return "" + // t := theme.CurrentTheme() + // baseStyle := styles.BaseStyle() + // + // if response.IsError { + // errContent := fmt.Sprintf("Error: %s", strings.ReplaceAll(response.Content, "\n", " ")) + // errContent = ansi.Truncate(errContent, width-1, "...") + // return baseStyle. + // Width(width). + // Foreground(t.Error()). + // Render(errContent) + // } + // + // resultContent := truncateHeight(response.Content, maxResultHeight) + // switch toolCall.Name { // case agent.AgentToolName: // return styles.ForceReplaceBackgroundWithLipgloss( // toMarkdown(resultContent, false, width), @@ -574,113 +563,113 @@ func renderToolResponse(toolCall message.ToolCall, response message.ToolResult, // } // // return baseStyle.Width(width).Foreground(t.TextMuted()).Render(strings.Join(toolCalls, "\n\n")) - default: - resultContent = fmt.Sprintf("```text\n%s\n```", resultContent) - return styles.ForceReplaceBackgroundWithLipgloss( - toMarkdown(resultContent, width), - t.Background(), - ) - } -} - -func renderToolMessage( - toolCall message.ToolCall, - allMessages []message.Message, - messagesService message.Service, - focusedUIMessageId string, - nested bool, - width int, - position int, -) string { - if nested { - width = width - 3 - } - - t := theme.CurrentTheme() - baseStyle := styles.BaseStyle() - - style := baseStyle. - Width(width - 1). - BorderLeft(true). - BorderStyle(lipgloss.ThickBorder()). - PaddingLeft(1). - BorderForeground(t.TextMuted()) - - response := findToolResponse(toolCall.ID, allMessages) - toolNameText := baseStyle.Foreground(t.TextMuted()). - Render(fmt.Sprintf("%s: ", renderToolName(toolCall.Name))) - - if !toolCall.Finished { - // Get a brief description of what the tool is doing - toolAction := renderToolAction(toolCall.Name) - - progressText := baseStyle. - Width(width - 2 - lipgloss.Width(toolNameText)). - Foreground(t.TextMuted()). - Render(fmt.Sprintf("%s", toolAction)) - - content := style.Render(lipgloss.JoinHorizontal(lipgloss.Left, toolNameText, progressText)) - return content - } - - params := renderToolParams(width-1-lipgloss.Width(toolNameText), toolCall) - responseContent := "" - if response != nil { - responseContent = renderToolResponse(toolCall, *response, width-2) - responseContent = strings.TrimSuffix(responseContent, "\n") - } else { - responseContent = baseStyle. - Italic(true). - Width(width - 2). - Foreground(t.TextMuted()). - Render("Waiting for response...") - } - - parts := []string{} - if !nested { - formattedParams := baseStyle. - Width(width - 2 - lipgloss.Width(toolNameText)). - Foreground(t.TextMuted()). - Render(params) - - parts = append(parts, lipgloss.JoinHorizontal(lipgloss.Left, toolNameText, formattedParams)) - } else { - prefix := baseStyle. - Foreground(t.TextMuted()). - Render(" └ ") - formattedParams := baseStyle. - Width(width - 2 - lipgloss.Width(toolNameText)). - Foreground(t.TextMuted()). - Render(params) - parts = append(parts, lipgloss.JoinHorizontal(lipgloss.Left, prefix, toolNameText, formattedParams)) - } - - // if toolCall.Name == agent.AgentToolName { - // taskMessages, _ := messagesService.List(context.Background(), toolCall.ID) - // toolCalls := []message.ToolCall{} - // for _, v := range taskMessages { - // toolCalls = append(toolCalls, v.ToolCalls()...) - // } - // for _, call := range toolCalls { - // rendered := renderToolMessage(call, []message.Message{}, messagesService, focusedUIMessageId, true, width, 0) - // parts = append(parts, rendered.content) - // } + // default: + // resultContent = fmt.Sprintf("```text\n%s\n```", resultContent) + // return styles.ForceReplaceBackgroundWithLipgloss( + // toMarkdown(resultContent, width), + // t.Background(), + // ) // } - if responseContent != "" && !nested { - parts = append(parts, responseContent) - } - - content := style.Render( - lipgloss.JoinVertical( - lipgloss.Left, - parts..., - ), - ) - if nested { - content = lipgloss.JoinVertical( - lipgloss.Left, - parts..., - ) - } - return content } + +// func renderToolMessage( +// toolCall message.ToolCall, +// allMessages []message.Message, +// messagesService message.Service, +// focusedUIMessageId string, +// nested bool, +// width int, +// position int, +// ) string { +// if nested { +// width = width - 3 +// } +// +// t := theme.CurrentTheme() +// baseStyle := styles.BaseStyle() +// +// style := baseStyle. +// Width(width - 1). +// BorderLeft(true). +// BorderStyle(lipgloss.ThickBorder()). +// PaddingLeft(1). +// BorderForeground(t.TextMuted()) +// +// response := findToolResponse(toolCall.ID, allMessages) +// toolNameText := baseStyle.Foreground(t.TextMuted()). +// Render(fmt.Sprintf("%s: ", renderToolName(toolCall.Name))) +// +// if !toolCall.Finished { +// // Get a brief description of what the tool is doing +// toolAction := renderToolAction(toolCall.Name) +// +// progressText := baseStyle. +// Width(width - 2 - lipgloss.Width(toolNameText)). +// Foreground(t.TextMuted()). +// Render(fmt.Sprintf("%s", toolAction)) +// +// content := style.Render(lipgloss.JoinHorizontal(lipgloss.Left, toolNameText, progressText)) +// return content +// } +// +// params := renderToolParams(width-1-lipgloss.Width(toolNameText), toolCall) +// responseContent := "" +// if response != nil { +// responseContent = renderToolResponse(toolCall, *response, width-2) +// responseContent = strings.TrimSuffix(responseContent, "\n") +// } else { +// responseContent = baseStyle. +// Italic(true). +// Width(width - 2). +// Foreground(t.TextMuted()). +// Render("Waiting for response...") +// } +// +// parts := []string{} +// if !nested { +// formattedParams := baseStyle. +// Width(width - 2 - lipgloss.Width(toolNameText)). +// Foreground(t.TextMuted()). +// Render(params) +// +// parts = append(parts, lipgloss.JoinHorizontal(lipgloss.Left, toolNameText, formattedParams)) +// } else { +// prefix := baseStyle. +// Foreground(t.TextMuted()). +// Render(" └ ") +// formattedParams := baseStyle. +// Width(width - 2 - lipgloss.Width(toolNameText)). +// Foreground(t.TextMuted()). +// Render(params) +// parts = append(parts, lipgloss.JoinHorizontal(lipgloss.Left, prefix, toolNameText, formattedParams)) +// } +// +// // if toolCall.Name == agent.AgentToolName { +// // taskMessages, _ := messagesService.List(context.Background(), toolCall.ID) +// // toolCalls := []message.ToolCall{} +// // for _, v := range taskMessages { +// // toolCalls = append(toolCalls, v.ToolCalls()...) +// // } +// // for _, call := range toolCalls { +// // rendered := renderToolMessage(call, []message.Message{}, messagesService, focusedUIMessageId, true, width, 0) +// // parts = append(parts, rendered.content) +// // } +// // } +// if responseContent != "" && !nested { +// parts = append(parts, responseContent) +// } +// +// content := style.Render( +// lipgloss.JoinVertical( +// lipgloss.Left, +// parts..., +// ), +// ) +// if nested { +// content = lipgloss.JoinVertical( +// lipgloss.Left, +// parts..., +// ) +// } +// return content +// } diff --git a/internal/tui/components/chat/messages.go b/internal/tui/components/chat/messages.go index 92e6ec471..50a0f4200 100644 --- a/internal/tui/components/chat/messages.go +++ b/internal/tui/components/chat/messages.go @@ -9,7 +9,6 @@ import ( "github.com/charmbracelet/bubbles/viewport" tea "github.com/charmbracelet/bubbletea" "github.com/charmbracelet/lipgloss" - "github.com/sst/opencode/internal/message" "github.com/sst/opencode/internal/tui/app" "github.com/sst/opencode/internal/tui/components/dialog" "github.com/sst/opencode/internal/tui/state" @@ -177,41 +176,41 @@ func (m *messagesCmp) View() string { ) } -func hasToolsWithoutResponse(messages []message.Message) bool { - toolCalls := make([]message.ToolCall, 0) - toolResults := make([]message.ToolResult, 0) - for _, m := range messages { - toolCalls = append(toolCalls, m.ToolCalls()...) - toolResults = append(toolResults, m.ToolResults()...) - } - - for _, v := range toolCalls { - found := false - for _, r := range toolResults { - if v.ID == r.ToolCallID { - found = true - break - } - } - if !found && v.Finished { - return true - } - } - return false -} - -func hasUnfinishedToolCalls(messages []message.Message) bool { - toolCalls := make([]message.ToolCall, 0) - for _, m := range messages { - toolCalls = append(toolCalls, m.ToolCalls()...) - } - for _, v := range toolCalls { - if !v.Finished { - return true - } - } - return false -} +// func hasToolsWithoutResponse(messages []message.Message) bool { +// toolCalls := make([]message.ToolCall, 0) +// toolResults := make([]message.ToolResult, 0) +// for _, m := range messages { +// toolCalls = append(toolCalls, m.ToolCalls()...) +// toolResults = append(toolResults, m.ToolResults()...) +// } +// +// for _, v := range toolCalls { +// found := false +// for _, r := range toolResults { +// if v.ID == r.ToolCallID { +// found = true +// break +// } +// } +// if !found && v.Finished { +// return true +// } +// } +// return false +// } + +// func hasUnfinishedToolCalls(messages []message.Message) bool { +// toolCalls := make([]message.ToolCall, 0) +// for _, m := range messages { +// toolCalls = append(toolCalls, m.ToolCalls()...) +// } +// for _, v := range toolCalls { +// if !v.Finished { +// return true +// } +// } +// return false +// } func (m *messagesCmp) working() string { text := "" diff --git a/internal/tui/components/dialog/filepicker.go b/internal/tui/components/dialog/filepicker.go index 980ab216b..088e205f2 100644 --- a/internal/tui/components/dialog/filepicker.go +++ b/internal/tui/components/dialog/filepicker.go @@ -17,7 +17,6 @@ import ( "github.com/charmbracelet/bubbles/viewport" tea "github.com/charmbracelet/bubbletea" "github.com/charmbracelet/lipgloss" - "github.com/sst/opencode/internal/message" "github.com/sst/opencode/internal/status" "github.com/sst/opencode/internal/tui/app" "github.com/sst/opencode/internal/tui/image" @@ -116,7 +115,7 @@ func (s stack) Pop() (stack, int) { } type AttachmentAddedMsg struct { - Attachment message.Attachment + Attachment app.Attachment } func (f *filepickerCmp) Init() tea.Cmd { @@ -269,7 +268,7 @@ func (f *filepickerCmp) addAttachmentToMessage() (tea.Model, tea.Cmd) { mimeBufferSize := min(512, len(content)) mimeType := http.DetectContentType(content[:mimeBufferSize]) fileName := filepath.Base(selectedFilePath) - attachment := message.Attachment{FilePath: selectedFilePath, FileName: fileName, MimeType: mimeType, Content: content} + attachment := app.Attachment{FilePath: selectedFilePath, FileName: fileName, MimeType: mimeType, Content: content} f.selectedFile = "" return f, util.CmdHandler(AttachmentAddedMsg{attachment}) } |
