summaryrefslogtreecommitdiff
path: root/helpfuncs.go
diff options
context:
space:
mode:
Diffstat (limited to 'helpfuncs.go')
-rw-r--r--helpfuncs.go82
1 files changed, 65 insertions, 17 deletions
diff --git a/helpfuncs.go b/helpfuncs.go
index 038e275..e28beda 100644
--- a/helpfuncs.go
+++ b/helpfuncs.go
@@ -5,7 +5,6 @@ import (
"gf-lt/models"
"gf-lt/pngmeta"
"image"
- "net/url"
"os"
"os/exec"
"path"
@@ -13,6 +12,7 @@ import (
"slices"
"strconv"
"strings"
+ "sync/atomic"
"time"
"unicode"
@@ -20,7 +20,8 @@ import (
)
// Cached model color - updated by background goroutine
-var cachedModelColor string = "orange"
+// var cachedModelColor string = "orange"
+var cachedModelColor atomic.Value
// startModelColorUpdater starts a background goroutine that periodically updates
// the cached model color. Only runs HTTP requests for local llama.cpp APIs.
@@ -39,20 +40,20 @@ func startModelColorUpdater() {
// updateCachedModelColor updates the global cachedModelColor variable
func updateCachedModelColor() {
if !isLocalLlamacpp() {
- cachedModelColor = "orange"
+ cachedModelColor.Store("orange")
return
}
// Check if model is loaded
loaded, err := isModelLoaded(chatBody.Model)
if err != nil {
// On error, assume not loaded (red)
- cachedModelColor = "red"
+ cachedModelColor.Store("red")
return
}
if loaded {
- cachedModelColor = "green"
+ cachedModelColor.Store("green")
} else {
- cachedModelColor = "red"
+ cachedModelColor.Store("red")
}
}
@@ -108,7 +109,7 @@ func refreshChatDisplay() {
textView.SetText(displayText)
colorText()
updateStatusLine()
- if scrollToEndEnabled {
+ if cfg.AutoScrollEnabled {
textView.ScrollToEnd()
}
}
@@ -323,19 +324,17 @@ func strInSlice(s string, sl []string) bool {
// isLocalLlamacpp checks if the current API is a local llama.cpp instance.
func isLocalLlamacpp() bool {
- u, err := url.Parse(cfg.CurrentAPI)
- if err != nil {
+ if strings.Contains(cfg.CurrentAPI, "openrouter") || strings.Contains(cfg.CurrentAPI, "deepseek") {
return false
}
- host := u.Hostname()
- return host == "localhost" || host == "127.0.0.1" || host == "::1"
+ return true
}
// getModelColor returns the cached color tag for the model name.
// The cached value is updated by a background goroutine every 5 seconds.
// For non-local models, returns orange. For local llama.cpp models, returns green if loaded, red if not.
func getModelColor() string {
- return cachedModelColor
+ return cachedModelColor.Load().(string)
}
func makeStatusLine() string {
@@ -521,7 +520,7 @@ func updateFlexLayout() {
if shellMode {
flex.AddItem(shellInput, 0, 10, false)
} else {
- flex.AddItem(textArea, 0, 10, false)
+ flex.AddItem(bottomFlex, 0, 10, true)
}
if positionVisible {
flex.AddItem(statusLineWidget, 0, 2, false)
@@ -542,7 +541,7 @@ func executeCommandAndDisplay(cmdText string) {
cmdText = strings.TrimSpace(cmdText)
if cmdText == "" {
fmt.Fprintf(textView, "\n[red]Error: No command provided[-:-:-]\n")
- if scrollToEndEnabled {
+ if cfg.AutoScrollEnabled {
textView.ScrollToEnd()
}
colorText()
@@ -574,7 +573,7 @@ func executeCommandAndDisplay(cmdText string) {
Content: "$ " + cmdText + "\n\n" + outputContent,
}
chatBody.Messages = append(chatBody.Messages, combinedMsg)
- if scrollToEndEnabled {
+ if cfg.AutoScrollEnabled {
textView.ScrollToEnd()
}
colorText()
@@ -589,7 +588,7 @@ func executeCommandAndDisplay(cmdText string) {
Content: "$ " + cmdText + "\n\n" + outputContent,
}
chatBody.Messages = append(chatBody.Messages, combinedMsg)
- if scrollToEndEnabled {
+ if cfg.AutoScrollEnabled {
textView.ScrollToEnd()
}
colorText()
@@ -637,7 +636,7 @@ func executeCommandAndDisplay(cmdText string) {
}
chatBody.Messages = append(chatBody.Messages, combinedMsg)
// Scroll to end and update colors
- if scrollToEndEnabled {
+ if cfg.AutoScrollEnabled {
textView.ScrollToEnd()
}
colorText()
@@ -967,3 +966,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
+}