mech.app
Dev Tools

Claude Fable 5's Container Environment: Agent Execution Boundaries in Practice

How Claude.ai's persistent container workspace handles multi-hour agent sessions, package installs, and the new pause-resume tool call mechanism.

Source: simonwillison.net
Claude Fable 5's Container Environment: Agent Execution Boundaries in Practice

Claude Fable 5 launched with a container environment that lets agents run code, install packages, and clone repositories across multi-hour sessions. Simon Willison’s 5.5-hour test session spent $110.42 and exposed the plumbing decisions behind persistent agent workspaces: what survives across turns, where security boundaries create friction, and how the new pause-resume tool call mechanism changes orchestration patterns.

The container environment provides full filesystem access, network connectivity, and package management within a single session. State persists across turns but wipes between sessions. Security boundaries block certain binary downloads, forcing manual uploads. The new llm.PauseChain exception enables human-in-the-loop approval gates without losing tool call state.

Container Environment Architecture

Claude.ai has offered container environments since September 2025, but Fable 5 sessions reveal how the boundaries work under sustained load.

What the container provides:

  • Full filesystem access with state persistence across turns
  • Network access for GitHub clones and package downloads
  • Package manager support (pip, apt-get)
  • Multi-step builds that span several minutes
  • File uploads that land in the container workspace

What gets wiped:

  • Nothing during an active session
  • Everything between sessions (no cross-chat persistence)

Willison’s session cloned simonw/micropython-wasm, installed dependencies, built a 13.9MB wheel, and uploaded it to a static host. The entire workflow stayed in one container across multiple prompts and tool calls.

Security Boundaries and Friction Points

The container has network access but blocks downloads of binary archives from certain hosts without explicit user upload. When Willison asked Fable to grab Brett Cannon’s CPython WASI builds, the agent hit an environment restriction. The workaround: manual upload.

Boundary decisions:

CapabilityAllowedRestrictionWorkaround
GitHub cloneYesNoneDirect via git
pip installYesNoneRuns in container
Arbitrary file downloadNoBinary archives from some hostsManual upload
CPython WASI buildsNo.zip downloads from external hostsUser uploads python-3.zip, _build-python-3.zip
Outbound HTTPYesNonecurl, wget work
Persistent storageNoCross-session stateUpload artifacts externally

This creates a pattern: the agent can orchestrate complex builds but needs human intervention for certain external resources. The friction is intentional. It prevents agents from pulling arbitrary binaries without visibility.

Pause-Resume Tool Call Mechanism

Fable 5 introduced llm.PauseChain, a new exception type that lets tools pause mid-execution and request human approval. This changes how tool orchestration works.

Before (blocking execution):

  • Tool executes to completion
  • Result returns to model
  • No mid-flight intervention

After (pause-resume):

  • Tool raises llm.PauseChain
  • Exception propagates with .tool_call and .tool_results attached
  • No model call happens with placeholder result
  • Human approves or modifies
  • Chain resumes from messages= history with unresolved tool calls

Willison’s Datasette Agent implementation uses this for ask_user(), a tool that pauses the chain and waits for human input before continuing.

from llm import PauseChain, ToolCall

def ask_user(question: str, llm_tool_call=None):
    """Pause execution and ask the human operator a question."""
    # llm_tool_call injected by framework based on parameter name
    pending_approval = {
        "question": question,
        "tool_call_id": llm_tool_call.tool_call_id
    }
    raise PauseChain(
        tool_call=llm_tool_call,
        tool_results=[]  # No sibling results yet
    )

