Chore: linter complaints

This commit is contained in:
Grail Finder
2026-02-27 20:03:47 +03:00
parent 1fcab8365e
commit 5b1cbb46fa
7 changed files with 71 additions and 140 deletions

View File

@@ -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())

52
bot.go
View File

@@ -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 {

View File

@@ -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]

77
llm.go
View File

@@ -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 {
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 if strippedMsg.Role == cfg.AssistantRole {
} 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

View File

@@ -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)
}
}
}) }
}

View File

@@ -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

10
tui.go
View File

@@ -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