Workspace Backends

Workspace backends decide where built-in workspace tools read and write files. The default is the local filesystem rooted at the session workspace. All four SDKs expose configuration for local files, S3-compatible object storage, and an optional HTTP/JSON remote git provider. Go uses value configurations where Node.js and Python use backend objects.

Use this surface when the host owns workspace placement: local development, browser or container workspaces, object-storage workspaces, or managed sessions. Rust hosts can also supply their own backend by implementing the workspace traits; see Host-provided Backend.

Feature Flags

The local backend and remote git are always compiled in. The S3 backend is behind the Cargo feature s3, which the server and full features include (core/Cargo.toml); the Core default feature set is local-code only.

PackageS3 in the published build
a3s-code-core (Rust)Only when you enable s3, server, or full.
@a3s-lab/code (Node.js)Yes; the published addon is built with advanced-harness,server.
a3s-code (Python)Yes; the published wheel is built with server. Without it, S3WorkspaceBackend is not exported.
Go bridge (a3s-code-go-bridge)No; the published bridge uses default features, so an S3 backend fails with FEATURE_DISABLED. Build the bridge with --features s3 (or server) to enable it.

Capability Matrix

BackendFile toolsSearch toolsShell and local git
Default local workspaceread, write, edit, patch, download, lssearch (grep, glob, bm25 modes)bash, git
LocalWorkspaceBackendSame as default local workspaceSame as default local workspaceSame as default local workspace
S3WorkspaceBackendread, write, edit, patch, lsOptional search when searchEnabled is setNot registered
S3WorkspaceBackend + remoteGitS3 file toolsOptional degraded S3 searchgit through remote git, no bash
Host-provided (Rust)read, write, edit, patch, lssearch when the host attaches searchOnly what the host attaches

download is registered only for a writable local root. code_symbols, code_navigation, and code_diagnostics are registered only when the backend carries a code-intelligence provider; the default local backend has none.

Object storage cannot service local processes. Do not promise shell execution on an S3 workspace unless the host provides a separate sandbox through MCP or A3S Box.

Local Backend

The explicit local backend is useful when host code wants one option surface for both local and remote sessions.

Rust
Node.js
Python
Go
Rust
use a3s_code_core::{Agent, SessionOptions, WorkspaceServices};
#[tokio::main]
async fn main() -> a3s_code_core::Result<()> {
let agent = Agent::new("agent.acl").await?;
let backend = WorkspaceServices::local("/repo");
let session = agent
.session_builder("/repo")
.options(SessionOptions::new().with_workspace_backend(backend))
.build()
.await?;
println!("{}", session.read_file("Cargo.toml").await?);
session.close().await;
agent.close().await;
Ok(())
}

Local download sink

A writable local backend also registers download. The tool accepts a public HTTP(S) url and writes only to a workspace-relative file_path; omitting the path produces a sanitized inferred filename. It is absent from S3 and other non-local backends because atomic adjacent temporary files, cancellation cleanup, symlink checks, and final promotion require local filesystem semantics.

overwrite defaults to false. Transfers default to a 512 MiB max_bytes limit and a 300-second timeout, with hard limits of 8 GiB and 3600 seconds. Range concurrency is adaptive or explicitly bounded to 1–4 connections, and expected_sha256 can require a 64-character hexadecimal digest before the destination is promoted. See Tools for transport and metadata details.

S3 Backend

S3WorkspaceBackend points the built-in file tools at any S3-compatible service, including AWS S3, MinIO, RustFS, Cloudflare R2, and Backblaze B2.

Rust
Node.js
Python
Go

The Rust crate must be built with its s3 feature.

S3 search is intentionally opt-in. When enabled, grep / glob degrade to object listing and bounded downloads. Configure maxObjectsScanned, maxGrepBytesPerObject, and searchConcurrency when the bucket can be large or the endpoint rate-limits.

S3 Options

