Daytona Sandbox Tools
Daytona Sandbox Tools
Section titled “Daytona Sandbox Tools”Daytona sandbox 工具让 CrewAI agents 能访问由 Daytona 提供支持的隔离、短暂存在的计算环境。共有三种工具可用,因此你可以精确地给 agent 提供所需能力:
DaytonaExecTool- 在 sandbox 中运行任意 shell 命令。DaytonaPythonTool- 在 sandbox 中执行一段 Python 源码。DaytonaFileTool- 在 sandbox 中读取、写入、追加、列出、删除和检查文件;还支持move、find(内容 grep)、search(文件名 glob)、chmod(权限)、replace(批量查找替换)和exists。
这三种工具共享同一套 sandbox 生命周期控制,因此你可以灵活组合它们,同时把状态保存在单个持久 sandbox 中。
uv add "crewai-tools[daytona]"# orpip install "crewai-tools[daytona]"设置 API key:
export DAYTONA_API_KEY="your-api-key"如果设置了,DAYTONA_API_URL 和 DAYTONA_TARGET 也会被识别。
Sandbox 生命周期
Section titled “Sandbox 生命周期”这三种工具都继承自 DaytonaBaseTool 的生命周期控制:
| Mode | How to enable | Sandbox created | Sandbox deleted |
|---|---|---|---|
| Ephemeral (default) | persistent=False (default) | 每次 _run 调用时创建 | 在同一次调用结束时删除 |
| Persistent | persistent=True | 第一次使用时懒创建 | 在进程退出时通过 atexit 删除,或手动调用 tool.close() |
| Attach | sandbox_id="<id>" | 从不创建新 sandbox - 只连接到现有 sandbox | 从不 - 工具不会删除它没有创建的 sandbox |
临时模式是安全的默认选择:如果 agent 忘记清理,不会留下任何残留。需要文件系统状态或已安装包在多次工具调用之间保留时,使用持久模式 - 这通常适合把 DaytonaFileTool 和 DaytonaExecTool 配对使用。
一次性 Python 执行(ephemeral)
Section titled “一次性 Python 执行(ephemeral)”from crewai_tools import DaytonaPythonTool
tool = DaytonaPythonTool()result = tool.run(code="print(sum(range(10)))")print(result)# {"exit_code": 0, "result": "45\n", "artifacts": ExecutionArtifacts(stdout="45\n", charts=[])}多步骤 shell 会话(persistent)
Section titled “多步骤 shell 会话(persistent)”from crewai_tools import DaytonaExecTool, DaytonaFileTool
# Create the persistent sandbox via the first tool, then attach the second# tool to it so both share state (installed packages, files, env vars).exec_tool = DaytonaExecTool(persistent=True)exec_tool.run(command="pip install httpx -q")file_tool = DaytonaFileTool(sandbox_id=exec_tool.active_sandbox_id)
file_tool.run( action="write", path="workspace/script.py", content="import httpx; print(f'httpx loaded, version {httpx.__version__}')",)exec_tool.run(command="python workspace/script.py")连接到已有 sandbox
Section titled “连接到已有 sandbox”from crewai_tools import DaytonaExecTool
tool = DaytonaExecTool(sandbox_id="my-long-lived-sandbox")result = tool.run(command="ls workspace")自定义 sandbox 参数
Section titled “自定义 sandbox 参数”通过 create_params 传入 Daytona 的 CreateSandboxFromSnapshotParams kwargs:
from crewai_tools import DaytonaExecTool
tool = DaytonaExecTool( persistent=True, create_params={ "language": "python", "env_vars": {"MY_FLAG": "1"}, "labels": {"owner": "crewai-agent"}, },)搜索、移动和修改文件
Section titled “搜索、移动和修改文件”from crewai_tools import DaytonaFileTool
file_tool = DaytonaFileTool(persistent=True)
# Find every TODO in the source tree (grep file contents recursively)file_tool.run(action="find", path="workspace/src", pattern="TODO:")
# Find all Python files (glob match on filenames)file_tool.run(action="search", path="workspace", pattern="*.py")
# Make a script executablefile_tool.run(action="chmod", path="workspace/run.sh", mode="755")
# Rename or move a filefile_tool.run( action="move", path="workspace/draft.md", destination="workspace/final.md",)
# Bulk find-and-replace across multiple filesfile_tool.run( action="replace", paths=["workspace/src/a.py", "workspace/src/b.py"], pattern="old_function", replacement="new_function",)
# Quick existence check before a destructive opfile_tool.run(action="exists", path="workspace/cache.db")Agent 集成
Section titled “Agent 集成”from crewai import Agent, Task, Crewfrom crewai_tools import DaytonaExecTool, DaytonaPythonTool, DaytonaFileTool
exec_tool = DaytonaExecTool(persistent=True)python_tool = DaytonaPythonTool(persistent=True)file_tool = DaytonaFileTool(persistent=True)
coder = Agent( role="Sandbox Engineer", goal="Write and run code in an isolated environment", backstory="An engineer who uses Daytona sandboxes to safely execute code and manage files.", tools=[exec_tool, python_tool, file_tool], verbose=True,)
task = Task( description="Write a Python script that prints the first 10 Fibonacci numbers, save it to workspace/fib.py, and run it.", expected_output="The first 10 Fibonacci numbers printed to stdout.", agent=coder,)
crew = Crew(agents=[coder], tasks=[task])result = crew.kickoff()共享(DaytonaBaseTool)
Section titled “共享(DaytonaBaseTool)”这三种工具在初始化时都接受以下参数:
| Parameter | Type | Default | Description |
|---|---|---|---|
api_key | str | None | $DAYTONA_API_KEY | Daytona API key。会回退到 DAYTONA_API_KEY 环境变量。 |
api_url | str | None | $DAYTONA_API_URL | Daytona API URL 覆盖值。 |
target | str | None | $DAYTONA_TARGET | Daytona 目标区域。 |
persistent | bool | False | 在所有调用之间复用一个 sandbox,并在进程退出时删除它。 |
sandbox_id | str | None | None | 通过 id 或 name 连接到已有 sandbox。 |
create_params | dict | None | None | 传给 CreateSandboxFromSnapshotParams 的额外 kwargs(例如 language、env_vars、labels)。 |
sandbox_timeout | float | 60.0 | sandbox 创建/删除操作的超时时间(秒)。 |
DaytonaExecTool
Section titled “DaytonaExecTool”| Parameter | Type | Required | Description |
|---|---|---|---|
command | str | ✓ | 要执行的 shell 命令。 |
cwd | str | None | sandbox 内的工作目录。 | |
env | dict[str, str] | None | 该命令的额外环境变量。 | |
timeout | int | None | 等待命令完成的最长秒数。 |
DaytonaPythonTool
Section titled “DaytonaPythonTool”| Parameter | Type | Required | Description |
|---|---|---|---|
code | str | ✓ | 要执行的 Python 源码。 |
argv | list[str] | None | 通过 CodeRunParams 传递的参数向量。 | |
env | dict[str, str] | None | 通过 CodeRunParams 传递的环境变量。 | |
timeout | int | None | 等待执行完成的最长秒数。 |
DaytonaFileTool
Section titled “DaytonaFileTool”| Parameter | Type | Required | Description |
|---|---|---|---|
action | str | ✓ | 取值之一:read、write、append、list、delete、mkdir、info、exists、move、find、search、chmod、replace。 |
path | str | None | ✓ for all actions except replace | sandbox 内的绝对路径。 |
content | str | None | ✓ for append | 要写入或追加的内容。 |
binary | bool | 如果为 True,写入时 content 会被视为 base64;读取时也会返回 base64。 | |
recursive | bool | 对于 delete:递归删除目录。 | |
mode | str | None | 对于 mkdir:新目录的八进制权限(默认 "0755")。对于 chmod:应用到目标的八进制权限。 | |
destination | str | None | ✓ for move | move 的目标路径。 |
pattern | str | None | ✓ for find, search, replace | 对于 find:与文件内容匹配的子字符串。对于 search:与文件名匹配的 glob(例如 *.py)。对于 replace:要在文件中替换的文本。 |
replacement | str | None | ✓ for replace | pattern 的替换文本。 |
paths | list[str] | None | ✓ for replace | 需要执行替换的文件路径列表。 |
owner | str | None | 对于 chmod:新的文件 owner。 | |
group | str | None | 对于 chmod:新的文件 group。 |