summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGrail Finder <wohilas@gmail.com>2026-02-27 20:03:47 +0300
committerGrail Finder <wohilas@gmail.com>2026-02-27 20:03:47 +0300
commit5b1cbb46faf4c082c95b9e61d62b790defecd06a (patch)
treebceda102bce26afe04ec60e6dc36050f3ae816f5
parent1fcab8365e8bdcf5658bfa601916e074a39a71e7 (diff)
Chore: linter complaints
-rw-r--r--agent/request.go4
-rw-r--r--bot.go52
-rw-r--r--helpfuncs.go12
-rw-r--r--llm.go81
-rw-r--r--main_test.go42
-rw-r--r--models/models.go10
-rw-r--r--tui.go10
7 files changed, 71 insertions, 140 deletions
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. <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) {
- 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, "<think>") {
- 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