diff options
| author | adamdotdevin <[email protected]> | 2025-07-21 05:52:02 -0500 |
|---|---|---|
| committer | adamdotdevin <[email protected]> | 2025-07-21 05:52:11 -0500 |
| commit | 8e8796507d9adcb89341dfe01ec499938611ebea (patch) | |
| tree | a4d503f71eed1280a478b1adaf2037a88594eac3 /packages/tui/internal/app/app.go | |
| parent | cef5c295834760d9d3a57334f2e52bd528c66e68 (diff) | |
| download | opencode-8e8796507d9adcb89341dfe01ec499938611ebea.tar.gz opencode-8e8796507d9adcb89341dfe01ec499938611ebea.zip | |
feat(tui): message history select with up/down arrows
Diffstat (limited to 'packages/tui/internal/app/app.go')
| -rw-r--r-- | packages/tui/internal/app/app.go | 103 |
1 files changed, 22 insertions, 81 deletions
diff --git a/packages/tui/internal/app/app.go b/packages/tui/internal/app/app.go index b73cfc3cd..a481cd101 100644 --- a/packages/tui/internal/app/app.go +++ b/packages/tui/internal/app/app.go @@ -6,7 +6,6 @@ import ( "path/filepath" "sort" "strings" - "time" "log/slog" @@ -15,7 +14,6 @@ import ( "github.com/sst/opencode/internal/clipboard" "github.com/sst/opencode/internal/commands" "github.com/sst/opencode/internal/components/toast" - "github.com/sst/opencode/internal/config" "github.com/sst/opencode/internal/id" "github.com/sst/opencode/internal/styles" "github.com/sst/opencode/internal/theme" @@ -35,7 +33,7 @@ type App struct { StatePath string Config *opencode.Config Client *opencode.Client - State *config.State + State *State ModeIndex int Mode *opencode.Mode Provider *opencode.Provider @@ -61,10 +59,7 @@ type ModelSelectedMsg struct { } type SessionClearedMsg struct{} type CompactSessionMsg struct{} -type SendMsg struct { - Text string - Attachments []opencode.FilePartInputParam -} +type SendPrompt = Prompt type SetEditorContentMsg struct { Text string } @@ -95,14 +90,14 @@ func New( } appStatePath := filepath.Join(appInfo.Path.State, "tui") - appState, err := config.LoadState(appStatePath) + appState, err := LoadState(appStatePath) if err != nil { - appState = config.NewState() - config.SaveState(appStatePath, appState) + appState = NewState() + SaveState(appStatePath, appState) } if appState.ModeModel == nil { - appState.ModeModel = make(map[string]config.ModeModel) + appState.ModeModel = make(map[string]ModeModel) } if configInfo.Theme != "" { @@ -127,7 +122,7 @@ func New( mode = &modes[modeIndex] if mode.Model.ModelID != "" { - appState.ModeModel[mode.Name] = config.ModeModel{ + appState.ModeModel[mode.Name] = ModeModel{ ProviderID: mode.Model.ProviderID, ModelID: mode.Model.ModelID, } @@ -241,11 +236,7 @@ func (a *App) cycleMode(forward bool) (*App, tea.Cmd) { } a.State.Mode = a.Mode.Name - - return a, func() tea.Msg { - a.SaveState() - return nil - } + return a, a.SaveState() } func (a *App) SwitchMode() (*App, tea.Cmd) { @@ -346,7 +337,7 @@ func (a *App) InitializeProvider() tea.Cmd { Model: *currentModel, })) if a.InitialPrompt != nil && *a.InitialPrompt != "" { - cmds = append(cmds, util.CmdHandler(SendMsg{Text: *a.InitialPrompt})) + cmds = append(cmds, util.CmdHandler(SendPrompt{Text: *a.InitialPrompt})) } return tea.Sequence(cmds...) } @@ -370,7 +361,6 @@ func (a *App) IsBusy() bool { if len(a.Messages) == 0 { return false } - lastMessage := a.Messages[len(a.Messages)-1] if casted, ok := lastMessage.Info.(opencode.AssistantMessage); ok { return casted.Time.Completed == 0 @@ -378,10 +368,13 @@ func (a *App) IsBusy() bool { return false } -func (a *App) SaveState() { - err := config.SaveState(a.StatePath, a.State) - if err != nil { - slog.Error("Failed to save state", "error", err) +func (a *App) SaveState() tea.Cmd { + return func() tea.Msg { + err := SaveState(a.StatePath, a.State) + if err != nil { + slog.Error("Failed to save state", "error", err) + } + return nil } } @@ -459,11 +452,7 @@ func (a *App) CreateSession(ctx context.Context) (*opencode.Session, error) { return session, nil } -func (a *App) SendChatMessage( - ctx context.Context, - text string, - attachments []opencode.FilePartInputParam, -) (*App, tea.Cmd) { +func (a *App) SendPrompt(ctx context.Context, prompt Prompt) (*App, tea.Cmd) { var cmds []tea.Cmd if a.Session.ID == "" { session, err := a.CreateSession(ctx) @@ -474,65 +463,18 @@ func (a *App) SendChatMessage( cmds = append(cmds, util.CmdHandler(SessionCreatedMsg{Session: session})) } - message := opencode.UserMessage{ - ID: id.Ascending(id.Message), - SessionID: a.Session.ID, - Role: opencode.UserMessageRoleUser, - Time: opencode.UserMessageTime{ - Created: float64(time.Now().UnixMilli()), - }, - } - - parts := []opencode.PartUnion{opencode.TextPart{ - ID: id.Ascending(id.Part), - MessageID: message.ID, - SessionID: a.Session.ID, - Type: opencode.TextPartTypeText, - Text: text, - }} - if len(attachments) > 0 { - for _, attachment := range attachments { - parts = append(parts, opencode.FilePart{ - ID: id.Ascending(id.Part), - MessageID: message.ID, - SessionID: a.Session.ID, - Type: opencode.FilePartTypeFile, - Filename: attachment.Filename.Value, - Mime: attachment.Mime.Value, - URL: attachment.URL.Value, - }) - } - } + messageID := id.Ascending(id.Message) + message := prompt.ToMessage(messageID, a.Session.ID) - a.Messages = append(a.Messages, Message{Info: message, Parts: parts}) + a.Messages = append(a.Messages, message) cmds = append(cmds, func() tea.Msg { - partsParam := []opencode.SessionChatParamsPartUnion{} - for _, part := range parts { - switch casted := part.(type) { - case opencode.TextPart: - partsParam = append(partsParam, opencode.TextPartInputParam{ - ID: opencode.F(casted.ID), - Type: opencode.F(opencode.TextPartInputType(casted.Type)), - Text: opencode.F(casted.Text), - }) - case opencode.FilePart: - partsParam = append(partsParam, opencode.FilePartInputParam{ - ID: opencode.F(casted.ID), - Mime: opencode.F(casted.Mime), - Type: opencode.F(opencode.FilePartInputType(casted.Type)), - URL: opencode.F(casted.URL), - Filename: opencode.F(casted.Filename), - }) - } - } - _, err := a.Client.Session.Chat(ctx, a.Session.ID, opencode.SessionChatParams{ - Parts: opencode.F(partsParam), - MessageID: opencode.F(message.ID), ProviderID: opencode.F(a.Provider.ID), ModelID: opencode.F(a.Model.ID), Mode: opencode.F(a.Mode.Name), + MessageID: opencode.F(messageID), + Parts: opencode.F(message.ToSessionChatParams()), }) if err != nil { errormsg := fmt.Sprintf("failed to send message: %v", err) @@ -557,7 +499,6 @@ func (a *App) Cancel(ctx context.Context, sessionID string) error { _, err := a.Client.Session.Abort(ctx, sessionID) if err != nil { slog.Error("Failed to cancel session", "error", err) - // status.Error(err.Error()) return err } return nil |
