feat: Phase 2 — chat templates, reasoning parser, collapsible TUI, mouse support
- internal/llama/template.go: ChatML/Llama3 template engine with stop tokens - internal/agent/reasoning.go: parse <think>/<reasoning> tags from LLM output - companion/promptbuilder.go: output structured BuildResult, add date/time context - agent/agent.go: wire templates + reasoning split into message loop - storage: add reasoning TEXT column to messages table + migration - channel/tui.go: collapsible reasoning (tab toggle), mouse scroll, polished dimmed style - config: CHAT_TEMPLATE env var (chatml|llama3|none) - plan.md: mark Phase 2 complete, add themes TODO
This commit is contained in:
41
internal/agent/reasoning.go
Normal file
41
internal/agent/reasoning.go
Normal file
@@ -0,0 +1,41 @@
|
||||
package agent
|
||||
|
||||
import (
|
||||
"strings"
|
||||
)
|
||||
|
||||
type ParsedResponse struct {
|
||||
Reasoning string
|
||||
Content string
|
||||
}
|
||||
|
||||
func ParseResponse(raw string) ParsedResponse {
|
||||
tags := []struct {
|
||||
open string
|
||||
close string
|
||||
}{
|
||||
{"<reasoning>", "</reasoning>"},
|
||||
{"<reason>", "</reason>"},
|
||||
{"<thinking>", "</thinking>"},
|
||||
{"<think>", "</think>"},
|
||||
{"", ""},
|
||||
}
|
||||
|
||||
for _, t := range tags {
|
||||
if t.open == "" {
|
||||
break
|
||||
}
|
||||
idxOpen := strings.Index(raw, t.open)
|
||||
idxClose := strings.LastIndex(raw, t.close)
|
||||
if idxOpen != -1 && idxClose != -1 && idxClose > idxOpen {
|
||||
reasoning := raw[idxOpen+len(t.open) : idxClose]
|
||||
content := raw[:idxOpen] + raw[idxClose+len(t.close):]
|
||||
return ParsedResponse{
|
||||
Reasoning: strings.TrimSpace(reasoning),
|
||||
Content: strings.TrimSpace(content),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return ParsedResponse{Content: strings.TrimSpace(raw)}
|
||||
}
|
||||
Reference in New Issue
Block a user