tui: Add --system-prompt handling
And some state handling changes
This commit is contained in:
parent
2b38db7db7
commit
aeeb7bb7f7
@ -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")
|
||||||
|
@ -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:
|
||||||
|
@ -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
|
||||||
|
Loading…
Reference in New Issue
Block a user