Configure file operations
Attach a durable Sandbox and the file-operation Tool group when an Agent needs private mutable workspace state. This guide writes an exact sentinel in one Turn and reads it from a new Session in another Turn.
Outcome
You will attach one Sandbox to an existing Agent, enable file operations, and
prove that durable.txt retains the exact value BA_DURABLE_42 across Turns.
Before you begin
You need an existing Agent, a backend SDK client, and available Sandbox capacity. Review Sandboxes, file operations, and Tools before enabling workspace access.
Create a Sandbox
The smallest valid client.sandboxes.create() request is an empty object.
Store the returned platform ID; the Agent attachment uses sandbox.id.
const sentinel = "BA_DURABLE_42";
const sandbox = await client.sandboxes.create({});
const agent = await client.agents.get(agentId);
const tools = agent.tools.includes("file_operation_sandbox")
? agent.tools
: [...agent.tools, "file_operation_sandbox" as const];
await client.agents.update(agentId, { sandboxId: sandbox.id, tools });
const writeTurn = await client.chat({
agentId,
message: { id: crypto.randomUUID(), role: "user", parts: [{
type: "text", text: `Use write to create durable.txt containing exactly ${sentinel}. Do not publish it.`,
}] },
});
for await (const _chunk of writeTurn.toUIMessageStream()) { /* drain */ }
const readTurn = await client.chat({
agentId,
message: { id: crypto.randomUUID(), role: "user", parts: [{
type: "text", text: "Use read to read durable.txt, then summarize.",
}] },
});
const sessionId = await readTurn.sessionId;
for await (const _chunk of readTurn.toUIMessageStream()) { /* drain */ }
const { data } = await client.sessions.messages(agentId, sessionId);
const read = data.flatMap((message) => message.parts).find((part) =>
part.type === "tool-read" && part.state === "output-available")?.output;
if (typeof read !== "object" || read === null || !("path" in read) || !("content" in read)
|| read.path !== "/workspace/durable.txt" || read.content !== sentinel) throw new Error("Persistence check failed");Attach the Sandbox and Tools
Agent updates leave omitted fields unchanged, while tools replaces the
complete Tool-group selection. Reading the Agent and adding
file_operation_sandbox preserves its unrelated configuration and existing
Tool groups.
Write a file in one Turn
The first client.chat() call creates a Session because it omits
sessionId. Draining its stream lets the Turn finish writing the private
workspace file.
Read it in another Turn
The second call also omits sessionId, so it creates a different Session.
Both Turns use the same Agent attachment and therefore the same Sandbox.
Verify persistence
After the second Turn succeeds, client.sessions.messages() returns its
persisted transcript. The final assertion requires a successful tool-read
result for /workspace/durable.txt containing the exact sentinel, proving
that the second Turn read the bytes written by the first.
Production notes
- Keep
sandboxIdandfile_operation_sandboxconsistent. Creation, update, detachment, and Turn dispatch reject a file-enabled Agent without a Sandbox. - One Sandbox admits one active Turn at a time. Turns also share fleet capacity; contention waits in durable queues rather than creating parallel workspace writers.
- Pass an
AbortSignalassignalto cancel a Turn. Filesystem changes that completed before cancellation remain, and capacity is released only after accepted operations settle and actor sleep is confirmed. - Detach the Sandbox before deletion. Deletion destroys its workspace and can
return either
"completed"or"pending"while durable cleanup continues. - Treat capacity and resource ceilings as production constraints; see limits and reliability.
Related capabilities
SDK and REST reference
- Create the Sandbox:
sandboxes.create()andPOST /v1/sandboxes - Read the Agent:
agents.get()andGET /v1/agents/:agentId - Attach the Sandbox and Tools:
agents.update()andPUT /v1/agents/:agentId - Create each Turn:
client.chat()andPOST .../sessions - Read persisted messages:
sessions.messages()andGET .../messages