Chore: refactoring
This commit is contained in:
216
helpfuncs.go
Normal file
216
helpfuncs.go
Normal file
@@ -0,0 +1,216 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"gf-lt/models"
|
||||
"gf-lt/pngmeta"
|
||||
"image"
|
||||
"os"
|
||||
"path"
|
||||
"strings"
|
||||
)
|
||||
|
||||
func colorText() {
|
||||
text := textView.GetText(false)
|
||||
quoteReplacer := strings.NewReplacer(
|
||||
`”`, `"`,
|
||||
`“`, `"`,
|
||||
`“`, `"`,
|
||||
`”`, `"`,
|
||||
`**`, `*`,
|
||||
)
|
||||
text = quoteReplacer.Replace(text)
|
||||
// Step 1: Extract code blocks and replace them with unique placeholders
|
||||
var codeBlocks []string
|
||||
placeholder := "__CODE_BLOCK_%d__"
|
||||
counter := 0
|
||||
// thinking
|
||||
var thinkBlocks []string
|
||||
placeholderThink := "__THINK_BLOCK_%d__"
|
||||
counterThink := 0
|
||||
// Replace code blocks with placeholders and store their styled versions
|
||||
text = codeBlockRE.ReplaceAllStringFunc(text, func(match string) string {
|
||||
// Style the code block and store it
|
||||
styled := fmt.Sprintf("[red::i]%s[-:-:-]", match)
|
||||
codeBlocks = append(codeBlocks, styled)
|
||||
// Generate a unique placeholder (e.g., "__CODE_BLOCK_0__")
|
||||
id := fmt.Sprintf(placeholder, counter)
|
||||
counter++
|
||||
return id
|
||||
})
|
||||
text = thinkRE.ReplaceAllStringFunc(text, func(match string) string {
|
||||
// Style the code block and store it
|
||||
styled := fmt.Sprintf("[red::i]%s[-:-:-]", match)
|
||||
thinkBlocks = append(thinkBlocks, styled)
|
||||
// Generate a unique placeholder (e.g., "__CODE_BLOCK_0__")
|
||||
id := fmt.Sprintf(placeholderThink, counterThink)
|
||||
counterThink++
|
||||
return id
|
||||
})
|
||||
// Step 2: Apply other regex styles to the non-code parts
|
||||
text = quotesRE.ReplaceAllString(text, `[orange::-]$1[-:-:-]`)
|
||||
text = starRE.ReplaceAllString(text, `[turquoise::i]$1[-:-:-]`)
|
||||
// text = thinkRE.ReplaceAllString(text, `[yellow::i]$1[-:-:-]`)
|
||||
// Step 3: Restore the styled code blocks from placeholders
|
||||
for i, cb := range codeBlocks {
|
||||
text = strings.Replace(text, fmt.Sprintf(placeholder, i), cb, 1)
|
||||
}
|
||||
logger.Debug("thinking debug", "blocks", thinkBlocks)
|
||||
for i, tb := range thinkBlocks {
|
||||
text = strings.Replace(text, fmt.Sprintf(placeholderThink, i), tb, 1)
|
||||
}
|
||||
textView.SetText(text)
|
||||
}
|
||||
|
||||
func updateStatusLine() {
|
||||
position.SetText(makeStatusLine())
|
||||
helpView.SetText(fmt.Sprintf(helpText, makeStatusLine()))
|
||||
}
|
||||
|
||||
func initSysCards() ([]string, error) {
|
||||
labels := []string{}
|
||||
labels = append(labels, sysLabels...)
|
||||
cards, err := pngmeta.ReadDirCards(cfg.SysDir, cfg.UserRole, logger)
|
||||
if err != nil {
|
||||
logger.Error("failed to read sys dir", "error", err)
|
||||
return nil, err
|
||||
}
|
||||
for _, cc := range cards {
|
||||
if cc.Role == "" {
|
||||
logger.Warn("empty role", "file", cc.FilePath)
|
||||
continue
|
||||
}
|
||||
sysMap[cc.Role] = cc
|
||||
labels = append(labels, cc.Role)
|
||||
}
|
||||
return labels, nil
|
||||
}
|
||||
|
||||
func startNewChat() {
|
||||
id, err := store.ChatGetMaxID()
|
||||
if err != nil {
|
||||
logger.Error("failed to get chat id", "error", err)
|
||||
}
|
||||
if ok := charToStart(cfg.AssistantRole); !ok {
|
||||
logger.Warn("no such sys msg", "name", cfg.AssistantRole)
|
||||
}
|
||||
// set chat body
|
||||
chatBody.Messages = chatBody.Messages[:2]
|
||||
textView.SetText(chatToText(cfg.ShowSys))
|
||||
newChat := &models.Chat{
|
||||
ID: id + 1,
|
||||
Name: fmt.Sprintf("%d_%s", id+1, cfg.AssistantRole),
|
||||
Msgs: string(defaultStarterBytes),
|
||||
Agent: cfg.AssistantRole,
|
||||
}
|
||||
activeChatName = newChat.Name
|
||||
chatMap[newChat.Name] = newChat
|
||||
updateStatusLine()
|
||||
colorText()
|
||||
}
|
||||
|
||||
func renameUser(oldname, newname string) {
|
||||
if oldname == "" {
|
||||
// not provided; deduce who user is
|
||||
// INFO: if user not yet spoke, it is hard to replace mentions in sysprompt and first message about thme
|
||||
roles := chatBody.ListRoles()
|
||||
for _, role := range roles {
|
||||
if role == cfg.AssistantRole {
|
||||
continue
|
||||
}
|
||||
if role == cfg.ToolRole {
|
||||
continue
|
||||
}
|
||||
if role == "system" {
|
||||
continue
|
||||
}
|
||||
oldname = role
|
||||
break
|
||||
}
|
||||
if oldname == "" {
|
||||
// still
|
||||
logger.Warn("fn: renameUser; failed to find old name", "newname", newname)
|
||||
return
|
||||
}
|
||||
}
|
||||
viewText := textView.GetText(false)
|
||||
viewText = strings.ReplaceAll(viewText, oldname, newname)
|
||||
chatBody.Rename(oldname, newname)
|
||||
textView.SetText(viewText)
|
||||
}
|
||||
|
||||
func setLogLevel(sl string) {
|
||||
switch sl {
|
||||
case "Debug":
|
||||
logLevel.Set(-4)
|
||||
case "Info":
|
||||
logLevel.Set(0)
|
||||
case "Warn":
|
||||
logLevel.Set(4)
|
||||
}
|
||||
}
|
||||
|
||||
func listRolesWithUser() []string {
|
||||
roles := chatBody.ListRoles()
|
||||
if !strInSlice(cfg.UserRole, roles) {
|
||||
roles = append(roles, cfg.UserRole)
|
||||
}
|
||||
return roles
|
||||
}
|
||||
|
||||
func loadImage() {
|
||||
filepath := defaultImage
|
||||
cc, ok := sysMap[cfg.AssistantRole]
|
||||
if ok {
|
||||
if strings.HasSuffix(cc.FilePath, ".png") {
|
||||
filepath = cc.FilePath
|
||||
}
|
||||
}
|
||||
file, err := os.Open(filepath)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
defer file.Close()
|
||||
img, _, err := image.Decode(file)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
imgView.SetImage(img)
|
||||
}
|
||||
|
||||
func strInSlice(s string, sl []string) bool {
|
||||
for _, el := range sl {
|
||||
if strings.EqualFold(s, el) {
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
func makeStatusLine() string {
|
||||
isRecording := false
|
||||
if asr != nil {
|
||||
isRecording = asr.IsRecording()
|
||||
}
|
||||
persona := cfg.UserRole
|
||||
if cfg.WriteNextMsgAs != "" {
|
||||
persona = cfg.WriteNextMsgAs
|
||||
}
|
||||
botPersona := cfg.AssistantRole
|
||||
if cfg.WriteNextMsgAsCompletionAgent != "" {
|
||||
botPersona = cfg.WriteNextMsgAsCompletionAgent
|
||||
}
|
||||
// Add image attachment info to status line
|
||||
var imageInfo string
|
||||
if imageAttachmentPath != "" {
|
||||
// Get just the filename from the path
|
||||
imageName := path.Base(imageAttachmentPath)
|
||||
imageInfo = fmt.Sprintf(" | attached img: [orange:-:b]%s[-:-:-]", imageName)
|
||||
} else {
|
||||
imageInfo = ""
|
||||
}
|
||||
statusLine := fmt.Sprintf(indexLineCompletion, botRespMode, cfg.AssistantRole, activeChatName,
|
||||
cfg.ToolUse, chatBody.Model, cfg.SkipLLMResp, cfg.CurrentAPI, cfg.ThinkUse, logLevel.Level(),
|
||||
isRecording, persona, botPersona, injectRole)
|
||||
return statusLine + imageInfo
|
||||
}
|
||||
Reference in New Issue
Block a user