Fix (race): mutex chatbody
This commit is contained in:
56
tui.go
56
tui.go
@@ -355,7 +355,7 @@ func init() {
|
||||
searchResults = nil // Clear search results
|
||||
searchResultLengths = nil // Clear search result lengths
|
||||
originalTextForSearch = ""
|
||||
textView.SetText(chatToText(chatBody.Messages, cfg.ShowSys)) // Reset text without search regions
|
||||
textView.SetText(chatToText(chatBody.GetMessages(), cfg.ShowSys)) // Reset text without search regions
|
||||
colorText() // Apply normal chat coloring
|
||||
} else {
|
||||
// Original logic if no search is active
|
||||
@@ -436,9 +436,11 @@ func init() {
|
||||
pages.RemovePage(editMsgPage)
|
||||
return nil
|
||||
}
|
||||
chatBody.Messages[selectedIndex].SetText(editedMsg)
|
||||
chatBody.WithLock(func(cb *models.ChatBody) {
|
||||
cb.Messages[selectedIndex].SetText(editedMsg)
|
||||
})
|
||||
// change textarea
|
||||
textView.SetText(chatToText(chatBody.Messages, cfg.ShowSys))
|
||||
textView.SetText(chatToText(chatBody.GetMessages(), cfg.ShowSys))
|
||||
pages.RemovePage(editMsgPage)
|
||||
editMode = false
|
||||
return nil
|
||||
@@ -466,9 +468,11 @@ func init() {
|
||||
pages.RemovePage(roleEditPage)
|
||||
return
|
||||
}
|
||||
if selectedIndex >= 0 && selectedIndex < len(chatBody.Messages) {
|
||||
chatBody.Messages[selectedIndex].Role = newRole
|
||||
textView.SetText(chatToText(chatBody.Messages, cfg.ShowSys))
|
||||
if selectedIndex >= 0 && selectedIndex < chatBody.GetMessageCount() {
|
||||
chatBody.WithLock(func(cb *models.ChatBody) {
|
||||
cb.Messages[selectedIndex].Role = newRole
|
||||
})
|
||||
textView.SetText(chatToText(chatBody.GetMessages(), cfg.ShowSys))
|
||||
colorText()
|
||||
pages.RemovePage(roleEditPage)
|
||||
}
|
||||
@@ -497,7 +501,7 @@ func init() {
|
||||
return nil
|
||||
}
|
||||
selectedIndex = siInt
|
||||
if len(chatBody.Messages)-1 < selectedIndex || selectedIndex < 0 {
|
||||
if chatBody.GetMessageCount()-1 < selectedIndex || selectedIndex < 0 {
|
||||
msg := "chosen index is out of bounds, will copy user input"
|
||||
logger.Warn(msg, "index", selectedIndex)
|
||||
showToast("error", msg)
|
||||
@@ -507,7 +511,7 @@ func init() {
|
||||
hideIndexBar() // Hide overlay instead of removing page directly
|
||||
return nil
|
||||
}
|
||||
m := chatBody.Messages[selectedIndex]
|
||||
m := chatBody.GetMessages()[selectedIndex]
|
||||
switch {
|
||||
case roleEditMode:
|
||||
hideIndexBar() // Hide overlay first
|
||||
@@ -574,7 +578,7 @@ func init() {
|
||||
searchResults = nil
|
||||
searchResultLengths = nil
|
||||
originalTextForSearch = ""
|
||||
textView.SetText(chatToText(chatBody.Messages, cfg.ShowSys))
|
||||
textView.SetText(chatToText(chatBody.GetMessages(), cfg.ShowSys))
|
||||
colorText()
|
||||
return
|
||||
} else {
|
||||
@@ -632,7 +636,7 @@ func init() {
|
||||
//
|
||||
textArea.SetMovedFunc(updateStatusLine)
|
||||
updateStatusLine()
|
||||
textView.SetText(chatToText(chatBody.Messages, cfg.ShowSys))
|
||||
textView.SetText(chatToText(chatBody.GetMessages(), cfg.ShowSys))
|
||||
colorText()
|
||||
if scrollToEndEnabled {
|
||||
textView.ScrollToEnd()
|
||||
@@ -646,7 +650,7 @@ func init() {
|
||||
if event.Key() == tcell.KeyRune && event.Rune() == '5' && event.Modifiers()&tcell.ModAlt != 0 {
|
||||
// switch cfg.ShowSys
|
||||
cfg.ShowSys = !cfg.ShowSys
|
||||
textView.SetText(chatToText(chatBody.Messages, cfg.ShowSys))
|
||||
textView.SetText(chatToText(chatBody.GetMessages(), cfg.ShowSys))
|
||||
colorText()
|
||||
}
|
||||
if event.Key() == tcell.KeyRune && event.Rune() == '3' && event.Modifiers()&tcell.ModAlt != 0 {
|
||||
@@ -679,7 +683,7 @@ func init() {
|
||||
// Handle Alt+T to toggle thinking block visibility
|
||||
if event.Key() == tcell.KeyRune && event.Rune() == 't' && event.Modifiers()&tcell.ModAlt != 0 {
|
||||
thinkingCollapsed = !thinkingCollapsed
|
||||
textView.SetText(chatToText(chatBody.Messages, cfg.ShowSys))
|
||||
textView.SetText(chatToText(chatBody.GetMessages(), cfg.ShowSys))
|
||||
colorText()
|
||||
status := "expanded"
|
||||
if thinkingCollapsed {
|
||||
@@ -691,7 +695,7 @@ func init() {
|
||||
// Handle Ctrl+T to toggle tool call/response visibility
|
||||
if event.Key() == tcell.KeyCtrlT {
|
||||
toolCollapsed = !toolCollapsed
|
||||
textView.SetText(chatToText(chatBody.Messages, cfg.ShowSys))
|
||||
textView.SetText(chatToText(chatBody.GetMessages(), cfg.ShowSys))
|
||||
colorText()
|
||||
status := "expanded"
|
||||
if toolCollapsed {
|
||||
@@ -734,14 +738,14 @@ func init() {
|
||||
}
|
||||
if event.Key() == tcell.KeyF2 && !botRespMode {
|
||||
// regen last msg
|
||||
if len(chatBody.Messages) == 0 {
|
||||
if chatBody.GetMessageCount() == 0 {
|
||||
showToast("info", "no messages to regenerate")
|
||||
return nil
|
||||
}
|
||||
chatBody.Messages = chatBody.Messages[:len(chatBody.Messages)-1]
|
||||
chatBody.TruncateMessages(chatBody.GetMessageCount() - 1)
|
||||
// there is no case where user msg is regenerated
|
||||
// lastRole := chatBody.Messages[len(chatBody.Messages)-1].Role
|
||||
textView.SetText(chatToText(chatBody.Messages, cfg.ShowSys))
|
||||
// lastRole := chatBody.GetMessages()[chatBody.GetMessageCount()-1].Role
|
||||
textView.SetText(chatToText(chatBody.GetMessages(), cfg.ShowSys))
|
||||
// go chatRound("", cfg.UserRole, textView, true, false)
|
||||
if cfg.TTS_ENABLED {
|
||||
TTSDoneChan <- true
|
||||
@@ -760,12 +764,12 @@ func init() {
|
||||
colorText()
|
||||
return nil
|
||||
}
|
||||
if len(chatBody.Messages) == 0 {
|
||||
if chatBody.GetMessageCount() == 0 {
|
||||
showToast("info", "no messages to delete")
|
||||
return nil
|
||||
}
|
||||
chatBody.Messages = chatBody.Messages[:len(chatBody.Messages)-1]
|
||||
textView.SetText(chatToText(chatBody.Messages, cfg.ShowSys))
|
||||
chatBody.TruncateMessages(chatBody.GetMessageCount() - 1)
|
||||
textView.SetText(chatToText(chatBody.GetMessages(), cfg.ShowSys))
|
||||
if cfg.TTS_ENABLED {
|
||||
TTSDoneChan <- true
|
||||
}
|
||||
@@ -813,7 +817,7 @@ func init() {
|
||||
if event.Key() == tcell.KeyF7 {
|
||||
// copy msg to clipboard
|
||||
editMode = false
|
||||
m := chatBody.Messages[len(chatBody.Messages)-1]
|
||||
m := chatBody.GetMessages()[chatBody.GetMessageCount()-1]
|
||||
msgText := m.GetText()
|
||||
if err := copyToClipboard(msgText); err != nil {
|
||||
logger.Error("failed to copy to clipboard", "error", err)
|
||||
@@ -997,10 +1001,10 @@ func init() {
|
||||
TTSDoneChan <- true
|
||||
}
|
||||
if event.Key() == tcell.KeyRune && event.Rune() == '0' && event.Modifiers()&tcell.ModAlt != 0 && cfg.TTS_ENABLED {
|
||||
if len(chatBody.Messages) > 0 {
|
||||
if chatBody.GetMessageCount() > 0 {
|
||||
// Stop any currently playing TTS first
|
||||
TTSDoneChan <- true
|
||||
lastMsg := chatBody.Messages[len(chatBody.Messages)-1]
|
||||
lastMsg := chatBody.GetMessages()[chatBody.GetMessageCount()-1]
|
||||
cleanedText := models.CleanText(lastMsg.GetText())
|
||||
if cleanedText != "" {
|
||||
// nolint: errcheck
|
||||
@@ -1012,7 +1016,7 @@ func init() {
|
||||
if event.Key() == tcell.KeyCtrlW {
|
||||
// INFO: continue bot/text message
|
||||
// without new role
|
||||
lastRole := chatBody.Messages[len(chatBody.Messages)-1].Role
|
||||
lastRole := chatBody.GetMessages()[chatBody.GetMessageCount()-1].Role
|
||||
// go chatRound("", lastRole, textView, false, true)
|
||||
chatRoundChan <- &models.ChatRoundReq{Role: lastRole, Resume: true}
|
||||
return nil
|
||||
@@ -1098,7 +1102,7 @@ func init() {
|
||||
if event.Key() == tcell.KeyRune && event.Modifiers() == tcell.ModAlt && event.Rune() == '9' {
|
||||
// Warm up (load) the currently selected model
|
||||
go warmUpModel()
|
||||
showToast("model warmup", "loading model: "+chatBody.Model)
|
||||
showToast("model warmup", "loading model: "+chatBody.GetModel())
|
||||
return nil
|
||||
}
|
||||
// cannot send msg in editMode or botRespMode
|
||||
@@ -1137,7 +1141,7 @@ func init() {
|
||||
}
|
||||
// add user icon before user msg
|
||||
fmt.Fprintf(textView, "%s[-:-:b](%d) <%s>: [-:-:-]\n%s\n",
|
||||
nl, len(chatBody.Messages), persona, msgText)
|
||||
nl, chatBody.GetMessageCount(), persona, msgText)
|
||||
textArea.SetText("", true)
|
||||
if scrollToEndEnabled {
|
||||
textView.ScrollToEnd()
|
||||
|
||||
Reference in New Issue
Block a user