pub trait FsBackend: Send + Sync {
// Required methods
fn read_text(
&self,
path: PathBuf,
line: Option<u32>,
limit: Option<u32>,
) -> BoxFuture<'_, Result<String, FsError>>;
fn write_text(
&self,
path: PathBuf,
content: String,
) -> BoxFuture<'_, Result<(), FsError>>;
// Provided methods
fn read_bytes(
&self,
path: PathBuf,
) -> BoxFuture<'_, Result<Vec<u8>, FsError>> { ... }
fn fingerprint(
&self,
path: PathBuf,
) -> BoxFuture<'_, Result<Fingerprint, FsError>> { ... }
}Expand description
Fs backend trait.
Two verbs cover all low-level operations of the fs tool family:
edit_fileis composed at the tool layer (firstread_textthenwrite_text); the backend is unaware of patch semantics- Delete / move / mkdir are not part of the fs tool family (ACP has no
corresponding inverse methods);
the LLM uses
bash
Parameters use owned PathBuf / String to confine the future’s lifetime to &'_ self,
avoiding explicit lifetime parameters; same trade-off as LlmProvider::complete.
Required Methods§
Sourcefn read_text(
&self,
path: PathBuf,
line: Option<u32>,
limit: Option<u32>,
) -> BoxFuture<'_, Result<String, FsError>>
fn read_text( &self, path: PathBuf, line: Option<u32>, limit: Option<u32>, ) -> BoxFuture<'_, Result<String, FsError>>
Reads the entire file as UTF-8 text.
line / limit have the same semantics as ACP ReadTextFileRequest:
line = Some(n)starts reading from line n (1-based)limit = Some(k)reads at most k lines- Both
Nonereads the full file
Sourcefn write_text(
&self,
path: PathBuf,
content: String,
) -> BoxFuture<'_, Result<(), FsError>>
fn write_text( &self, path: PathBuf, content: String, ) -> BoxFuture<'_, Result<(), FsError>>
Write a UTF-8 text file, overwriting any existing content.
The backend is responsible for ensuring the parent directory exists (mkdir -p
semantics).
Line-ending / atomicity responsibilities are split as:
- Local backend performs line-ending normalization and atomic write via
tmp + rename - Delegated backend leaves the decision to the client
Provided Methods§
Sourcefn read_bytes(&self, path: PathBuf) -> BoxFuture<'_, Result<Vec<u8>, FsError>>
fn read_bytes(&self, path: PathBuf) -> BoxFuture<'_, Result<Vec<u8>, FsError>>
Reads the raw bytes of an entire file. The read_file tool takes this path when
it detects a binary type such as an image, passing the bytes to the caller for
base64 encoding into a multimodal tool_result.
The default implementation returns FsError::NotPermitted — the delegated
backend (AcpFsBackend) uses the ACP fs/read_text_file reverse channel, which
is text-only and cannot obtain binary data. In ACP environments, reading images is
discouraged by the system prompt (the # Environment section notes that the
frontend is delegated). The local backend (LocalFsBackend) overrides this to
read directly from disk.
Sourcefn fingerprint(
&self,
path: PathBuf,
) -> BoxFuture<'_, Result<Fingerprint, FsError>>
fn fingerprint( &self, path: PathBuf, ) -> BoxFuture<'_, Result<Fingerprint, FsError>>
Returns a “content fingerprint” used by edit_file to detect concurrent write
conflicts in the read–modify–write window.
The default implementation reads the full content via FsBackend::read_text and
computes Fingerprint::of — this allows delegating backends (e.g.
AcpFsBackend) to work without additional protocol methods. Local backends may
override this method to use cheaper checks like mtime + size.
Dyn Compatibility§
This trait is dyn compatible.
In older versions of Rust, dyn compatibility was called "object safety".