deepagents icon indicating copy to clipboard operation
deepagents copied to clipboard

Fix Windows Path Handling in Filesystem Operations

Open EgoAlpha opened this issue 5 months ago • 1 comments

Fix Windows Path Handling in Filesystem Operations

Summary

This PR fixes Windows path handling issues in the filesystem backend and middleware that prevented proper file operations on Windows systems. **Fixes #340 **

Problem

The codebase had multiple issues with Windows path handling:

  1. Path Validation Issue: The _validate_path() function in middleware incorrectly added a leading slash to Windows absolute paths (e.g., C:/Users/... became /C:/Users/...), breaking path resolution in the backend.

  2. Inconsistent Path Separators: The FilesystemBackend.ls_info() method mixed Windows backslashes and POSIX forward slashes, causing test failures and inconsistent behavior (e.g., returning /\local.txt instead of /local.txt).

Reproduction Steps

This procedure demonstrates the incorrect path handling on Windows:

  1. Environment: Win10, Powershell (or any Windows terminal).
  2. Setup: Checkout the commit (9ed6483e...) and run the application:
    cd libs\deepagents-cli
    uv run deepagents
    
  3. Execute the Command: Ask the deep agent to list the contents of the current working directory
  4. Agent move The agent will use tool ls(.)
  5. Observed Failure: The agent incorrectly reports that the directory is empty.

⚠️ Temporary File Modification Required for Testing ⚠️ We might need to add an exception handler for ModuleNotFoundError: No module named 'termios' within execution.py to ensure successful startup of deepagents on Windows environments. This module is typically Unix-specific, and catching the exception would allow the program to gracefully proceed without terminal control features

Root Cause

When an AI agent called ls("C:\..."):

  1. Middleware's _validate_path() normalized it to /C:/... (added leading /)
  2. FilesystemBackend._resolve_path() treated this as a relative path
  3. Path resolution failed, resulting in empty directory listings

In backends/filesystem.py: ls_info

dir_path = self._resolve_path(path)
if not dir_path.exists() or not dir_path.is_dir():
    return [] # <--

Additionally, the backend's ls_info() returned paths with mixed separators on Windows, breaking cross-platform compatibility.

Solution

1. Improved Windows Path Detection (middleware/filesystem.py)

Before:

if not normalized.startswith("/") and not (len(normalized) >= 2 and normalized[1] == ":"):
    normalized = f"/{normalized}"

After:

# Use os.path.splitdrive for robust Windows path detection
drive, _ = os.path.splitdrive(normalized)
if not normalized.startswith("/") and not drive:
    normalized = f"/{normalized}"

Benefits:

  • Handles Windows drive letters correctly (e.g., C:, D:)
  • Supports UNC paths (e.g., \\server\share)
  • Prevents incorrectly adding leading slash to Windows absolute paths

2. Consistent POSIX-Style Path Normalization (backends/filesystem.py)

Updated ls_info(), grep_raw(), and glob_info() to consistently normalize all returned paths to POSIX style (forward slashes only):

# Normalize to POSIX style (forward slashes only) for consistency
abs_path = abs_path.replace("\\", "/")
relative_path = relative_path.replace("\\", "/")

Benefits:

  • Consistent path format across platforms

3. Updated Tests for Cross-Platform Compatibility

Modified test assertions to normalize paths before comparison:

# Before
assert str(root / "file1.txt") in root_paths

# After
assert str(root / "file1.txt").replace("\\", "/") in root_paths

Unit Tests on Windows

Before Fix

FAILED libs/deepagents/tests/unit_tests/backends/test_filesystem_backend.py::test_filesystem_backend_normal_mode
FAILED libs/deepagents/tests/unit_tests/backends/test_filesystem_backend.py::test_filesystem_backend_virtual_mode
FAILED libs/deepagents/tests/unit_tests/backends/test_filesystem_backend.py::test_filesystem_backend_ls_nested_directories
FAILED libs/deepagents/tests/unit_tests/backends/test_composite_backend.py::test_composite_backend_filesystem_plus_store
FAILED libs/deepagents/tests/unit_tests/backends/test_composite_backend.py::test_composite_backend_ls_nested_directories

5 failed, 73 passed

After Fix

78 passed

EgoAlpha avatar Nov 08 '25 17:11 EgoAlpha

Thanks! This is blocking me selecting deepagents🫡

wey-gu avatar Nov 25 '25 23:11 wey-gu