Node.js optionPython optionRequiredPurpose
bucketbucketyesS3 bucket that stores the workspace objects.
prefixprefixyesLogical workspace root inside the bucket; use "" for the bucket root.
accessKeyIdaccess_key_idyesAccess key id, normally read from the host environment.
secretAccessKeysecret_access_keyyesSecret access key, normally read from the host environment or a secret manager.
endpointendpointnoCustom S3-compatible endpoint; omit for AWS S3 defaults.
regionregionnoRegion, defaulting to us-east-1 when omitted.
sessionTokensession_tokennoSTS session token when temporary credentials are used.
forcePathStyleforce_path_stylenoSet true for MinIO, RustFS, and most non-AWS endpoints.
maxReadBytesmax_read_bytesnoPer-read size ceiling; defaults to 10 MiB.
searchEnabledsearch_enablednoEnables degraded S3 grep / glob; defaults to false.
maxObjectsScannedmax_objects_scannednoPer-search object scan cap; defaults to 500. Used only when search is enabled.
maxGrepBytesPerObjectmax_grep_bytes_per_objectnoPer-object grep download cap; defaults to 1 MiB. Used only with search.
searchConcurrencysearch_concurrencynoConcurrent grep object downloads; defaults to 8. Used only with search.

Go exposes the same fields on S3BackendConfig: Bucket, Prefix, AccessKeyID, SecretAccessKey, Endpoint, Region, SessionToken, ForcePathStyle, MaxReadBytes, SearchEnabled, MaxObjectsScanned, MaxGrepBytesPerObject, and SearchConcurrency. Go additionally accepts RequestTimeoutMS, a per-request S3 timeout that the Node.js and Python backends do not expose.

Remote Git

remoteGit attaches an HTTP/JSON git provider on top of workspaceBackend. It is designed for non-local workspaces where the built-in git tool cannot use a local .git directory.

remoteGit requires workspaceBackend; passing it alone is rejected.

Rust
Node.js
Python
Go

Keep remote git credentials out of agent.acl and agent directories. Inject them from the host environment or secret manager.

Remote Git Options

Node.js optionPython optionRequiredPurpose
baseUrlbase_urlyesRemote git service base URL, without a trailing slash.
repoIdrepo_idyesOpaque repository id negotiated with the remote git service.
bearerTokenbearer_tokenproductionBearer credential for the remote git service; omit only in trusted development setups.
clientCertPemclient_cert_pemnomTLS client certificate path; must be paired with the client key.
clientKeyPemclient_key_pemnomTLS client key path; must be paired with the certificate.
requestTimeoutMsrequest_timeout_msnoPer-call HTTP timeout in milliseconds; defaults to 30000.
maxDiffBytesmax_diff_bytesnoClient-side cap on diff response bytes; defaults to 1 MiB.
maxLogEntriesmax_log_entriesnoClient-side cap on log entries; defaults to 200.

Go exposes the same fields on RemoteGitBackendConfig: BaseURL, RepoID, BearerToken, ClientCertPEM, ClientKeyPEM, RequestTimeoutMS, MaxDiffBytes, and MaxLogEntries.

Host-provided Backend

A Rust host can back a session with its own storage by implementing WorkspaceFileSystem (read_text, write_text, list_dir) and, optionally, WorkspaceCommandRunner, WorkspaceSearch, and WorkspaceGit. The traits are Send + Sync and exported from the crate root. WorkspaceServices::builder starts with read and write capabilities; each attached service enables the matching capability and tools.

Rust
use std::sync::Arc;
use a3s_code_core::{SessionOptions, WorkspaceFileSystem, WorkspaceRef, WorkspaceServices};
fn host_backend(files: Arc<dyn WorkspaceFileSystem>) -> SessionOptions {
let services = WorkspaceServices::builder(
WorkspaceRef::new("tenant-42/workspace", "/workspace"),
files,
)
.build();
SessionOptions::new().with_workspace_backend(services)
}

Attach .command_runner(...) for bash, .search(...) for search, .git(...) for git, and .code_intelligence(...) for the code-intelligence tools. A non-local backend keeps its own command runner: the native Bash sandbox applies only to local workspaces, so the host is responsible for confining commands it runs. Effect isolation never reuses a host-provided backend. The Node.js, Python, and Go SDKs do not expose custom backends.

Choosing A Backend

  • Use the default local workspace for normal developer machines and CI checkouts.
  • Use LocalWorkspaceBackend when your host always passes a typed backend object.
  • Use S3WorkspaceBackend when workspace state must live in object storage.
  • Add remoteGit when a non-local workspace still needs the built-in git tool.
  • Use MCP or A3S Box for shell-like execution that cannot run inside the selected workspace backend.