Local File System

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 adk/backend/local/v0.2.1.

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
    fcontent, err := backend.Read(ctx, &filesystem.ReadRequest{
        FilePath: "/tmp/hello.txt",
    })
    fmt.Println(fcontent.Content)
}

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 does running grep fail with ripgrep (rg) is not installed or not in PATH. Please install it: https://github.com/BurntSushi/ripgrep#installation?

The local Grep command relies on ripgrep by default. If your system does not have ripgrep installed, install it following the official guide.

Q: Does GrepRaw support regex?

Yes. GrepRaw uses ripgrep under the hood for grep operations, so regex patterns are supported.

Q: Windows support?

Not supported, depends on /bin/sh.