Tweaks/cleanups to conversation management in tui
- Pass around message/conversation values instead of pointers where it makes more sense, and store values instead of pointers in the globally (within the TUI) shared `App` (pointers provide no utility here). - Split conversation persistence into separate conversation/message saving stages
This commit is contained in:
@@ -16,7 +16,7 @@ import (
|
||||
type AppModel struct {
|
||||
Ctx *lmcli.Context
|
||||
Conversations conversation.ConversationList
|
||||
Conversation *conversation.Conversation
|
||||
Conversation conversation.Conversation
|
||||
Messages []conversation.Message
|
||||
Model string
|
||||
ProviderName string
|
||||
@@ -27,12 +27,13 @@ type AppModel struct {
|
||||
func NewAppModel(ctx *lmcli.Context, initialConversation *conversation.Conversation) *AppModel {
|
||||
app := &AppModel{
|
||||
Ctx: ctx,
|
||||
Conversation: initialConversation,
|
||||
Model: *ctx.Config.Defaults.Model,
|
||||
}
|
||||
|
||||
if initialConversation == nil {
|
||||
app.NewConversation()
|
||||
} else {
|
||||
|
||||
}
|
||||
|
||||
model, provider, _, _ := ctx.GetModelProvider(*ctx.Config.Defaults.Model, "")
|
||||
@@ -61,7 +62,7 @@ const (
|
||||
)
|
||||
|
||||
func (m *AppModel) ClearConversation() {
|
||||
m.Conversation = nil
|
||||
m.Conversation = conversation.Conversation{}
|
||||
m.Messages = []conversation.Message{}
|
||||
}
|
||||
|
||||
@@ -96,10 +97,6 @@ func (a *AppModel) GenerateConversationTitle(messages []conversation.Message) (s
|
||||
return cmdutil.GenerateTitle(a.Ctx, messages)
|
||||
}
|
||||
|
||||
func (a *AppModel) UpdateConversationTitle(conversation *conversation.Conversation) error {
|
||||
return a.Ctx.Conversations.UpdateConversation(conversation)
|
||||
}
|
||||
|
||||
func (a *AppModel) CloneMessage(message conversation.Message, selected bool) (*conversation.Message, error) {
|
||||
msg, _, err := a.Ctx.Conversations.CloneBranch(message)
|
||||
if err != nil {
|
||||
@@ -182,33 +179,54 @@ func (a *AppModel) CycleSelectedReply(message *conversation.Message, dir Message
|
||||
return nextReply, nil
|
||||
}
|
||||
|
||||
func (a *AppModel) PersistConversation(conversation *conversation.Conversation, messages []conversation.Message) (*conversation.Conversation, []conversation.Message, error) {
|
||||
var err error
|
||||
if conversation == nil || conversation.ID == 0 {
|
||||
conversation, messages, err = a.Ctx.Conversations.StartConversation(messages...)
|
||||
if err != nil {
|
||||
return nil, nil, fmt.Errorf("Could not start new conversation: %v", err)
|
||||
}
|
||||
return conversation, messages, nil
|
||||
}
|
||||
|
||||
for i := range messages {
|
||||
if messages[i].ID > 0 {
|
||||
err := a.Ctx.Conversations.UpdateMessage(&messages[i])
|
||||
func (a *AppModel) PersistMessages() ([]conversation.Message, error) {
|
||||
messages := make([]conversation.Message, len(a.Messages))
|
||||
for i, m := range a.Messages {
|
||||
if i == 0 && m.ID == 0 {
|
||||
m.Conversation = &a.Conversation
|
||||
m, err := a.Ctx.Conversations.SaveMessage(m)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
return nil, fmt.Errorf("Could not create first message %d: %v", a.Messages[i].ID, err)
|
||||
}
|
||||
messages[i] = *m
|
||||
// let's set the conversation root message(s), as this is the first message
|
||||
m.Conversation.RootMessages = []conversation.Message{*m}
|
||||
m.Conversation.SelectedRoot = &m.Conversation.RootMessages[0]
|
||||
a.Ctx.Conversations.UpdateConversation(m.Conversation)
|
||||
} else if m.ID > 0 {
|
||||
// Existing message, update it
|
||||
err := a.Ctx.Conversations.UpdateMessage(&m)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("Could not update message %d: %v", a.Messages[i].ID, err)
|
||||
}
|
||||
messages[i] = m
|
||||
} else if i > 0 {
|
||||
saved, err := a.Ctx.Conversations.Reply(&messages[i-1], messages[i])
|
||||
// New message, reply to previous
|
||||
replies, err := a.Ctx.Conversations.Reply(&messages[i-1], m)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
return nil, fmt.Errorf("Could not reply with new message: %v", err)
|
||||
}
|
||||
messages[i] = saved[0]
|
||||
messages[i] = replies[0]
|
||||
} else {
|
||||
return nil, nil, fmt.Errorf("Error: no messages to reply to")
|
||||
return nil, fmt.Errorf("No messages to reply to (this is a bug)")
|
||||
}
|
||||
}
|
||||
return conversation, messages, nil
|
||||
return messages, nil
|
||||
}
|
||||
|
||||
func (a *AppModel) PersistConversation() (conversation.Conversation, error) {
|
||||
conv := a.Conversation
|
||||
var err error
|
||||
if a.Conversation.ID > 0 {
|
||||
err = a.Ctx.Conversations.UpdateConversation(&conv)
|
||||
} else {
|
||||
c, e := a.Ctx.Conversations.CreateConversation("")
|
||||
err = e
|
||||
if e == nil && c != nil {
|
||||
conv = *c
|
||||
}
|
||||
}
|
||||
return conv, err
|
||||
}
|
||||
|
||||
func (a *AppModel) ExecuteToolCalls(toolCalls []api.ToolCall) ([]api.ToolResult, error) {
|
||||
|
||||
Reference in New Issue
Block a user