diff options
| author | adamdottv <[email protected]> | 2025-05-30 15:34:22 -0500 |
|---|---|---|
| committer | adamdottv <[email protected]> | 2025-05-30 15:34:25 -0500 |
| commit | c69c9327da4a43a63928807fcf36b24755cfac18 (patch) | |
| tree | df79a6c58976af977a28717619d70db4a62f4853 /internal/tui/components | |
| parent | f5e2c596d4f887daa4df579975dd5451fadc8457 (diff) | |
| download | opencode-c69c9327da4a43a63928807fcf36b24755cfac18.tar.gz opencode-c69c9327da4a43a63928807fcf36b24755cfac18.zip | |
wip: refactoring tui
Diffstat (limited to 'internal/tui/components')
| -rw-r--r-- | internal/tui/components/core/status.go | 5 | ||||
| -rw-r--r-- | internal/tui/components/dialog/models.go | 236 |
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, + } } |
