summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--bot.go44
-rw-r--r--helpfuncs.go21
-rw-r--r--popups.go20
-rw-r--r--props_table.go8
-rw-r--r--session.go16
-rw-r--r--tables.go44
-rw-r--r--tools.go2
-rw-r--r--tui.go102
8 files changed, 74 insertions, 183 deletions
diff --git a/bot.go b/bot.go
index 60d8f22..d1f4eaa 100644
--- a/bot.go
+++ b/bot.go
@@ -268,9 +268,7 @@ func warmUpModel() {
// Continue with warmup attempt anyway
}
if loaded {
- if err := notifyUser("model already loaded", "Model "+chatBody.Model+" is already loaded."); err != nil {
- logger.Debug("failed to notify user", "error", err)
- }
+ showToast("model already loaded", "Model "+chatBody.Model+" is already loaded.")
return
}
go func() {
@@ -483,9 +481,7 @@ func monitorModelLoad(modelID string) {
continue
}
if loaded {
- if err := notifyUser("model loaded", "Model "+modelID+" is now loaded and ready."); err != nil {
- logger.Debug("failed to notify user", "error", err)
- }
+ showToast("model loaded", "Model "+modelID+" is now loaded and ready.")
refreshChatDisplay()
return
}
@@ -572,9 +568,7 @@ func sendMsgToLLM(body io.Reader) {
req, err := http.NewRequest("POST", cfg.CurrentAPI, body)
if err != nil {
logger.Error("newreq error", "error", err)
- if err := notifyUser("error", "apicall failed:"+err.Error()); err != nil {
- logger.Error("failed to notify", "error", err)
- }
+ showToast("error", "apicall failed:"+err.Error())
streamDone <- true
return
}
@@ -586,9 +580,7 @@ func sendMsgToLLM(body io.Reader) {
resp, err := httpClient.Do(req)
if err != nil {
logger.Error("llamacpp api", "error", err)
- if err := notifyUser("error", "apicall failed:"+err.Error()); err != nil {
- logger.Error("failed to notify", "error", err)
- }
+ showToast("error", "apicall failed:"+err.Error())
streamDone <- true
return
}
@@ -599,9 +591,7 @@ func sendMsgToLLM(body io.Reader) {
if err != nil {
logger.Error("failed to read error response body", "error", err, "status_code", resp.StatusCode)
detailedError := fmt.Sprintf("HTTP Status: %d, Failed to read response body: %v", resp.StatusCode, err)
- if err := notifyUser("API Error", detailedError); err != nil {
- logger.Error("failed to notify", "error", err)
- }
+ showToast("API Error", detailedError)
resp.Body.Close()
streamDone <- true
return
@@ -609,9 +599,7 @@ func sendMsgToLLM(body io.Reader) {
// Parse the error response for detailed information
detailedError := extractDetailedErrorFromBytes(bodyBytes, resp.StatusCode)
logger.Error("API returned error status", "status_code", resp.StatusCode, "detailed_error", detailedError)
- if err := notifyUser("API Error", detailedError); err != nil {
- logger.Error("failed to notify", "error", err)
- }
+ showToast("API Error", detailedError)
resp.Body.Close()
streamDone <- true
return
@@ -648,16 +636,12 @@ func sendMsgToLLM(body io.Reader) {
detailedError := fmt.Sprintf("Streaming connection closed unexpectedly (Status: %d). This may indicate an API error. Check your API provider and model settings.", resp.StatusCode)
logger.Error("error reading response body", "error", err, "detailed_error", detailedError,
"status_code", resp.StatusCode, "user_role", cfg.UserRole, "parser", chunkParser, "link", cfg.CurrentAPI)
- if err := notifyUser("API Error", detailedError); err != nil {
- logger.Error("failed to notify", "error", err)
- }
+ showToast("API Error", detailedError)
} else {
logger.Error("error reading response body", "error", err, "line", string(line),
"user_role", cfg.UserRole, "parser", chunkParser, "link", cfg.CurrentAPI)
// if err.Error() != "EOF" {
- if err := notifyUser("API error", err.Error()); err != nil {
- logger.Error("failed to notify", "error", err)
- }
+ showToast("API error", err.Error())
}
streamDone <- true
break
@@ -684,9 +668,7 @@ func sendMsgToLLM(body io.Reader) {
if err != nil {
logger.Error("error parsing response body", "error", err,
"line", string(line), "url", cfg.CurrentAPI)
- if err := notifyUser("LLM Response Error", "Failed to parse LLM response: "+err.Error()); err != nil {
- logger.Error("failed to notify user", "error", err)
- }
+ showToast("LLM Response Error", "Failed to parse LLM response: "+err.Error())
streamDone <- true
break
}
@@ -1456,15 +1438,15 @@ func refreshLocalModelsIfEmpty() {
func summarizeAndStartNewChat() {
if len(chatBody.Messages) == 0 {
- _ = notifyUser("info", "No chat history to summarize")
+ showToast("info", "No chat history to summarize")
return
}
- _ = notifyUser("info", "Summarizing chat history...")
+ showToast("info", "Summarizing chat history...")
// Call the summarize_chat tool via agent
summaryBytes := callToolWithAgent("summarize_chat", map[string]string{})
summary := string(summaryBytes)
if summary == "" {
- _ = notifyUser("error", "Failed to generate summary")
+ showToast("error", "Failed to generate summary")
return
}
// Start a new chat
@@ -1483,7 +1465,7 @@ func summarizeAndStartNewChat() {
if err := updateStorageChat(activeChatName, chatBody.Messages); err != nil {
logger.Warn("failed to update storage after injecting summary", "error", err)
}
- _ = notifyUser("info", "Chat summarized and new chat started with summary as tool response")
+ showToast("info", "Chat summarized and new chat started with summary as tool response")
}
func init() {
diff --git a/helpfuncs.go b/helpfuncs.go
index 3132c9d..038e275 100644
--- a/helpfuncs.go
+++ b/helpfuncs.go
@@ -491,10 +491,7 @@ func listChatRoles() []string {
func deepseekModelValidator() error {
if cfg.CurrentAPI == cfg.DeepSeekChatAPI || cfg.CurrentAPI == cfg.DeepSeekCompletionAPI {
if chatBody.Model != "deepseek-chat" && chatBody.Model != "deepseek-reasoner" {
- if err := notifyUser("bad request", "wrong deepseek model name"); err != nil {
- logger.Warn("failed ot notify user", "error", err)
- return err
- }
+ showToast("bad request", "wrong deepseek model name")
return nil
}
}
@@ -694,9 +691,7 @@ func performSearch(term string) {
searchResults = nil
searchResultLengths = nil
notification := "Pattern not found: " + term
- if err := notifyUser("search", notification); err != nil {
- logger.Error("failed to send notification", "error", err)
- }
+ showToast("search", notification)
return
}
// Store the formatted text positions and lengths for accurate highlighting
@@ -729,9 +724,7 @@ func highlightCurrentMatch() {
textView.Highlight(currentRegion).ScrollToHighlight()
// Send notification about which match we're at
notification := fmt.Sprintf("Match %d of %d", searchIndex+1, len(searchResults))
- if err := notifyUser("search", notification); err != nil {
- logger.Error("failed to send notification", "error", err)
- }
+ showToast("search", notification)
}
// showSearchBar shows the search input field as an overlay
@@ -821,9 +814,7 @@ func addRegionTags(text string, positions []int, lengths []int, currentIdx int,
// searchNext finds the next occurrence of the search term
func searchNext() {
if len(searchResults) == 0 {
- if err := notifyUser("search", "No search results to navigate"); err != nil {
- logger.Error("failed to send notification", "error", err)
- }
+ showToast("search", "No search results to navigate")
return
}
searchIndex = (searchIndex + 1) % len(searchResults)
@@ -833,9 +824,7 @@ func searchNext() {
// searchPrev finds the previous occurrence of the search term
func searchPrev() {
if len(searchResults) == 0 {
- if err := notifyUser("search", "No search results to navigate"); err != nil {
- logger.Error("failed to send notification", "error", err)
- }
+ showToast("search", "No search results to navigate")
return
}
if searchIndex == 0 {
diff --git a/popups.go b/popups.go
index eae50a3..38f42cd 100644
--- a/popups.go
+++ b/popups.go
@@ -40,9 +40,7 @@ func showModelSelectionPopup() {
default:
message = "No llama.cpp models loaded. Ensure llama.cpp server is running with models."
}
- if err := notifyUser("Empty list", message); err != nil {
- logger.Error("failed to send notification", "error", err)
- }
+ showToast("Empty list", message)
return
}
// Create a list primitive
@@ -119,9 +117,7 @@ func showAPILinkSelectionPopup() {
if len(apiLinks) == 0 {
logger.Warn("no API links available for selection")
message := "No API links available. Please configure API links in your config file."
- if err := notifyUser("Empty list", message); err != nil {
- logger.Error("failed to send notification", "error", err)
- }
+ showToast("Empty list", message)
return
}
// Create a list primitive
@@ -206,9 +202,7 @@ func showUserRoleSelectionPopup() {
if len(roles) == 0 {
logger.Warn("no roles available for selection")
message := "No roles available for selection."
- if err := notifyUser("Empty list", message); err != nil {
- logger.Error("failed to send notification", "error", err)
- }
+ showToast("Empty list", message)
return
}
// Create a list primitive
@@ -285,9 +279,7 @@ func showBotRoleSelectionPopup() {
if len(roles) == 0 {
logger.Warn("no roles available for selection")
message := "No roles available for selection."
- if err := notifyUser("Empty list", message); err != nil {
- logger.Error("failed to send notification", "error", err)
- }
+ showToast("Empty list", message)
return
}
// Create a list primitive
@@ -512,9 +504,7 @@ func showColorschemeSelectionPopup() {
if len(schemeNames) == 0 {
logger.Warn("no colorschemes available for selection")
message := "No colorschemes available."
- if err := notifyUser("Empty list", message); err != nil {
- logger.Error("failed to send notification", "error", err)
- }
+ showToast("Empty list", message)
return
}
// Create a list primitive
diff --git a/props_table.go b/props_table.go
index f8432cd..ec66812 100644
--- a/props_table.go
+++ b/props_table.go
@@ -259,9 +259,7 @@ func makePropsTable(props map[string]float32) *tview.Table {
// Handle nil options
if data.Options == nil {
logger.Error("options list is nil for", "label", label)
- if err := notifyUser("Configuration error", "Options list is nil for "+label); err != nil {
- logger.Error("failed to send notification", "error", err)
- }
+ showToast("Configuration error", "Options list is nil for "+label)
return
}
@@ -279,9 +277,7 @@ func makePropsTable(props map[string]float32) *tview.Table {
message = "No llama.cpp models loaded. Ensure llama.cpp server is running with models."
}
}
- if err := notifyUser("Empty list", message); err != nil {
- logger.Error("failed to send notification", "error", err)
- }
+ showToast("Empty list", message)
return
}
// Create a list primitive
diff --git a/session.go b/session.go
index 42d5001..980d998 100644
--- a/session.go
+++ b/session.go
@@ -168,19 +168,3 @@ func copyToClipboard(text string) error {
cmd.Stdin = strings.NewReader(text)
return cmd.Run()
}
-
-func notifyUser(topic, message string) error {
- // Sanitize message to remove control characters that notify-send doesn't handle
- sanitized := strings.Map(func(r rune) rune {
- if r < 32 && r != '\t' {
- return -1
- }
- return r
- }, message)
- // Truncate if too long
- if len(sanitized) > 200 {
- sanitized = sanitized[:197] + "..."
- }
- cmd := exec.Command("notify-send", topic, sanitized)
- return cmd.Run()
-}
diff --git a/tables.go b/tables.go
index 0cec551..baa1c36 100644
--- a/tables.go
+++ b/tables.go
@@ -147,9 +147,7 @@ func makeChatTable(chatMap map[string]models.Chat) *tview.Table {
if err := store.RemoveChat(sc.ID); err != nil {
logger.Error("failed to remove chat from db", "chat_id", sc.ID, "chat_name", sc.Name)
}
- if err := notifyUser("chat deleted", selectedChat+" was deleted"); err != nil {
- logger.Error("failed to send notification", "error", err)
- }
+ showToast("chat deleted", selectedChat+" was deleted")
// load last chat
chatBody.Messages = loadOldChatOrGetNew()
textView.SetText(chatToText(chatBody.Messages, cfg.ShowSys))
@@ -162,9 +160,7 @@ func makeChatTable(chatMap map[string]models.Chat) *tview.Table {
cc := GetCardByRole(agentName)
if cc == nil {
logger.Warn("no such card", "agent", agentName)
- if err := notifyUser("error", "no such card: "+agentName); err != nil {
- logger.Warn("failed ot notify", "error", err)
- }
+ showToast("error", "no such card: "+agentName)
return
}
cc.SysPrompt = chatBody.Messages[0].Content
@@ -186,9 +182,7 @@ func makeChatTable(chatMap map[string]models.Chat) *tview.Table {
cc := GetCardByRole(agentName)
if cc == nil {
logger.Warn("no such card", "agent", agentName)
- if err := notifyUser("error", "no such card: "+agentName); err != nil {
- logger.Warn("failed to notify", "error", err)
- }
+ showToast("error", "no such card: "+agentName)
return
}
newCard, err := pngmeta.ReadCard(cc.FilePath, cfg.UserRole)
@@ -197,9 +191,7 @@ func makeChatTable(chatMap map[string]models.Chat) *tview.Table {
newCard, err = pngmeta.ReadCardJson(cc.FilePath)
if err != nil {
logger.Error("failed to reload charcard", "path", cc.FilePath, "error", err)
- if err := notifyUser("error", "failed to reload card: "+cc.FilePath); err != nil {
- logger.Warn("failed to notify", "error", err)
- }
+ showToast("error", "failed to reload card: "+cc.FilePath)
return
}
}
@@ -448,13 +440,13 @@ func makeRAGTable(fileList []string, loadedFiles []string) *tview.Flex {
go func() {
if err := ragger.LoadRAG(fpath); err != nil {
logger.Error("failed to embed file", "chat", fpath, "error", err)
- _ = notifyUser("RAG", "failed to embed file; error: "+err.Error())
+ showToast("RAG", "failed to embed file; error: "+err.Error())
app.QueueUpdate(func() {
pages.RemovePage(RAGPage)
})
return
}
- _ = notifyUser("RAG", "file loaded successfully")
+ showToast("RAG", "file loaded successfully")
app.QueueUpdate(func() {
pages.RemovePage(RAGPage)
})
@@ -465,13 +457,13 @@ func makeRAGTable(fileList []string, loadedFiles []string) *tview.Flex {
go func() {
if err := ragger.RemoveFile(f.name); err != nil {
logger.Error("failed to unload file from RAG", "filename", f.name, "error", err)
- _ = notifyUser("RAG", "failed to unload file; error: "+err.Error())
+ showToast("RAG", "failed to unload file; error: "+err.Error())
app.QueueUpdate(func() {
pages.RemovePage(RAGPage)
})
return
}
- _ = notifyUser("RAG", "file unloaded successfully")
+ showToast("RAG", "file unloaded successfully")
app.QueueUpdate(func() {
pages.RemovePage(RAGPage)
})
@@ -483,9 +475,7 @@ func makeRAGTable(fileList []string, loadedFiles []string) *tview.Flex {
logger.Error("failed to delete file", "filename", fpath, "error", err)
return
}
- if err := notifyUser("chat deleted", fpath+" was deleted"); err != nil {
- logger.Error("failed to send notification", "error", err)
- }
+ showToast("chat deleted", fpath+" was deleted")
return
default:
pages.RemovePage(RAGPage)
@@ -594,9 +584,7 @@ func makeAgentTable(agentList []string) *tview.Table {
if err := store.RemoveChat(sc.ID); err != nil {
logger.Error("failed to remove chat from db", "chat_id", sc.ID, "chat_name", sc.Name)
}
- if err := notifyUser("chat deleted", selected+" was deleted"); err != nil {
- logger.Error("failed to send notification", "error", err)
- }
+ showToast("chat deleted", selected+" was deleted")
pages.RemovePage(agentPage)
return
default:
@@ -667,13 +655,9 @@ func makeCodeBlockTable(codeBlocks []string) *tview.Table {
switch tc.Text {
case "copy":
if err := copyToClipboard(selected); err != nil {
- if err := notifyUser("error", err.Error()); err != nil {
- logger.Error("failed to send notification", "error", err)
- }
- }
- if err := notifyUser("copied", selected); err != nil {
- logger.Error("failed to send notification", "error", err)
+ showToast("error", err.Error())
}
+ showToast("copied", selected)
pages.RemovePage(codeBlockPage)
app.SetFocus(textArea)
return
@@ -766,9 +750,7 @@ func makeImportChatTable(filenames []string) *tview.Table {
if err := store.RemoveChat(sc.ID); err != nil {
logger.Error("failed to remove chat from db", "chat_id", sc.ID, "chat_name", sc.Name)
}
- if err := notifyUser("chat deleted", selected+" was deleted"); err != nil {
- logger.Error("failed to send notification", "error", err)
- }
+ showToast("chat deleted", selected+" was deleted")
pages.RemovePage(historyPage)
return
default:
diff --git a/tools.go b/tools.go
index 84ef23d..8cca673 100644
--- a/tools.go
+++ b/tools.go
@@ -268,7 +268,7 @@ func updateToolCapabilities() {
} else {
logger.Info("model does not have vision support", "model", cfg.CurrentModel, "api", cfg.CurrentAPI)
if windowToolsAvailable && !prevHasVision && !modelHasVision {
- _ = notifyUser("window tools", "Window capture-and-view unavailable: model lacks vision support")
+ showToast("window tools", "Window capture-and-view unavailable: model lacks vision support")
}
}
registerWindowTools()
diff --git a/tui.go b/tui.go
index 67f2775..b23c3ff 100644
--- a/tui.go
+++ b/tui.go
@@ -140,7 +140,20 @@ func setShellMode(enabled bool) {
// showToast displays a temporary message in the top‑right corner.
// It auto‑hides after 3 seconds and disappears when clicked.
func showToast(title, message string) {
- // Create a small, bordered text view for the notification.
+ sanitize := func(s string, maxLen int) string {
+ sanitized := strings.Map(func(r rune) rune {
+ if r < 32 && r != '\t' {
+ return -1
+ }
+ return r
+ }, s)
+ if len(sanitized) > maxLen {
+ sanitized = sanitized[:maxLen-3] + "..."
+ }
+ return sanitized
+ }
+ title = sanitize(title, 50)
+ message = sanitize(message, 197)
notification := tview.NewTextView().
SetTextAlign(tview.AlignCenter).
SetDynamicColors(true).
@@ -363,9 +376,7 @@ func init() {
defer colorText()
editedMsg := editArea.GetText()
if editedMsg == "" {
- if err := notifyUser("edit", "no edit provided"); err != nil {
- logger.Error("failed to send notification", "error", err)
- }
+ showToast("edit", "no edit provided")
pages.RemovePage(editMsgPage)
return nil
}
@@ -395,9 +406,7 @@ func init() {
case tcell.KeyEnter:
newRole := roleEditWindow.GetText()
if newRole == "" {
- if err := notifyUser("edit", "no role provided"); err != nil {
- logger.Error("failed to send notification", "error", err)
- }
+ showToast("edit", "no role provided")
pages.RemovePage(roleEditPage)
return
}
@@ -424,9 +433,7 @@ func init() {
siInt, err := strconv.Atoi(si)
if err != nil {
logger.Error("failed to convert provided index", "error", err, "si", si)
- if err := notifyUser("cancel", "no index provided, copying user input"); err != nil {
- logger.Error("failed to send notification", "error", err)
- }
+ showToast("cancel", "no index provided, copying user input")
if err := copyToClipboard(textArea.GetText()); err != nil {
logger.Error("failed to copy to clipboard", "error", err)
}
@@ -437,9 +444,7 @@ func init() {
if len(chatBody.Messages)-1 < selectedIndex || selectedIndex < 0 {
msg := "chosen index is out of bounds, will copy user input"
logger.Warn(msg, "index", selectedIndex)
- if err := notifyUser("error", msg); err != nil {
- logger.Error("failed to send notification", "error", err)
- }
+ showToast("error", msg)
if err := copyToClipboard(textArea.GetText()); err != nil {
logger.Error("failed to copy to clipboard", "error", err)
}
@@ -465,9 +470,7 @@ func init() {
}
previewLen := min(30, len(msgText))
notification := fmt.Sprintf("msg '%s' was copied to the clipboard", msgText[:previewLen])
- if err := notifyUser("copied", notification); err != nil {
- logger.Error("failed to send notification", "error", err)
- }
+ showToast("copied", notification)
hideIndexBar() // Hide overlay after copying
}
return nil
@@ -499,9 +502,7 @@ func init() {
logger.Error("failed to upsert chat", "error", err, "chat", currentChat)
}
notification := fmt.Sprintf("renamed chat to '%s'", activeChatName)
- if err := notifyUser("renamed", notification); err != nil {
- logger.Error("failed to send notification", "error", err)
- }
+ showToast("renamed", notification)
}
return event
})
@@ -612,9 +613,6 @@ func init() {
status = "enabled"
}
showToast("autoscroll", "Auto-scrolling "+status)
- if err := notifyUser("autoscroll", "Auto-scrolling "+status); err != nil {
- logger.Error("failed to send notification", "error", err)
- }
updateStatusLine()
}
// Handle Alt+7 to toggle injectRole
@@ -631,9 +629,7 @@ func init() {
if thinkingCollapsed {
status = "collapsed"
}
- if err := notifyUser("thinking", "Thinking blocks "+status); err != nil {
- logger.Error("failed to send notification", "error", err)
- }
+ showToast("thinking", "Thinking blocks "+status)
return nil
}
// Handle Ctrl+T to toggle tool call/response visibility
@@ -645,9 +641,7 @@ func init() {
if toolCollapsed {
status = "collapsed"
}
- if err := notifyUser("tools", "Tool calls/responses "+status); err != nil {
- logger.Error("failed to send notification", "error", err)
- }
+ showToast("tools", "Tool calls/responses "+status)
return nil
}
if event.Key() == tcell.KeyRune && event.Rune() == 'i' && event.Modifiers()&tcell.ModAlt != 0 {
@@ -667,9 +661,7 @@ func init() {
// Check if there are no chats for this agent
if len(chatList) == 0 {
notification := "no chats found for agent: " + cfg.AssistantRole
- if err := notifyUser("info", notification); err != nil {
- logger.Error("failed to send notification", "error", err)
- }
+ showToast("info", notification)
return nil
}
chatMap := make(map[string]models.Chat)
@@ -687,9 +679,7 @@ func init() {
if event.Key() == tcell.KeyF2 && !botRespMode {
// regen last msg
if len(chatBody.Messages) == 0 {
- if err := notifyUser("info", "no messages to regenerate"); err != nil {
- logger.Error("failed to send notification", "error", err)
- }
+ showToast("info", "no messages to regenerate")
return nil
}
chatBody.Messages = chatBody.Messages[:len(chatBody.Messages)-1]
@@ -715,9 +705,7 @@ func init() {
return nil
}
if len(chatBody.Messages) == 0 {
- if err := notifyUser("info", "no messages to delete"); err != nil {
- logger.Error("failed to send notification", "error", err)
- }
+ showToast("info", "no messages to delete")
return nil
}
chatBody.Messages = chatBody.Messages[:len(chatBody.Messages)-1]
@@ -776,9 +764,7 @@ func init() {
}
previewLen := min(30, len(msgText))
notification := fmt.Sprintf("msg '%s' was copied to the clipboard", msgText[:previewLen])
- if err := notifyUser("copied", notification); err != nil {
- logger.Error("failed to send notification", "error", err)
- }
+ showToast("copied", notification)
return nil
}
if event.Key() == tcell.KeyF8 {
@@ -792,9 +778,7 @@ func init() {
text := textView.GetText(false)
cb := codeBlockRE.FindAllString(text, -1)
if len(cb) == 0 {
- if err := notifyUser("notify", "no code blocks in chat"); err != nil {
- logger.Error("failed to send notification", "error", err)
- }
+ showToast("notify", "no code blocks in chat")
return nil
}
table := makeCodeBlockTable(cb)
@@ -809,9 +793,7 @@ func init() {
// read files in chat_exports
filelist, err := os.ReadDir(exportDir)
if err != nil {
- if err := notifyUser("failed to load exports", err.Error()); err != nil {
- logger.Error("failed to send notification", "error", err)
- }
+ showToast("failed to load exports", err.Error())
return nil
}
fli := []string{}
@@ -841,9 +823,7 @@ func init() {
logger.Error("failed to export chat;", "error", err, "chat_name", activeChatName)
return nil
}
- if err := notifyUser("exported chat", "chat: "+activeChatName+" was exported"); err != nil {
- logger.Error("failed to send notification", "error", err)
- }
+ showToast("exported chat", "chat: "+activeChatName+" was exported")
return nil
}
if event.Key() == tcell.KeyCtrlP {
@@ -882,9 +862,7 @@ func init() {
labels, err := initSysCards()
if err != nil {
logger.Error("failed to read sys dir", "error", err)
- if err := notifyUser("error", "failed to read: "+cfg.SysDir); err != nil {
- logger.Debug("failed to notify user", "error", err)
- }
+ showToast("error", "failed to read: "+cfg.SysDir)
return nil
}
at := makeAgentTable(labels)
@@ -941,9 +919,7 @@ func init() {
if err != nil {
msg := "failed to inference user speech; error:" + err.Error()
logger.Error(msg)
- if err := notifyUser("stt error", msg); err != nil {
- logger.Error("failed to notify user", "error", err)
- }
+ showToast("stt error", msg)
return nil
}
if userSpeech != "" {
@@ -1023,26 +999,20 @@ func init() {
// Create the RAG directory if it doesn't exist
if mkdirErr := os.MkdirAll(cfg.RAGDir, 0755); mkdirErr != nil {
logger.Error("failed to create RAG directory", "dir", cfg.RAGDir, "error", mkdirErr)
- if notifyerr := notifyUser("failed to create RAG directory", mkdirErr.Error()); notifyerr != nil {
- logger.Error("failed to send notification", "error", notifyerr)
- }
+ showToast("failed to create RAG directory", mkdirErr.Error())
return nil
}
// Now try to read the directory again after creating it
files, err = os.ReadDir(cfg.RAGDir)
if err != nil {
logger.Error("failed to read dir after creating it", "dir", cfg.RAGDir, "error", err)
- if notifyerr := notifyUser("failed to read RAG directory", err.Error()); notifyerr != nil {
- logger.Error("failed to send notification", "error", notifyerr)
- }
+ showToast("failed to read RAG directory", err.Error())
return nil
}
} else {
// Other error (permissions, etc.)
logger.Error("failed to read dir", "dir", cfg.RAGDir, "error", err)
- if notifyerr := notifyUser("failed to open RAG files dir", err.Error()); notifyerr != nil {
- logger.Error("failed to send notification", "error", notifyerr)
- }
+ showToast("failed to open RAG files dir", err.Error())
return nil
}
}
@@ -1072,9 +1042,7 @@ func init() {
if event.Key() == tcell.KeyRune && event.Modifiers() == tcell.ModAlt && event.Rune() == '9' {
// Warm up (load) the currently selected model
go warmUpModel()
- if err := notifyUser("model warmup", "loading model: "+chatBody.Model); err != nil {
- logger.Debug("failed to notify user", "error", err)
- }
+ showToast("model warmup", "loading model: "+chatBody.Model)
return nil
}
// cannot send msg in editMode or botRespMode