Skip to content

Guides

Run Strands agents in a Promigence sandbox

Give a Strands agent a Promigence sandbox, so its shell and file-editor tools run there with output streamed back as it is written.

Also as markdown: /docs/guides/strands.md

Strands Agents has a sandbox interface: give an Agent a sandbox and it gets shell and file-editor tools bound to it. The strands-promigence package provides PromigenceSandbox, so those tools act on a Promigence sandbox instead of the machine running your agent. Output streams back while a command is still running.

What you need#

  • A Promigence API key in PROMIGENCE_API_KEY.
  • Python 3.10 or newer.
  • strands-agents 1.56.0. The sandbox interface is young, so the package pins >=1.56,<2.

Install#

Terminal
pip install strands-promigence
export PROMIGENCE_API_KEY=prom_api_...
export PROMIGENCE_SPEND_CAP=5
Language: bash

A minimal example#

Python
import asyncio
from strands import Agent
from strands_promigence import PromigenceSandbox

async def main() -> None:
    async with PromigenceSandbox(image="python:3.12-slim", spend_cap=1) as sandbox:
        agent = Agent(sandbox=sandbox)
        await agent.invoke_async("Install httpx and print its version.")

asyncio.run(main())
Language: python

Agent(sandbox=...) registers two tools, sandbox_shell and sandbox_file_editor, unless you already have tools with those names. The async with form creates the sandbox up front and ends it on exit. Without it, nothing is created until the first command runs, so you can build an Agent before a key is even set. In that case end it with await sandbox.aclose().

Pass exactly one of image or snapshot. The first time you name an image, Promigence pins its tag to a digest, builds a snapshot from it and checks it. A snapshot is a saved, verified environment, and each sandbox starts as a fresh copy of it, so later sandboxes reuse what was built. That build is billed per second while it runs, whether it verifies or not, up to $0.17 at the default small size (quickstart), and the sandboxes that reuse it pay no further build charge. Useful options include tier (small, medium or large), working_dir, env, user, setup and verify to prepare and check the snapshot, allow_internet_access=False for no network, and registry_secret for a private image.

How sandboxes map to agents#

One PromigenceSandbox is one sandbox. Give each agent, or each task you want kept apart, its own instance. Sharing one across several agents shares one filesystem.

Output is read while the command runs, every 250 ms by default (poll_ms), so a line written early reaches the agent within one read rather than at exit. That suits logs and test output well.

Setting a spend cap#

spend_cap is the most one sandbox may spend, in US dollars. It falls back to PROMIGENCE_SPEND_CAP, then to your organization's default, and a configuration error is raised if there is none. sandbox_timeout_sec (3600 by default) bounds the sandbox's lifetime.

Cleaning up#

async with ends the sandbox for you. Otherwise call await sandbox.aclose(). A sandbox you forget ends on its own at sandbox_timeout_sec.

When something fails, you can tell whose failure it was. A non-zero exit is an ExecutionResult with the exit code. A timeout raises SandboxTimeoutError with whatever the command had written. A failure on the Promigence side raises PromigenceAdapterError with failure_class == "env", so it never looks like the agent's command failed.

What is not supported yet#

  • An interactive terminal tool. The Strands sandbox interface has no place for one.
  • output_files. It is always empty; the agent reads files it produced with the file tools.
  • Changing directory between commands. working_dir is resolved once, so a cd does not carry over.
  • The image needs /bin/sh. Running code also needs base64 and the interpreter you name.

Next#

Read the agent briefing for what a sandbox gives an agent, or start with the quickstart.

Get started

Leave your work email and we will get you started.

See our Privacy Policy for how we use your email.