Backend: Local FileSystem

Local Backend

Package: github.com/cloudwego/eino-ext/adk/backend/local

Note: If your eino version is v0.8.0 or above, you need to use local backend v0.2.0-alpha version.

Overview

Local Backend is the local file system implementation of EINO ADK FileSystem, directly operating on the local file system, providing native performance and zero-configuration experience.

Core Features

  • Zero Configuration - Works out of the box
  • Native Performance - Direct file system access, no network overhead
  • Path Safety - Enforces absolute paths
  • Streaming Execution - Supports real-time command output streaming
  • Command Validation - Optional security validation hooks

Installation

go get github.com/cloudwego/eino-ext/adk/backend/local

Configuration

type Config struct {
    // Optional: Command validation function for Execute() security control
    ValidateCommand func(string) error
}

Quick Start

Basic Usage

import (
    "context"

    "github.com/cloudwego/eino-ext/adk/backend/local"
    "github.com/cloudwego/eino/adk/filesystem"
)

func main() {
    ctx := context.Background()

    backend, err := local.NewBackend(ctx, &local.Config{})
    if err != nil {
        panic(err)
    }

    // Write file (must be absolute path)
    err = backend.Write(ctx, &filesystem.WriteRequest{
        FilePath: "/tmp/hello.txt",
        Content:  "Hello, Local Backend!",
    })

    // Read file
    content, err := backend.Read(ctx, &filesystem.ReadRequest{
        FilePath: "/tmp/hello.txt",
    })
}

With Command Validation

func validateCommand(cmd string) error {
    allowed := map[string]bool{"ls": true, "cat": true, "grep": true}
    parts := strings.Fields(cmd)
    if len(parts) == 0 || !allowed[parts[0]] {
        return fmt.Errorf("command not allowed: %s", parts[0])
    }
    return nil
}

backend, _ := local.NewBackend(ctx, &local.Config{
    ValidateCommand: validateCommand,
})

Integration with Agent

import (
    "github.com/cloudwego/eino/adk"
    fsMiddleware "github.com/cloudwego/eino/adk/middlewares/filesystem"
)

// Create Backend
backend, _ := local.NewBackend(ctx, &local.Config{})

// Create Middleware
middleware, _ := fsMiddleware.New(ctx, &fsMiddleware.Config{
    Backend: backend,
    StreamingShell: backend,
})

// Create Agent
agent, _ := adk.NewChatModelAgent(ctx, &adk.ChatModelAgentConfig{
    Name:        "LocalFileAgent",
    Description: "AI Agent with local file system access capabilities",
    Model:       chatModel,
    Handlers:    []adk.ChatModelAgentMiddleware{middleware},
})

API Reference

MethodDescription
LsInfoList directory contents
ReadRead file content (supports pagination, default 200 lines)
WriteCreate new file (error if exists)
EditReplace file content
GrepRawSearch file content (literal match)
GlobInfoFind files by pattern
ExecuteExecute shell commands
ExecuteStreamingExecute commands with streaming output

Examples

// List directory
files, _ := backend.LsInfo(ctx, &filesystem.LsInfoRequest{
    Path: "/home/user",
})

// Read file (paginated)
content, _ := backend.Read(ctx, &filesystem.ReadRequest{
    FilePath: "/path/to/file.txt",
    Offset:   0,
    Limit:    50,
})

// Search content (literal match, not regex)
matches, _ := backend.GrepRaw(ctx, &filesystem.GrepRequest{
    Path:    "/home/user/project",
    Pattern: "TODO",
    Glob:    "*.go",
})

// Find files
files, _ := backend.GlobInfo(ctx, &filesystem.GlobInfoRequest{
    Path:    "/home/user",
    Pattern: "**/*.go",
})

// Edit file
backend.Edit(ctx, &filesystem.EditRequest{
    FilePath:   "/tmp/file.txt",
    OldString:  "old",
    NewString:  "new",
    ReplaceAll: true,
})

// Execute command
result, _ := backend.Execute(ctx, &filesystem.ExecuteRequest{
    Command: "ls -la /tmp",
})

// Streaming execution
reader, _ := backend.ExecuteStreaming(ctx, &filesystem.ExecuteRequest{
    Command: "tail -f /var/log/app.log",
})
for {
    resp, err := reader.Recv()
    if err == io.EOF {
        break
    }
    fmt.Print(resp.Stdout)
}

Path Requirements

All paths must be absolute paths (starting with /):

// Correct
backend.Read(ctx, &filesystem.ReadRequest{FilePath: "/home/user/file.txt"})

// Incorrect
backend.Read(ctx, &filesystem.ReadRequest{FilePath: "./file.txt"})

Convert relative paths:

absPath, _ := filepath.Abs("./relative/path")

Comparison with Agentkit Backend

FeatureLocalAgentkit
Execution ModelLocal DirectRemote Sandbox
Network DependencyNoneRequired
Configuration ComplexityZero ConfigRequires Credentials
Security ModelOS PermissionsIsolated Sandbox
Streaming OutputSupportedNot Supported
Platform SupportUnix/Linux/macOSAny
Use CasesDevelopment/LocalMulti-tenant/Production

FAQ

Q: Why are absolute paths required?

To prevent directory traversal attacks. Use filepath.Abs() to convert.

Q: Write fails

File already exists (security feature), path is not absolute, or insufficient permissions.

Q: Does GrepRaw support regex?

No, it uses literal matching. For regex, use Execute to call system grep.

Q: Windows support?

Not supported, depends on /bin/sh.


Last modified March 2, 2026: feat: sync eino docs (#1512) (96139d41)