Files
2026-07-13 12:49:10 +08:00

305 lines
9.9 KiB
Go

/*
* Copyright 2025 CloudWeGo Authors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
// Package filesystem provides file system operations.
package filesystem
import (
"context"
"github.com/cloudwego/eino/schema"
)
// FileInfo represents basic file metadata information.
type FileInfo struct {
// Path is the path of the file or directory, which can be a filename, relative path, or absolute path.
Path string
// IsDir indicates whether the entry is a directory.
// true for directories, false for regular files.
IsDir bool
// Size is the file size in bytes.
// For directories, this value may be 0 or platform-dependent.
Size int64
// ModifiedAt is the last modification time in ISO 8601 format.
// Example: "2025-01-15T10:30:00Z"
ModifiedAt string
}
// GrepMatch represents a single pattern match result.
type GrepMatch struct {
Content string
// Path is the file path where the match was found.
Path string
// Line is the 1-based line number of the match.
Line int
}
// LsInfoRequest contains parameters for listing file information.
type LsInfoRequest struct {
// Path specifies the directory path to list.
Path string
}
// ReadRequest contains parameters for reading file content.
type ReadRequest struct {
// FilePath is the path to the file to be read.
FilePath string
// Offset specifies the starting line number (1-based) for reading.
// Line 1 is the first line of the file.
// Use this when the file is too large to read at once.
// Defaults to 1 (start from the first line).
// Values < 1 will be treated as 1.
Offset int
// Limit specifies the maximum number of lines to read.
// When Limit is 0 (default), the entire file content is returned.
Limit int
}
// MultiModalReadRequest extends ReadRequest with parameters only applicable
// to MultiModalReader implementations (e.g. PDF page ranges).
type MultiModalReadRequest struct {
ReadRequest
// Pages specifies the page range for PDF files (e.g. "1-5", "3", "10-20").
Pages string
}
// GrepRequest contains parameters for searching file content.
type GrepRequest struct {
// ===== Search Parameters =====
// Pattern is the search pattern, supports full regular expression syntax.
// Uses ripgrep syntax (not grep). Examples:
// - "log.*Error" matches lines with "log" followed by "Error"
// - "function\\s+\\w+" matches "function" followed by whitespace and word characters
// - Literal braces need escaping: "interface\\{\\}" matches "interface{}"
Pattern string
// Path is an optional directory path to limit the search scope.
Path string
// ===== File Filtering =====
// Glob is an optional pattern to filter the files to be searched.
// It filters by file path, not content. If empty, no files are filtered.
// Supports standard glob wildcards:
// - `*` matches any characters except path separators.
// - `**` matches any directories recursively.
// - `?` matches a single character.
// - `[abc]` matches one character from the set.
Glob string
// FileType is the file type filter, e.g., "js", "py", "rust".
// More efficient than Glob for standard file types.
FileType string
// ===== Search Options =====
// CaseInsensitive enables case insensitive search.
CaseInsensitive bool
// EnableMultiline enables multiline mode where patterns can span lines.
// Default: false (patterns match within single lines only).
EnableMultiline bool
// ===== Context Display (Content mode only) =====
// AfterLines shows N lines after each match.
// Only applicable when OutputMode is "content".
// Values <= 0 are treated as unset.
AfterLines int
// BeforeLines shows N lines before each match.
// Only applicable when OutputMode is "content".
// Values <= 0 are treated as unset.
BeforeLines int
}
// GlobInfoRequest contains parameters for glob pattern matching.
type GlobInfoRequest struct {
// Pattern is the glob expression used to match file paths.
// It supports standard glob syntax:
// - `*` matches any characters except path separators.
// - `**` matches any directories recursively.
// - `?` matches a single character.
// - `[abc]` matches one character from the set.
Pattern string
// Path is the base directory from which to start the search.
Path string
}
// WriteRequest contains parameters for writing file content.
type WriteRequest struct {
// FilePath is the path of the file to write.
FilePath string
// Content is the data to be written to the file.
Content string
}
// EditRequest contains parameters for editing file content.
type EditRequest struct {
// FilePath is the path of the file to edit.
FilePath string
// OldString is the exact string to be replaced. It must be non-empty and will be matched literally, including whitespace.
OldString string
// NewString is the string that will replace OldString.
// It must be different from OldString.
// An empty string can be used to effectively delete OldString.
NewString string
// ReplaceAll controls the replacement behavior.
// If true, all occurrences of OldString are replaced.
// If false, the operation fails unless OldString appears exactly once in the file.
ReplaceAll bool
}
// FileContentPartType defines the type of a multimodal file content part.
type FileContentPartType string
const (
// FileContentPartTypeImage represents an image part (e.g. PNG, JPG).
FileContentPartTypeImage FileContentPartType = "image"
// FileContentPartTypePDF represents a file part (e.g. PDF).
FileContentPartTypePDF FileContentPartType = "pdf"
)
// FileContentPart represents a multimodal part of file content.
// Data holds raw bytes; encoding (e.g. base64) is handled by the consumer.
type FileContentPart struct {
// Type is the kind of content this part represents.
// Required.
Type FileContentPartType
// MIMEType is the MIME type of the content (e.g. "image/png", "application/pdf").
// Required.
MIMEType string
// Data is the raw binary content.
// Required.
Data []byte
}
// FileContent holds the result of a Read operation.
type FileContent struct {
// Content holds the plain text content of the file.
Content string
}
// MultiFileContent holds the result of a MultiModalRead operation.
//
// FileContent and Parts are mutually exclusive (one-of):
// - Set FileContent for plain text results (same as a normal Read).
// - Set Parts for multimodal results (images, PDFs, etc.).
//
// When Parts is non-empty, FileContent is ignored.
type MultiFileContent struct {
*FileContent
// Parts holds multimodal output parts (e.g. image, PDF).
Parts []FileContentPart
}
// MultiModalReader is an optional extension interface for Backend.
// Backends that implement this interface support multimodal file reading,
// returning structured parts (images, PDFs) instead of plain text.
//
// For large file handling, there are two approaches to control output size:
// - Implement size control within MultiModalRead (e.g. reject files exceeding a threshold,
// downsample images, or limit PDF page counts at the backend level).
// - Use ToolMiddleware's EnhancedInvokable to customize result transformation,
// or use the built-in reduction middleware with configurable policies.
type MultiModalReader interface {
MultiModalRead(ctx context.Context, req *MultiModalReadRequest) (*MultiFileContent, error)
}
// Backend is a pluggable, unified file backend protocol interface.
//
// All methods use struct-based parameters to allow future extensibility
// without breaking backward compatibility.
type Backend interface {
// LsInfo lists file information under the given path.
//
// Returns:
// - []FileInfo: List of matching file information
// - error: Error if the operation fails
LsInfo(ctx context.Context, req *LsInfoRequest) ([]FileInfo, error)
// Read reads file content with support for line-based offset and limit.
//
// Returns:
// - string: The file content read
// - error: Error if file does not exist or read fails
Read(ctx context.Context, req *ReadRequest) (*FileContent, error)
// GrepRaw searches for content matching the specified pattern in files.
//
// Returns:
// - []GrepMatch: List of all matching results
// - error: Error if the search fails
GrepRaw(ctx context.Context, req *GrepRequest) ([]GrepMatch, error)
// GlobInfo returns file information matching the glob pattern.
//
// Returns:
// - []FileInfo: List of matching file information
// - error: Error if the pattern is invalid or operation fails
GlobInfo(ctx context.Context, req *GlobInfoRequest) ([]FileInfo, error)
// Write creates or updates file content.
//
// Returns:
// - error: Error if the write operation fails
Write(ctx context.Context, req *WriteRequest) error
// Edit replaces string occurrences in a file.
//
// Returns:
// - error: Error if file does not exist, OldString is empty, or OldString is not found
Edit(ctx context.Context, req *EditRequest) error
}
// ExecuteRequest contains parameters for executing a command.
type ExecuteRequest struct {
Command string // The command to execute
RunInBackendGround bool
}
// ExecuteResponse contains the response result of command execution.
type ExecuteResponse struct {
Output string // Command output content
ExitCode *int // Command exit code
Truncated bool // Whether the output was truncated
}
type Shell interface {
Execute(ctx context.Context, input *ExecuteRequest) (result *ExecuteResponse, err error)
}
type StreamingShell interface {
ExecuteStreaming(ctx context.Context, input *ExecuteRequest) (result *schema.StreamReader[*ExecuteResponse], err error)
}