fix(test): normalize file separator to make vcr cassette match

Andrey Nering created

Change summary

internal/agent/prompt/prompt.go |  2 +-
internal/agent/tools/bash.go    | 17 ++++++++++++++++-
internal/agent/tools/glob.go    |  7 +++++++
internal/agent/tools/grep.go    |  2 +-
internal/agent/tools/ls.go      |  6 +++---
5 files changed, 28 insertions(+), 6 deletions(-)

Detailed changes

internal/agent/prompt/prompt.go 🔗

@@ -167,7 +167,7 @@ func (p *Prompt) promptData(ctx context.Context, provider, model string, cfg con
 		Provider:   provider,
 		Model:      model,
 		Config:     cfg,
-		WorkingDir: workingDir,
+		WorkingDir: filepath.ToSlash(workingDir),
 		IsGitRepo:  isGit,
 		Platform:   platform,
 		Date:       p.now().Format("1/2/2006"),

internal/agent/tools/bash.go 🔗

@@ -6,6 +6,9 @@ import (
 	_ "embed"
 	"fmt"
 	"html/template"
+	"os"
+	"path/filepath"
+	"runtime"
 	"strings"
 	"time"
 
@@ -289,7 +292,7 @@ func NewBashTool(permissions permission.Service, workingDir string, attribution
 			if stdout == "" {
 				return fantasy.WithResponseMetadata(fantasy.NewTextResponse(BashNoOutput), metadata), nil
 			}
-			stdout += fmt.Sprintf("\n\n<cwd>%s</cwd>", currentWorkingDir)
+			stdout += fmt.Sprintf("\n\n<cwd>%s</cwd>", normalizeWorkingDir(currentWorkingDir))
 			return fantasy.WithResponseMetadata(fantasy.NewTextResponse(stdout), metadata), nil
 		})
 }
@@ -313,3 +316,15 @@ func countLines(s string) int {
 	}
 	return len(strings.Split(s, "\n"))
 }
+
+func normalizeWorkingDir(path string) string {
+	if runtime.GOOS == "windows" {
+		cwd, err := os.Getwd()
+		if err != nil {
+			cwd = "C:"
+		}
+		path = strings.ReplaceAll(path, filepath.VolumeName(cwd), "")
+	}
+
+	return filepath.ToSlash(path)
+}

internal/agent/tools/glob.go 🔗

@@ -53,6 +53,7 @@ func NewGlobTool(workingDir string) fantasy.AgentTool {
 			if len(files) == 0 {
 				output = "No files found"
 			} else {
+				normalizeFilePaths(files)
 				output = strings.Join(files, "\n")
 				if truncated {
 					output += "\n\n(Results are truncated. Consider using a more specific path or pattern.)"
@@ -116,3 +117,9 @@ func runRipgrep(cmd *exec.Cmd, searchRoot string, limit int) ([]string, error) {
 	}
 	return matches, nil
 }
+
+func normalizeFilePaths(paths []string) {
+	for i, p := range paths {
+		paths[i] = filepath.ToSlash(p)
+	}
+}

internal/agent/tools/grep.go 🔗

@@ -150,7 +150,7 @@ func NewGrepTool(workingDir string) fantasy.AgentTool {
 							output.WriteString("\n")
 						}
 						currentFile = match.path
-						fmt.Fprintf(&output, "%s:\n", match.path)
+						fmt.Fprintf(&output, "%s:\n", filepath.ToSlash(match.path))
 					}
 					if match.lineNum > 0 {
 						lineText := match.lineText

internal/agent/tools/ls.go 🔗

@@ -210,9 +210,9 @@ func printTree(tree []*TreeNode, rootPath string) string {
 	var result strings.Builder
 
 	result.WriteString("- ")
-	result.WriteString(rootPath)
+	result.WriteString(filepath.ToSlash(rootPath))
 	if rootPath[len(rootPath)-1] != '/' {
-		result.WriteByte(filepath.Separator)
+		result.WriteByte('/')
 	}
 	result.WriteByte('\n')
 
@@ -228,7 +228,7 @@ func printNode(builder *strings.Builder, node *TreeNode, level int) {
 
 	nodeName := node.Name
 	if node.Type == "directory" {
-		nodeName = nodeName + string(filepath.Separator)
+		nodeName = nodeName + "/"
 	}
 
 	fmt.Fprintf(builder, "%s- %s\n", indent, nodeName)