Refactor Goal Name Extraction and Add Markdown Formatting Stripping

- Enhanced the `extractGoalName` function to skip empty lines, markdown headers, and horizontal rules while extracting the first meaningful line as the goal name.
- Implemented a new `stripMarkdownFormatting` function to remove various markdown formatting elements, including bold, italic, inline code, and link syntax.
- Added comprehensive unit tests for both `extractGoalName` and `stripMarkdownFormatting` to ensure correct functionality across various markdown scenarios.
This commit is contained in:
Max 2026-01-24 17:21:06 +08:00
parent 0e72aa9d8f
commit fe67deb3e2
2 changed files with 209 additions and 18 deletions

View file

@ -2,6 +2,7 @@ package standard
import (
"fmt"
"strings"
"sync/atomic"
"time"
@ -523,29 +524,88 @@ func extractGoalName(goals *robottypes.Goals) string {
return ""
}
// Extract first line or first sentence as the goal name
// Extract first non-empty, non-markdown-header line as the goal name
content := goals.Content
// Find first newline
if idx := indexAny(content, "\n\r"); idx > 0 {
content = content[:idx]
}
// Limit length
if len(content) > 150 {
content = content[:150] + "..."
}
return content
}
lines := strings.Split(content, "\n")
// indexAny returns the index of the first occurrence of any char in chars
func indexAny(s string, chars string) int {
for i, c := range s {
for _, ch := range chars {
if c == ch {
return i
for _, line := range lines {
line = strings.TrimSpace(line)
if line == "" {
continue
}
// Skip markdown headers (# ## ### etc.)
if strings.HasPrefix(line, "#") {
continue
}
// Skip markdown horizontal rules (--- or ***)
if strings.HasPrefix(line, "---") || strings.HasPrefix(line, "***") {
continue
}
// Found a content line - strip markdown formatting
line = stripMarkdownFormatting(line)
// Limit length
if len(line) > 150 {
line = line[:150] + "..."
}
return line
}
// Fallback: if all lines are headers, use first header without # prefix
for _, line := range lines {
line = strings.TrimSpace(line)
if line == "" {
continue
}
// Strip leading # symbols
line = strings.TrimLeft(line, "#")
line = strings.TrimSpace(line)
line = stripMarkdownFormatting(line)
if line != "" {
if len(line) > 150 {
line = line[:150] + "..."
}
return line
}
}
return -1
return ""
}
// stripMarkdownFormatting removes common markdown formatting from text
func stripMarkdownFormatting(s string) string {
// Remove bold/italic markers
s = strings.ReplaceAll(s, "**", "")
s = strings.ReplaceAll(s, "__", "")
s = strings.ReplaceAll(s, "*", "")
s = strings.ReplaceAll(s, "_", "")
// Remove inline code
s = strings.ReplaceAll(s, "`", "")
// Remove link syntax [text](url) -> text
// Simple approach: just remove brackets and parentheses content
for {
start := strings.Index(s, "[")
if start == -1 {
break
}
end := strings.Index(s[start:], "]")
if end == -1 {
break
}
linkEnd := start + end
// Check if followed by (url)
if linkEnd+1 < len(s) && s[linkEnd+1] == '(' {
parenEnd := strings.Index(s[linkEnd+1:], ")")
if parenEnd != -1 {
// Extract just the link text
linkText := s[start+1 : linkEnd]
s = s[:start] + linkText + s[linkEnd+1+parenEnd+1:]
continue
}
}
// Just remove brackets
s = s[:start] + s[start+1:linkEnd] + s[linkEnd+1:]
}
return strings.TrimSpace(s)
}
// Verify Executor implements types.Executor

View file

@ -307,6 +307,137 @@ func TestExtractGoalName(t *testing.T) {
name := extractGoalName(goals)
assert.Equal(t, "First goal", name)
})
t.Run("skips_markdown_h1_header", func(t *testing.T) {
goals := &robottypes.Goals{
Content: "# Goals\nSystem optimization and monitoring",
}
name := extractGoalName(goals)
assert.Equal(t, "System optimization and monitoring", name)
})
t.Run("skips_markdown_h2_header", func(t *testing.T) {
goals := &robottypes.Goals{
Content: "## Goals\n\nPerform system maintenance tasks",
}
name := extractGoalName(goals)
assert.Equal(t, "Perform system maintenance tasks", name)
})
t.Run("skips_multiple_markdown_headers", func(t *testing.T) {
goals := &robottypes.Goals{
Content: "## Goals\n### 1. [High] First Goal\nActual description here",
}
name := extractGoalName(goals)
assert.Equal(t, "Actual description here", name)
})
t.Run("strips_bold_formatting", func(t *testing.T) {
goals := &robottypes.Goals{
Content: "**Important** task to complete",
}
name := extractGoalName(goals)
assert.Equal(t, "Important task to complete", name)
})
t.Run("strips_italic_formatting", func(t *testing.T) {
goals := &robottypes.Goals{
Content: "*Urgent* system update needed",
}
name := extractGoalName(goals)
assert.Equal(t, "Urgent system update needed", name)
})
t.Run("strips_inline_code", func(t *testing.T) {
goals := &robottypes.Goals{
Content: "Run `npm install` command",
}
name := extractGoalName(goals)
assert.Equal(t, "Run npm install command", name)
})
t.Run("skips_empty_lines", func(t *testing.T) {
goals := &robottypes.Goals{
Content: "\n\n\nFirst real content\nSecond line",
}
name := extractGoalName(goals)
assert.Equal(t, "First real content", name)
})
t.Run("fallback_to_header_content_if_only_headers", func(t *testing.T) {
goals := &robottypes.Goals{
Content: "## Goals\n### Tasks",
}
name := extractGoalName(goals)
assert.Equal(t, "Goals", name)
})
t.Run("skips_horizontal_rules", func(t *testing.T) {
goals := &robottypes.Goals{
Content: "---\nActual content here",
}
name := extractGoalName(goals)
assert.Equal(t, "Actual content here", name)
})
t.Run("handles_complex_markdown_content", func(t *testing.T) {
goals := &robottypes.Goals{
Content: "## Goals\n\n### 1. [High] System Maintenance\n**Description**: Perform system optimization based on diagnostic results\n**Reason**: Time-sensitive maintenance",
}
name := extractGoalName(goals)
assert.Equal(t, "Description: Perform system optimization based on diagnostic results", name)
})
}
// ============================================================================
// stripMarkdownFormatting Tests
// ============================================================================
func TestStripMarkdownFormatting(t *testing.T) {
t.Run("strips_bold", func(t *testing.T) {
result := stripMarkdownFormatting("**bold text**")
assert.Equal(t, "bold text", result)
})
t.Run("strips_italic_asterisk", func(t *testing.T) {
result := stripMarkdownFormatting("*italic text*")
assert.Equal(t, "italic text", result)
})
t.Run("strips_italic_underscore", func(t *testing.T) {
result := stripMarkdownFormatting("_italic text_")
assert.Equal(t, "italic text", result)
})
t.Run("strips_inline_code", func(t *testing.T) {
result := stripMarkdownFormatting("`code`")
assert.Equal(t, "code", result)
})
t.Run("strips_link_syntax", func(t *testing.T) {
result := stripMarkdownFormatting("[link text](https://example.com)")
assert.Equal(t, "link text", result)
})
t.Run("preserves_plain_text", func(t *testing.T) {
result := stripMarkdownFormatting("plain text without formatting")
assert.Equal(t, "plain text without formatting", result)
})
t.Run("handles_mixed_formatting", func(t *testing.T) {
result := stripMarkdownFormatting("**bold** and *italic* and `code`")
assert.Equal(t, "bold and italic and code", result)
})
}
// ============================================================================