From 5b1cbb46faf4c082c95b9e61d62b790defecd06a Mon Sep 17 00:00:00 2001 From: Grail Finder Date: Fri, 27 Feb 2026 20:03:47 +0300 Subject: Chore: linter complaints --- agent/request.go | 4 +-- bot.go | 52 +++++++++++++----------------------- helpfuncs.go | 12 --------- llm.go | 81 ++++++++++++++++++++++++++++++-------------------------- main_test.go | 42 ----------------------------- models/models.go | 10 +++---- tui.go | 10 +------ 7 files changed, 71 insertions(+), 140 deletions(-) delete mode 100644 main_test.go diff --git a/agent/request.go b/agent/request.go index 0ed5d40..f42b06e 100644 --- a/agent/request.go +++ b/agent/request.go @@ -71,8 +71,8 @@ func (ag *AgentClient) buildRequest(sysprompt, msg string) ([]byte, error) { // Build prompt for completion endpoints if isCompletion { var sb strings.Builder - for _, m := range messages { - sb.WriteString(m.ToPrompt()) + for i := range messages { + sb.WriteString(messages[i].ToPrompt()) sb.WriteString("\n") } prompt := strings.TrimSpace(sb.String()) diff --git a/bot.go b/bot.go index 90a49be..c5fe92d 100644 --- a/bot.go +++ b/bot.go @@ -143,16 +143,16 @@ func filterMessagesForCharacter(messages []models.RoleMsg, character string) []m return messages } filtered := make([]models.RoleMsg, 0, len(messages)) - for _, msg := range messages { + for i := range messages { // If KnownTo is nil or empty, message is visible to all // system msg cannot be filtered - if len(msg.KnownTo) == 0 || msg.Role == "system" { - filtered = append(filtered, msg) + if len(messages[i].KnownTo) == 0 || messages[i].Role == "system" { + filtered = append(filtered, messages[i]) continue } - if slices.Contains(msg.KnownTo, character) { + if slices.Contains(messages[i].KnownTo, character) { // Check if character is in KnownTo lis - filtered = append(filtered, msg) + filtered = append(filtered, messages[i]) } } return filtered @@ -164,11 +164,11 @@ func cleanToolCalls(messages []models.RoleMsg) []models.RoleMsg { return consolidateAssistantMessages(messages) } cleaned := make([]models.RoleMsg, 0, len(messages)) - for i, msg := range messages { + for i := range messages { // recognize the message as the tool call and remove it // tool call in last msg should stay - if msg.ToolCallID == "" || i == len(messages)-1 { - cleaned = append(cleaned, msg) + if messages[i].ToolCallID == "" || i == len(messages)-1 { + cleaned = append(cleaned, messages[i]) } } return consolidateAssistantMessages(cleaned) @@ -1207,25 +1207,25 @@ func findCall(msg, toolCall string) bool { func chatToTextSlice(messages []models.RoleMsg, showSys bool) []string { resp := make([]string, len(messages)) - for i, msg := range messages { + for i := range messages { // Handle tool call indicators (assistant messages with tool call but empty content) - if (msg.Role == cfg.AssistantRole || msg.Role == "assistant") && msg.ToolCallID != "" && msg.Content == "" && len(msg.ToolCalls) > 0 { + if (messages[i].Role == cfg.AssistantRole || messages[i].Role == "assistant") && messages[i].ToolCallID != "" && messages[i].Content == "" && len(messages[i].ToolCalls) > 0 { // This is a tool call indicator - show collapsed if toolCollapsed { - toolName := msg.ToolCalls[0].Name + toolName := messages[i].ToolCalls[0].Name resp[i] = fmt.Sprintf("[yellow::i][tool call: %s (press Ctrl+T to expand)][-:-:-]", toolName) } else { // Show full tool call info - toolName := msg.ToolCalls[0].Name - resp[i] = fmt.Sprintf("[yellow::i][tool call: %s][-:-:-]\nargs: %s", toolName, msg.ToolCalls[0].Args) + toolName := messages[i].ToolCalls[0].Name + resp[i] = fmt.Sprintf("[yellow::i][tool call: %s][-:-:-]\nargs: %s", toolName, messages[i].ToolCalls[0].Args) } continue } // Handle tool responses - if msg.Role == cfg.ToolRole || msg.Role == "tool" { + if messages[i].Role == cfg.ToolRole || messages[i].Role == "tool" { // Always show shell commands - if msg.IsShellCommand { - resp[i] = msg.ToText(i) + if messages[i].IsShellCommand { + resp[i] = messages[i].ToText(i) continue } // Hide non-shell tool responses when collapsed @@ -1233,14 +1233,14 @@ func chatToTextSlice(messages []models.RoleMsg, showSys bool) []string { continue } // When expanded, show tool responses - resp[i] = msg.ToText(i) + resp[i] = messages[i].ToText(i) continue } // INFO: skips system msg when showSys is false - if !showSys && msg.Role == "system" { + if !showSys && messages[i].Role == "system" { continue } - resp[i] = msg.ToText(i) + resp[i] = messages[i].ToText(i) } return resp } @@ -1274,20 +1274,6 @@ func chatToText(messages []models.RoleMsg, showSys bool) string { return text } -func removeThinking(chatBody *models.ChatBody) { - msgs := []models.RoleMsg{} - for _, msg := range chatBody.Messages { - // Filter out tool messages and thinking markers - if msg.Role == cfg.ToolRole { - continue - } - // find thinking and remove it - use SetText to preserve ContentParts - msg.SetText(thinkRE.ReplaceAllString(msg.GetText(), "")) - msgs = append(msgs, msg) - } - chatBody.Messages = msgs -} - func addNewChat(chatName string) { id, err := store.ChatGetMaxID() if err != nil { diff --git a/helpfuncs.go b/helpfuncs.go index f47fdd1..b24697a 100644 --- a/helpfuncs.go +++ b/helpfuncs.go @@ -15,8 +15,6 @@ import ( "time" "unicode" - "math/rand/v2" - "github.com/rivo/tview" ) @@ -375,16 +373,6 @@ func makeStatusLine() string { return statusLine + imageInfo + shellModeInfo } -var letters = []rune("abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ") - -func randString(n int) string { - b := make([]rune, n) - for i := range b { - b[i] = letters[rand.IntN(len(letters))] - } - return string(b) -} - // set of roles within card definition and mention in chat history func listChatRoles() []string { currentChat, ok := chatMap[activeChatName] diff --git a/llm.go b/llm.go index 375163e..e9a3b0e 100644 --- a/llm.go +++ b/llm.go @@ -14,8 +14,8 @@ var lastImg string // for ctrl+j // containsToolSysMsg checks if the toolSysMsg already exists in the chat body func containsToolSysMsg() bool { - for _, msg := range chatBody.Messages { - if msg.Role == cfg.ToolRole && msg.Content == toolSysMsg { + for i := range chatBody.Messages { + if chatBody.Messages[i].Role == cfg.ToolRole && chatBody.Messages[i].Content == toolSysMsg { return true } } @@ -147,8 +147,8 @@ func (lcp LCPCompletion) FormMsg(msg, role string, resume bool) (io.Reader, erro } filteredMessages, botPersona := filterMessagesForCurrentCharacter(chatBody.Messages) messages := make([]string, len(filteredMessages)) - for i, m := range filteredMessages { - messages[i] = stripThinkingFromMsg(&m).ToPrompt() + for i := range filteredMessages { + messages[i] = stripThinkingFromMsg(&filteredMessages[i]).ToPrompt() } prompt := strings.Join(messages, "\n") // Add multimodal media markers to the prompt text when multimodal data is present @@ -284,12 +284,12 @@ func (op LCPChat) FormMsg(msg, role string, resume bool) (io.Reader, error) { filteredMessages, _ := filterMessagesForCurrentCharacter(chatBody.Messages) // Filter out tool call indicators (assistant messages with ToolCallID but empty content) var filteredForLLM []models.RoleMsg - for _, msg := range filteredMessages { - isToolCallIndicator := msg.Role != "system" && msg.ToolCallID != "" && msg.Content == "" && len(msg.ToolCalls) > 0 + for i := range filteredMessages { + isToolCallIndicator := filteredMessages[i].Role != "system" && filteredMessages[i].ToolCallID != "" && filteredMessages[i].Content == "" && len(filteredMessages[i].ToolCalls) > 0 if isToolCallIndicator { continue } - filteredForLLM = append(filteredForLLM, msg) + filteredForLLM = append(filteredForLLM, filteredMessages[i]) } // openai /v1/chat does not support custom roles; needs to be user, assistant, system // Add persona suffix to the last user message to indicate who the assistant should reply as @@ -298,18 +298,19 @@ func (op LCPChat) FormMsg(msg, role string, resume bool) (io.Reader, error) { Model: chatBody.Model, Stream: chatBody.Stream, } - for i, msg := range filteredForLLM { - strippedMsg := *stripThinkingFromMsg(&msg) - if strippedMsg.Role == cfg.UserRole { + for i := range filteredForLLM { + strippedMsg := *stripThinkingFromMsg(&filteredForLLM[i]) + switch strippedMsg.Role { + case cfg.UserRole: bodyCopy.Messages[i] = strippedMsg bodyCopy.Messages[i].Role = "user" - } else if strippedMsg.Role == cfg.AssistantRole { + case cfg.AssistantRole: bodyCopy.Messages[i] = strippedMsg bodyCopy.Messages[i].Role = "assistant" - } else if strippedMsg.Role == cfg.ToolRole { + case cfg.ToolRole: bodyCopy.Messages[i] = strippedMsg bodyCopy.Messages[i].Role = "tool" - } else { + default: bodyCopy.Messages[i] = strippedMsg } // Clear ToolCalls - they're stored in chat history for display but not sent to LLM @@ -375,8 +376,8 @@ func (ds DeepSeekerCompletion) FormMsg(msg, role string, resume bool) (io.Reader } filteredMessages, botPersona := filterMessagesForCurrentCharacter(chatBody.Messages) messages := make([]string, len(filteredMessages)) - for i, m := range filteredMessages { - messages[i] = stripThinkingFromMsg(&m).ToPrompt() + for i := range filteredMessages { + messages[i] = stripThinkingFromMsg(&filteredMessages[i]).ToPrompt() } prompt := strings.Join(messages, "\n") // strings builder? @@ -442,12 +443,12 @@ func (ds DeepSeekerChat) FormMsg(msg, role string, resume bool) (io.Reader, erro filteredMessages, _ := filterMessagesForCurrentCharacter(chatBody.Messages) // Filter out tool call indicators (assistant messages with ToolCallID but empty content) var filteredForLLM []models.RoleMsg - for _, msg := range filteredMessages { - isToolCallIndicator := msg.Role != "system" && msg.ToolCallID != "" && msg.Content == "" && len(msg.ToolCalls) > 0 + for i := range filteredMessages { + isToolCallIndicator := filteredMessages[i].Role != "system" && filteredMessages[i].ToolCallID != "" && filteredMessages[i].Content == "" && len(filteredMessages[i].ToolCalls) > 0 if isToolCallIndicator { continue } - filteredForLLM = append(filteredForLLM, msg) + filteredForLLM = append(filteredForLLM, filteredMessages[i]) } // Add persona suffix to the last user message to indicate who the assistant should reply as bodyCopy := &models.ChatBody{ @@ -455,18 +456,23 @@ func (ds DeepSeekerChat) FormMsg(msg, role string, resume bool) (io.Reader, erro Model: chatBody.Model, Stream: chatBody.Stream, } - for i, msg := range filteredForLLM { - strippedMsg := *stripThinkingFromMsg(&msg) - if strippedMsg.Role == cfg.UserRole || i == 1 { - bodyCopy.Messages[i] = strippedMsg - bodyCopy.Messages[i].Role = "user" - } else if strippedMsg.Role == cfg.AssistantRole { + for i := range filteredForLLM { + strippedMsg := *stripThinkingFromMsg(&filteredForLLM[i]) + switch strippedMsg.Role { + case cfg.UserRole: + if i == 1 { + bodyCopy.Messages[i] = strippedMsg + bodyCopy.Messages[i].Role = "user" + } else { + bodyCopy.Messages[i] = strippedMsg + } + case cfg.AssistantRole: bodyCopy.Messages[i] = strippedMsg bodyCopy.Messages[i].Role = "assistant" - } else if strippedMsg.Role == cfg.ToolRole { + case cfg.ToolRole: bodyCopy.Messages[i] = strippedMsg bodyCopy.Messages[i].Role = "tool" - } else { + default: bodyCopy.Messages[i] = strippedMsg } // Clear ToolCalls - they're stored in chat history for display but not sent to LLM @@ -523,8 +529,8 @@ func (or OpenRouterCompletion) FormMsg(msg, role string, resume bool) (io.Reader } filteredMessages, botPersona := filterMessagesForCurrentCharacter(chatBody.Messages) messages := make([]string, len(filteredMessages)) - for i, m := range filteredMessages { - messages[i] = stripThinkingFromMsg(&m).ToPrompt() + for i := range filteredMessages { + messages[i] = stripThinkingFromMsg(&filteredMessages[i]).ToPrompt() } prompt := strings.Join(messages, "\n") // strings builder? @@ -623,12 +629,12 @@ func (or OpenRouterChat) FormMsg(msg, role string, resume bool) (io.Reader, erro filteredMessages, _ := filterMessagesForCurrentCharacter(chatBody.Messages) // Filter out tool call indicators (assistant messages with ToolCallID but empty content) var filteredForLLM []models.RoleMsg - for _, msg := range filteredMessages { - isToolCallIndicator := msg.Role != "system" && msg.ToolCallID != "" && msg.Content == "" && len(msg.ToolCalls) > 0 + for i := range filteredMessages { + isToolCallIndicator := filteredMessages[i].Role != "system" && filteredMessages[i].ToolCallID != "" && filteredMessages[i].Content == "" && len(filteredMessages[i].ToolCalls) > 0 if isToolCallIndicator { continue } - filteredForLLM = append(filteredForLLM, msg) + filteredForLLM = append(filteredForLLM, filteredMessages[i]) } // Add persona suffix to the last user message to indicate who the assistant should reply as bodyCopy := &models.ChatBody{ @@ -636,18 +642,19 @@ func (or OpenRouterChat) FormMsg(msg, role string, resume bool) (io.Reader, erro Model: chatBody.Model, Stream: chatBody.Stream, } - for i, msg := range filteredForLLM { - strippedMsg := *stripThinkingFromMsg(&msg) - if strippedMsg.Role == cfg.UserRole { + for i := range filteredForLLM { + strippedMsg := *stripThinkingFromMsg(&filteredForLLM[i]) + switch strippedMsg.Role { + case cfg.UserRole: bodyCopy.Messages[i] = strippedMsg bodyCopy.Messages[i].Role = "user" - } else if strippedMsg.Role == cfg.AssistantRole { + case cfg.AssistantRole: bodyCopy.Messages[i] = strippedMsg bodyCopy.Messages[i].Role = "assistant" - } else if strippedMsg.Role == cfg.ToolRole { + case cfg.ToolRole: bodyCopy.Messages[i] = strippedMsg bodyCopy.Messages[i].Role = "tool" - } else { + default: bodyCopy.Messages[i] = strippedMsg } // Clear ToolCalls - they're stored in chat history for display but not sent to LLM diff --git a/main_test.go b/main_test.go deleted file mode 100644 index 998778c..0000000 --- a/main_test.go +++ /dev/null @@ -1,42 +0,0 @@ -package main - -import ( - "fmt" - "gf-lt/config" - "gf-lt/models" - "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. I should thank user and continue the conversation 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) { - cfg = &config.Config{ToolRole: "tool"} // Initialize cfg.ToolRole for test - mNum := len(tc.cb.Messages) - removeThinking(tc.cb) - if len(tc.cb.Messages) != mNum-int(tc.toolMsgs) { - t.Errorf("failed to delete tools msg %v; expected %d, got %d", tc.cb.Messages, mNum-int(tc.toolMsgs), len(tc.cb.Messages)) - } - for _, msg := range tc.cb.Messages { - if strings.Contains(msg.Content, "") { - t.Errorf("msg contains think tag; msg: %s\n", msg.Content) - } - } - }) } -} diff --git a/models/models.go b/models/models.go index f430dd5..7ac9ec9 100644 --- a/models/models.go +++ b/models/models.go @@ -523,16 +523,16 @@ type ChatBody struct { } func (cb *ChatBody) Rename(oldname, newname string) { - for i, m := range cb.Messages { - cb.Messages[i].Content = strings.ReplaceAll(m.Content, oldname, newname) - cb.Messages[i].Role = strings.ReplaceAll(m.Role, oldname, newname) + for i := range cb.Messages { + cb.Messages[i].Content = strings.ReplaceAll(cb.Messages[i].Content, oldname, newname) + cb.Messages[i].Role = strings.ReplaceAll(cb.Messages[i].Role, oldname, newname) } } func (cb *ChatBody) ListRoles() []string { namesMap := make(map[string]struct{}) - for _, m := range cb.Messages { - namesMap[m.Role] = struct{}{} + for i := range cb.Messages { + namesMap[cb.Messages[i].Role] = struct{}{} } resp := make([]string, len(namesMap)) i := 0 diff --git a/tui.go b/tui.go index 14ca1aa..1fe3adb 100644 --- a/tui.go +++ b/tui.go @@ -565,7 +565,7 @@ func init() { return nil } // Handle Ctrl+T to toggle tool call/response visibility - if event.Key() == tcell.KeyRune && event.Rune() == 't' && event.Modifiers()&tcell.ModCtrl != 0 { + if event.Key() == tcell.KeyCtrlT { toolCollapsed = !toolCollapsed textView.SetText(chatToText(chatBody.Messages, cfg.ShowSys)) colorText() @@ -796,14 +796,6 @@ func init() { showModelSelectionPopup() return nil } - if event.Key() == tcell.KeyCtrlT { - // clear context - // remove tools and thinking - removeThinking(chatBody) - textView.SetText(chatToText(chatBody.Messages, cfg.ShowSys)) - colorText() - return nil - } if event.Key() == tcell.KeyCtrlV { if isFullScreenPageActive() { return event -- cgit v1.2.3