diff options
| author | Dax <[email protected]> | 2025-08-07 16:32:12 -0400 |
|---|---|---|
| committer | GitHub <[email protected]> | 2025-08-07 16:32:12 -0400 |
| commit | c34aec060f2abb78486857b0e0d678cac52e2fab (patch) | |
| tree | 7d2b42a0c87ab016ffbc096e332b186ec4bce7ac /packages/tui/internal/components/chat | |
| parent | 12f1ad521fef2e1fa6f1b0ce6ec939664d61899f (diff) | |
| download | opencode-c34aec060f2abb78486857b0e0d678cac52e2fab.tar.gz opencode-c34aec060f2abb78486857b0e0d678cac52e2fab.zip | |
Merge agent and mode into one (#1689)
The concept of mode has been deprecated, there is now only the agent field in the config.
An agent can be cycled through as your primary agent with <tab> or you can spawn a subagent by @ mentioning it. if you include a description of when to use it, the primary agent will try to automatically use it
Full docs here: https://opencode.ai/docs/agents/
Diffstat (limited to 'packages/tui/internal/components/chat')
| -rw-r--r-- | packages/tui/internal/components/chat/editor.go | 25 | ||||
| -rw-r--r-- | packages/tui/internal/components/chat/message.go | 43 | ||||
| -rw-r--r-- | packages/tui/internal/components/chat/messages.go | 8 |
3 files changed, 74 insertions, 2 deletions
diff --git a/packages/tui/internal/components/chat/editor.go b/packages/tui/internal/components/chat/editor.go index 1263a6e72..509de6244 100644 --- a/packages/tui/internal/components/chat/editor.go +++ b/packages/tui/internal/components/chat/editor.go @@ -288,6 +288,31 @@ func (m *editorComponent) Update(msg tea.Msg) (tea.Model, tea.Cmd) { m.textarea.InsertAttachment(attachment) m.textarea.InsertString(" ") return m, nil + case "agents": + atIndex := m.textarea.LastRuneIndex('@') + if atIndex == -1 { + // Should not happen, but as a fallback, just insert. + m.textarea.InsertString(msg.Item.Value + " ") + return m, nil + } + + cursorCol := m.textarea.CursorColumn() + m.textarea.ReplaceRange(atIndex, cursorCol, "") + + name := msg.Item.Value + attachment := &attachment.Attachment{ + ID: uuid.NewString(), + Type: "agent", + Display: "@" + name, + Source: &attachment.AgentSource{ + Name: name, + }, + } + + m.textarea.InsertAttachment(attachment) + m.textarea.InsertString(" ") + return m, nil + default: slog.Debug("Unknown provider", "provider", msg.Item.ProviderID) return m, nil diff --git a/packages/tui/internal/components/chat/message.go b/packages/tui/internal/components/chat/message.go index 0a1982718..60d0fab55 100644 --- a/packages/tui/internal/components/chat/message.go +++ b/packages/tui/internal/components/chat/message.go @@ -209,6 +209,7 @@ func renderText( width int, extra string, fileParts []opencode.FilePart, + agentParts []opencode.AgentPart, toolCalls ...opencode.ToolPart, ) string { t := theme.CurrentTheme() @@ -229,9 +230,47 @@ func renderText( // Apply highlighting to filenames and base style to rest of text BEFORE wrapping textLen := int64(len(text)) + + // Collect all parts to highlight (both file and agent parts) + type highlightPart struct { + start int64 + end int64 + color compat.AdaptiveColor + } + var highlights []highlightPart + + // Add file parts with secondary color for _, filePart := range fileParts { - highlight := base.Foreground(t.Secondary()) - start, end := filePart.Source.Text.Start, filePart.Source.Text.End + highlights = append(highlights, highlightPart{ + start: filePart.Source.Text.Start, + end: filePart.Source.Text.End, + color: t.Secondary(), + }) + } + + // Add agent parts with secondary color (same as file parts) + for _, agentPart := range agentParts { + highlights = append(highlights, highlightPart{ + start: agentPart.Source.Start, + end: agentPart.Source.End, + color: t.Secondary(), + }) + } + + // Sort highlights by start position + slices.SortFunc(highlights, func(a, b highlightPart) int { + if a.start < b.start { + return -1 + } + if a.start > b.start { + return 1 + } + return 0 + }) + + for _, part := range highlights { + highlight := base.Foreground(part.color) + start, end := part.start, part.end if end > textLen { end = textLen diff --git a/packages/tui/internal/components/chat/messages.go b/packages/tui/internal/components/chat/messages.go index 5702cec5d..46036b75f 100644 --- a/packages/tui/internal/components/chat/messages.go +++ b/packages/tui/internal/components/chat/messages.go @@ -300,12 +300,17 @@ func (m *messagesComponent) renderView() tea.Cmd { } remainingParts := message.Parts[partIndex+1:] fileParts := make([]opencode.FilePart, 0) + agentParts := make([]opencode.AgentPart, 0) for _, part := range remainingParts { switch part := part.(type) { case opencode.FilePart: if part.Source.Text.Start >= 0 && part.Source.Text.End >= part.Source.Text.Start { fileParts = append(fileParts, part) } + case opencode.AgentPart: + if part.Source.Start >= 0 && part.Source.End >= part.Source.Start { + agentParts = append(agentParts, part) + } } } flexItems := []layout.FlexItem{} @@ -355,6 +360,7 @@ func (m *messagesComponent) renderView() tea.Cmd { width, files, fileParts, + agentParts, ) content = lipgloss.PlaceHorizontal( m.width, @@ -433,6 +439,7 @@ func (m *messagesComponent) renderView() tea.Cmd { width, "", []opencode.FilePart{}, + []opencode.AgentPart{}, toolCallParts..., ) content = lipgloss.PlaceHorizontal( @@ -453,6 +460,7 @@ func (m *messagesComponent) renderView() tea.Cmd { width, "", []opencode.FilePart{}, + []opencode.AgentPart{}, toolCallParts..., ) content = lipgloss.PlaceHorizontal( |
