返回 DeepSeek-Reasonix
goal_display.go
根目录 / internal / agent / goal_display.go
1 package agent
2
3 import (
4 "fmt"
5 "strings"
6 )
7
8 // StripGoalMarkers removes goal status markers like [goal:complete],
9 // [goal:continue], and [goal:blocked:...] from display text so users see
10 // natural language instead of protocol markers. Exported for use by frontends.
11 // The markers are still kept in the session history for controller parsing.
12 func StripGoalMarkers(text string) string {
13 text = strings.TrimSpace(text)
14 lines := strings.Split(text, "\n")
15 cleaned := make([]string, 0, len(lines))
16 for _, line := range lines {
17 trimmed := strings.TrimSpace(line)
18 if trimmed == "[goal:complete]" || trimmed == "[goal:continue]" {
19 continue
20 }
21 if strings.HasPrefix(trimmed, "[goal:blocked:") && strings.HasSuffix(trimmed, "]") {
22 reason := strings.TrimPrefix(trimmed, "[goal:blocked:")
23 reason = strings.TrimSuffix(reason, "]")
24 if reason != "" {
25 cleaned = append(cleaned, fmt.Sprintf("\u26a0\ufe0f Blocked: %s", reason))
26 }
27 continue
28 }
29 cleaned = append(cleaned, line)
30 }
31 return strings.TrimSpace(strings.Join(cleaned, "\n"))
32 }
33
34 const (
35 autoResearchEvidenceOpen = "<autoresearch-evidence>"
36 autoResearchEvidenceClose = "</autoresearch-evidence>"
37 )
38
39 // StripAutoResearchEvidenceBlocks removes historical <autoresearch-evidence>
40 // blocks at display boundaries only. Raw transcripts remain unchanged; current
41 // Goal semantics never parse these blocks or write state from them.
42 func StripAutoResearchEvidenceBlocks(text string) string {
43 var b strings.Builder
44 rest := text
45 for {
46 start := strings.Index(rest, autoResearchEvidenceOpen)
47 if start < 0 {
48 b.WriteString(rest)
49 return strings.TrimSpace(b.String())
50 }
51 b.WriteString(rest[:start])
52 afterOpen := rest[start+len(autoResearchEvidenceOpen):]
53 _, after, ok := strings.Cut(afterOpen, autoResearchEvidenceClose)
54 if !ok {
55 return strings.TrimSpace(b.String())
56 }
57 rest = after
58 }
59 }
60
61 // DisplayAssistantText is the single display filter for assistant answer text:
62 // it removes every protocol artifact ([goal:*] markers, autoresearch evidence
63 // blocks) before the text reaches a sink. Session history keeps the raw text —
64 // apply this at emission or render boundaries only.
65 func DisplayAssistantText(text string) string {
66 return StripGoalMarkers(StripAutoResearchEvidenceBlocks(text))
67 }
68
68 lines GO