Fix: display and upsert correct roles and icons

This commit is contained in:
Grail Finder
2024-12-10 17:55:10 +03:00
parent 67f36d417f
commit 5f780287ae
8 changed files with 53 additions and 37 deletions

View File

@@ -49,5 +49,5 @@
- no selection focus on modal sys buttons after opening it a second time; (cannot reproduce) + - no selection focus on modal sys buttons after opening it a second time; (cannot reproduce) +
- chat should contain char in it (one to many: char: []chats); + - chat should contain char in it (one to many: char: []chats); +
- all page names should be vars; - all page names should be vars;
- normal case regen omits assistant icon; - normal case regen omits assistant icon; +
- user icon (and role?) from config is not used; - user icon (and role?) from config is not used; +

13
bot.go
View File

@@ -115,7 +115,8 @@ func chatRound(userMsg, role string, tv *tview.TextView, regen bool) {
return return
} }
go sendMsgToLLM(reader) go sendMsgToLLM(reader)
if userMsg != "" && !regen { // no need to write assistant icon since we continue old message // if userMsg != "" && !regen { // no need to write assistant icon since we continue old message
if userMsg != "" || regen {
fmt.Fprintf(tv, "(%d) ", len(chatBody.Messages)) fmt.Fprintf(tv, "(%d) ", len(chatBody.Messages))
fmt.Fprint(tv, cfg.AssistantIcon) fmt.Fprint(tv, cfg.AssistantIcon)
fmt.Fprint(tv, "\n") fmt.Fprint(tv, "\n")
@@ -181,7 +182,7 @@ func chatToTextSlice(showSys bool) []string {
if !showSys && (msg.Role != cfg.AssistantRole && msg.Role != cfg.UserRole) { if !showSys && (msg.Role != cfg.AssistantRole && msg.Role != cfg.UserRole) {
continue continue
} }
resp[i] = msg.ToText(i) resp[i] = msg.ToText(i, cfg)
} }
return resp return resp
} }
@@ -193,6 +194,8 @@ func chatToText(showSys bool) string {
func applyCharCard(cc *models.CharCard) { func applyCharCard(cc *models.CharCard) {
cfg.AssistantRole = cc.Role cfg.AssistantRole = cc.Role
// TODO: need map role->icon
cfg.AssistantIcon = "<" + cc.Role + ">: "
// try to load last active chat // try to load last active chat
history, err := loadAgentsLastChat(cfg.AssistantRole) history, err := loadAgentsLastChat(cfg.AssistantRole)
if err != nil { if err != nil {
@@ -254,12 +257,12 @@ func charToStart(agentName string) bool {
// } // }
func init() { func init() {
cfg = config.LoadConfigOrDefault("config.example.toml") cfg = config.LoadConfigOrDefault("config.toml")
defaultStarter = []models.RoleMsg{ defaultStarter = []models.RoleMsg{
{Role: "system", Content: basicSysMsg}, {Role: "system", Content: basicSysMsg},
{Role: cfg.AssistantRole, Content: defaultFirstMsg}, {Role: cfg.AssistantRole, Content: defaultFirstMsg},
} }
file, err := os.OpenFile(cfg.LogFile, os.O_APPEND|os.O_CREATE|os.O_WRONLY, 0644) logfile, err := os.OpenFile(cfg.LogFile, os.O_APPEND|os.O_CREATE|os.O_WRONLY, 0644)
if err != nil { if err != nil {
logger.Error("failed to open log file", "error", err, "filename", cfg.LogFile) logger.Error("failed to open log file", "error", err, "filename", cfg.LogFile)
return return
@@ -273,7 +276,7 @@ func init() {
basicCard.Role = cfg.AssistantRole basicCard.Role = cfg.AssistantRole
toolCard.Role = cfg.AssistantRole toolCard.Role = cfg.AssistantRole
// //
logger = slog.New(slog.NewTextHandler(file, nil)) logger = slog.New(slog.NewTextHandler(logfile, nil))
store = storage.NewProviderSQL("test.db", logger) store = storage.NewProviderSQL("test.db", logger)
// https://github.com/coreydaley/ggerganov-llama.cpp/blob/master/examples/server/README.md // https://github.com/coreydaley/ggerganov-llama.cpp/blob/master/examples/server/README.md
// load all chats in memory // load all chats in memory

View File

@@ -34,8 +34,12 @@ func LoadConfigOrDefault(fn string) *Config {
config.UserRole = "user" config.UserRole = "user"
config.ToolRole = "tool" config.ToolRole = "tool"
config.AssistantRole = "assistant" config.AssistantRole = "assistant"
config.AssistantIcon = "<assistant>: "
config.UserIcon = "<user>: "
config.UserIcon = "<tool>: "
config.SysDir = "sysprompts" config.SysDir = "sysprompts"
config.ChunkLimit = 8192 config.ChunkLimit = 8192
} }
// if any value is empty fill with default
return config return config
} }

View File

@@ -1,6 +1,7 @@
package models package models
import ( import (
"elefant/config"
"fmt" "fmt"
"strings" "strings"
) )
@@ -55,21 +56,21 @@ type RoleMsg struct {
Content string `json:"content"` Content string `json:"content"`
} }
func (m RoleMsg) ToText(i int) string { func (m RoleMsg) ToText(i int, cfg *config.Config) string {
icon := "" icon := ""
switch m.Role { switch m.Role {
case "assistant": case "assistant":
icon = fmt.Sprintf("(%d) <🤖>: ", i) icon = fmt.Sprintf("(%d) %s", i, cfg.AssistantIcon)
case "user": case "user":
icon = fmt.Sprintf("(%d) <user>: ", i) icon = fmt.Sprintf("(%d) %s", i, cfg.UserIcon)
case "system": case "system":
icon = fmt.Sprintf("(%d) <system>: ", i) icon = fmt.Sprintf("(%d) <system>: ", i)
case "tool": case "tool":
icon = fmt.Sprintf("(%d) <tool>: ", i) icon = fmt.Sprintf("(%d) %s", i, cfg.ToolIcon)
default: default:
icon = fmt.Sprintf("(%d) <%s>: ", i, m.Role) icon = fmt.Sprintf("(%d) <%s>: ", i, m.Role)
} }
textMsg := fmt.Sprintf("[-:-:u]%s[-:-:-]\n%s\n", icon, m.Content) textMsg := fmt.Sprintf("[-:-:b]%s[-:-:-]\n%s\n", icon, m.Content)
return strings.ReplaceAll(textMsg, "\n\n", "\n") return strings.ReplaceAll(textMsg, "\n\n", "\n")
} }

View File

@@ -27,7 +27,7 @@ func TestReadMeta(t *testing.T) {
if err != nil { if err != nil {
t.Errorf("Expected no error, but got %v\n", err) t.Errorf("Expected no error, but got %v\n", err)
} }
fmt.Printf("%+v\n", v.Simplify("Adam")) fmt.Printf("%+v\n", v.Simplify("Adam", tc.Filename))
}) })
} }
} }

