From 4f0bce50c53267a9f53938ad1b264d5094a08ce4 Mon Sep 17 00:00:00 2001 From: Grail Finder Date: Sat, 7 Mar 2026 19:11:13 +0300 Subject: [PATCH] Chore: one init for clear call order --- bot.go | 52 ++----------------------------------------------- helpfuncs.go | 49 ++++++++++++++++++++++++++++++++++++++++++++++ tools.go | 55 +--------------------------------------------------- tui.go | 3 ++- 4 files changed, 54 insertions(+), 105 deletions(-) diff --git a/bot.go b/bot.go index 663dd0b..0b4328f 100644 --- a/bot.go +++ b/bot.go @@ -1548,55 +1548,7 @@ func init() { } // Initialize scrollToEndEnabled based on config scrollToEndEnabled = cfg.AutoScrollEnabled - go updateModelLists() go chatWatcher(ctx) -} - -func getValidKnowToRecipient(msg *models.RoleMsg) (string, bool) { - if cfg == nil || !cfg.CharSpecificContextEnabled { - return "", false - } - // case where all roles are in the tag => public message - cr := listChatRoles() - slices.Sort(cr) - slices.Sort(msg.KnownTo) - if slices.Equal(cr, msg.KnownTo) { - logger.Info("got msg with tag mentioning every role") - return "", false - } - // Check each character in the KnownTo list - for _, recipient := range msg.KnownTo { - if recipient == msg.Role || recipient == cfg.ToolRole { - // weird cases, skip - continue - } - // Skip if this is the user character (user handles their own turn) - // If user is in KnownTo, stop processing - it's the user's turn - if recipient == cfg.UserRole || recipient == cfg.WriteNextMsgAs { - return "", false - } - return recipient, true - } - return "", false -} - -// triggerPrivateMessageResponses checks if a message was sent privately to specific characters -// and triggers those non-user characters to respond -func triggerPrivateMessageResponses(msg *models.RoleMsg) { - recipient, ok := getValidKnowToRecipient(msg) - if !ok || recipient == "" { - return - } - // Trigger the recipient character to respond - triggerMsg := recipient + ":\n" - // Send empty message so LLM continues naturally from the conversation - crr := &models.ChatRoundReq{ - UserMsg: triggerMsg, - Role: recipient, - Resume: true, - } - fmt.Fprintf(textView, "\n[-:-:b](%d) ", len(chatBody.Messages)) - fmt.Fprint(textView, roleToIcon(recipient)) - fmt.Fprint(textView, "[-:-:-]\n") - chatRoundChan <- crr + initTUI() + initTools() } diff --git a/helpfuncs.go b/helpfuncs.go index 370f4de..178406d 100644 --- a/helpfuncs.go +++ b/helpfuncs.go @@ -964,3 +964,52 @@ func extractDisplayPath(p, bp string) string { } return p } + +func getValidKnowToRecipient(msg *models.RoleMsg) (string, bool) { + if cfg == nil || !cfg.CharSpecificContextEnabled { + return "", false + } + // case where all roles are in the tag => public message + cr := listChatRoles() + slices.Sort(cr) + slices.Sort(msg.KnownTo) + if slices.Equal(cr, msg.KnownTo) { + logger.Info("got msg with tag mentioning every role") + return "", false + } + // Check each character in the KnownTo list + for _, recipient := range msg.KnownTo { + if recipient == msg.Role || recipient == cfg.ToolRole { + // weird cases, skip + continue + } + // Skip if this is the user character (user handles their own turn) + // If user is in KnownTo, stop processing - it's the user's turn + if recipient == cfg.UserRole || recipient == cfg.WriteNextMsgAs { + return "", false + } + return recipient, true + } + return "", false +} + +// triggerPrivateMessageResponses checks if a message was sent privately to specific characters +// and triggers those non-user characters to respond +func triggerPrivateMessageResponses(msg *models.RoleMsg) { + recipient, ok := getValidKnowToRecipient(msg) + if !ok || recipient == "" { + return + } + // Trigger the recipient character to respond + triggerMsg := recipient + ":\n" + // Send empty message so LLM continues naturally from the conversation + crr := &models.ChatRoundReq{ + UserMsg: triggerMsg, + Role: recipient, + Resume: true, + } + fmt.Fprintf(textView, "\n[-:-:b](%d) ", len(chatBody.Messages)) + fmt.Fprint(textView, roleToIcon(recipient)) + fmt.Fprint(textView, "[-:-:-]\n") + chatRoundChan <- crr +} diff --git a/tools.go b/tools.go index 3e5d402..e66533a 100644 --- a/tools.go +++ b/tools.go @@ -207,7 +207,7 @@ var ( modelHasVision bool ) -func init() { +func initTools() { sysMap[basicCard.ID] = basicCard roleToID["assistant"] = basicCard.ID sa, err := searcher.NewWebSurfer(searcher.SearcherTypeScraper, "") @@ -2273,56 +2273,3 @@ var baseTools = []models.Tool{ }, }, } - -func init() { - if windowToolsAvailable { - baseTools = append(baseTools, - models.Tool{ - Type: "function", - Function: models.ToolFunc{ - Name: "list_windows", - Description: "List all visible windows with their IDs and names. Returns a map of window ID to window name.", - Parameters: models.ToolFuncParams{ - Type: "object", - Required: []string{}, - Properties: map[string]models.ToolArgProps{}, - }, - }, - }, - models.Tool{ - Type: "function", - Function: models.ToolFunc{ - Name: "capture_window", - Description: "Capture a screenshot of a specific window and save it to /tmp. Requires window parameter (window ID or name substring).", - Parameters: models.ToolFuncParams{ - Type: "object", - Required: []string{"window"}, - Properties: map[string]models.ToolArgProps{ - "window": models.ToolArgProps{ - Type: "string", - Description: "window ID or window name (partial match)", - }, - }, - }, - }, - }, - models.Tool{ - Type: "function", - Function: models.ToolFunc{ - Name: "capture_window_and_view", - Description: "Capture a screenshot of a specific window, save it to /tmp, and return the image for viewing. Requires window parameter (window ID or name substring).", - Parameters: models.ToolFuncParams{ - Type: "object", - Required: []string{"window"}, - Properties: map[string]models.ToolArgProps{ - "window": models.ToolArgProps{ - Type: "string", - Description: "window ID or window name (partial match)", - }, - }, - }, - }, - }, - ) - } -} diff --git a/tui.go b/tui.go index c6ab392..9c81f7d 100644 --- a/tui.go +++ b/tui.go @@ -224,7 +224,7 @@ func showToast(title, message string) { }) } -func init() { +func initTUI() { // Start background goroutine to update model color cache startModelColorUpdater() tview.Styles = colorschemes["default"] @@ -1173,4 +1173,5 @@ func init() { } return event }) + go updateModelLists() }