Commit 8e5cd0f
Changed files (1)
cmd
del
cmd/del/main.go
@@ -67,13 +67,13 @@ func NewDel(model string) *Del {
Content: `You are Del, an AI coding assistant. When users need file operations or code analysis, use your available tools.
Available tools:
-- read_file: Read file contents (requires: path)
-- list_dir: List directory contents (optional: path, defaults to current dir)
-- run_command: Execute shell commands (requires: command)
-- git_status: Check git repository status (no args needed)
-- write_file: Write content to files (requires: path, content)
-- analyze_code: Analyze code structure (optional: path, content, language - auto-detects files if none provided)
-- search_code: Search for patterns in code (requires: pattern, optional: path)
+- read_file: Read file contents
+- list_dir: List directory contents
+- run_command: Execute shell commands
+- git_status: Check git repository status
+- write_file: Write content to files
+- analyze_code: Analyze code structure (auto-detects files if no path provided)
+- search_code: Search for patterns in code
Use tools by generating calls in this format:
function<|tool▁sep|>tool_name
@@ -85,7 +85,15 @@ EXAMPLES:
- When user says "read main.go": use read_file with {"path": "main.go"}
- When user says "check git status": use git_status with {}
-IMPORTANT: Stop immediately after making tool calls. Don't generate fake results or outputs.`,
+FORMATTING: Always format your responses using markdown. Use:
+- ## Headers for main sections
+- **bold** for important terms
+- backticks for inline code, file names, and commands
+- - bullet points for lists
+- 1. numbered lists for steps
+- code blocks for multi-line code
+
+IMPORTANT: Use tools first, then provide a natural markdown response based on the results.`,
},
},
}
@@ -107,6 +115,102 @@ func isCodeFile(name string) bool {
strings.HasSuffix(name, ".rb") || strings.HasSuffix(name, ".php")
}
+// ANSI color codes for terminal formatting
+const (
+ ColorReset = "\033[0m"
+ ColorBold = "\033[1m"
+ ColorDim = "\033[2m"
+ ColorItalic = "\033[3m"
+ ColorRed = "\033[31m"
+ ColorGreen = "\033[32m"
+ ColorYellow = "\033[33m"
+ ColorBlue = "\033[34m"
+ ColorPurple = "\033[35m"
+ ColorCyan = "\033[36m"
+ ColorWhite = "\033[37m"
+ ColorGray = "\033[90m"
+)
+
+// renderMarkdown converts markdown text to terminal-formatted output
+func renderMarkdown(text string) string {
+ lines := strings.Split(text, "\n")
+ var result []string
+ inCodeBlock := false
+
+ for _, line := range lines {
+ // Code blocks
+ if strings.HasPrefix(line, "```") {
+ inCodeBlock = !inCodeBlock
+ if inCodeBlock {
+ result = append(result, ColorGray+"┌─────────────────────────────────────────────────────────┐"+ColorReset)
+ } else {
+ result = append(result, ColorGray+"└─────────────────────────────────────────────────────────┘"+ColorReset)
+ }
+ continue
+ }
+
+ if inCodeBlock {
+ result = append(result, ColorGray+"│ "+ColorCyan+line+ColorReset+ColorGray+" │"+ColorReset)
+ continue
+ }
+
+ // Headers
+ if strings.HasPrefix(line, "### ") {
+ header := strings.TrimPrefix(line, "### ")
+ result = append(result, "")
+ result = append(result, ColorBold+ColorBlue+"▸ "+header+ColorReset)
+ continue
+ }
+ if strings.HasPrefix(line, "## ") {
+ header := strings.TrimPrefix(line, "## ")
+ result = append(result, "")
+ result = append(result, ColorBold+ColorGreen+"◆ "+header+ColorReset)
+ continue
+ }
+ if strings.HasPrefix(line, "# ") {
+ header := strings.TrimPrefix(line, "# ")
+ result = append(result, "")
+ result = append(result, ColorBold+ColorYellow+"● "+header+ColorReset)
+ continue
+ }
+
+ // Lists
+ if strings.HasPrefix(line, "- ") || regexp.MustCompile(`^\d+\. `).MatchString(line) {
+ // Handle numbered lists
+ if regexp.MustCompile(`^\d+\. `).MatchString(line) {
+ parts := regexp.MustCompile(`^(\d+)\. (.*)$`).FindStringSubmatch(line)
+ if len(parts) == 3 {
+ line = ColorBold+ColorBlue+parts[1]+"."+ColorReset+" "+parts[2]
+ }
+ } else {
+ // Handle bullet lists
+ content := strings.TrimPrefix(line, "- ")
+ line = ColorBold+ColorGreen+"•"+ColorReset+" "+content
+ }
+ result = append(result, " "+line)
+ continue
+ }
+
+ // Inline code
+ line = regexp.MustCompile("`([^`]+)`").ReplaceAllString(line, ColorCyan+"$1"+ColorReset)
+
+ // Bold text
+ line = regexp.MustCompile(`\*\*([^*]+)\*\*`).ReplaceAllString(line, ColorBold+"$1"+ColorReset)
+
+ // Italic text
+ line = regexp.MustCompile(`\*([^*]+)\*`).ReplaceAllString(line, ColorItalic+"$1"+ColorReset)
+
+ // Empty lines for spacing
+ if strings.TrimSpace(line) == "" {
+ result = append(result, "")
+ } else {
+ result = append(result, line)
+ }
+ }
+
+ return strings.Join(result, "\n")
+}
+
func (d *Del) registerTools() {
d.tools["read_file"] = d.readFile
d.tools["list_dir"] = d.listDir
@@ -714,25 +818,11 @@ func (d *Del) formatArgs(args map[string]interface{}) string {
}
func (d *Del) streamResponseChunks(ctx context.Context, text string) {
- // Real streaming simulation - send in meaningful chunks
- words := strings.Fields(text)
- for i, word := range words {
- d.emit(StreamMessage{
- Type: MessageTypeAssistant,
- Content: word,
- })
-
- // Natural pause between words
- if i < len(words)-1 {
- d.emit(StreamMessage{
- Type: MessageTypeAssistant,
- Content: " ",
- })
- }
-
- // Small delay for natural typing feel
- time.Sleep(20 * time.Millisecond)
- }
+ // Instead of word-by-word streaming, send the full response for better markdown rendering
+ d.emit(StreamMessage{
+ Type: MessageTypeAssistant,
+ Content: text,
+ })
}
func (d *Del) processMessage(ctx context.Context, userInput string) {
@@ -811,11 +901,24 @@ func (d *Del) renderUI() {
currentLine = ""
case MessageTypeAssistant:
- if currentLine == "" {
- fmt.Print("🤖 Del: ")
+ if currentLine != "" {
+ fmt.Println()
}
- fmt.Print(msg.Content)
- currentLine += msg.Content
+ fmt.Print("🤖 Del: ")
+
+ // Render markdown content
+ rendered := renderMarkdown(msg.Content)
+
+ // Indent the content to align with the prefix
+ lines := strings.Split(rendered, "\n")
+ for i, line := range lines {
+ if i == 0 {
+ fmt.Println(line)
+ } else {
+ fmt.Printf(" %s\n", line) // 8 spaces to align with "🤖 Del: "
+ }
+ }
+ currentLine = ""
case MessageTypeTool:
if currentLine != "" {