[Bug] ADK virtual filesystem paths are cleaned with filepath, so InMemoryBackend and its middlewares return nothing on Windows
Describe the bug
The ADK treats filesystem.Backend paths as virtual, slash-separated paths — InMemoryBackend's glob and prefix matching hard-code /:
// backend_inmemory.go
matchPath = strings.TrimPrefix(normalizedFilePath, basePath+"/")
matched, err := doublestar.Match(globPattern, matchPath) // "/" is the separator
return filepath.Clean(path) // ← but this is host-dependentnormalizePath (and path.Base / path.Ext call sites) uses path/filepath, so on Windows every stored path is rewritten with backslashes (/skills/my-skill/SKILL.md → \skills\my-skill\SKILL.md) while the matching above still assumes /. Nothing matches, and the backend returns an empty result set instead of an error.
The same pattern runs through the ADK middlewares that read and write through the backend (filepath.Join, filepath.Dir, filepath.Base), so they also stop finding the files they just wrote.
To Reproduce
On Windows:
$ go test ./adk/filesystem/... ./adk/middlewares/skill/... ./adk/middlewares/agentsmd/... \
./adk/middlewares/filesystem/... ./adk/middlewares/plantask/... \
./adk/middlewares/reduction/... ./adk/middlewares/agentsmd/...
FAIL github.com/cloudwego/eino/adk/filesystem
FAIL github.com/cloudwego/eino/adk/middlewares/agentsmd
FAIL github.com/cloudwego/eino/adk/middlewares/filesystem
FAIL github.com/cloudwego/eino/adk/middlewares/plantask
FAIL github.com/cloudwego/eino/adk/middlewares/reduction
FAIL github.com/cloudwego/eino/adk/middlewares/skilladk/filesystem fails TestInMemoryBackend_LsInfo / TestInMemoryBackend_GlobInfo; the middlewares fail because a file written through the backend is not found again (file not found), e.g. plantask "Task created successfully" followed by TaskGet get Task #1 failed, err: file not found.
A minimal shape:
backend := filesystem.NewInMemoryBackend()
_ = backend.Write(ctx, &filesystem.WriteRequest{FilePath: "/tasks/1.json", Content: "{}"})
// LsInfo/GlobInfo on "/tasks" returns nothing on Windows, the file on LinuxExpected behavior
Paths of a virtual backend should not depend on the host OS. The in-memory backend and the ADK middlewares should use the slash-only path package for these paths (path.Clean/Base/Ext/Join/Dir), so behaviour is identical on every platform. filepath stays correct for the real-OS reads/writes that exist in adk/prebuilt/deep tests.
Version:
main (v0.9.x).
Environment:
$ go version
go version go1.26.2 windows/amd64Additional context
- CI runs
ubuntu-latestonly, wherepath.Clean == filepath.Clean, so this is invisible upstream and only affects Windows users. InMemoryBackendis the onlyBackendimplementation in-tree and is exported API, so this is not a test-only concern.- Secondary test-quality issue on the same path:
adk/middlewares/skill/filesystem_backend_test.goindexesskills[0]without a length assertion, so the real failure surfaces aspanic: index out of rangeinstead of a clear assertion.
A PR follows that fixes the backend, the five middlewares that use it, and their test helpers.
Source: cloudwego/eino