Key plumbing details:

  • Every tool call now gets a unique tool_call_id (synthesized as tc_-prefixed ULID if provider doesn’t supply one, per LLM issue #1481)
  • Tools can declare llm_tool_call parameter to access the current invocation context
  • Async sibling tool calls run to completion before pause exception propagates
  • Chains resume by executing pending tool calls through normal before_call/after_call hooks

The LLM library implements this as a first-class exception type with full state preservation, not a workaround.

Latency and UX cost:

Pausing adds wall-clock time but no token cost. The agent stops generating until the human responds. Resuming does not require re-contextualization because the pause exception preserves the full tool call state and sibling results. The model picks up exactly where it left off. In Willison’s session, pauses for approval added minutes to the workflow, but the agent never lost track of what it was doing.

State Management Across Multi-Turn Sessions

Fable sessions persist container state across turns, but the model has no built-in memory of what files exist or what packages are installed. The agent must track this itself or re-discover it each turn.

State persistence patterns observed:

  • Cloned repositories stay in /workspace across prompts
  • Installed packages remain in the Python environment
  • Generated artifacts (wheels, binaries) persist until session ends
  • No automatic cleanup between turns

This creates a notable failure mode: the agent can forget what it installed three turns ago and try to reinstall, or assume a file exists when it doesn’t. The container doesn’t help with this, but the model’s context window does.

Willison’s session showed the agent successfully tracking multi-step builds across several minutes and multiple prompts. The key: each turn included enough context about prior steps that the model could pick up where it left off.

Deployment Shape and Cost Structure

Fable 5 pricing is $10/million input tokens and $50/million output tokens. No context window surcharge. 1M token context, 128K max output.

Real-world usage from Willison’s session:

  • $110.42 spent in one day across multiple projects
  • Longest single task: multi-hour coding session with 4 separate feature implementations
  • Token distribution: heavily skewed toward output (code generation, documentation)

The container environment is included in the subscription ($100/month Max plan), but Fable usage will be billed separately after June 22nd.

Cost comparison for pelican SVG generation:

Thinking effortOutput tokensCost
low1,929$0.096
medium2,290$0.115
high2,057$0.103
xhigh5,992$0.300
max14,430$0.722

The container adds no per-execution cost, but long-running builds consume wall-clock time. The agent doesn’t pay for compute, but you pay for the tokens it generates while waiting.

Observability and Failure Modes

Willison used AgentsView to track local LLM usage across different coding agents. The tool required custom pricing configuration for Fable, but otherwise worked out of the box.

Observability gaps:

  • No built-in tracking of container resource usage (CPU, memory, disk)
  • No visibility into network calls made by tools
  • No automatic logging of package installs or file operations
  • Token usage tracking requires external tools
  • No container state snapshot when pause-resume workflow triggers (operator must manually inspect /workspace to see what files exist or what packages are installed before approving)

Likely failure modes:

  • Agent forgets prior installs and re-downloads packages
  • Long-running builds hit timeout limits (not documented)
  • Network restrictions block certain downloads without clear error messages
  • Cross-session state loss forces re-cloning of repositories
  • Async tool execution silently drops calls to non-existent tools (fixed in LLM 0.32a3)

The last one is unexpected: before the fix, if an agent called a tool that didn’t exist, the async executor would silently drop it. The sync executor returned an error. This created non-deterministic behavior depending on execution mode.

Technical Verdict

Use Fable 5’s container environment if:

Your agent needs to build Python wheels or compile binaries with pip and you can manually upload external resources when the agent hits download restrictions. Willison’s WASI binary block shows this pattern: the agent identified the right build, but couldn’t fetch it autonomously. If you can drop files into the chat when prompted, this works. If you need fully autonomous downloads of arbitrary binaries, it doesn’t.

Your workflow includes human approval gates and you’re running LLM 0.32a3 or later. The pause-resume pattern is production-ready, but only after the async tool executor bug fix. Earlier versions silently drop tool calls in async mode. Verify your library version before deploying.

You’re building single-session prototypes or one-off automation tasks where state persistence across days doesn’t matter. The container wipes between sessions. If your project spans multiple days, you need external artifact storage and orchestration to restore state. The container is not a database.

You have external observability tools like AgentsView to track token usage and can afford $50/million output tokens for sustained code generation. Willison’s $110 session shows what multi-hour workflows cost. Budget accordingly.

Avoid it if:

You need deterministic tool execution without manual intervention for every external download. The security boundaries are intentional but create friction. If your agent must autonomously fetch binaries from arbitrary hosts, this environment will block it.

Your workflow requires cross-session state persistence. The container is ephemeral. Use external storage (S3, artifact repos) and orchestration to restore state between sessions.

You need visibility into container resource usage or network calls. The observability gaps are real. You can’t see CPU, memory, or disk I/O. You can’t audit network calls. If compliance or debugging requires this, add your own instrumentation.

Your budget constraints make $100+ daily sessions infeasible. The cost structure favors short, focused sessions over day-long marathons.

The pause-resume mechanism adds latency (minutes of wall-clock time waiting for human approval) but preserves full tool call state. If your workflow needs non-blocking execution without acknowledgment, the blocking model is simpler. If you need approval gates, this is the cleanest implementation available.