Fix: thinking
This commit is contained in:
8
bot.go
8
bot.go
@@ -39,7 +39,7 @@ var (
|
|||||||
chunkParser ChunkParser
|
chunkParser ChunkParser
|
||||||
defaultLCPProps = map[string]float32{
|
defaultLCPProps = map[string]float32{
|
||||||
"temperature": 0.8,
|
"temperature": 0.8,
|
||||||
"dry_multiplier": 0.6,
|
"dry_multiplier": 0.0,
|
||||||
"min_p": 0.05,
|
"min_p": 0.05,
|
||||||
"n_predict": -1.0,
|
"n_predict": -1.0,
|
||||||
}
|
}
|
||||||
@@ -108,6 +108,7 @@ func sendMsgToLLM(body io.Reader) {
|
|||||||
}
|
}
|
||||||
// starts with -> data:
|
// starts with -> data:
|
||||||
line = line[6:]
|
line = line[6:]
|
||||||
|
logger.Info("debugging resp", "line", string(line))
|
||||||
content, stop, err := chunkParser.ParseChunk(line)
|
content, stop, err := chunkParser.ParseChunk(line)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
logger.Error("error parsing response body", "error", err, "line", string(line), "url", cfg.CurrentAPI)
|
logger.Error("error parsing response body", "error", err, "line", string(line), "url", cfg.CurrentAPI)
|
||||||
@@ -185,6 +186,10 @@ func chatRound(userMsg, role string, tv *tview.TextView, regen bool) {
|
|||||||
fmt.Fprintf(tv, "(%d) ", len(chatBody.Messages))
|
fmt.Fprintf(tv, "(%d) ", len(chatBody.Messages))
|
||||||
fmt.Fprint(tv, roleToIcon(cfg.AssistantRole))
|
fmt.Fprint(tv, roleToIcon(cfg.AssistantRole))
|
||||||
fmt.Fprint(tv, "\n")
|
fmt.Fprint(tv, "\n")
|
||||||
|
if cfg.ThinkUse && !strings.Contains(cfg.CurrentAPI, "v1") {
|
||||||
|
// fmt.Fprint(tv, "<think>")
|
||||||
|
chunkChan <- "<think>"
|
||||||
|
}
|
||||||
}
|
}
|
||||||
respText := strings.Builder{}
|
respText := strings.Builder{}
|
||||||
out:
|
out:
|
||||||
@@ -201,6 +206,7 @@ out:
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
botRespMode = false
|
botRespMode = false
|
||||||
|
// how can previous messages be affected?
|
||||||
chatBody.Messages = append(chatBody.Messages, models.RoleMsg{
|
chatBody.Messages = append(chatBody.Messages, models.RoleMsg{
|
||||||
Role: cfg.AssistantRole, Content: respText.String(),
|
Role: cfg.AssistantRole, Content: respText.String(),
|
||||||
})
|
})
|
||||||
|
|||||||
@@ -17,6 +17,7 @@ type Config struct {
|
|||||||
UserRole string `toml:"UserRole"`
|
UserRole string `toml:"UserRole"`
|
||||||
ToolRole string `toml:"ToolRole"`
|
ToolRole string `toml:"ToolRole"`
|
||||||
ToolUse bool `toml:"ToolUse"`
|
ToolUse bool `toml:"ToolUse"`
|
||||||
|
ThinkUse bool `toml:"ThinkUse"`
|
||||||
AssistantRole string `toml:"AssistantRole"`
|
AssistantRole string `toml:"AssistantRole"`
|
||||||
SysDir string `toml:"SysDir"`
|
SysDir string `toml:"SysDir"`
|
||||||
ChunkLimit uint32 `toml:"ChunkLimit"`
|
ChunkLimit uint32 `toml:"ChunkLimit"`
|
||||||
|
|||||||
11
llm.go
11
llm.go
@@ -30,9 +30,6 @@ type OpenAIer struct {
|
|||||||
|
|
||||||
func (lcp LlamaCPPeer) FormMsg(msg, role string) (io.Reader, error) {
|
func (lcp LlamaCPPeer) FormMsg(msg, role string) (io.Reader, error) {
|
||||||
if msg != "" { // otherwise let the bot continue
|
if msg != "" { // otherwise let the bot continue
|
||||||
// if role == cfg.UserRole {
|
|
||||||
// msg = msg + cfg.AssistantRole + ":"
|
|
||||||
// }
|
|
||||||
newMsg := models.RoleMsg{Role: role, Content: msg}
|
newMsg := models.RoleMsg{Role: role, Content: msg}
|
||||||
chatBody.Messages = append(chatBody.Messages, newMsg)
|
chatBody.Messages = append(chatBody.Messages, newMsg)
|
||||||
// if rag
|
// if rag
|
||||||
@@ -51,11 +48,17 @@ func (lcp LlamaCPPeer) FormMsg(msg, role string) (io.Reader, error) {
|
|||||||
messages[i] = m.ToPrompt()
|
messages[i] = m.ToPrompt()
|
||||||
}
|
}
|
||||||
prompt := strings.Join(messages, "\n")
|
prompt := strings.Join(messages, "\n")
|
||||||
|
// strings builder?
|
||||||
if cfg.ToolUse && msg != "" {
|
if cfg.ToolUse && msg != "" {
|
||||||
prompt += "\n" + cfg.ToolRole + ":\n" + toolSysMsg
|
prompt += "\n" + cfg.ToolRole + ":\n" + toolSysMsg
|
||||||
}
|
}
|
||||||
botMsgStart := "\n" + cfg.AssistantRole + ":\n"
|
botMsgStart := "\n" + cfg.AssistantRole + ":\n"
|
||||||
payload := models.NewLCPReq(prompt+botMsgStart, cfg, defaultLCPProps)
|
prompt += botMsgStart
|
||||||
|
// if cfg.ThinkUse && msg != "" && !cfg.ToolUse {
|
||||||
|
if cfg.ThinkUse && !cfg.ToolUse {
|
||||||
|
prompt += "<think>"
|
||||||
|
}
|
||||||
|
payload := models.NewLCPReq(prompt, cfg, defaultLCPProps)
|
||||||
data, err := json.Marshal(payload)
|
data, err := json.Marshal(payload)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
logger.Error("failed to form a msg", "error", err)
|
logger.Error("failed to form a msg", "error", err)
|
||||||
|
|||||||
2
main.go
2
main.go
@@ -12,7 +12,7 @@ var (
|
|||||||
botRespMode = false
|
botRespMode = false
|
||||||
editMode = false
|
editMode = false
|
||||||
selectedIndex = int(-1)
|
selectedIndex = int(-1)
|
||||||
indexLine = "F12 to show keys help | bot resp mode: %v (F6) | char: %s (ctrl+s) | chat: %s (F1) | RAGEnabled: %v (F11) | toolUseAdviced: %v (ctrl+k) | model: %s (ctrl+l)\nAPI_URL: %s (ctrl+v)"
|
indexLine = "F12 to show keys help | bot resp mode: %v (F6) | char: %s (ctrl+s) | chat: %s (F1) | RAGEnabled: %v (F11) | toolUseAdviced: %v (ctrl+k) | model: %s (ctrl+l)\nAPI_URL: %s (ctrl+v) | ThinkUse: %v (ctrl+p)"
|
||||||
focusSwitcher = map[tview.Primitive]tview.Primitive{}
|
focusSwitcher = map[tview.Primitive]tview.Primitive{}
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|||||||
2
tools.go
2
tools.go
@@ -12,7 +12,7 @@ var (
|
|||||||
toolCallRE = regexp.MustCompile(`__tool_call__\s*([\s\S]*?)__tool_call__`)
|
toolCallRE = regexp.MustCompile(`__tool_call__\s*([\s\S]*?)__tool_call__`)
|
||||||
quotesRE = regexp.MustCompile(`(".*?")`)
|
quotesRE = regexp.MustCompile(`(".*?")`)
|
||||||
starRE = regexp.MustCompile(`(\*.*?\*)`)
|
starRE = regexp.MustCompile(`(\*.*?\*)`)
|
||||||
thinkRE = regexp.MustCompile(`(<think>.*?</think>)`)
|
thinkRE = regexp.MustCompile(`(<think>\s*([\s\S]*?)</think>)`)
|
||||||
codeBlockRE = regexp.MustCompile(`(?s)\x60{3}(?:.*?)\n(.*?)\n\s*\x60{3}\s*`)
|
codeBlockRE = regexp.MustCompile(`(?s)\x60{3}(?:.*?)\n(.*?)\n\s*\x60{3}\s*`)
|
||||||
basicSysMsg = `Large Language Model that helps user with any of his requests.`
|
basicSysMsg = `Large Language Model that helps user with any of his requests.`
|
||||||
toolSysMsg = `You can do functions call if needed.
|
toolSysMsg = `You can do functions call if needed.
|
||||||
|
|||||||
27
tui.go
27
tui.go
@@ -65,7 +65,7 @@ var (
|
|||||||
[yellow]Ctrl+t[white]: remove thinking (<think>) and tool messages from context (delete from chat)
|
[yellow]Ctrl+t[white]: remove thinking (<think>) and tool messages from context (delete from chat)
|
||||||
[yellow]Ctrl+l[white]: update connected model name (llamacpp)
|
[yellow]Ctrl+l[white]: update connected model name (llamacpp)
|
||||||
[yellow]Ctrl+k[white]: switch tool use (recommend tool use to llm after user msg)
|
[yellow]Ctrl+k[white]: switch tool use (recommend tool use to llm after user msg)
|
||||||
[yellow]Ctrl+i[white]: if chat agent is char.png will show the image; then any key to return
|
[yellow]Ctrl+j[white]: if chat agent is char.png will show the image; then any key to return
|
||||||
|
|
||||||
Press Enter to go back
|
Press Enter to go back
|
||||||
`
|
`
|
||||||
@@ -97,6 +97,10 @@ func colorText() {
|
|||||||
var codeBlocks []string
|
var codeBlocks []string
|
||||||
placeholder := "__CODE_BLOCK_%d__"
|
placeholder := "__CODE_BLOCK_%d__"
|
||||||
counter := 0
|
counter := 0
|
||||||
|
// thinking
|
||||||
|
var thinkBlocks []string
|
||||||
|
placeholderThink := "__THINK_BLOCK_%d__"
|
||||||
|
counterThink := 0
|
||||||
// Replace code blocks with placeholders and store their styled versions
|
// Replace code blocks with placeholders and store their styled versions
|
||||||
text = codeBlockRE.ReplaceAllStringFunc(text, func(match string) string {
|
text = codeBlockRE.ReplaceAllStringFunc(text, func(match string) string {
|
||||||
// Style the code block and store it
|
// Style the code block and store it
|
||||||
@@ -107,19 +111,31 @@ func colorText() {
|
|||||||
counter++
|
counter++
|
||||||
return id
|
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(codeBlocks, styled)
|
||||||
|
// Generate a unique placeholder (e.g., "__CODE_BLOCK_0__")
|
||||||
|
id := fmt.Sprintf(placeholderThink, counterThink)
|
||||||
|
counter++
|
||||||
|
return id
|
||||||
|
})
|
||||||
// Step 2: Apply other regex styles to the non-code parts
|
// Step 2: Apply other regex styles to the non-code parts
|
||||||
text = quotesRE.ReplaceAllString(text, `[orange::-]$1[-:-:-]`)
|
text = quotesRE.ReplaceAllString(text, `[orange::-]$1[-:-:-]`)
|
||||||
text = starRE.ReplaceAllString(text, `[turquoise::i]$1[-:-:-]`)
|
text = starRE.ReplaceAllString(text, `[turquoise::i]$1[-:-:-]`)
|
||||||
text = thinkRE.ReplaceAllString(text, `[turquoise::i]$1[-:-:-]`)
|
// text = thinkRE.ReplaceAllString(text, `[yellow::i]$1[-:-:-]`)
|
||||||
// Step 3: Restore the styled code blocks from placeholders
|
// Step 3: Restore the styled code blocks from placeholders
|
||||||
for i, cb := range codeBlocks {
|
for i, cb := range codeBlocks {
|
||||||
text = strings.Replace(text, fmt.Sprintf(placeholder, i), cb, 1)
|
text = strings.Replace(text, fmt.Sprintf(placeholder, i), cb, 1)
|
||||||
}
|
}
|
||||||
|
for i, tb := range thinkBlocks {
|
||||||
|
text = strings.Replace(text, fmt.Sprintf(placeholderThink, i), tb, 1)
|
||||||
|
}
|
||||||
textView.SetText(text)
|
textView.SetText(text)
|
||||||
}
|
}
|
||||||
|
|
||||||
func updateStatusLine() {
|
func updateStatusLine() {
|
||||||
position.SetText(fmt.Sprintf(indexLine, botRespMode, cfg.AssistantRole, activeChatName, cfg.RAGEnabled, cfg.ToolUse, currentModel, cfg.CurrentAPI))
|
position.SetText(fmt.Sprintf(indexLine, botRespMode, cfg.AssistantRole, activeChatName, cfg.RAGEnabled, cfg.ToolUse, currentModel, cfg.CurrentAPI, cfg.ThinkUse))
|
||||||
}
|
}
|
||||||
|
|
||||||
func initSysCards() ([]string, error) {
|
func initSysCards() ([]string, error) {
|
||||||
@@ -167,6 +183,9 @@ func startNewChat() {
|
|||||||
func makePropsForm(props map[string]float32) *tview.Form {
|
func makePropsForm(props map[string]float32) *tview.Form {
|
||||||
form := tview.NewForm().
|
form := tview.NewForm().
|
||||||
AddTextView("Notes", "Props for llamacpp completion call", 40, 2, true, false).
|
AddTextView("Notes", "Props for llamacpp completion call", 40, 2, true, false).
|
||||||
|
AddCheckbox("Insert <think> (/completion only)", cfg.ThinkUse, func(checked bool) {
|
||||||
|
cfg.ThinkUse = checked
|
||||||
|
}).
|
||||||
AddButton("Quit", func() {
|
AddButton("Quit", func() {
|
||||||
pages.RemovePage(propsPage)
|
pages.RemovePage(propsPage)
|
||||||
})
|
})
|
||||||
@@ -588,7 +607,7 @@ func init() {
|
|||||||
updateStatusLine()
|
updateStatusLine()
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
if event.Key() == tcell.KeyCtrlI {
|
if event.Key() == tcell.KeyCtrlJ {
|
||||||
// show image
|
// show image
|
||||||
loadImage()
|
loadImage()
|
||||||
pages.AddPage(imgPage, imgView, true, true)
|
pages.AddPage(imgPage, imgView, true, true)
|
||||||
|
|||||||
Reference in New Issue
Block a user