Feat (status line): add model name

This commit is contained in:
Grail Finder
2025-01-15 16:46:59 +03:00
parent 85f96aa401
commit 1ea19ba11e
7 changed files with 66 additions and 35 deletions

View File

@@ -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

51
bot.go
View File

@@ -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()
}

View File

@@ -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{}
)

View File

@@ -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"`
}

View File

@@ -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)

Binary file not shown.

Before

Width:  |  Height:  |  Size: 539 KiB

15
tui.go
View File

@@ -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
}