@@ -22,9 +22,15 @@ const (
22 defaultWidth = 60
22 defaultWidth = 60
26+ LargeModelType int = iota
25// ModelSelectedMsg is sent when a model is selected
30// ModelSelectedMsg is sent when a model is selected
26type ModelSelectedMsg struct {
31type ModelSelectedMsg struct {
27− Model config.PreferredModel
32+ Model config.PreferredModel
33+ ModelType config.ModelType
30// CloseModelDialogMsg is sent when a model is selected
36// CloseModelDialogMsg is sent when a model is selected
@@ -42,12 +48,13 @@ type ModelOption struct {
43type modelDialogCmp struct {
49type modelDialogCmp struct {
45− wWidth int // Width of the terminal window
51+ wWidth int
46− wHeight int // Height of the terminal window
52+ wHeight int
48 modelList list.ListModel
54 modelList list.ListModel
49 keyMap KeyMap
55 keyMap KeyMap
50 help help.Model
56 help help.Model
53func NewModelDialogCmp() ModelDialog {
60func NewModelDialogCmp() ModelDialog {
@@ -80,34 +87,13 @@ func NewModelDialogCmp() ModelDialog {
80 width: defaultWidth,
87 width: defaultWidth,
81 keyMap: DefaultKeyMap(),
88 keyMap: DefaultKeyMap(),
82 help: help,
89 help: help,
90+ modelType: LargeModelType,
86func (m *modelDialogCmp) Init() tea.Cmd {
94func (m *modelDialogCmp) Init() tea.Cmd {
87− providers := config.Providers()
95+ m.SetModelType(m.modelType)
88−
96+ return m.modelList.Init()
89− modelItems := []util.Model{}
91− agentModel := config.GetAgentModel(config.AgentCoder)
92− agentProvider := config.GetAgentProvider(config.AgentCoder)
93− for _, provider := range providers {
94− name := provider.Name
96− name = string(provider.ID)
98− modelItems = append(modelItems, commands.NewItemSection(name))
99− for _, model := range provider.Models {
100− modelItems = append(modelItems, completions.NewCompletionItem(model.Name, ModelOption{
104− if model.ID == agentModel.ID && provider.ID == agentProvider.ID {
105− selectIndex = len(modelItems) - 1 // Set the selected index to the current model
110− return tea.Sequence(m.modelList.Init(), m.modelList.SetItems(modelItems), m.modelList.SetSelected(selectIndex))
113func (m *modelDialogCmp) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
99func (m *modelDialogCmp) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
@@ -115,24 +101,41 @@ func (m *modelDialogCmp) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
115 case tea.WindowSizeMsg:
101 case tea.WindowSizeMsg:
116 m.wWidth = msg.Width
102 m.wWidth = msg.Width
117 m.wHeight = msg.Height
103 m.wHeight = msg.Height
104+ m.SetModelType(m.modelType)
118 return m, m.modelList.SetSize(m.listWidth(), m.listHeight())
105 return m, m.modelList.SetSize(m.listWidth(), m.listHeight())
119 case tea.KeyPressMsg:
106 case tea.KeyPressMsg:
121 case key.Matches(msg, m.keyMap.Select):
108 case key.Matches(msg, m.keyMap.Select):
122 selectedItemInx := m.modelList.SelectedIndex()
109 selectedItemInx := m.modelList.SelectedIndex()
123 if selectedItemInx == list.NoSelection {
110 if selectedItemInx == list.NoSelection {
124− return m, nil // No item selected, do nothing
111+ return m, nil
126 items := m.modelList.Items()
113 items := m.modelList.Items()
127 selectedItem := items[selectedItemInx].(completions.CompletionItem).Value().(ModelOption)
114 selectedItem := items[selectedItemInx].(completions.CompletionItem).Value().(ModelOption)
116+ var modelType config.ModelType
117+ if m.modelType == LargeModelType {
118+ modelType = config.LargeModel
120+ modelType = config.SmallModel
129 return m, tea.Sequence(
123 return m, tea.Sequence(
130 util.CmdHandler(dialogs.CloseDialogMsg{}),
124 util.CmdHandler(dialogs.CloseDialogMsg{}),
131− util.CmdHandler(ModelSelectedMsg{Model: config.PreferredModel{
125+ util.CmdHandler(ModelSelectedMsg{
126+ Model: config.PreferredModel{
132− ModelID: selectedItem.Model.ID,
127+ ModelID: selectedItem.Model.ID,
133− Provider: selectedItem.Provider.ID,
128+ Provider: selectedItem.Provider.ID,
130+ ModelType: modelType,
133+ case key.Matches(msg, m.keyMap.Tab):
134+ if m.modelType == LargeModelType {
135+ return m, m.SetModelType(SmallModelType)
137+ return m, m.SetModelType(LargeModelType)
136 case key.Matches(msg, m.keyMap.Close):
139 case key.Matches(msg, m.keyMap.Close):
137 return m, util.CmdHandler(dialogs.CloseDialogMsg{})
140 return m, util.CmdHandler(dialogs.CloseDialogMsg{})
@@ -147,9 +150,10 @@ func (m *modelDialogCmp) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
147func (m *modelDialogCmp) View() tea.View {
150func (m *modelDialogCmp) View() tea.View {
148 t := styles.CurrentTheme()
151 t := styles.CurrentTheme()
149 listView := m.modelList.View()
152 listView := m.modelList.View()
153+ radio := m.modelTypeRadio()
150 content := lipgloss.JoinVertical(
154 content := lipgloss.JoinVertical(
151 lipgloss.Left,
155 lipgloss.Left,
152− t.S().Base.Padding(0, 1, 1, 1).Render(core.Title("Switch Model", m.width-4)),
156+ t.S().Base.Padding(0, 1, 1, 1).Render(core.Title("Switch Model", m.width-lipgloss.Width(radio)-5)+" "+radio),
153 listView.String(),
157 listView.String(),
155 t.S().Base.Width(m.width-2).PaddingLeft(1).AlignHorizontal(lipgloss.Left).Render(m.help.View(m.keyMap)),
159 t.S().Base.Width(m.width-2).PaddingLeft(1).AlignHorizontal(lipgloss.Left).Render(m.help.View(m.keyMap)),
@@ -197,3 +201,49 @@ func (m *modelDialogCmp) moveCursor(cursor *tea.Cursor) *tea.Cursor {
197func (m *modelDialogCmp) ID() dialogs.DialogID {
201func (m *modelDialogCmp) ID() dialogs.DialogID {
198 return ModelsDialogID
202 return ModelsDialogID
205+func (m *modelDialogCmp) modelTypeRadio() string {
206+ t := styles.CurrentTheme()
207+ choices := []string{"Large", "Small"}
209+ iconUnselected := "○"
210+ if m.modelType == LargeModelType {
211+ return t.S().Base.Foreground(t.FgHalfMuted).Render(iconSelected + " " + choices[0] + " " + iconUnselected + " " + choices[1])
213+ return t.S().Base.Foreground(t.FgHalfMuted).Render(iconUnselected + " " + choices[0] + " " + iconSelected + " " + choices[1])
216+func (m *modelDialogCmp) SetModelType(modelType int) tea.Cmd {
217+ m.modelType = modelType
219+ providers := config.Providers()
220+ modelItems := []util.Model{}
224+ var currentModel config.PreferredModel
225+ if m.modelType == LargeModelType {
226+ currentModel = cfg.Models.Large
228+ currentModel = cfg.Models.Small
231+ for _, provider := range providers {
232+ name := provider.Name
234+ name = string(provider.ID)
236+ modelItems = append(modelItems, commands.NewItemSection(name))
237+ for _, model := range provider.Models {
238+ modelItems = append(modelItems, completions.NewCompletionItem(model.Name, ModelOption{
242+ if model.ID == currentModel.ModelID && provider.ID == currentModel.Provider {
243+ selectIndex = len(modelItems) - 1 // Set the selected index to the current model
248+ return tea.Sequence(m.modelList.SetItems(modelItems), m.modelList.SetSelected(selectIndex))