summaryrefslogtreecommitdiffhomepage
path: root/packages/tui/internal/app
diff options
context:
space:
mode:
authoradamdottv <[email protected]>2025-07-10 09:53:18 -0500
committeradamdottv <[email protected]>2025-07-10 10:06:51 -0500
commitce4cb820f72591d58ea78d1c0d955a7ca50a0217 (patch)
treeeaf4d26f01c7bd6f4c737cabfd6484ab5abd3401 /packages/tui/internal/app
parentba5be6b6257ea06302db70e3f706e0e29359a77d (diff)
downloadopencode-ce4cb820f72591d58ea78d1c0d955a7ca50a0217.tar.gz
opencode-ce4cb820f72591d58ea78d1c0d955a7ca50a0217.zip
feat(tui): modes
Diffstat (limited to 'packages/tui/internal/app')
-rw-r--r--packages/tui/internal/app/app.go95
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)