summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGrail Finder <wohilas@gmail.com>2025-11-24 12:00:46 +0300
committerGrail Finder <wohilas@gmail.com>2025-11-24 12:00:46 +0300
commit8a62e987894dc6b0b083d23acfcfad9547fa1106 (patch)
tree91f2b3b866874815c162a5333e77e0b6f73f82a4
parent504af1a2132ca51f50ab24cd95f2690a4d45323e (diff)
Fix: apilinks rotation
-rw-r--r--config/config.go29
-rw-r--r--llm.go24
-rw-r--r--main.go1
-rw-r--r--tui.go24
4 files changed, 68 insertions, 10 deletions
diff --git a/config/config.go b/config/config.go
index fab9259..681757d 100644
--- a/config/config.go
+++ b/config/config.go
@@ -84,10 +84,33 @@ func LoadConfig(fn string) (*Config, error) {
config.OpenRouterCompletionAPI: config.OpenRouterChatAPI,
config.OpenRouterChatAPI: config.ChatAPI,
}
- for _, el := range []string{config.ChatAPI, config.CompletionAPI, config.DeepSeekChatAPI, config.DeepSeekCompletionAPI} {
- if el != "" {
- config.ApiLinks = append(config.ApiLinks, el)
+ // Build ApiLinks slice with only non-empty API links
+ // Only include DeepSeek APIs if DeepSeekToken is provided
+ if config.DeepSeekToken != "" {
+ if config.DeepSeekChatAPI != "" {
+ config.ApiLinks = append(config.ApiLinks, config.DeepSeekChatAPI)
}
+ if config.DeepSeekCompletionAPI != "" {
+ config.ApiLinks = append(config.ApiLinks, config.DeepSeekCompletionAPI)
+ }
+ }
+
+ // Only include OpenRouter APIs if OpenRouterToken is provided
+ if config.OpenRouterToken != "" {
+ if config.OpenRouterChatAPI != "" {
+ config.ApiLinks = append(config.ApiLinks, config.OpenRouterChatAPI)
+ }
+ if config.OpenRouterCompletionAPI != "" {
+ config.ApiLinks = append(config.ApiLinks, config.OpenRouterCompletionAPI)
+ }
+ }
+
+ // Always include basic APIs
+ if config.ChatAPI != "" {
+ config.ApiLinks = append(config.ApiLinks, config.ChatAPI)
+ }
+ if config.CompletionAPI != "" {
+ config.ApiLinks = append(config.ApiLinks, config.CompletionAPI)
}
// if any value is empty fill with default
return config, nil
diff --git a/llm.go b/llm.go
index a63317e..d22ede2 100644
--- a/llm.go
+++ b/llm.go
@@ -205,7 +205,6 @@ func (op OpenAIer) FormMsg(msg, role string, resume bool) (io.Reader, error) {
newMsg = models.NewRoleMsg(role, msg)
}
chatBody.Messages = append(chatBody.Messages, newMsg)
-
// if rag - add as system message to avoid conflicts with tool usage
if cfg.RAGEnabled {
ragResp, err := chatRagUse(newMsg.Content)
@@ -485,7 +484,28 @@ func (or OpenRouterChat) FormMsg(msg, role string, resume bool) (io.Reader, erro
chatBody.Messages = append(chatBody.Messages, models.RoleMsg{Role: cfg.ToolRole, Content: toolSysMsg})
}
if msg != "" { // otherwise let the bot continue
- newMsg := models.RoleMsg{Role: role, Content: msg}
+ var newMsg models.RoleMsg
+ // Check if we have an image to add to this message
+ if imageAttachmentPath != "" {
+ // Create a multimodal message with both text and image
+ newMsg = models.NewMultimodalMsg(role, []interface{}{})
+ // Add the text content
+ newMsg.AddTextPart(msg)
+ // Add the image content
+ imageURL, err := models.CreateImageURLFromPath(imageAttachmentPath)
+ if err != nil {
+ logger.Error("failed to create image URL from path", "error", err, "path", imageAttachmentPath)
+ // If image processing fails, fall back to simple text message
+ newMsg = models.NewRoleMsg(role, msg)
+ imageAttachmentPath = "" // Clear the attachment
+ } else {
+ newMsg.AddImagePart(imageURL)
+ imageAttachmentPath = "" // Clear the attachment after use
+ }
+ } else {
+ // Create a simple text message
+ newMsg = models.NewRoleMsg(role, msg)
+ }
chatBody.Messages = append(chatBody.Messages, newMsg)
// if rag - add as system message to avoid conflicts with tool usage
if cfg.RAGEnabled {
diff --git a/main.go b/main.go
index 94aa9f7..6aeedbe 100644
--- a/main.go
+++ b/main.go
@@ -13,6 +13,7 @@ var (
editMode = false
injectRole = true
selectedIndex = int(-1)
+ currentAPIIndex = 0 // Index to track current API in ApiLinks slice
// indexLine = "F12 to show keys help | bot resp mode: [orange:-:b]%v[-:-:-] (F6) | card's char: [orange:-:b]%s[-:-:-] (ctrl+s) | chat: [orange:-:b]%s[-:-:-] (F1) | toolUseAdviced: [orange:-:b]%v[-:-:-] (ctrl+k) | model: [orange:-:b]%s[-:-:-] (ctrl+l) | skip LLM resp: [orange:-:b]%v[-:-:-] (F10)\nAPI_URL: [orange:-:b]%s[-:-:-] (ctrl+v) | ThinkUse: [orange:-:b]%v[-:-:-] (ctrl+p) | Log Level: [orange:-:b]%v[-:-:-] (ctrl+p) | Recording: [orange:-:b]%v[-:-:-] (ctrl+r) | Writing as: [orange:-:b]%s[-:-:-] (ctrl+q)"
indexLineCompletion = "F12 to show keys help | bot resp mode: [orange:-:b]%v[-:-:-] (F6) | card's char: [orange:-:b]%s[-:-:-] (ctrl+s) | chat: [orange:-:b]%s[-:-:-] (F1) | toolUseAdviced: [orange:-:b]%v[-:-:-] (ctrl+k) | model: [orange:-:b]%s[-:-:-] (ctrl+l) | skip LLM resp: [orange:-:b]%v[-:-:-] (F10)\nAPI_URL: [orange:-:b]%s[-:-:-] (ctrl+v) | ThinkUse: [orange:-:b]%v[-:-:-] (ctrl+p) | Log Level: [orange:-:b]%v[-:-:-] (ctrl+p) | Recording: [orange:-:b]%v[-:-:-] (ctrl+r) | Writing as: [orange:-:b]%s[-:-:-] (ctrl+q) | Bot will write as [orange:-:b]%s[-:-:-] (ctrl+x) | role_inject [orange:-:b]%v[-:-:-]"
focusSwitcher = map[tview.Primitive]tview.Primitive{}
diff --git a/tui.go b/tui.go
index 89c636e..714b710 100644
--- a/tui.go
+++ b/tui.go
@@ -764,13 +764,27 @@ func init() {
return nil
}
if event.Key() == tcell.KeyCtrlV {
- // switch between /chat and /completion api
- newAPI := cfg.APIMap[cfg.CurrentAPI]
- if newAPI == "" {
- // do not switch
+ // switch between API links using index-based rotation
+ if len(cfg.ApiLinks) == 0 {
+ // No API links to rotate through
return nil
}
- cfg.CurrentAPI = newAPI
+ // Find current API in the list to get the current index
+ currentIndex := -1
+ for i, api := range cfg.ApiLinks {
+ if api == cfg.CurrentAPI {
+ currentIndex = i
+ break
+ }
+ }
+ // If current API is not in the list, start from beginning
+ // Otherwise, advance to next API in the list (with wrap-around)
+ if currentIndex == -1 {
+ currentAPIIndex = 0
+ } else {
+ currentAPIIndex = (currentIndex + 1) % len(cfg.ApiLinks)
+ }
+ cfg.CurrentAPI = cfg.ApiLinks[currentAPIIndex]
choseChunkParser()
updateStatusLine()
return nil