diff options
author | Grail Finder <wohilas@gmail.com> | 2025-01-15 16:46:59 +0300 |
---|---|---|
committer | Grail Finder <wohilas@gmail.com> | 2025-01-15 16:46:59 +0300 |
commit | 1ea19ba11ec835370399fce9de3954ca2f58829c (patch) | |
tree | 0d613f1418bb04fd03e36146177e952192391923 | |
parent | 85f96aa4013f9cedaf333c6d1027fe6d901cf561 (diff) |
Feat (status line): add model name
-rw-r--r-- | README.md | 8 | ||||
-rw-r--r-- | bot.go | 51 | ||||
-rw-r--r-- | main.go | 2 | ||||
-rw-r--r-- | models/models.go | 18 | ||||
-rw-r--r-- | storage/storage.go | 7 | ||||
-rw-r--r-- | sysprompts/default_Seraphina.png | bin | 551901 -> 0 bytes | |||
-rw-r--r-- | tui.go | 15 |
7 files changed, 66 insertions, 35 deletions
@@ -24,18 +24,19 @@ - directory with sys prompts (charcards png & json); + - colourschemes, colours or markdown of quotes and styles; (partially done) + - source file name to group by rag vectors; + +- RAG support|implementation; + +- delete chat option; + +- RAG file loading status/progress; + - change temp, min-p and other params from tui; - fullscreen textarea option (bothersome to implement); - consider adding use /completion of llamacpp, since openai endpoint clearly has template|format issues; - separate messages that are stored and chat and send to the bot, i.e. option to omit tool calls (there might be a point where they are no longer needed in ctx); -- RAG support|implementation; - char card is the sys message, but how about giving tools to char that does not have it? - it is a bit clumsy to mix chats in db and chars from the external files, maybe load external files in db on startup? - lets say we have two (or more) agents with the same name across multiple chats. These agents go and ask db for topics they memorised. Now they can access topics that aren't meant for them. (so memory should have an option: shareable; that indicates if that memory can be shared across chats); -- delete chat option; - server mode: no tui but api calls with the func calling, rag, other middleware; - boolean flag to use/not use tools. I see it as a msg from a tool to an llm "Hey, it might be good idea to use me!"; -- RAG file loading status/progress; +- connection to a model status; ### FIX: - bot responding (or hanging) blocks everything; + @@ -59,4 +60,3 @@ - number of sentences in a batch should depend on number of words there. + - F1 can load any chat, by loading chat of other agent it does not switch agents, if that chat is continued, it will rewrite agent in db; (either allow only chats from current agent OR switch agent on chat loading); - after chat is deleted: load undeleted chat; -- edit mode remove extra \n, but it should not be there in a first place. after edit no styles @@ -13,6 +13,7 @@ import ( "log/slog" "net/http" "os" + "path" "strings" "time" @@ -35,6 +36,7 @@ var ( defaultStarterBytes = []byte{} interruptResp = false ragger *rag.RAG + currentModel = "none" ) // ==== @@ -62,6 +64,23 @@ func formMsg(chatBody *models.ChatBody, newMsg, role string) io.Reader { return bytes.NewReader(data) } +func fetchModelName() { + api := "http://localhost:8080/v1/models" + resp, err := httpClient.Get(api) + if err != nil { + logger.Warn("failed to get model", "link", api, "error", err) + return + } + defer resp.Body.Close() + llmModel := models.LLMModels{} + if err := json.NewDecoder(resp.Body).Decode(&llmModel); err != nil { + logger.Warn("failed to decode resp", "link", api, "error", err) + return + } + currentModel = path.Base(llmModel.Data[0].ID) + updateStatusLine() +} + // func sendMsgToLLM(body io.Reader) (*models.LLMRespChunk, error) { func sendMsgToLLM(body io.Reader) { // nolint @@ -281,30 +300,13 @@ func charToStart(agentName string) bool { return true } -// func textToMsg(rawMsg string) models.RoleMsg { -// msg := models.RoleMsg{} -// // system and tool? -// if strings.HasPrefix(rawMsg, cfg.AssistantIcon) { -// msg.Role = cfg.AssistantRole -// msg.Content = strings.TrimPrefix(rawMsg, cfg.AssistantIcon) -// return msg -// } -// if strings.HasPrefix(rawMsg, cfg.UserIcon) { -// msg.Role = cfg.UserRole -// msg.Content = strings.TrimPrefix(rawMsg, cfg.UserIcon) -// return msg -// } -// return msg -// } - -// func textSliceToChat(chat []string) []models.RoleMsg { -// resp := make([]models.RoleMsg, len(chat)) -// for i, rawMsg := range chat { -// msg := textToMsg(rawMsg) -// resp[i] = msg -// } -// return resp -// } +func runModelNameTicker(n time.Duration) { + ticker := time.NewTicker(n) + for { + <-ticker.C + fetchModelName() + } +} func init() { cfg = config.LoadConfigOrDefault("config.toml") @@ -345,5 +347,6 @@ func init() { Stream: true, Messages: lastChat, } + go runModelNameTicker(time.Second * 20) // tempLoad() } @@ -10,7 +10,7 @@ var ( botRespMode = false editMode = false selectedIndex = int(-1) - indexLine = "F12 to show keys help; bot resp mode: %v; char: %s; chat: %s; RAGEnabled: %v; toolUseAdviced: %v" + indexLine = "F12 to show keys help; bot resp mode: %v; char: %s; chat: %s; RAGEnabled: %v; toolUseAdviced: %v; model: %s" focusSwitcher = map[tview.Primitive]tview.Primitive{} ) diff --git a/models/models.go b/models/models.go index bbf1bd0..eb215a6 100644 --- a/models/models.go +++ b/models/models.go @@ -125,3 +125,21 @@ type EmbeddingResp struct { // Object string `json:"object"` // } `json:"data"` // } + +type LLMModels struct { + Object string `json:"object"` + Data []struct { + ID string `json:"id"` + Object string `json:"object"` + Created int `json:"created"` + OwnedBy string `json:"owned_by"` + Meta struct { + VocabType int `json:"vocab_type"` + NVocab int `json:"n_vocab"` + NCtxTrain int `json:"n_ctx_train"` + NEmbd int `json:"n_embd"` + NParams int64 `json:"n_params"` + Size int64 `json:"size"` + } `json:"meta"` + } `json:"data"` +} diff --git a/storage/storage.go b/storage/storage.go index cfaaf0a..f759700 100644 --- a/storage/storage.go +++ b/storage/storage.go @@ -18,6 +18,7 @@ type FullRepo interface { type ChatHistory interface { ListChats() ([]models.Chat, error) GetChatByID(id uint32) (*models.Chat, error) + GetChatByChar(char string) ([]models.Chat, error) GetLastChat() (*models.Chat, error) GetLastChatByAgent(agent string) (*models.Chat, error) UpsertChat(chat *models.Chat) (*models.Chat, error) @@ -37,6 +38,12 @@ func (p ProviderSQL) ListChats() ([]models.Chat, error) { return resp, err } +func (p ProviderSQL) GetChatByChar(char string) ([]models.Chat, error) { + resp := []models.Chat{} + err := p.db.Select(&resp, "SELECT * FROM chats WHERE agent=$1;", char) + return resp, err +} + func (p ProviderSQL) GetChatByID(id uint32) (*models.Chat, error) { resp := models.Chat{} err := p.db.Get(&resp, "SELECT * FROM chats WHERE id=$1;", id) diff --git a/sysprompts/default_Seraphina.png b/sysprompts/default_Seraphina.png Binary files differdeleted file mode 100644 index 14f3c14..0000000 --- a/sysprompts/default_Seraphina.png +++ /dev/null @@ -8,7 +8,6 @@ import ( "os" "strconv" "strings" - "time" "github.com/gdamore/tcell/v2" "github.com/rivo/tview" @@ -85,7 +84,7 @@ func colorText() { } func updateStatusLine() { - position.SetText(fmt.Sprintf(indexLine, botRespMode, cfg.AssistantRole, activeChatName, cfg.RAGEnabled, cfg.ToolUse)) + position.SetText(fmt.Sprintf(indexLine, botRespMode, cfg.AssistantRole, activeChatName, cfg.RAGEnabled, cfg.ToolUse, currentModel)) } func initSysCards() ([]string, error) { @@ -108,7 +107,6 @@ func startNewChat() { if err != nil { logger.Error("failed to get chat id", "error", err) } - // TODO: get the current agent and it's starter if ok := charToStart(cfg.AssistantRole); !ok { logger.Warn("no such sys msg", "name", cfg.AssistantRole) } @@ -117,7 +115,7 @@ func startNewChat() { textView.SetText(chatToText(cfg.ShowSys)) newChat := &models.Chat{ ID: id + 1, - Name: fmt.Sprintf("%v_%v", "new", time.Now().Unix()), + Name: fmt.Sprintf("%d_%s", id+1, cfg.AssistantRole), Msgs: string(defaultStarterBytes), Agent: cfg.AssistantRole, } @@ -322,12 +320,17 @@ func init() { } app.SetInputCapture(func(event *tcell.EventKey) *tcell.EventKey { if event.Key() == tcell.KeyF1 { - chatList, err := loadHistoryChats() + // chatList, err := loadHistoryChats() + chatList, err := store.GetChatByChar(cfg.AssistantRole) if err != nil { logger.Error("failed to load chat history", "error", err) return nil } - chatActTable := makeChatTable(chatList) + nameList := make([]string, len(chatList)) + for i, chat := range chatList { + nameList[i] = chat.Name + } + chatActTable := makeChatTable(nameList) pages.AddPage(historyPage, chatActTable, true, true) return nil } |