diff options
| author | spoons-and-mirrors <[email protected]> | 2025-08-11 14:00:32 +0200 |
|---|---|---|
| committer | GitHub <[email protected]> | 2025-08-11 07:00:32 -0500 |
| commit | 73a8356b10d537f7d2b31a9fb777192a8522ab54 (patch) | |
| tree | 3205439f152f1c4d23b9703dadca338a30d85725 | |
| parent | 8db75266d0da48bfd1257d528373549dc0814584 (diff) | |
| download | opencode-73a8356b10d537f7d2b31a9fb777192a8522ab54.tar.gz opencode-73a8356b10d537f7d2b31a9fb777192a8522ab54.zip | |
Feat: Add F2 Keybind to Cycle Through the 5 Most Recent Models (#1778)
| -rw-r--r-- | packages/tui/internal/app/app.go | 33 | ||||
| -rw-r--r-- | packages/tui/internal/commands/command.go | 6 | ||||
| -rw-r--r-- | packages/tui/internal/tui/tui.go | 5 |
3 files changed, 44 insertions, 0 deletions
diff --git a/packages/tui/internal/app/app.go b/packages/tui/internal/app/app.go index 517cafd23..48f4684fe 100644 --- a/packages/tui/internal/app/app.go +++ b/packages/tui/internal/app/app.go @@ -280,6 +280,39 @@ func (a *App) SwitchAgentReverse() (*App, tea.Cmd) { return a.cycleMode(false) } +func (a *App) CycleRecentModel() (*App, tea.Cmd) { + recentModels := a.State.RecentlyUsedModels + if len(recentModels) > 5 { + recentModels = recentModels[:5] + } + if len(recentModels) < 2 { + return a, toast.NewInfoToast("Need at least 2 recent models to cycle") + } + nextIndex := 0 + for i, recentModel := range recentModels { + if a.Provider != nil && a.Model != nil && recentModel.ProviderID == a.Provider.ID && recentModel.ModelID == a.Model.ID { + nextIndex = (i + 1) % len(recentModels) + break + } + } + for range recentModels { + currentRecentModel := recentModels[nextIndex%len(recentModels)] + provider, model := findModelByProviderAndModelID(a.Providers, currentRecentModel.ProviderID, currentRecentModel.ModelID) + if provider != nil && model != nil { + a.Provider, a.Model = provider, model + a.State.AgentModel[a.Agent().Name] = AgentModel{ProviderID: provider.ID, ModelID: model.ID} + return a, tea.Sequence(a.SaveState(), toast.NewSuccessToast(fmt.Sprintf("Switched to %s (%s)", model.Name, provider.Name))) + } + recentModels = append(recentModels[:nextIndex%len(recentModels)], recentModels[nextIndex%len(recentModels)+1:]...) + if len(recentModels) < 2 { + a.State.RecentlyUsedModels = recentModels + return a, tea.Sequence(a.SaveState(), toast.NewInfoToast("Not enough valid recent models to cycle")) + } + } + a.State.RecentlyUsedModels = recentModels + return a, toast.NewErrorToast("Recent model not found") +} + // findModelByFullID finds a model by its full ID in the format "provider/model" func findModelByFullID( providers []opencode.Provider, diff --git a/packages/tui/internal/commands/command.go b/packages/tui/internal/commands/command.go index 55f118aaa..516caab79 100644 --- a/packages/tui/internal/commands/command.go +++ b/packages/tui/internal/commands/command.go @@ -121,6 +121,7 @@ const ( ToolDetailsCommand CommandName = "tool_details" ModelListCommand CommandName = "model_list" AgentListCommand CommandName = "agent_list" + ModelCycleRecentCommand CommandName = "model_cycle_recent" ThemeListCommand CommandName = "theme_list" FileListCommand CommandName = "file_list" FileCloseCommand CommandName = "file_close" @@ -257,6 +258,11 @@ func LoadFromConfig(config *opencode.Config) CommandRegistry { Trigger: []string{"agents"}, }, { + Name: ModelCycleRecentCommand, + Description: "cycle recent models", + Keybindings: parseBindings("f2"), + }, + { Name: ThemeListCommand, Description: "list themes", Keybindings: parseBindings("<leader>t"), diff --git a/packages/tui/internal/tui/tui.go b/packages/tui/internal/tui/tui.go index ea9f0560b..499d67c65 100644 --- a/packages/tui/internal/tui/tui.go +++ b/packages/tui/internal/tui/tui.go @@ -1148,6 +1148,11 @@ func (a Model) executeCommand(command commands.Command) (tea.Model, tea.Cmd) { case commands.AgentListCommand: agentDialog := dialog.NewAgentDialog(a.app) a.modal = agentDialog + case commands.ModelCycleRecentCommand: + slog.Debug("ModelCycleRecentCommand triggered") + updated, cmd := a.app.CycleRecentModel() + a.app = updated + cmds = append(cmds, cmd) case commands.ThemeListCommand: themeDialog := dialog.NewThemeDialog() a.modal = themeDialog |
