From f367ad266ad48a544f23c34e80cb6d28f8a8c9cf Mon Sep 17 00:00:00 2001 From: Grail Finder Date: Sun, 15 Dec 2024 22:02:32 +0300 Subject: Enha: chat management table --- README.md | 2 +- session.go | 2 + tui.go | 125 ++++++++++++++++++++++++++++++++++++++----------------------- 3 files changed, 82 insertions(+), 47 deletions(-) diff --git a/README.md b/README.md index 0f16cb1..a62b6d4 100644 --- a/README.md +++ b/README.md @@ -22,11 +22,11 @@ - ctrl+n to start new chat; + - export whole chat into a json file; + - directory with sys prompts (charcards png & json); + +- colourschemes, colours or markdown of quotes and styles; (partially done) + - change temp, min-p and other params from tui; - fullscreen textarea option (bothersome to implement); - consider adding use /completion of llamacpp, since openai endpoint clearly has template|format issues; - separate messages that are stored and chat and send to the bot, i.e. option to omit tool calls (there might be a point where they are no longer needed in ctx); -- colourschemes, colours or markdown of quotes and styles; - RAG support|implementation; - change card-chat pair with one binding; - char card is the sys message, but how about giving tools to char that does not have it? diff --git a/session.go b/session.go index e34c98c..ee38843 100644 --- a/session.go +++ b/session.go @@ -76,6 +76,8 @@ func loadHistoryChat(chatName string) ([]models.RoleMsg, error) { return nil, err } activeChatName = chatName + cfg.AssistantRole = chat.Agent + cfg.AssistantIcon = "<" + chat.Agent + ">: " return chat.ToHistory() } diff --git a/tui.go b/tui.go index 73ea66e..719ea8c 100644 --- a/tui.go +++ b/tui.go @@ -53,6 +53,81 @@ Press Enter to go back ` ) +func makeChatTable(chatList []string) *tview.Table { + actions := []string{"load", "rename", "delete"} + rows, cols := len(chatList), len(actions)+1 + chatActTable := tview.NewTable(). + SetBorders(true) + for r := 0; r < rows; r++ { + for c := 0; c < cols; c++ { + color := tcell.ColorWhite + if c < 1 { + chatActTable.SetCell(r, c, + tview.NewTableCell(chatList[r]). + SetTextColor(color). + SetAlign(tview.AlignCenter)) + } else { + chatActTable.SetCell(r, c, + tview.NewTableCell(actions[c-1]). + SetTextColor(color). + SetAlign(tview.AlignCenter)) + } + } + } + chatActTable.Select(0, 0).SetFixed(1, 1).SetDoneFunc(func(key tcell.Key) { + if key == tcell.KeyEsc || key == tcell.KeyF1 { + pages.RemovePage(historyPage) + return + } + if key == tcell.KeyEnter { + chatActTable.SetSelectable(true, true) + } + }).SetSelectedFunc(func(row int, column int) { + tc := chatActTable.GetCell(row, column) + tc.SetTextColor(tcell.ColorRed) + chatActTable.SetSelectable(false, false) + selectedChat := chatList[row] + // notification := fmt.Sprintf("chat: %s; action: %s", selectedChat, tc.Text) + switch tc.Text { + case "load": + history, err := loadHistoryChat(selectedChat) + if err != nil { + logger.Error("failed to read history file", "chat", selectedChat) + pages.RemovePage(historyPage) + return + } + chatBody.Messages = history + textView.SetText(chatToText(cfg.ShowSys)) + activeChatName = selectedChat + pages.RemovePage(historyPage) + colorText() + updateStatusLine() + return + case "rename": + pages.RemovePage(historyPage) + pages.AddPage(renamePage, renameWindow, true, true) + return + case "delete": + sc, ok := chatMap[selectedChat] + if !ok { + // no chat found + pages.RemovePage(historyPage) + return + } + if err := store.RemoveChat(sc.ID); err != nil { + logger.Error("failed to remove chat from db", "chat_id", sc.ID, "chat_name", sc.Name) + } + notifyUser("chat deleted", selectedChat+" was deleted") + pages.RemovePage(historyPage) + return + default: + pages.RemovePage(historyPage) + return + } + }) + return chatActTable +} + // // code block colors get interrupted by " & * // func codeBlockColor(text string) string { // fi := strings.Index(text, "```") @@ -154,46 +229,6 @@ func init() { AddItem(textView, 0, 40, false). AddItem(textArea, 0, 10, true). AddItem(position, 0, 1, false) - chatOpts := []string{"cancel", "new", "rename current"} - chatList, err := loadHistoryChats() - if err != nil { - logger.Error("failed to load chat history", "error", err) - chatList = []string{} - } - chatActModal := tview.NewModal(). - SetText("Chat actions:"). - AddButtons(append(chatOpts, chatList...)). - SetDoneFunc(func(buttonIndex int, buttonLabel string) { - switch buttonLabel { - case "new": - startNewChat() - pages.RemovePage(historyPage) - return - // set text - case "cancel": - pages.RemovePage(historyPage) - return - case "rename current": - // add input field - pages.RemovePage(historyPage) - pages.AddPage(renamePage, renameWindow, true, true) - return - default: - fn := buttonLabel - history, err := loadHistoryChat(fn) - if err != nil { - logger.Error("failed to read history file", "chat", fn) - pages.RemovePage(historyPage) - return - } - chatBody.Messages = history - textView.SetText(chatToText(cfg.ShowSys)) - activeChatName = fn - pages.RemovePage(historyPage) - colorText() - return - } - }) sysModal = tview.NewModal(). SetText("Switch sys msg:"). SetDoneFunc(func(buttonIndex int, buttonLabel string) { @@ -253,7 +288,7 @@ func init() { return event case tcell.KeyEnter: si := indexPickWindow.GetText() - selectedIndex, err = strconv.Atoi(si) + selectedIndex, err := strconv.Atoi(si) if err != nil { logger.Error("failed to convert provided index", "error", err, "si", si) } @@ -336,7 +371,7 @@ func init() { textView.SetText(chatToText(cfg.ShowSys)) colorText() textView.ScrollToEnd() - _, err = initSysCards() + _, err := initSysCards() if err != nil { logger.Error("failed to init sys cards", "error", err) } @@ -347,10 +382,8 @@ func init() { logger.Error("failed to load chat history", "error", err) return nil } - chatOpts := append(chatOpts, chatList...) - chatActModal.ClearButtons() - chatActModal.AddButtons(chatOpts) - pages.AddPage(historyPage, chatActModal, true, true) + chatActTable := makeChatTable(chatList) + pages.AddPage(historyPage, chatActTable, true, true) return nil } if event.Key() == tcell.KeyF2 { -- cgit v1.2.3