Private
Public Access
1
0

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:
2024-10-25 16:57:15 +00:00
parent 07c96082e7
commit ec21a02ec0
9 changed files with 116 additions and 86 deletions

View File

@@ -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) {