tui: Add --system-prompt handling

And some state handling changes
This commit is contained in:
Matt Low 2024-05-07 08:07:48 +00:00
parent 2b38db7db7
commit aeeb7bb7f7
3 changed files with 33 additions and 20 deletions

View File

@ -115,6 +115,14 @@ func newChatModel(tui *model) chatModel {
)), )),
} }
system := tui.ctx.GetSystemPrompt()
if system != "" {
m.messages = []models.Message{{
Role: models.MessageRoleSystem,
Content: system,
}}
}
m.input.Focus() m.input.Focus()
m.input.MaxHeight = 0 m.input.MaxHeight = 0
m.input.CharLimit = 0 m.input.CharLimit = 0
@ -177,16 +185,17 @@ func (m *chatModel) handleInput(msg tea.KeyMsg) (bool, tea.Cmd) {
switch msg.String() { switch msg.String() {
case "esc": case "esc":
return true, func() tea.Msg {
return msgChangeState(stateConversations)
}
case "ctrl+c":
if m.waitingForReply { if m.waitingForReply {
m.stopSignal <- struct{}{} m.stopSignal <- struct{}{}
return true, nil return true, nil
} }
return true, func() tea.Msg { return true, func() tea.Msg {
return msgChangeState(stateConversations) return msgStateChange(stateConversations)
}
case "ctrl+c":
if m.waitingForReply {
m.stopSignal <- struct{}{}
return true, nil
} }
case "ctrl+p": case "ctrl+p":
m.persistence = !m.persistence m.persistence = !m.persistence
@ -227,10 +236,12 @@ func (m *chatModel) handleResize(width, height int) {
func (m chatModel) Update(msg tea.Msg) (chatModel, tea.Cmd) { func (m chatModel) Update(msg tea.Msg) (chatModel, tea.Cmd) {
var cmds []tea.Cmd var cmds []tea.Cmd
switch msg := msg.(type) { switch msg := msg.(type) {
case msgChangeState: case msgStateEnter:
if m.opts.convShortname != "" && m.conversation.ShortName.String != m.opts.convShortname { if m.opts.convShortname != "" && m.conversation.ShortName.String != m.opts.convShortname {
cmds = append(cmds, m.loadConversation(m.opts.convShortname)) cmds = append(cmds, m.loadConversation(m.opts.convShortname))
} }
m.rebuildMessageCache()
m.updateContent()
case tea.WindowSizeMsg: case tea.WindowSizeMsg:
m.handleResize(msg.Width, msg.Height) m.handleResize(msg.Width, msg.Height)
case msgTempfileEditorClosed: case msgTempfileEditorClosed:
@ -254,7 +265,8 @@ func (m chatModel) Update(msg tea.Msg) (chatModel, tea.Cmd) {
cmds = append(cmds, m.loadMessages(m.conversation)) cmds = append(cmds, m.loadMessages(m.conversation))
case msgMessagesLoaded: case msgMessagesLoaded:
m.selectedMessage = len(msg) - 1 m.selectedMessage = len(msg) - 1
m.setMessages(msg) m.messages = msg
m.rebuildMessageCache()
m.updateContent() m.updateContent()
m.content.GotoBottom() m.content.GotoBottom()
case msgResponseChunk: case msgResponseChunk:
@ -358,10 +370,12 @@ func (m chatModel) Update(msg tea.Msg) (chatModel, tea.Cmd) {
fixedHeight := height(m.views.header) + height(m.views.error) + height(m.views.footer) fixedHeight := height(m.views.header) + height(m.views.error) + height(m.views.footer)
// calculate clamped input height to accomodate input text // calculate clamped input height to accomodate input text
// minimum 4 lines, maximum half of content area
newHeight := max(4, min((m.height-fixedHeight-1)/2, m.input.LineCount())) newHeight := max(4, min((m.height-fixedHeight-1)/2, m.input.LineCount()))
m.input.SetHeight(newHeight) m.input.SetHeight(newHeight)
m.views.input = m.input.View() m.views.input = m.input.View()
// remaining height towards content
m.content.Height = m.height - fixedHeight - height(m.views.input) m.content.Height = m.height - fixedHeight - height(m.views.input)
m.views.content = m.content.View() m.views.content = m.content.View()
} }
@ -701,11 +715,6 @@ func (m *chatModel) footerView() string {
return footerStyle.Width(m.width).Render(footer) return footerStyle.Width(m.width).Render(footer)
} }
func (m *chatModel) setMessages(messages []models.Message) {
m.messages = messages
m.rebuildMessageCache()
}
func (m *chatModel) setMessage(i int, msg models.Message) { func (m *chatModel) setMessage(i int, msg models.Message) {
if i >= len(m.messages) { if i >= len(m.messages) {
panic("i out of range") panic("i out of range")

View File

@ -115,7 +115,7 @@ func (m *conversationsModel) handleResize(width, height int) {
func (m conversationsModel) Update(msg tea.Msg) (conversationsModel, tea.Cmd) { func (m conversationsModel) Update(msg tea.Msg) (conversationsModel, tea.Cmd) {
var cmds []tea.Cmd var cmds []tea.Cmd
switch msg := msg.(type) { switch msg := msg.(type) {
case msgChangeState: case msgStateChange:
cmds = append(cmds, m.loadConversations()) cmds = append(cmds, m.loadConversations())
m.content.SetContent(m.renderConversationList()) m.content.SetContent(m.renderConversationList())
case tea.WindowSizeMsg: case tea.WindowSizeMsg:

View File

@ -35,8 +35,10 @@ type views struct {
} }
type ( type (
// send to change the current app state // send to change the current state
msgChangeState state msgStateChange state
// sent to a state when it is entered
msgStateEnter struct{}
// sent when an error occurs // sent when an error occurs
msgError error msgError error
) )
@ -81,7 +83,7 @@ func (m model) Init() tea.Cmd {
m.conversations.Init(), m.conversations.Init(),
m.chat.Init(), m.chat.Init(),
func() tea.Msg { func() tea.Msg {
return msgChangeState(m.state) return msgStateChange(m.state)
}, },
) )
} }
@ -124,18 +126,20 @@ func (m model) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
if handled { if handled {
return m, cmd return m, cmd
} }
case msgChangeState: case msgStateChange:
switch msg { m.state = state(msg)
switch m.state {
case stateChat: case stateChat:
m.chat.handleResize(m.width, m.height) m.chat.handleResize(m.width, m.height)
case stateConversations: case stateConversations:
m.conversations.handleResize(m.width, m.height) m.conversations.handleResize(m.width, m.height)
} }
m.state = state(msg) return m, func() tea.Msg { return msgStateEnter(struct{}{}) }
case msgConversationSelected: case msgConversationSelected:
// passed up through conversation list model
m.opts.convShortname = msg.ShortName.String m.opts.convShortname = msg.ShortName.String
cmds = append(cmds, func() tea.Msg { cmds = append(cmds, func() tea.Msg {
return msgChangeState(stateChat) return msgStateChange(stateChat)
}) })
case tea.WindowSizeMsg: case tea.WindowSizeMsg:
m.width, m.height = msg.Width, msg.Height m.width, m.height = msg.Width, msg.Height