Enha: change textview chat history based on current user persona
This commit is contained in:
15
bot.go
15
bot.go
@@ -153,7 +153,8 @@ func filterMessagesForCharacter(messages []models.RoleMsg, character string) []m
|
|||||||
return messages
|
return messages
|
||||||
}
|
}
|
||||||
filtered := make([]models.RoleMsg, 0, len(messages))
|
filtered := make([]models.RoleMsg, 0, len(messages))
|
||||||
for _, msg := range messages {
|
for i, msg := range messages {
|
||||||
|
logger.Info("filtering messages", "character", character, "index", i, "known_to", msg.KnownTo)
|
||||||
// If KnownTo is nil or empty, message is visible to all
|
// If KnownTo is nil or empty, message is visible to all
|
||||||
if len(msg.KnownTo) == 0 {
|
if len(msg.KnownTo) == 0 {
|
||||||
filtered = append(filtered, msg)
|
filtered = append(filtered, msg)
|
||||||
@@ -1003,9 +1004,9 @@ func findCall(msg, toolCall string, tv *tview.TextView) {
|
|||||||
chatRound("", cfg.AssistantRole, tv, false, false)
|
chatRound("", cfg.AssistantRole, tv, false, false)
|
||||||
}
|
}
|
||||||
|
|
||||||
func chatToTextSlice(showSys bool) []string {
|
func chatToTextSlice(messages []models.RoleMsg, showSys bool) []string {
|
||||||
resp := make([]string, len(chatBody.Messages))
|
resp := make([]string, len(messages))
|
||||||
for i, msg := range chatBody.Messages {
|
for i, msg := range messages {
|
||||||
// INFO: skips system msg and tool msg
|
// INFO: skips system msg and tool msg
|
||||||
if !showSys && (msg.Role == cfg.ToolRole || msg.Role == "system") {
|
if !showSys && (msg.Role == cfg.ToolRole || msg.Role == "system") {
|
||||||
continue
|
continue
|
||||||
@@ -1015,8 +1016,8 @@ func chatToTextSlice(showSys bool) []string {
|
|||||||
return resp
|
return resp
|
||||||
}
|
}
|
||||||
|
|
||||||
func chatToText(showSys bool) string {
|
func chatToText(messages []models.RoleMsg, showSys bool) string {
|
||||||
s := chatToTextSlice(showSys)
|
s := chatToTextSlice(messages, showSys)
|
||||||
return strings.Join(s, "\n")
|
return strings.Join(s, "\n")
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1140,7 +1141,7 @@ func summarizeAndStartNewChat() {
|
|||||||
}
|
}
|
||||||
chatBody.Messages = append(chatBody.Messages, toolMsg)
|
chatBody.Messages = append(chatBody.Messages, toolMsg)
|
||||||
// Update UI
|
// Update UI
|
||||||
textView.SetText(chatToText(cfg.ShowSys))
|
textView.SetText(chatToText(chatBody.Messages, cfg.ShowSys))
|
||||||
colorText()
|
colorText()
|
||||||
// Update storage
|
// Update storage
|
||||||
if err := updateStorageChat(activeChatName, chatBody.Messages); err != nil {
|
if err := updateStorageChat(activeChatName, chatBody.Messages); err != nil {
|
||||||
|
|||||||
@@ -34,3 +34,6 @@ Again, this is not going to work with openais /v1/chat endpoint since it convert
|
|||||||
|
|
||||||
|
|
||||||
alternative approach to the tag string would be to have a judge agent to determine after each message what characters should hae access to it. but it means to make an additional call to llm after each msg.
|
alternative approach to the tag string would be to have a judge agent to determine after each message what characters should hae access to it. but it means to make an additional call to llm after each msg.
|
||||||
|
|
||||||
|
|
||||||
|
need to update character card loader to support multiple characters
|
||||||
|
|||||||
@@ -109,7 +109,7 @@ func startNewChat() {
|
|||||||
}
|
}
|
||||||
// set chat body
|
// set chat body
|
||||||
chatBody.Messages = chatBody.Messages[:2]
|
chatBody.Messages = chatBody.Messages[:2]
|
||||||
textView.SetText(chatToText(cfg.ShowSys))
|
textView.SetText(chatToText(chatBody.Messages, cfg.ShowSys))
|
||||||
newChat := &models.Chat{
|
newChat := &models.Chat{
|
||||||
ID: id + 1,
|
ID: id + 1,
|
||||||
Name: fmt.Sprintf("%d_%s", id+1, cfg.AssistantRole),
|
Name: fmt.Sprintf("%d_%s", id+1, cfg.AssistantRole),
|
||||||
|
|||||||
1
llm.go
1
llm.go
@@ -180,7 +180,6 @@ func (lcp LCPCompletion) FormMsg(msg, role string, resume bool) (io.Reader, erro
|
|||||||
}
|
}
|
||||||
prompt = sb.String()
|
prompt = sb.String()
|
||||||
}
|
}
|
||||||
|
|
||||||
logger.Debug("checking prompt for /completion", "tool_use", cfg.ToolUse,
|
logger.Debug("checking prompt for /completion", "tool_use", cfg.ToolUse,
|
||||||
"msg", msg, "resume", resume, "prompt", prompt, "multimodal_data_count", len(multimodalData))
|
"msg", msg, "resume", resume, "prompt", prompt, "multimodal_data_count", len(multimodalData))
|
||||||
payload := models.NewLCPReq(prompt, chatBody.Model, multimodalData, defaultLCPProps, chatBody.MakeStopSlice())
|
payload := models.NewLCPReq(prompt, chatBody.Model, multimodalData, defaultLCPProps, chatBody.MakeStopSlice())
|
||||||
|
|||||||
10
tables.go
10
tables.go
@@ -119,7 +119,7 @@ func makeChatTable(chatMap map[string]models.Chat) *tview.Table {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
chatBody.Messages = history
|
chatBody.Messages = history
|
||||||
textView.SetText(chatToText(cfg.ShowSys))
|
textView.SetText(chatToText(chatBody.Messages, cfg.ShowSys))
|
||||||
activeChatName = selectedChat
|
activeChatName = selectedChat
|
||||||
pages.RemovePage(historyPage)
|
pages.RemovePage(historyPage)
|
||||||
return
|
return
|
||||||
@@ -142,7 +142,7 @@ func makeChatTable(chatMap map[string]models.Chat) *tview.Table {
|
|||||||
}
|
}
|
||||||
// load last chat
|
// load last chat
|
||||||
chatBody.Messages = loadOldChatOrGetNew()
|
chatBody.Messages = loadOldChatOrGetNew()
|
||||||
textView.SetText(chatToText(cfg.ShowSys))
|
textView.SetText(chatToText(chatBody.Messages, cfg.ShowSys))
|
||||||
pages.RemovePage(historyPage)
|
pages.RemovePage(historyPage)
|
||||||
return
|
return
|
||||||
case "update card":
|
case "update card":
|
||||||
@@ -175,7 +175,7 @@ func makeChatTable(chatMap map[string]models.Chat) *tview.Table {
|
|||||||
case "move sysprompt onto 1st msg":
|
case "move sysprompt onto 1st msg":
|
||||||
chatBody.Messages[1].Content = chatBody.Messages[0].Content + chatBody.Messages[1].Content
|
chatBody.Messages[1].Content = chatBody.Messages[0].Content + chatBody.Messages[1].Content
|
||||||
chatBody.Messages[0].Content = rpDefenitionSysMsg
|
chatBody.Messages[0].Content = rpDefenitionSysMsg
|
||||||
textView.SetText(chatToText(cfg.ShowSys))
|
textView.SetText(chatToText(chatBody.Messages, cfg.ShowSys))
|
||||||
activeChatName = selectedChat
|
activeChatName = selectedChat
|
||||||
pages.RemovePage(historyPage)
|
pages.RemovePage(historyPage)
|
||||||
return
|
return
|
||||||
@@ -546,7 +546,7 @@ func makeAgentTable(agentList []string) *tview.Table {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
// replace textview
|
// replace textview
|
||||||
textView.SetText(chatToText(cfg.ShowSys))
|
textView.SetText(chatToText(chatBody.Messages, cfg.ShowSys))
|
||||||
colorText()
|
colorText()
|
||||||
updateStatusLine()
|
updateStatusLine()
|
||||||
// sysModal.ClearButtons()
|
// sysModal.ClearButtons()
|
||||||
@@ -715,7 +715,7 @@ func makeImportChatTable(filenames []string) *tview.Table {
|
|||||||
colorText()
|
colorText()
|
||||||
updateStatusLine()
|
updateStatusLine()
|
||||||
// redraw the text in text area
|
// redraw the text in text area
|
||||||
textView.SetText(chatToText(cfg.ShowSys))
|
textView.SetText(chatToText(chatBody.Messages, cfg.ShowSys))
|
||||||
pages.RemovePage(historyPage)
|
pages.RemovePage(historyPage)
|
||||||
app.SetFocus(textArea)
|
app.SetFocus(textArea)
|
||||||
return
|
return
|
||||||
|
|||||||
2
tools.go
2
tools.go
@@ -945,7 +945,7 @@ func summarizeChat(args map[string]string) []byte {
|
|||||||
return []byte("No chat history to summarize.")
|
return []byte("No chat history to summarize.")
|
||||||
}
|
}
|
||||||
// Format chat history for the agent
|
// Format chat history for the agent
|
||||||
chatText := chatToText(true) // include system and tool messages
|
chatText := chatToText(chatBody.Messages, true) // include system and tool messages
|
||||||
return []byte(chatText)
|
return []byte(chatText)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
35
tui.go
35
tui.go
@@ -310,7 +310,7 @@ func performSearch(term string) {
|
|||||||
searchResultLengths = nil
|
searchResultLengths = nil
|
||||||
originalTextForSearch = ""
|
originalTextForSearch = ""
|
||||||
// Re-render text without highlights
|
// Re-render text without highlights
|
||||||
textView.SetText(chatToText(cfg.ShowSys))
|
textView.SetText(chatToText(chatBody.Messages, cfg.ShowSys))
|
||||||
colorText()
|
colorText()
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
@@ -517,7 +517,7 @@ func init() {
|
|||||||
searchResults = nil // Clear search results
|
searchResults = nil // Clear search results
|
||||||
searchResultLengths = nil // Clear search result lengths
|
searchResultLengths = nil // Clear search result lengths
|
||||||
originalTextForSearch = ""
|
originalTextForSearch = ""
|
||||||
textView.SetText(chatToText(cfg.ShowSys)) // Reset text without search regions
|
textView.SetText(chatToText(chatBody.Messages, cfg.ShowSys)) // Reset text without search regions
|
||||||
colorText() // Apply normal chat coloring
|
colorText() // Apply normal chat coloring
|
||||||
} else {
|
} else {
|
||||||
// Original logic if no search is active
|
// Original logic if no search is active
|
||||||
@@ -594,7 +594,7 @@ func init() {
|
|||||||
}
|
}
|
||||||
chatBody.Messages[selectedIndex].Content = editedMsg
|
chatBody.Messages[selectedIndex].Content = editedMsg
|
||||||
// change textarea
|
// change textarea
|
||||||
textView.SetText(chatToText(cfg.ShowSys))
|
textView.SetText(chatToText(chatBody.Messages, cfg.ShowSys))
|
||||||
pages.RemovePage(editMsgPage)
|
pages.RemovePage(editMsgPage)
|
||||||
editMode = false
|
editMode = false
|
||||||
return nil
|
return nil
|
||||||
@@ -627,7 +627,7 @@ func init() {
|
|||||||
}
|
}
|
||||||
if selectedIndex >= 0 && selectedIndex < len(chatBody.Messages) {
|
if selectedIndex >= 0 && selectedIndex < len(chatBody.Messages) {
|
||||||
chatBody.Messages[selectedIndex].Role = newRole
|
chatBody.Messages[selectedIndex].Role = newRole
|
||||||
textView.SetText(chatToText(cfg.ShowSys))
|
textView.SetText(chatToText(chatBody.Messages, cfg.ShowSys))
|
||||||
colorText()
|
colorText()
|
||||||
pages.RemovePage(roleEditPage)
|
pages.RemovePage(roleEditPage)
|
||||||
}
|
}
|
||||||
@@ -739,7 +739,7 @@ func init() {
|
|||||||
searchResults = nil
|
searchResults = nil
|
||||||
searchResultLengths = nil
|
searchResultLengths = nil
|
||||||
originalTextForSearch = ""
|
originalTextForSearch = ""
|
||||||
textView.SetText(chatToText(cfg.ShowSys))
|
textView.SetText(chatToText(chatBody.Messages, cfg.ShowSys))
|
||||||
colorText()
|
colorText()
|
||||||
return
|
return
|
||||||
} else {
|
} else {
|
||||||
@@ -787,7 +787,7 @@ func init() {
|
|||||||
//
|
//
|
||||||
textArea.SetMovedFunc(updateStatusLine)
|
textArea.SetMovedFunc(updateStatusLine)
|
||||||
updateStatusLine()
|
updateStatusLine()
|
||||||
textView.SetText(chatToText(cfg.ShowSys))
|
textView.SetText(chatToText(chatBody.Messages, cfg.ShowSys))
|
||||||
colorText()
|
colorText()
|
||||||
if scrollToEndEnabled {
|
if scrollToEndEnabled {
|
||||||
textView.ScrollToEnd()
|
textView.ScrollToEnd()
|
||||||
@@ -801,7 +801,7 @@ func init() {
|
|||||||
if event.Key() == tcell.KeyRune && event.Rune() == '5' && event.Modifiers()&tcell.ModAlt != 0 {
|
if event.Key() == tcell.KeyRune && event.Rune() == '5' && event.Modifiers()&tcell.ModAlt != 0 {
|
||||||
// switch cfg.ShowSys
|
// switch cfg.ShowSys
|
||||||
cfg.ShowSys = !cfg.ShowSys
|
cfg.ShowSys = !cfg.ShowSys
|
||||||
textView.SetText(chatToText(cfg.ShowSys))
|
textView.SetText(chatToText(chatBody.Messages, cfg.ShowSys))
|
||||||
colorText()
|
colorText()
|
||||||
}
|
}
|
||||||
if event.Key() == tcell.KeyRune && event.Rune() == '3' && event.Modifiers()&tcell.ModAlt != 0 {
|
if event.Key() == tcell.KeyRune && event.Rune() == '3' && event.Modifiers()&tcell.ModAlt != 0 {
|
||||||
@@ -866,7 +866,7 @@ func init() {
|
|||||||
chatBody.Messages = chatBody.Messages[:len(chatBody.Messages)-1]
|
chatBody.Messages = chatBody.Messages[:len(chatBody.Messages)-1]
|
||||||
// there is no case where user msg is regenerated
|
// there is no case where user msg is regenerated
|
||||||
// lastRole := chatBody.Messages[len(chatBody.Messages)-1].Role
|
// lastRole := chatBody.Messages[len(chatBody.Messages)-1].Role
|
||||||
textView.SetText(chatToText(cfg.ShowSys))
|
textView.SetText(chatToText(chatBody.Messages, cfg.ShowSys))
|
||||||
go chatRound("", cfg.UserRole, textView, true, false)
|
go chatRound("", cfg.UserRole, textView, true, false)
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
@@ -888,7 +888,7 @@ func init() {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
chatBody.Messages = chatBody.Messages[:len(chatBody.Messages)-1]
|
chatBody.Messages = chatBody.Messages[:len(chatBody.Messages)-1]
|
||||||
textView.SetText(chatToText(cfg.ShowSys))
|
textView.SetText(chatToText(chatBody.Messages, cfg.ShowSys))
|
||||||
colorText()
|
colorText()
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
@@ -1052,7 +1052,7 @@ func init() {
|
|||||||
// clear context
|
// clear context
|
||||||
// remove tools and thinking
|
// remove tools and thinking
|
||||||
removeThinking(chatBody)
|
removeThinking(chatBody)
|
||||||
textView.SetText(chatToText(cfg.ShowSys))
|
textView.SetText(chatToText(chatBody.Messages, cfg.ShowSys))
|
||||||
colorText()
|
colorText()
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
@@ -1184,20 +1184,26 @@ func init() {
|
|||||||
if strings.EqualFold(role, persona) {
|
if strings.EqualFold(role, persona) {
|
||||||
if i == len(roles)-1 {
|
if i == len(roles)-1 {
|
||||||
cfg.WriteNextMsgAs = roles[0] // reached last, get first
|
cfg.WriteNextMsgAs = roles[0] // reached last, get first
|
||||||
|
persona = cfg.WriteNextMsgAs
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
cfg.WriteNextMsgAs = roles[i+1] // get next role
|
cfg.WriteNextMsgAs = roles[i+1] // get next role
|
||||||
|
persona = cfg.WriteNextMsgAs
|
||||||
logger.Info("picked role", "roles", roles, "index", i+1)
|
logger.Info("picked role", "roles", roles, "index", i+1)
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
// role got switch, update textview with character specific context for user
|
||||||
|
filtered := filterMessagesForCharacter(chatBody.Messages, persona)
|
||||||
|
textView.SetText(chatToText(filtered, cfg.ShowSys))
|
||||||
updateStatusLine()
|
updateStatusLine()
|
||||||
|
colorText()
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
if event.Key() == tcell.KeyCtrlX {
|
if event.Key() == tcell.KeyCtrlX {
|
||||||
persona := cfg.AssistantRole
|
botPersona := cfg.AssistantRole
|
||||||
if cfg.WriteNextMsgAsCompletionAgent != "" {
|
if cfg.WriteNextMsgAsCompletionAgent != "" {
|
||||||
persona = cfg.WriteNextMsgAsCompletionAgent
|
botPersona = cfg.WriteNextMsgAsCompletionAgent
|
||||||
}
|
}
|
||||||
roles := chatBody.ListRoles()
|
roles := chatBody.ListRoles()
|
||||||
if len(roles) == 0 {
|
if len(roles) == 0 {
|
||||||
@@ -1207,12 +1213,14 @@ func init() {
|
|||||||
roles = append(roles, cfg.AssistantRole)
|
roles = append(roles, cfg.AssistantRole)
|
||||||
}
|
}
|
||||||
for i, role := range roles {
|
for i, role := range roles {
|
||||||
if strings.EqualFold(role, persona) {
|
if strings.EqualFold(role, botPersona) {
|
||||||
if i == len(roles)-1 {
|
if i == len(roles)-1 {
|
||||||
cfg.WriteNextMsgAsCompletionAgent = roles[0] // reached last, get first
|
cfg.WriteNextMsgAsCompletionAgent = roles[0] // reached last, get first
|
||||||
|
botPersona = cfg.WriteNextMsgAsCompletionAgent
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
cfg.WriteNextMsgAsCompletionAgent = roles[i+1] // get next role
|
cfg.WriteNextMsgAsCompletionAgent = roles[i+1] // get next role
|
||||||
|
botPersona = cfg.WriteNextMsgAsCompletionAgent
|
||||||
logger.Info("picked role", "roles", roles, "index", i+1)
|
logger.Info("picked role", "roles", roles, "index", i+1)
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
@@ -1295,7 +1303,6 @@ func init() {
|
|||||||
// cannot send msg in editMode or botRespMode
|
// cannot send msg in editMode or botRespMode
|
||||||
if event.Key() == tcell.KeyEscape && !editMode && !botRespMode {
|
if event.Key() == tcell.KeyEscape && !editMode && !botRespMode {
|
||||||
msgText := textArea.GetText()
|
msgText := textArea.GetText()
|
||||||
// TODO: add shellmode command -> output to the chat history, or at least have an option
|
|
||||||
if shellMode && msgText != "" {
|
if shellMode && msgText != "" {
|
||||||
// In shell mode, execute command instead of sending to LLM
|
// In shell mode, execute command instead of sending to LLM
|
||||||
executeCommandAndDisplay(msgText)
|
executeCommandAndDisplay(msgText)
|
||||||
|
|||||||
Reference in New Issue
Block a user