Feat: remove thinking and tool msgs from ctx

This commit is contained in:
Grail Finder
2025-02-02 10:05:43 +03:00
parent 84c94ecea3
commit 4e9b31baf8
5 changed files with 69 additions and 13 deletions

View File

@@ -9,7 +9,7 @@
- ability to copy message; +
- menu with old chats (chat files); +
- tab to switch selection between textview and textarea (input and chat); +
- basic tools: memorize and recall;
- basic tools: memorize and recall; +
- stop stream from the bot; +
- sqlitedb instead of chatfiles; +
- define tools and sys prompt for them to be used; +
@@ -28,7 +28,7 @@
- delete chat option; +
- RAG file loading status/progress; +
- in chat management table add preview of the last message; +
===== /llamacpp specific (it has a different body -> interface instead of global var)
===== /llamacpp specific (it has a different body -> interface instead of global var) +
- edit syscards; +
- consider adding use /completion of llamacpp, since openai endpoint clearly has template|format issues; +
- change temp, min-p and other params from tui; +

25
bot.go
View File

@@ -257,6 +257,7 @@ func findCall(msg string, tv *tview.TextView) {
func chatToTextSlice(showSys bool) []string {
resp := make([]string, len(chatBody.Messages))
for i, msg := range chatBody.Messages {
// INFO: skips system msg
if !showSys && (msg.Role != cfg.AssistantRole && msg.Role != cfg.UserRole) {
continue
}
@@ -270,15 +271,23 @@ func chatToText(showSys bool) string {
return strings.Join(s, "")
}
// func removeThinking() {
// s := chatToTextSlice(false) // will delete tools messages though
// chat := strings.Join(s, "")
// chat = thinkRE.ReplaceAllString(chat, "")
// reS := fmt.Sprintf("[%s:\n,%s:\n]", cfg.AssistantRole, cfg.UserRole)
// // no way to know what agent wrote which msg
// s = regexp.MustCompile(reS).Split(chat, -1)
// }
func removeThinking(chatBody *models.ChatBody) {
msgs := []models.RoleMsg{}
for _, msg := range chatBody.Messages {
rm := models.RoleMsg{}
if msg.Role == cfg.ToolRole {
continue
}
// find thinking and remove it
rm.Content = thinkRE.ReplaceAllString(msg.Content, "")
rm.Role = msg.Role
msgs = append(msgs, rm)
}
chatBody.Messages = msgs
}
// what is the purpose of this func?
// is there a case where using text from widget is more appropriate than chatbody.messages?
func textToMsgs(text string) []models.RoleMsg {
lines := strings.Split(text, "\n")
roleRE := regexp.MustCompile(`^\(\d+\) <.*>:`)

41
main_test.go Normal file
View File

@@ -0,0 +1,41 @@
package main
import (
"elefant/models"
"fmt"
"strings"
"testing"
)
func TestRemoveThinking(t *testing.T) {
cases := []struct {
cb *models.ChatBody
toolMsgs uint8
}{
{cb: &models.ChatBody{
Stream: true,
Messages: []models.RoleMsg{
{Role: "tool", Content: "should be ommited"},
{Role: "system", Content: "should stay"},
{Role: "user", Content: "hello, how are you?"},
{Role: "assistant", Content: "Oh, hi. <think>I should thank user and continue the conversation</think> I am geat, thank you! How are you?"},
},
},
toolMsgs: uint8(1),
},
}
for i, tc := range cases {
t.Run(fmt.Sprintf("run_%d", i), func(t *testing.T) {
mNum := len(tc.cb.Messages)
removeThinking(tc.cb)
if len(tc.cb.Messages) != mNum-int(tc.toolMsgs) {
t.Error("failed to delete tools msg", tc.cb.Messages, cfg.ToolRole)
}
for _, msg := range tc.cb.Messages {
if strings.Contains(msg.Content, "<think>") {
t.Errorf("msg contains think tag; msg: %s\n", msg.Content)
}
}
})
}
}

View File

@@ -9,9 +9,6 @@ func TestReadMeta(t *testing.T) {
cases := []struct {
Filename string
}{
{
Filename: "../sysprompts/default_Seraphina.png",
},
{
Filename: "../sysprompts/llama.png",
},

9
tui.go
View File

@@ -59,6 +59,7 @@ var (
[yellow]Ctrl+p[white]: props edit form (min-p, dry, etc.)
[yellow]Ctrl+v[white]: switch between /completion and /chat api (if provided in config)
[yellow]Ctrl+r[white]: menu of files that can be loaded in vector db (RAG)
[yellow]Ctrl+t[white]: remove thinking (<think>) and tool messages from context (delete from chat)
Press Enter to go back
`
@@ -475,6 +476,14 @@ func init() {
startNewChat()
return nil
}
if event.Key() == tcell.KeyCtrlT {
// clear context
// remove tools and thinking
removeThinking(chatBody)
textView.SetText(chatToText(cfg.ShowSys))
colorText()
return nil
}
if event.Key() == tcell.KeyCtrlV {
// switch between /chat and /completion api
prevAPI := cfg.CurrentAPI