orcapods, @agent-orc/..., sdks/go) and they target the /vfs/... HTTP surface directly.
Use a VirtualFS SDK when application code needs to:
- Read or write files in tenant-scoped mounts from outside the agent runtime.
- Run sealed shell commands against the VirtualFS without going through the conductor.
- Expose VFS as agent tools to OpenAI, Vercel AI SDK, or Claude SDK loops.
- Provide a sandbox-shaped facade to existing agent runtime code.
Package map
The VirtualFS SDKs ship as four packages in this repository:
Runnable examples live under
virtualfs/examples/python and virtualfs/examples/typescript.
There is no Go VirtualFS SDK. Go callers use virtualfs.New(dispatcher, policy) and Workspace.Execute(ctx, cmd, ExecOpts) directly from the in-process Go package documented in the API Reference Workspace Execute section.
Server prerequisites
Every SDK client speaks the structured/vfs/... surface plus POST /vfs/exec. Boot a server before running any SDK example:
- Standalone
servelistens on:8080. The compose-backed VirtualFS service (thevfsservice indocker-compose.yml) is reachable athttp://localhost:18080on the host, or athttp://vfs:8080from inside the compose network. - Without
VFS_AUTH_TOKEN, the local server usessmokeAuthand accepts a caller-supplied bearer token. SetVFS_AUTH_TOKENfor any non-local deployment. - The smoke driver seeds
/s3/log.jsonland/s3/report.parquetunless--seed=falseis passed.
When VirtualFS is fronted by the conductor (
/api/vfs/*), client Authorization headers are stripped and the proxy injects Bearer ${VFS_AUTH_TOKEN} server-side (the conductor reads VFS_AUTH_TOKEN directly). When fronted by the Vercel-hosted dashboard (/vfs/* rewrite), Edge middleware injects Bearer ${VFS_TOKEN}, a separate Vercel project env var that must be kept in sync with the Railway vfs service’s VFS_AUTH_TOKEN. In both cases client Authorization headers are stripped and overwritten server-side. The SDK token argument is for direct use against a standalone or Railway-hosted VirtualFS, not for browser code that already routes through one of those proxies.Python: agent-orc-vfs
A thin async + sync HTTP client built on httpx and Pydantic v2.
Install
The package is not yet on PyPI. Install from the repo:uv:
>=3.11, httpx>=0.27, pydantic>=2.7.
Workspace
Workspace is the entry point. It carries declared mount metadata used by file_prompt and by validate() plus a base URL and bearer token used by every HTTP call.
The instance lazily opens an
httpx.AsyncClient and httpx.Client the first time async or sync methods are called. Both close paths are explicit:
Mount factories
Mount specs declare the backend each path is expected to be backed by. The server validates the declaration at connect time viavalidate().
RamMount, R2Mount). Clients cannot register additional mount kinds; the server is the source of truth for which paths exist. Call validate() (or validate_sync()) to assert that every declared path exists on the server and that its kind, bucket, and endpoint match. See Strict mount validation.
Typed file operations
Every async helper has a sync sibling. All operations target the typedPOST /vfs/... endpoints described in the API reference.
cat, ls, stat, find, grep, write, delete, and execute all accept an optional session_id keyword argument that scopes the call to a session’s mount allowlist (see Sessions below).
Sessions
Sessions are server-side records that scope a caller’s file and shell operations to a subset of mounts (the session’s allowlist). Create a session, then pass its id assession_id= on subsequent calls; the server enforces the allowlist and raises SessionForbidden (HTTP 403) for any path outside it.
SessionInfo fields: id: str, allowed_mounts: list[str].
Strict mount validation (Python)
Callvalidate() immediately after constructing Workspace so a misconfigured server fails fast instead of silently routing reads to the wrong store.
MountMismatch: a declared path is not registered on the server, or the backend kind, bucket, or endpoint does not match what the server reports.MountUnavailable: the server has the mount but its backend failed to initialize at boot; the server-reportedreasonis included in the exception message.
Shell execution
execute and execute_sync post to POST /vfs/exec. There is no host shell fallback; unsupported syntax raises a VfsError subclass.
Response models
All responses are Pydantic v2 models. Use.model_dump() for plain dicts.
MountBackend is not exported from the top-level agent_orc_vfs package; access it as an attribute of a MountInfo instance (mount_info.backend), or import it directly from agent_orc_vfs.workspace. Only MountInfo is part of the package’s public __all__.
file_prompt
ws.file_prompt returns a system-prompt fragment describing the configured mounts. Pass it to the agent’s instructions or prepend it to the system prompt.
file_prompt_template=callable to the constructor.
OpenAI function tools
tools(ws) returns a list of OpenAI chat-completions tool dicts. Each entry carries an extra executor callable used for local dispatch. The surface is intentionally two tools:
tools(...):
Errors
All non-2xx responses are mapped to typed exceptions:code (string), message, and detail (dict). The shared error code table is in Error codes below.
TypeScript: @agent-orc/vfs
An ESM + CJS package that ships a thin Workspace HTTP client, mount factories, a Vercel AI SDK / OpenAI tool bundle, and an in-package SandboxClient facade.
Install
The package is not published to npm. Install it from this repository:dist/index.js (ESM), dist/index.cjs (CJS), and dist/index.d.ts. The only runtime dependency is zod ^3.23.8.
Workspace
fetch and exposes one request<T>(method, path, body?) private helper that injects Authorization: Bearer ${TOKEN} and parses non-2xx responses through parseErrorResponse.
Mount factories
Mount = R2Mount | RamMount | NotionMount. NotionMount is a placeholder for a future driver. describeMountAt(mountPath, mount) is exported for custom prompt templates.
Typed file operations
Every
opts object above also accepts sessionId?: string, sent to the server as session_id, to scope the call to a session’s mount allowlist. See Sessions below.
Sessions
Sessions are server-side records that scope a caller’s file and shell operations to a subset of mounts (the session’s allowlist). Create a session, then pass its id assessionId in an op’s opts to enforce the allowlist; a path outside it rejects with SessionForbidden.
Session fields: id: string, allowedMounts: string[].
Strict mount validation (TypeScript)
Callvalidate() immediately after constructing Workspace so a misconfigured server fails fast instead of silently routing reads to the wrong store.
MountMismatch: a declared path is not registered on the server, or the backend kind, bucket, or endpoint does not match what the server reports.MountUnavailable: the server has the mount but its backend failed to initialize at boot; the server-reportedreasonis included.
The TypeScript
stat() swallows NOT_FOUND and returns null, while the Python stat() raises NotFound. Pick one shape per call site rather than mixing.Response types
file_prompt
ws.file_prompt is a getter, not a method. It renders the configured mounts using defaultFilePromptTemplate unless opts.filePromptTemplate was supplied.
Agent tools
tools(ws) returns a VfsTools object compatible with the Vercel AI SDK tools: argument and with manual OpenAI function-calling loops. Each entry has a Zod inputSchema and an execute(input) callable that routes through Workspace.
vfs_execute returns { stdout, stderr, exitCode, durationMs }, and vfs_grep returns { matches }.
SandboxClient
The TypeScript SDK ships its sandbox facade in-package. There is no separate @agent-orc/openai-vfs for TypeScript; the OpenAI Agents adapter is Python-only.
Unlike the Python
agent-orc-vfs-openai adapter’s open_sandbox(), which memoizes and returns the same id on every call, the TypeScript openSandbox() is not memoized.
Errors
The TypeScript SDK has a baseVfsError class with code, message, httpStatus, and optional allowed, plus three dedicated subclasses: MountUnavailable (MOUNT_UNAVAILABLE), MountMismatch (MOUNT_MISMATCH), and SessionForbidden (SESSION_FORBIDDEN, HTTP 403). parseErrorResponse maps those three codes to their subclass and falls back to plain VfsError for every other code. Catch a specific subclass, or branch on err.code for the rest.
Claude adapter: @agent-orc/claude-vfs
A TypeScript-only adapter that exposes Claude’s Bash tool and routes its invocations through Workspace.execute(). Lives at virtualfs/sdk/adapters/claude-sdk.
Install
@anthropic-ai/sdk as an optional peer dependency (>=0.26.0); the adapter itself does not import the SDK at module load time, so it can be used with any Anthropic SDK loop or with no SDK at all.
Surface
bashTool(ws) returns { definition, handler }:
Usage
Behavior notes
restart: trueis a no-op. The VFS shell is stateless, so the handler returns a notice withexit_code: 0instead of clearing any session state.- An empty
commandstring returns{ output: "", exit_code: 0 }. stdoutandstderrare concatenated intooutput;stderris appended afterstdoutwhen both are present.- Any thrown error (
VfsError, network error, etc.) is caught and surfaced as{ output: error.message, exit_code: 1 }so the agent loop can keep running.
SandboxClient from @agent-orc/vfs (TypeScript) or agent-orc-vfs-openai (Python).
OpenAI Agents adapter: agent-orc-vfs-openai
A Python-only adapter that wraps a Workspace in a sandbox-shaped facade for agent runtime code that expects BaseSandboxClient-style operations. Lives at virtualfs/sdk/adapters/openai-agents.
Install
openai-agents at module load time. The OpenAI Agents SDK’s sandbox surface (BaseSandboxClient, SandboxSession) is still beta; this package exposes a smaller SandboxClientProtocol that is direct-protocol compatible today and can be wrapped in the future when agent-orc adopts the official shape.
Surface
Methods
Usage
VfsError and its subclasses propagate from run_command, read_file, and write_file exactly as they do from the underlying Workspace.
Error codes
Every endpoint uses the shared{ "error": { "code", "message", ... } } envelope. The Python SDK maps each code to a dedicated exception class. The TypeScript SDK also has dedicated subclasses for three codes (MountUnavailable, MountMismatch, SessionForbidden, all extending VfsError); every other code surfaces only as a plain VfsError with code set, so callers branch on err.code for those.
The
cmd shape that triggers UNSUPPORTED_SHELL_FEATURE and the full builtin list live in the Shell Parser and Compiler section of the API reference.
Examples
Runnable scripts ship with the SDKs:
To run them, boot a server with
go run ./virtualfs/cmd/vfs serve, export VFS_BASE_URL and VFS_TOKEN, then follow the README.md in the example directory.