Enha: id for card map
This commit is contained in:
4
bot.go
4
bot.go
@@ -1382,8 +1382,8 @@ func applyCharCard(cc *models.CharCard, loadHistory bool) {
|
||||
}
|
||||
|
||||
func charToStart(agentName string, keepSysP bool) bool {
|
||||
cc, ok := sysMap[agentName]
|
||||
if !ok {
|
||||
cc := GetCardByRole(agentName)
|
||||
if cc == nil {
|
||||
return false
|
||||
}
|
||||
applyCharCard(cc, keepSysP)
|
||||
|
||||
20
helpfuncs.go
20
helpfuncs.go
@@ -198,7 +198,11 @@ func initSysCards() ([]string, error) {
|
||||
logger.Warn("empty role", "file", cc.FilePath)
|
||||
continue
|
||||
}
|
||||
sysMap[cc.Role] = cc
|
||||
if cc.ID == "" {
|
||||
cc.ID = models.ComputeCardID(cc.Role, cc.FilePath)
|
||||
}
|
||||
sysMap[cc.ID] = cc
|
||||
roleToID[cc.Role] = cc.ID
|
||||
labels = append(labels, cc.Role)
|
||||
}
|
||||
return labels, nil
|
||||
@@ -289,8 +293,8 @@ func listRolesWithUser() []string {
|
||||
|
||||
func loadImage() {
|
||||
filepath := defaultImage
|
||||
cc, ok := sysMap[cfg.AssistantRole]
|
||||
if ok {
|
||||
cc := GetCardByRole(cfg.AssistantRole)
|
||||
if cc != nil {
|
||||
if strings.HasSuffix(cc.FilePath, ".png") {
|
||||
filepath = cc.FilePath
|
||||
}
|
||||
@@ -468,13 +472,9 @@ func listChatRoles() []string {
|
||||
if !ok {
|
||||
return cbc
|
||||
}
|
||||
currentCard, ok := sysMap[currentChat.Agent]
|
||||
if !ok {
|
||||
// case which won't let to switch roles:
|
||||
// started new chat (basic_sys or any other), at the start it yet be saved or have chatbody
|
||||
// if it does not have a card or chars, it'll return an empty slice
|
||||
// log error
|
||||
logger.Warn("failed to find current card in sysMap", "agent", currentChat.Agent, "sysMap", sysMap)
|
||||
currentCard := GetCardByRole(currentChat.Agent)
|
||||
if currentCard == nil {
|
||||
logger.Warn("failed to find current card", "agent", currentChat.Agent)
|
||||
return cbc
|
||||
}
|
||||
charset := []string{}
|
||||
|
||||
@@ -1,6 +1,10 @@
|
||||
package models
|
||||
|
||||
import "strings"
|
||||
import (
|
||||
"crypto/md5"
|
||||
"fmt"
|
||||
"strings"
|
||||
)
|
||||
|
||||
// https://github.com/malfoyslastname/character-card-spec-v2/blob/main/spec_v2.md
|
||||
// what a bloat; trim to Role->Msg pair and first msg
|
||||
@@ -31,6 +35,7 @@ func (c *CharCardSpec) Simplify(userName, fpath string) *CharCard {
|
||||
fm := strings.ReplaceAll(strings.ReplaceAll(c.FirstMes, "{{char}}", c.Name), "{{user}}", userName)
|
||||
sysPr := strings.ReplaceAll(strings.ReplaceAll(c.Description, "{{char}}", c.Name), "{{user}}", userName)
|
||||
return &CharCard{
|
||||
ID: ComputeCardID(c.Name, fpath),
|
||||
SysPrompt: sysPr,
|
||||
FirstMsg: fm,
|
||||
Role: c.Name,
|
||||
@@ -39,7 +44,12 @@ func (c *CharCardSpec) Simplify(userName, fpath string) *CharCard {
|
||||
}
|
||||
}
|
||||
|
||||
func ComputeCardID(role, filePath string) string {
|
||||
return fmt.Sprintf("%x", md5.Sum([]byte(role+filePath)))
|
||||
}
|
||||
|
||||
type CharCard struct {
|
||||
ID string `json:"id"`
|
||||
SysPrompt string `json:"sys_prompt"`
|
||||
FirstMsg string `json:"first_msg"`
|
||||
Role string `json:"role"`
|
||||
|
||||
@@ -109,6 +109,12 @@ func ReadCardJson(fname string) (*models.CharCard, error) {
|
||||
if err := json.Unmarshal(data, &card); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if card.FilePath == "" {
|
||||
card.FilePath = fname
|
||||
}
|
||||
if card.ID == "" {
|
||||
card.ID = models.ComputeCardID(card.Role, card.FilePath)
|
||||
}
|
||||
return &card, nil
|
||||
}
|
||||
|
||||
|
||||
33
tables.go
33
tables.go
@@ -159,27 +159,18 @@ func makeChatTable(chatMap map[string]models.Chat) *tview.Table {
|
||||
// save updated card
|
||||
fi := strings.Index(selectedChat, "_")
|
||||
agentName := selectedChat[fi+1:]
|
||||
cc, ok := sysMap[agentName]
|
||||
if !ok {
|
||||
cc := GetCardByRole(agentName)
|
||||
if cc == nil {
|
||||
logger.Warn("no such card", "agent", agentName)
|
||||
//no:lint
|
||||
if err := notifyUser("error", "no such card: "+agentName); err != nil {
|
||||
logger.Warn("failed ot notify", "error", err)
|
||||
}
|
||||
return
|
||||
}
|
||||
// if chatBody.Messages[0].Role != "system" || chatBody.Messages[1].Role != agentName {
|
||||
// if err := notifyUser("error", "unexpected chat structure; card: "+agentName); err != nil {
|
||||
// logger.Warn("failed ot notify", "error", err)
|
||||
// }
|
||||
// return
|
||||
// }
|
||||
// change sys_prompt + first msg
|
||||
cc.SysPrompt = chatBody.Messages[0].Content
|
||||
cc.FirstMsg = chatBody.Messages[1].Content
|
||||
if err := pngmeta.WriteToPng(cc.ToSpec(cfg.UserRole), cc.FilePath, cc.FilePath); err != nil {
|
||||
logger.Error("failed to write charcard",
|
||||
"error", err)
|
||||
logger.Error("failed to write charcard", "error", err)
|
||||
}
|
||||
return
|
||||
case "move sysprompt onto 1st msg":
|
||||
@@ -190,18 +181,16 @@ func makeChatTable(chatMap map[string]models.Chat) *tview.Table {
|
||||
pages.RemovePage(historyPage)
|
||||
return
|
||||
case "new_chat_from_card":
|
||||
// Reread card from file and start fresh chat
|
||||
fi := strings.Index(selectedChat, "_")
|
||||
agentName := selectedChat[fi+1:]
|
||||
cc, ok := sysMap[agentName]
|
||||
if !ok {
|
||||
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)
|
||||
}
|
||||
return
|
||||
}
|
||||
// Reload card from disk
|
||||
newCard, err := pngmeta.ReadCard(cc.FilePath, cfg.UserRole)
|
||||
if err != nil {
|
||||
logger.Error("failed to reload charcard", "path", cc.FilePath, "error", err)
|
||||
@@ -214,9 +203,11 @@ func makeChatTable(chatMap map[string]models.Chat) *tview.Table {
|
||||
return
|
||||
}
|
||||
}
|
||||
// Update sysMap with fresh card data
|
||||
sysMap[agentName] = newCard
|
||||
// fetching sysprompt and first message anew from the card
|
||||
if newCard.ID == "" {
|
||||
newCard.ID = models.ComputeCardID(newCard.Role, newCard.FilePath)
|
||||
}
|
||||
sysMap[newCard.ID] = newCard
|
||||
roleToID[newCard.Role] = newCard.ID
|
||||
startNewChat(false)
|
||||
pages.RemovePage(historyPage)
|
||||
return
|
||||
@@ -529,8 +520,8 @@ func makeAgentTable(agentList []string) *tview.Table {
|
||||
SetSelectable(false))
|
||||
case 1:
|
||||
if actions[c-1] == "filepath" {
|
||||
cc, ok := sysMap[agentList[r]]
|
||||
if !ok {
|
||||
cc := GetCardByRole(agentList[r])
|
||||
if cc == nil {
|
||||
continue
|
||||
}
|
||||
chatActTable.SetCell(r, c,
|
||||
|
||||
20
tools.go
20
tools.go
@@ -162,13 +162,15 @@ After that you are free to respond to the user.
|
||||
readURLSysPrompt = `Extract and summarize the content from the webpage. Provide key information, main points, and any relevant details.`
|
||||
summarySysPrompt = `Please provide a concise summary of the following conversation. Focus on key points, decisions, and actions. Provide only the summary, no additional commentary.`
|
||||
basicCard = &models.CharCard{
|
||||
ID: models.ComputeCardID("assistant", "basic_sys"),
|
||||
SysPrompt: basicSysMsg,
|
||||
FirstMsg: defaultFirstMsg,
|
||||
Role: "",
|
||||
FilePath: "",
|
||||
Role: "assistant",
|
||||
FilePath: "basic_sys",
|
||||
}
|
||||
sysMap = map[string]*models.CharCard{"basic_sys": basicCard}
|
||||
sysLabels = []string{"basic_sys"}
|
||||
sysMap = map[string]*models.CharCard{}
|
||||
roleToID = map[string]string{}
|
||||
sysLabels = []string{"assistant"}
|
||||
|
||||
webAgentClient *agent.AgentClient
|
||||
webAgentClientOnce sync.Once
|
||||
@@ -206,6 +208,8 @@ var (
|
||||
)
|
||||
|
||||
func init() {
|
||||
sysMap[basicCard.ID] = basicCard
|
||||
roleToID["assistant"] = basicCard.ID
|
||||
sa, err := searcher.NewWebSurfer(searcher.SearcherTypeScraper, "")
|
||||
if err != nil {
|
||||
panic("failed to init seachagent; error: " + err.Error())
|
||||
@@ -218,6 +222,14 @@ func init() {
|
||||
registerWindowTools()
|
||||
}
|
||||
|
||||
func GetCardByRole(role string) *models.CharCard {
|
||||
cardID, ok := roleToID[role]
|
||||
if !ok {
|
||||
return nil
|
||||
}
|
||||
return sysMap[cardID]
|
||||
}
|
||||
|
||||
func checkWindowTools() {
|
||||
xdotoolPath, _ = exec.LookPath("xdotool")
|
||||
maimPath, _ = exec.LookPath("maim")
|
||||
|
||||
Reference in New Issue
Block a user