@@ -299,6 +299,11 @@ func (m *UI) Init() tea.Cmd {
299299 if m.QueryCapabilities {
300300 cmds = append(cmds, tea.RequestTerminalVersion)
301301 }
302+ if m.state == uiOnboarding {
303+ if cmd := m.openModelsDialog(); cmd != nil {
304+ cmds = append(cmds, cmd)
305+ }
306+ }
302307 // load the user commands async
303308 cmds = append(cmds, m.loadCustomCommands())
304309 return tea.Batch(cmds...)
@@ -1028,10 +1033,23 @@ func (m *UI) handleDialogMsg(msg tea.Msg) tea.Cmd {
10281033 return tea.Batch(cmds...)
10291034 }
10301035
1036+ isOnboarding := m.state == uiOnboarding
1037+
10311038 switch msg := action.(type) {
10321039 // Generic dialog messages
10331040 case dialog.ActionClose:
1041+ if isOnboarding && m.dialog.ContainsDialog(dialog.ModelsID) {
1042+ break
1043+ }
1044+
10341045 m.dialog.CloseFrontDialog()
1046+
1047+ if isOnboarding {
1048+ if cmd := m.openModelsDialog(); cmd != nil {
1049+ cmds = append(cmds, cmd)
1050+ }
1051+ }
1052+
10351053 if m.focus == uiFocusEditor {
10361054 cmds = append(cmds, m.textarea.Focus())
10371055 }
@@ -1164,10 +1182,18 @@ func (m *UI) handleDialogMsg(msg tea.Msg) tea.Cmd {
11641182
11651183 if err := cfg.UpdatePreferredModel(msg.ModelType, msg.Model); err != nil {
11661184 cmds = append(cmds, uiutil.ReportError(err))
1185+ } else if _, ok := cfg.Models[config.SelectedModelTypeSmall]; !ok {
1186+ // Ensure small model is set is unset.
1187+ smallModel := m.com.App.GetDefaultSmallModel(providerID)
1188+ if err := cfg.UpdatePreferredModel(config.SelectedModelTypeSmall, smallModel); err != nil {
1189+ cmds = append(cmds, uiutil.ReportError(err))
1190+ }
11671191 }
11681192
11691193 cmds = append(cmds, func() tea.Msg {
1170− m.com.App.UpdateAgentModel(context.TODO())
1194+ if err := m.com.App.UpdateAgentModel(context.TODO()); err != nil {
1195+ return uiutil.ReportError(err)
1196+ }
11711197
11721198 modelMsg := fmt.Sprintf("%s model changed to %s", msg.ModelType, msg.Model.Model)
11731199
@@ -1177,6 +1203,16 @@ func (m *UI) handleDialogMsg(msg tea.Msg) tea.Cmd {
11771203 m.dialog.CloseDialog(dialog.APIKeyInputID)
11781204 m.dialog.CloseDialog(dialog.OAuthID)
11791205 m.dialog.CloseDialog(dialog.ModelsID)
1206+
1207+ if isOnboarding {
1208+ m.state = uiLanding
1209+ m.focus = uiFocusEditor
1210+
1211+ m.com.Config().SetupAgents()
1212+ if err := m.com.App.InitCoderAgent(context.TODO()); err != nil {
1213+ cmds = append(cmds, uiutil.ReportError(err))
1214+ }
1215+ }
11801216 case dialog.ActionSelectReasoningEffort:
11811217 if m.isAgentBusy() {
11821218 cmds = append(cmds, uiutil.ReportWarn("Agent is busy, please wait..."))
@@ -1284,15 +1320,17 @@ func (m *UI) openAuthenticationDialog(provider catwalk.Provider, model config.Se
12841320 var (
12851321 dlg dialog.Dialog
12861322 cmd tea.Cmd
1323+
1324+ isOnboarding = m.state == uiOnboarding
12871325 )
12881326
12891327 switch provider.ID {
12901328 case "hyper":
1291− dlg, cmd = dialog.NewOAuthHyper(m.com, provider, model, modelType)
1329+ dlg, cmd = dialog.NewOAuthHyper(m.com, isOnboarding, provider, model, modelType)
12921330 case catwalk.InferenceProviderCopilot:
1293− dlg, cmd = dialog.NewOAuthCopilot(m.com, provider, model, modelType)
1331+ dlg, cmd = dialog.NewOAuthCopilot(m.com, isOnboarding, provider, model, modelType)
12941332 default:
1295− dlg, cmd = dialog.NewAPIKeyInput(m.com, provider, model, modelType)
1333+ dlg, cmd = dialog.NewAPIKeyInput(m.com, isOnboarding, provider, model, modelType)
12961334 }
12971335
12981336 if m.dialog.ContainsDialog(dlg.ID()) {
@@ -1648,12 +1686,8 @@ func (m *UI) Draw(scr uv.Screen, area uv.Rectangle) *tea.Cursor {
16481686 header := uv.NewStyledString(m.header)
16491687 header.Draw(scr, layout.header)
16501688
1651− mainView := lipgloss.NewStyle().Width(layout.main.Dx()).
1652− Height(layout.main.Dy()).
1653− Background(lipgloss.ANSIColor(rand.Intn(256))).
1654− Render(" Onboarding ")
1655− main := uv.NewStyledString(mainView)
1656− main.Draw(scr, layout.main)
1689+ // NOTE: Onboarding flow will be rendered as dialogs below, but
1690+ // positioned at the bottom left of the screen.
16571691
16581692 case uiInitialize:
16591693 header := uv.NewStyledString(m.header)
@@ -1697,11 +1731,14 @@ func (m *UI) Draw(scr uv.Screen, area uv.Rectangle) *tea.Cursor {
16971731 }
16981732 }
16991733
1734+ isOnboarding := m.state == uiOnboarding
1735+
17001736 // Add status and help layer
1737+ m.status.SetHideHelp(isOnboarding)
17011738 m.status.Draw(scr, layout.status)
17021739
17031740 // Draw completions popup if open
1704− if m.completionsOpen && m.completions.HasItems() {
1741+ if !isOnboarding && m.completionsOpen && m.completions.HasItems() {
17051742 w, h := m.completions.Size()
17061743 x := m.completionsPositionStart.X
17071744 y := m.completionsPositionStart.Y - h
@@ -2606,7 +2643,8 @@ func (m *UI) openModelsDialog() tea.Cmd {
26062643 return nil
26072644 }
26082645
2609− modelsDialog, err := dialog.NewModels(m.com)
2646+ isOnboarding := m.state == uiOnboarding
2647+ modelsDialog, err := dialog.NewModels(m.com, isOnboarding)
26102648 if err != nil {
26112649 return uiutil.ReportError(err)
26122650 }