diff options
| author | adamdottv <[email protected]> | 2025-07-10 09:53:18 -0500 |
|---|---|---|
| committer | adamdottv <[email protected]> | 2025-07-10 10:06:51 -0500 |
| commit | ce4cb820f72591d58ea78d1c0d955a7ca50a0217 (patch) | |
| tree | eaf4d26f01c7bd6f4c737cabfd6484ab5abd3401 /packages/tui/internal/app | |
| parent | ba5be6b6257ea06302db70e3f706e0e29359a77d (diff) | |
| download | opencode-ce4cb820f72591d58ea78d1c0d955a7ca50a0217.tar.gz opencode-ce4cb820f72591d58ea78d1c0d955a7ca50a0217.zip | |
feat(tui): modes
Diffstat (limited to 'packages/tui/internal/app')
| -rw-r--r-- | packages/tui/internal/app/app.go | 95 |
1 files changed, 87 insertions, 8 deletions
diff --git a/packages/tui/internal/app/app.go b/packages/tui/internal/app/app.go index bd16036af..b41bbaeaf 100644 --- a/packages/tui/internal/app/app.go +++ b/packages/tui/internal/app/app.go @@ -23,11 +23,15 @@ import ( type App struct { Info opencode.App + Modes []opencode.Mode + Providers []opencode.Provider Version string StatePath string Config *opencode.Config Client *opencode.Client State *config.State + ModeIndex int + Mode *opencode.Mode Provider *opencode.Provider Model *opencode.Model Session *opencode.Session @@ -64,6 +68,7 @@ func New( ctx context.Context, version string, appInfo opencode.App, + modes []opencode.Mode, httpClient *opencode.Client, model *string, prompt *string, @@ -87,14 +92,33 @@ func New( config.SaveState(appStatePath, appState) } + if appState.ModeModel == nil { + appState.ModeModel = make(map[string]config.ModeModel) + } + if configInfo.Theme != "" { appState.Theme = configInfo.Theme } - if configInfo.Model != "" { - splits := strings.Split(configInfo.Model, "/") - appState.Provider = splits[0] - appState.Model = strings.Join(splits[1:], "/") + var modeIndex int + var mode *opencode.Mode + modeName := "build" + if appState.Mode != "" { + modeName = appState.Mode + } + for i, m := range modes { + if m.Name == modeName { + modeIndex = i + break + } + } + mode = &modes[modeIndex] + + if mode.Model.ModelID != "" { + appState.ModeModel[mode.Name] = config.ModeModel{ + ProviderID: mode.Model.ProviderID, + ModelID: mode.Model.ModelID, + } } if err := theme.LoadThemesFromDirectories( @@ -119,11 +143,14 @@ func New( app := &App{ Info: appInfo, + Modes: modes, Version: version, StatePath: appStatePath, Config: configInfo, State: appState, Client: httpClient, + ModeIndex: modeIndex, + Mode: mode, Session: &opencode.Session{}, Messages: []opencode.MessageUnion{}, Commands: commands.LoadFromConfig(configInfo), @@ -162,6 +189,45 @@ func (a *App) SetClipboard(text string) tea.Cmd { return tea.Sequence(cmds...) } +func (a *App) SwitchMode() (*App, tea.Cmd) { + a.ModeIndex++ + if a.ModeIndex >= len(a.Modes) { + a.ModeIndex = 0 + } + a.Mode = &a.Modes[a.ModeIndex] + + modelID := a.Mode.Model.ModelID + providerID := a.Mode.Model.ProviderID + if modelID == "" { + if model, ok := a.State.ModeModel[a.Mode.Name]; ok { + modelID = model.ModelID + providerID = model.ProviderID + } + } + + if modelID != "" { + for _, provider := range a.Providers { + if provider.ID == providerID { + a.Provider = &provider + for _, model := range provider.Models { + if model.ID == modelID { + a.Model = &model + break + } + } + break + } + } + } + + a.State.Mode = a.Mode.Name + + return a, func() tea.Msg { + a.SaveState() + return nil + } +} + func (a *App) InitializeProvider() tea.Cmd { providersResponse, err := a.Client.Config.Providers(context.Background()) if err != nil { @@ -198,6 +264,14 @@ func (a *App) InitializeProvider() tea.Cmd { return nil } + a.Providers = providers + + // retains backwards compatibility with old state format + if model, ok := a.State.ModeModel[a.State.Mode]; ok { + a.State.Provider = model.ProviderID + a.State.Model = model.ModelID + } + var currentProvider *opencode.Provider var currentModel *opencode.Model for _, provider := range providers { @@ -322,10 +396,14 @@ func (a *App) CompactSession(ctx context.Context) tea.Cmd { a.compactCancel = nil }() - _, err := a.Client.Session.Summarize(compactCtx, a.Session.ID, opencode.SessionSummarizeParams{ - ProviderID: opencode.F(a.Provider.ID), - ModelID: opencode.F(a.Model.ID), - }) + _, err := a.Client.Session.Summarize( + compactCtx, + a.Session.ID, + opencode.SessionSummarizeParams{ + ProviderID: opencode.F(a.Provider.ID), + ModelID: opencode.F(a.Model.ID), + }, + ) if err != nil { if compactCtx.Err() != context.Canceled { slog.Error("Failed to compact session", "error", err) @@ -417,6 +495,7 @@ func (a *App) SendChatMessage( Parts: opencode.F(parts), ProviderID: opencode.F(a.Provider.ID), ModelID: opencode.F(a.Model.ID), + Mode: opencode.F(a.Mode.Name), }) if err != nil { errormsg := fmt.Sprintf("failed to send message: %v", err) |