View File

@@ -57,12 +57,12 @@ func loadHistoryChats() ([]string, error) {
if err != nil { if err != nil {
return nil, err return nil, err
} }
resp := []string{} resp := make([]string, len(chats))
for _, chat := range chats { for i, chat := range chats {
if chat.Name == "" { if chat.Name == "" {
chat.Name = fmt.Sprintf("%d_%v", chat.ID, chat.CreatedAt.Unix()) chat.Name = fmt.Sprintf("%d_%v", chat.ID, chat.Agent)
} }
resp = append(resp, chat.Name) resp[i] = chat.Name
chatMap[chat.Name] = &chat chatMap[chat.Name] = &chat
} }
return resp, nil return resp, nil
@@ -98,33 +98,37 @@ func loadAgentsLastChat(agent string) ([]models.RoleMsg, error) {
} }
func loadOldChatOrGetNew() []models.RoleMsg { func loadOldChatOrGetNew() []models.RoleMsg {
newChat := &models.Chat{
ID: 0,
CreatedAt: time.Now(),
UpdatedAt: time.Now(),
}
newChat.Name = fmt.Sprintf("%d_%v", newChat.ID, newChat.CreatedAt.Unix())
// find last chat // find last chat
chat, err := store.GetLastChat() chat, err := store.GetLastChat()
if err != nil { if err != nil {
logger.Warn("failed to load history chat", "error", err) logger.Warn("failed to load history chat", "error", err)
activeChatName = newChat.Name chat := &models.Chat{
chatMap[newChat.Name] = newChat ID: 0,
CreatedAt: time.Now(),
UpdatedAt: time.Now(),
Agent: cfg.AssistantRole,
}
chat.Name = fmt.Sprintf("%s_%v", chat.Agent, chat.CreatedAt.Unix())
activeChatName = chat.Name
chatMap[chat.Name] = chat
return defaultStarter return defaultStarter
} }
history, err := chat.ToHistory() history, err := chat.ToHistory()
if err != nil { if err != nil {
logger.Warn("failed to load history chat", "error", err) logger.Warn("failed to load history chat", "error", err)
activeChatName = newChat.Name activeChatName = chat.Name
chatMap[newChat.Name] = newChat chatMap[chat.Name] = chat
return defaultStarter return defaultStarter
} }
if chat.Name == "" { // if chat.Name == "" {
logger.Warn("empty chat name", "id", chat.ID) // logger.Warn("empty chat name", "id", chat.ID)
chat.Name = fmt.Sprintf("%d_%v", chat.ID, chat.CreatedAt.Unix()) // chat.Name = fmt.Sprintf("%s_%v", chat.Agent, chat.CreatedAt.Unix())
} // }
chatMap[chat.Name] = chat chatMap[chat.Name] = chat
activeChatName = chat.Name activeChatName = chat.Name
cfg.AssistantRole = chat.Agent
// TODO: update assistant icon
cfg.AssistantIcon = "<" + chat.Agent + ">: "
return history return history
} }

