4. Tool Sandbox¶
AgentScope Runtime’s Sandbox is a versatile tool that provides a secure and isolated environment for a wide range of operations, including tool execution, browser automation, and file system operations. This tutorial will empower you to set up the tool sandbox dependency and run tools in an environment that you can tailor to your specific needs.
Prerequisites¶
Note
The current sandbox environment utilizes Docker for default isolation. In addition, we offer support for Kubernetes (K8s) as a remote service backend. Looking ahead, we plan to incorporate more third-party hosting solutions in future releases.
Warning
For Apple Silicon devices (such as M1/M2), we recommend the following options to run an x86 Docker environment for maximum compatibility:
Docker Desktop: Please refer to the Docker Desktop installation guide to enable Rosetta 2, ensuring compatibility with x86_64 images.
Colima: Ensure that Rosetta 2 support is enabled. You can start Colima with the following command to achieve compatibility:
colima start --vm-type=vz --vz-rosetta --memory 8 --cpu 1
Docker
(Optional, remote mode only) Kubernetes
Setup¶
Install Dependencies¶
First, install AgentScope Runtime with sandbox support:
pip install "agentscope-runtime[sandbox]"
Prepare the Docker Images¶
The sandbox uses different Docker images for various functionalities. You can pull only the images you need or all of them for complete functionality:
Option 1: Pull All Images (Recommended)¶
To ensure a complete sandbox experience with all features enabled, follow the steps below to pull and tag the necessary Docker images from our repository:
Note
Image Source: Alibaba Cloud Container Registry
All Docker images are hosted on Alibaba Cloud Container Registry (ACR) for optimal performance and reliability worldwide. Images are pulled from ACR and tagged with standard names for seamless integration with the AgentScope runtime environment.
# Base image
docker pull agentscope-registry.ap-southeast-1.cr.aliyuncs.com/agentscope/runtime-sandbox-base:latest && docker tag agentscope-registry.ap-southeast-1.cr.aliyuncs.com/agentscope/runtime-sandbox-base:latest agentscope/runtime-sandbox-base:latest
# Filesystem image
docker pull agentscope-registry.ap-southeast-1.cr.aliyuncs.com/agentscope/runtime-sandbox-filesystem:latest && docker tag agentscope-registry.ap-southeast-1.cr.aliyuncs.com/agentscope/runtime-sandbox-filesystem:latest agentscope/runtime-sandbox-filesystem:latest
# Browser image
docker pull agentscope-registry.ap-southeast-1.cr.aliyuncs.com/agentscope/runtime-sandbox-browser:latest && docker tag agentscope-registry.ap-southeast-1.cr.aliyuncs.com/agentscope/runtime-sandbox-browser:latest agentscope/runtime-sandbox-browser:latest
Option 2: Pull Specific Images¶
Choose the images based on your specific needs:
Image |
Purpose |
When to Use |
---|---|---|
Base Image |
Python code execution, shell commands |
Essential for basic tool execution |
Filesystem Image |
File system operations |
When you need file read/write/management |
Browser Image |
Web browser automation |
When you need web scraping or browser control |
Training Image |
Training and evaluating agent |
Used for training and evaluating agent on some benchmark (see Training Sandbox for details) |
Verify Installation¶
You can verify that everything is set up correctly by calling run_ipython_cell
:
import json
from agentscope_runtime.sandbox.tools.base import run_ipython_cell
# Model Context Protocol (MCP)-compatible tool call results
result = run_ipython_cell(code="print('Setup successful!')")
print(json.dumps(result, indent=4, ensure_ascii=False))
(Optional) Built the Docker Images from Scratch¶
If you prefer to build the Docker images yourself or need custom modifications, you can build them from scratch. Please refer to Advanced Usage of Tool Sandbox for detailed instructions.
Tool Usage¶
Call a Tool¶
The most basic usage is to directly call built-in tools (such as running Python code or shell commands):
Note
The following two functions will execute independently in separate sandboxes. Each function call will start an embedded sandbox, execute the function within it, and then close the sandbox. The lifecycle of each sandbox is confined to the duration of the function call in this way.
from agentscope_runtime.sandbox.tools.base import (
run_ipython_cell,
run_shell_command,
)
print(run_ipython_cell(code="print('hello world')"))
print(run_shell_command(command="whoami"))
Bind Sandbox to a Tool¶
In addition to directly calling tools, you can bind a specific sandbox to a tool using the bind method. This allows you to specify which sandbox the function will run in, giving you more control over the execution environment. It’s important to note that the function’s type and the sandbox type must match; otherwise, the function will not execute properly. Here’s how you can do it:
from agentscope_runtime.sandbox import BaseSandbox
with BaseSandbox() as sandbox:
# Ensure the function's sandbox type matches the sandbox instance type
assert run_ipython_cell.sandbox_type == sandbox.sandbox_type
# Bind the sandbox to the tool functions
func1 = run_ipython_cell.bind(sandbox=sandbox)
func2 = run_shell_command.bind(sandbox=sandbox)
# Execute the function within the sandbox
print(func1(code="repo = 'agentscope-runtime'"))
print(func1(code="print(repo)"))
print(func2(command="whoami"))
Convert MCP Server to Tools¶
You can also integrate external MCP servers to extend the tools. This example demonstrates how to convert MCP server configurations into built-in tools using the MCPConfigConverter
class.
from agentscope_runtime.sandbox.tools.mcp_tool import MCPConfigConverter
mcp_tools = MCPConfigConverter(
server_configs={
"mcpServers": {
"time": {
"command": "uvx",
"args": [
"mcp-server-time",
"--local-timezone=America/New_York",
],
},
},
},
).to_builtin_tools()
print(mcp_tools)
Function Tool¶
Besides the tools that run in sandbox environments, you can also add in-process functions as tools for agents. These function tools execute directly within the current Python process without requiring sandbox isolation, making them suitable for lightweight operations and calculations.
Function tools offer two creation methods:
FunctionTool
wrapper: Wrap existing functions or methods using theFunctionTool
classDecorator approach: Use the
@function_tool
decorator to annotate functions directly
from agentscope_runtime.sandbox.tools.function_tool import (
FunctionTool,
function_tool,
)
class MathCalculator:
def calculate_power(self, base: int, exponent: int) -> int:
"""Calculate the power of a number."""
print(f"Calculating {base}^{exponent}...")
return base**exponent
calculator = MathCalculator()
@function_tool(
name="calculate_power",
description="Calculate the base raised to the power of the exponent",
)
def another_calculate_power(base: int, exponent: int) -> int:
"""Calculate the base raised to the power of the exponent."""
print(f"Calculating {base}^{exponent}...")
return base**exponent
tool_0 = FunctionTool(calculator.calculate_power)
tool_1 = another_calculate_power
print(tool_0, tool_1)
Tool Schema¶
Each tool has a defined schema
that specifies the expected structure and types of its input parameters. This schema is useful for understanding how to properly use the tool and what parameters are required. Here’s an example of how you can view the schema:
print(json.dumps(run_ipython_cell.schema, indent=4, ensure_ascii=False))
Function-like Tool Design Philosophy¶
Note
This section explains the design principles behind our tool module. You can skip this section if you’re only interested in practical usage.
Our tool module is designed with a function-like interface that abstracts the complexity of sandbox management while providing maximum flexibility. Here are the key design principles:
1. Intuitive Function Call Interface¶
Our tool module provides a function-like interface, allowing you to call tools with a simple function call. Tools behave like regular Python functions, making them easy to use and integrate:
# Simple function-like calls
result = run_ipython_cell(code="print('hello world')")
result = tool_instance(param1="value1", param2="value2")
2. Flexible Sandbox Priority System¶
The tool module supports three levels of sandbox specification with clear priority:
Temporary sandbox (highest priority, specified during initialization):
tool(sandbox=temp_sandbox, **kwargs)
Instance-bound sandbox (second priority, specified through the binding method):
bound_tool = tool.bind(sandbox)
Dry-run mode (lowest priority, no sandbox specified): Automatically creates temporary sandbox when none specified
3. Immutable Binding Pattern¶
The bind method creates new tool instances rather than modifying existing ones:
# Creates a new instance, original tool remains unchanged
bound_tool = original_tool.bind(sandbox=my_sandbox)
This ensures thread safety and allows multiple sandbox-bound versions of the same tool to coexist.
Sandbox Usage¶
Create a Sandbox¶
The previous section introduced tool-centered usage methods, while this section introduces sandbox-centered usage methods.
You can create different types of sandboxes via sandbox
sdk:
BaseSandbox: Basic sandbox for Python code execution and shell commands.
from agentscope_runtime.sandbox import BaseSandbox
# Create a base sandbox
with BaseSandbox() as box:
print(box.list_tools())
print(box.run_ipython_cell(code="print('hi')"))
print(box.run_shell_command(command="echo hello"))
FilesystemSandbox: Sandbox with file system operations support.
from agentscope_runtime.sandbox import FilesystemSandbox
# Create a filesystem sandbox
with FilesystemSandbox() as box:
print(box.list_tools())
print(box.create_directory("test"))
print(box.list_allowed_directories())
BrowserSandbox: Sandbox for web automation and browser control powered by Steel Browser.
from agentscope_runtime.sandbox import BrowserSandbox
# Create a browser sandbox
with BrowserSandbox() as box:
print(box.list_tools())
print(box.browser_navigate("https://www.example.com/"))
print(box.browser_snapshot())
TrainingSandbox: Sandbox for training and evaluation,please refer to Training Sandbox for details。
from agentscope_runtime.sandbox import TrainingSandbox
# Create a training sandbox
with TrainingSandbox() as box:
profile_list = box.get_env_profile(env_type="appworld", split="train")
print(profile_list)
Note
We’ll be expanding with more types of sandboxes soon—stay tuned!
Add MCP Server to Sandbox¶
MCP (Model Context Protocol) is a standardized protocol that enables AI applications to connect to external data sources and tools securely. By integrating MCP servers into your sandbox, you can extend the sandbox’s capabilities with specialized tools and services without compromising security.
The sandbox supports integrating MCP servers via the add_mcp_servers
method. Once added, you can discover available tools using list_tools
and execute them with call_tool
. Here’s an example of adding a time server that provides timezone-aware time functions:
with BaseSandbox() as sandbox:
mcp_server_configs = {
"mcpServers": {
"time": {
"command": "uvx",
"args": [
"mcp-server-time",
"--local-timezone=America/New_York",
],
},
},
}
# Add the MCP server to the sandbox
sandbox.add_mcp_servers(server_configs=mcp_server_configs)
# List all available tools (now includes MCP tools)
print(sandbox.list_tools())
# Use the time tool provided by the MCP server
print(
sandbox.call_tool(
"get_current_time",
arguments={
"timezone": "America/New_York",
},
),
)
Connect to Remote Sandbox¶
Note
Remote deployment is beneficial for:
Separating comput-intensive tasks to dedicated servers
Multiple clients sharing the same sandbox environment
Developing on resource-constrained local machines while executing on high-performance servers
Deploy sandbox server with K8S
For more advanced usage of sandbox-server, please refer to Advanced Usage of Tool Sandbox for detailed instructions.
You can start the sandbox server on your local machine or different machines for convenient remote access. You should start a sandbox server via:
runtime-sandbox-server
To connect to the remote sandbox service, pass in base_url
:
# Connect to remote sandbox server (replace with actual server IP)
with BaseSandbox(base_url="http://your_IP_address:8000") as box:
print(box.run_ipython_cell(code="print('hi')"))
Tool List¶
Base Tools (Available in all sandbox types)
Browser Tools (Available in
BrowserSandbox
)Filesystem Tools (Available in
FilesystemSandbox
)
Category |
Tool Name |
Description |
---|---|---|
Base Tools |
|
Execute Python code in an IPython environment |
|
Execute shell commands in the sandbox |
|
Filesystem Tools |
|
Read the complete contents of a file |
|
Read multiple files simultaneously |
|
|
Create or overwrite a file with content |
|
|
Make line-based edits to a text file |
|
|
Create a new directory |
|
|
List all files and directories in a path |
|
|
Get recursive tree view of directory structure |
|
|
Move or rename files and directories |
|
|
Search for files matching a pattern |
|
|
Get detailed metadata about a file or directory |
|
|
List directories the server can access |
|
Browser Tools |
|
Navigate to a specific URL |
|
Go back to the previous page |
|
|
Go forward to the next page |
|
|
Close the current browser page |
|
|
Resize the browser window |
|
|
Click on a web element |
|
|
Type text into an input field |
|
|
Hover over a web element |
|
|
Drag and drop between elements |
|
|
Select options in a dropdown |
|
|
Press a keyboard key |
|
|
Upload files to the page |
|
|
Capture accessibility snapshot of the current page |
|
|
Take a screenshot of the page or element |
|
|
Save the current page as PDF |
|
|
List all open browser tabs |
|
|
Open a new tab |
|
|
Switch to a specific tab |
|
|
Close a tab (current tab if index not specified) |
|
|
Wait for conditions or time to pass |
|
|
Get all console messages from the page |
|
|
Get all network requests since page load |
|
|
Handle browser dialogs (alert, confirm, prompt) |
Troubleshooting¶
If you encounter any issues while using the browser module, here are some troubleshooting steps:
Docker Connection Error¶
If you encounter the following error:
docker.errors.DockerException: Error while fetching server API version: ('Connection aborted.', FileNotFoundError(2, 'No such file or directory'))
This error typically indicates that the Docker Python SDK is unable to connect to the Docker service. If you are using Colima, you need to ensure that the Docker Python SDK is configured to use Colima’s Docker service. You can do this by setting the DOCKER_HOST
environment variable:
export DOCKER_HOST=unix://$HOME/.colima/docker.sock
After setting the DOCKER_HOST
environment variable, try running your command again. This should resolve the connection issue.