summaryrefslogtreecommitdiffhomepage
path: root/internal/tui/components
diff options
context:
space:
mode:
authoradamdottv <[email protected]>2025-05-30 15:34:22 -0500
committeradamdottv <[email protected]>2025-05-30 15:34:25 -0500
commitc69c9327da4a43a63928807fcf36b24755cfac18 (patch)
treedf79a6c58976af977a28717619d70db4a62f4853 /internal/tui/components
parentf5e2c596d4f887daa4df579975dd5451fadc8457 (diff)
downloadopencode-c69c9327da4a43a63928807fcf36b24755cfac18.tar.gz
opencode-c69c9327da4a43a63928807fcf36b24755cfac18.zip
wip: refactoring tui
Diffstat (limited to 'internal/tui/components')
-rw-r--r--internal/tui/components/core/status.go5
-rw-r--r--internal/tui/components/dialog/models.go236
2 files changed, 101 insertions, 140 deletions
diff --git a/internal/tui/components/core/status.go b/internal/tui/components/core/status.go
index fd782ee49..18a0ad6b1 100644
--- a/internal/tui/components/core/status.go
+++ b/internal/tui/components/core/status.go
@@ -335,7 +335,10 @@ func (m *statusCmp) projectDiagnostics() string {
func (m statusCmp) model() string {
t := theme.CurrentTheme()
- model := "Claude Sonnet 4" // models.SupportedModels[coder.Model]
+ model := "None"
+ if m.app.Model != nil {
+ model = *m.app.Model.Name
+ }
return styles.Padded().
Background(t.Secondary()).
diff --git a/internal/tui/components/dialog/models.go b/internal/tui/components/dialog/models.go
index 1d8c4f495..2dd1e2fea 100644
--- a/internal/tui/components/dialog/models.go
+++ b/internal/tui/components/dialog/models.go
@@ -1,14 +1,18 @@
package dialog
import (
+ "context"
+ "fmt"
+
"github.com/charmbracelet/bubbles/key"
tea "github.com/charmbracelet/bubbletea"
"github.com/charmbracelet/lipgloss"
- "github.com/sst/opencode/internal/config"
+ "github.com/sst/opencode/internal/tui/app"
"github.com/sst/opencode/internal/tui/layout"
"github.com/sst/opencode/internal/tui/styles"
"github.com/sst/opencode/internal/tui/theme"
"github.com/sst/opencode/internal/tui/util"
+ "github.com/sst/opencode/pkg/client"
)
const (
@@ -16,24 +20,25 @@ const (
maxDialogWidth = 40
)
-// ModelSelectedMsg is sent when a model is selected
-type ModelSelectedMsg struct {
- // Model models.Model
-}
-
// CloseModelDialogMsg is sent when a model is selected
-type CloseModelDialogMsg struct{}
+type CloseModelDialogMsg struct {
+ Provider *client.ProviderInfo
+ Model *client.ProviderModel
+}
// ModelDialog interface for the model selection dialog
type ModelDialog interface {
tea.Model
layout.Bindings
+
+ SetProviders(providers []client.ProviderInfo)
}
type modelDialogCmp struct {
- // models []models.Model
- // provider models.ModelProvider
- // availableProviders []models.ModelProvider
+ app *app.App
+ availableProviders []client.ProviderInfo
+ provider client.ProviderInfo
+ model *client.ProviderModel
selectedIdx int
width int
@@ -100,10 +105,28 @@ var modelKeys = modelKeyMap{
}
func (m *modelDialogCmp) Init() tea.Cmd {
- m.setupModels()
+ // cfg := config.Get()
+ // modelInfo := GetSelectedModel(cfg)
+ // m.availableProviders = getEnabledProviders(cfg)
+ // m.hScrollPossible = len(m.availableProviders) > 1
+
+ // m.provider = modelInfo.Provider
+ // m.hScrollOffset = findProviderIndex(m.availableProviders, m.provider)
+
+ // m.setupModelsForProvider(m.provider)
+
+ m.availableProviders, _ = m.app.ListProviders(context.Background())
+ m.hScrollOffset = 0
+ m.hScrollPossible = len(m.availableProviders) > 1
+ m.provider = m.availableProviders[m.hScrollOffset]
+
return nil
}
+func (m *modelDialogCmp) SetProviders(providers []client.ProviderInfo) {
+ m.availableProviders = providers
+}
+
func (m *modelDialogCmp) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
switch msg := msg.(type) {
case tea.KeyMsg:
@@ -121,7 +144,7 @@ func (m *modelDialogCmp) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
m.switchProvider(1)
}
case key.Matches(msg, modelKeys.Enter):
- // return m, util.CmdHandler(ModelSelectedMsg{Model: m.models[m.selectedIdx]})
+ return m, util.CmdHandler(CloseModelDialogMsg{Provider: &m.provider, Model: &m.provider.Models[m.selectedIdx]})
case key.Matches(msg, modelKeys.Escape):
return m, util.CmdHandler(CloseModelDialogMsg{})
}
@@ -138,8 +161,8 @@ func (m *modelDialogCmp) moveSelectionUp() {
if m.selectedIdx > 0 {
m.selectedIdx--
} else {
- // m.selectedIdx = len(m.models) - 1
- // m.scrollOffset = max(0, len(m.models)-numVisibleModels)
+ m.selectedIdx = len(m.provider.Models) - 1
+ m.scrollOffset = max(0, len(m.provider.Models)-numVisibleModels)
}
// Keep selection visible
@@ -150,12 +173,12 @@ func (m *modelDialogCmp) moveSelectionUp() {
// moveSelectionDown moves the selection down or wraps to top
func (m *modelDialogCmp) moveSelectionDown() {
- // if m.selectedIdx < len(m.models)-1 {
- // m.selectedIdx++
- // } else {
- // m.selectedIdx = 0
- // m.scrollOffset = 0
- // }
+ if m.selectedIdx < len(m.provider.Models)-1 {
+ m.selectedIdx++
+ } else {
+ m.selectedIdx = 0
+ m.scrollOffset = 0
+ }
// Keep selection visible
if m.selectedIdx >= m.scrollOffset+numVisibleModels {
@@ -167,16 +190,16 @@ func (m *modelDialogCmp) switchProvider(offset int) {
newOffset := m.hScrollOffset + offset
// Ensure we stay within bounds
- // if newOffset < 0 {
- // newOffset = len(m.availableProviders) - 1
- // }
- // if newOffset >= len(m.availableProviders) {
- // newOffset = 0
- // }
+ if newOffset < 0 {
+ newOffset = len(m.availableProviders) - 1
+ }
+ if newOffset >= len(m.availableProviders) {
+ newOffset = 0
+ }
m.hScrollOffset = newOffset
- // m.provider = m.availableProviders[m.hScrollOffset]
- // m.setupModelsForProvider(m.provider)
+ m.provider = m.availableProviders[m.hScrollOffset]
+ m.setupModelsForProvider(m.provider.Id)
}
func (m *modelDialogCmp) View() string {
@@ -184,33 +207,32 @@ func (m *modelDialogCmp) View() string {
baseStyle := styles.BaseStyle()
// Capitalize first letter of provider name
- // providerName := strings.ToUpper(string(m.provider)[:1]) + string(m.provider[1:])
- // title := baseStyle.
- // Foreground(t.Primary()).
- // Bold(true).
- // Width(maxDialogWidth).
- // Padding(0, 0, 1).
- // Render(fmt.Sprintf("Select %s Model", providerName))
+ title := baseStyle.
+ Foreground(t.Primary()).
+ Bold(true).
+ Width(maxDialogWidth).
+ Padding(0, 0, 1).
+ Render(fmt.Sprintf("Select %s Model", m.provider.Name))
// Render visible models
- // endIdx := min(m.scrollOffset+numVisibleModels, len(m.models))
- // modelItems := make([]string, 0, endIdx-m.scrollOffset)
- //
- // for i := m.scrollOffset; i < endIdx; i++ {
- // itemStyle := baseStyle.Width(maxDialogWidth)
- // if i == m.selectedIdx {
- // itemStyle = itemStyle.Background(t.Primary()).
- // Foreground(t.Background()).Bold(true)
- // }
- // modelItems = append(modelItems, itemStyle.Render(m.models[i].Name))
- // }
+ endIdx := min(m.scrollOffset+numVisibleModels, len(m.provider.Models))
+ modelItems := make([]string, 0, endIdx-m.scrollOffset)
+
+ for i := m.scrollOffset; i < endIdx; i++ {
+ itemStyle := baseStyle.Width(maxDialogWidth)
+ if i == m.selectedIdx {
+ itemStyle = itemStyle.Background(t.Primary()).
+ Foreground(t.Background()).Bold(true)
+ }
+ modelItems = append(modelItems, itemStyle.Render(*m.provider.Models[i].Name))
+ }
scrollIndicator := m.getScrollIndicators(maxDialogWidth)
content := lipgloss.JoinVertical(
lipgloss.Left,
- // title,
- // baseStyle.Width(maxDialogWidth).Render(lipgloss.JoinVertical(lipgloss.Left, modelItems...)),
+ title,
+ baseStyle.Width(maxDialogWidth).Render(lipgloss.JoinVertical(lipgloss.Left, modelItems...)),
scrollIndicator,
)
@@ -225,22 +247,22 @@ func (m *modelDialogCmp) View() string {
func (m *modelDialogCmp) getScrollIndicators(maxWidth int) string {
var indicator string
- // if len(m.models) > numVisibleModels {
- // if m.scrollOffset > 0 {
- // indicator += "↑ "
- // }
- // if m.scrollOffset+numVisibleModels < len(m.models) {
- // indicator += "↓ "
- // }
- // }
+ if len(m.provider.Models) > numVisibleModels {
+ if m.scrollOffset > 0 {
+ indicator += "↑ "
+ }
+ if m.scrollOffset+numVisibleModels < len(m.provider.Models) {
+ indicator += "↓ "
+ }
+ }
if m.hScrollPossible {
if m.hScrollOffset > 0 {
indicator = "← " + indicator
}
- // if m.hScrollOffset < len(m.availableProviders)-1 {
- // indicator += "→"
- // }
+ if m.hScrollOffset < len(m.availableProviders)-1 {
+ indicator += "→"
+ }
}
if indicator == "" {
@@ -262,70 +284,26 @@ func (m *modelDialogCmp) BindingKeys() []key.Binding {
return layout.KeyMapToSlice(modelKeys)
}
-func (m *modelDialogCmp) setupModels() {
- // cfg := config.Get()
- // modelInfo := GetSelectedModel(cfg)
- // m.availableProviders = getEnabledProviders(cfg)
- // m.hScrollPossible = len(m.availableProviders) > 1
- //
- // m.provider = modelInfo.Provider
- // m.hScrollOffset = findProviderIndex(m.availableProviders, m.provider)
- //
- // m.setupModelsForProvider(m.provider)
-}
-
-func GetSelectedModel(cfg *config.Config) string {
- return "Claude Sonnet 4"
- // agentCfg := cfg.Agents[config.AgentPrimary]
- // selectedModelId := agentCfg.Model
- // return models.SupportedModels[selectedModelId]
-}
-
-func getEnabledProviders(cfg *config.Config) []string {
- return []string{"anthropic", "openai", "google"}
- // var providers []models.ModelProvider
- // for providerId, provider := range cfg.Providers {
- // if !provider.Disabled {
- // providers = append(providers, providerId)
- // }
- // }
- //
- // // Sort by provider popularity
- // slices.SortFunc(providers, func(a, b models.ModelProvider) int {
- // rA := models.ProviderPopularity[a]
- // rB := models.ProviderPopularity[b]
- //
- // // models not included in popularity ranking default to last
- // if rA == 0 {
- // rA = 999
- // }
- // if rB == 0 {
- // rB = 999
- // }
- // return rA - rB
- // })
- // return providers
-}
-
// findProviderIndex returns the index of the provider in the list, or -1 if not found
-func findProviderIndex(providers []string, provider string) int {
- for i, p := range providers {
- if p == provider {
- return i
- }
- }
- return -1
-}
+// func findProviderIndex(providers []string, provider string) int {
+// for i, p := range providers {
+// if p == provider {
+// return i
+// }
+// }
+// return -1
+// }
+
+func (m *modelDialogCmp) setupModelsForProvider(_ string) {
+ m.selectedIdx = 0
+ m.scrollOffset = 0
-func (m *modelDialogCmp) setupModelsForProvider(provider string) {
// cfg := config.Get()
// agentCfg := cfg.Agents[config.AgentPrimary]
// selectedModelId := agentCfg.Model
// m.provider = provider
// m.models = getModelsForProvider(provider)
- m.selectedIdx = 0
- m.scrollOffset = 0
// Try to select the current model if it belongs to this provider
// if provider == models.SupportedModels[selectedModelId].Provider {
@@ -342,28 +320,8 @@ func (m *modelDialogCmp) setupModelsForProvider(provider string) {
// }
}
-func getModelsForProvider(provider string) []string {
- return []string{"Claude Sonnet 4"}
- // var providerModels []models.Model
- // for _, model := range models.SupportedModels {
- // if model.Provider == provider {
- // providerModels = append(providerModels, model)
- // }
- // }
-
- // reverse alphabetical order (if llm naming was consistent latest would appear first)
- // slices.SortFunc(providerModels, func(a, b models.Model) int {
- // if a.Name > b.Name {
- // return -1
- // } else if a.Name < b.Name {
- // return 1
- // }
- // return 0
- // })
-
- // return providerModels
-}
-
-func NewModelDialogCmp() ModelDialog {
- return &modelDialogCmp{}
+func NewModelDialogCmp(app *app.App) ModelDialog {
+ return &modelDialogCmp{
+ app: app,
+ }
}