View File

@@ -56,8 +56,8 @@ func (p ProviderSQL) GetLastChatByAgent(agent string) (*models.Chat, error) {
func (p ProviderSQL) UpsertChat(chat *models.Chat) (*models.Chat, error) { func (p ProviderSQL) UpsertChat(chat *models.Chat) (*models.Chat, error) {
// Prepare the SQL statement // Prepare the SQL statement
query := ` query := `
INSERT OR REPLACE INTO chats (id, name, msgs, created_at, updated_at) INSERT OR REPLACE INTO chats (id, name, msgs, agent, created_at, updated_at)
VALUES (:id, :name, :msgs, :created_at, :updated_at) VALUES (:id, :name, :msgs, :agent, :created_at, :updated_at)
RETURNING *;` RETURNING *;`
stmt, err := p.db.PrepareNamed(query) stmt, err := p.db.PrepareNamed(query)
if err != nil { if err != nil {

12
tui.go
View File

@@ -92,7 +92,6 @@ func startNewChat() {
chatMap[newChat.Name] = newChat chatMap[newChat.Name] = newChat
updateStatusLine() updateStatusLine()
colorText() colorText()
return
} }
func init() { func init() {
@@ -313,7 +312,10 @@ func init() {
textView.SetText(chatToText(cfg.ShowSys)) textView.SetText(chatToText(cfg.ShowSys))
colorText() colorText()
textView.ScrollToEnd() textView.ScrollToEnd()
initSysCards() _, err = initSysCards()
if err != nil {
logger.Error("failed to init sys cards", "error", err)
}
app.SetInputCapture(func(event *tcell.EventKey) *tcell.EventKey { app.SetInputCapture(func(event *tcell.EventKey) *tcell.EventKey {
if event.Key() == tcell.KeyF1 { if event.Key() == tcell.KeyF1 {
chatList, err := loadHistoryChats() chatList, err := loadHistoryChats()
@@ -400,7 +402,9 @@ func init() {
logger.Error("failed to export chat;", "error", err, "chat_name", activeChatName) logger.Error("failed to export chat;", "error", err, "chat_name", activeChatName)
return nil return nil
} }
notifyUser("exported chat", "chat: "+activeChatName+" was exported") if err := notifyUser("exported chat", "chat: "+activeChatName+" was exported"); err != nil {
logger.Error("failed to send notification", "error", err)
}
return nil return nil
} }
if event.Key() == tcell.KeyCtrlA { if event.Key() == tcell.KeyCtrlA {
@@ -442,7 +446,7 @@ func init() {
nl = "" nl = ""
} }
if msgText != "" { if msgText != "" {
fmt.Fprintf(textView, "%s[-:-:u](%d) <%s>: [-:-:-]\n%s\n", fmt.Fprintf(textView, "%s[-:-:b](%d) <%s>: [-:-:-]\n%s\n",
nl, len(chatBody.Messages), cfg.UserRole, msgText) nl, len(chatBody.Messages), cfg.UserRole, msgText)
textArea.SetText("", true) textArea.SetText("", true)
textView.ScrollToEnd() textView.ScrollToEnd()