Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -163,6 +163,12 @@ Read more about E2B on the [E2B website](https://e2b.dev) and the official [E2B
<td><a href="https://github.com/e2b-dev/e2b-cookbook/tree/main/examples/stirrup-python">Python</a></td>
<td>-</td>
</tr>
<tr>
<td>BU Agent SDK</td>
<td>Minimal SDK for building agents</td>
<td><a href="https://github.com/e2b-dev/e2b-cookbook/tree/main/examples/bu-agent-sdk-python">Python</a></td>
<td>-</td>
</tr>
</tbody>
</table>

Expand Down
5 changes: 5 additions & 0 deletions examples/bu-agent-sdk-python/.env.template
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
# Get your E2B API key from https://e2b.dev/dashboard?tab=keys
E2B_API_KEY=

# Get your Anthropic API key from https://platform.claude.com/settings/keys
ANTHROPIC_API_KEY=
5 changes: 5 additions & 0 deletions examples/bu-agent-sdk-python/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
# Virtual environments
.venv

# Environment files
.env
29 changes: 29 additions & 0 deletions examples/bu-agent-sdk-python/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
# BU Agent SDK with E2B Code Interpreter

This example shows how to use [bu-agent-sdk](https://github.com/browser-use/agent-sdk) with E2B's [Code Interpreter SDK](https://github.com/e2b-dev/code-interpreter) for data analysis. The agent analyzes CSV data and generates visualizations.

## Setup & run

### 1. Install dependencies

```bash
uv sync
```

### 2. Set up `.env`

1. Copy `.env.template` to `.env`
2. Get [E2B API key](https://e2b.dev/dashboard?tab=keys)
3. Get [Anthropic API key](https://platform.claude.com/settings/keys)

### 3. Run the example

```bash
uv run python main.py
```

The agent will:
- Spin up an E2B sandbox with pandas, numpy, matplotlib
- Upload `data/employees.csv`
- Analyze the data and generate charts
- Download charts to `output/`
11 changes: 11 additions & 0 deletions examples/bu-agent-sdk-python/data/employees.csv
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
name,age,city,salary,department
Alice,28,New York,75000,Engineering
Bob,35,San Francisco,95000,Engineering
Charlie,42,Chicago,110000,Management
Diana,31,New York,82000,Marketing
Eve,26,San Francisco,68000,Engineering
Frank,38,Chicago,98000,Management
Grace,29,New York,71000,Marketing
Henry,45,San Francisco,125000,Management
Ivy,33,Chicago,88000,Engineering
Jack,27,New York,65000,Marketing
101 changes: 101 additions & 0 deletions examples/bu-agent-sdk-python/main.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,101 @@
"""Data analysis agent with E2B sandbox and bu-agent-sdk."""

import asyncio
from pathlib import Path
from typing import Annotated

from dotenv import load_dotenv
from e2b_code_interpreter import Sandbox

from bu_agent_sdk import Agent
from bu_agent_sdk.agent import FinalResponseEvent, ToolCallEvent, ToolResultEvent
from bu_agent_sdk.llm import ChatAnthropic
from bu_agent_sdk.tools import Depends, tool

load_dotenv()

# Config

INPUT_FILE = Path("data/employees.csv")
OUTPUT_DIR = Path("output")
SYSTEM_PROMPT = "You are a data analyst. Use run_code to execute Python. pandas/numpy/matplotlib are available. Save charts with plt.savefig()."
USER_PROMPT = "Analyze employees.csv: show stats, count by department/city, find highest/lowest paid. Create charts."

# Sandbox Utils

_sandbox: Sandbox | None = None


def get_sandbox() -> Sandbox:
if _sandbox is None:
raise RuntimeError("Sandbox not initialized")
return _sandbox


def download_charts(sandbox: Sandbox):
for f in sandbox.files.list("/home/user"):
if f.name.endswith(".png"):
content = sandbox.files.read(f"/home/user/{f.name}", format="bytes")
(OUTPUT_DIR / f.name).write_bytes(content)


# Tools


@tool("Run Python code")
async def run_code(code: str, sandbox: Annotated[Sandbox, Depends(get_sandbox)]) -> str:
"""Execute Python code in the sandbox and return output."""
result = sandbox.run_code(code)

output = "\n".join(filter(None, [
"\n".join(result.logs.stdout or []),
"\n".join(result.logs.stderr or []),
f"Error: {result.error.name}: {result.error.value}" if result.error else "",
]))

return output or "(no output)"


# Main Agent Loop


async def main():
global _sandbox

OUTPUT_DIR.mkdir(exist_ok=True)
_sandbox = Sandbox.create(timeout=300)
print(f"Sandbox: {_sandbox.sandbox_id}\n")

try:
# Upload input data
_sandbox.files.write(INPUT_FILE.name, INPUT_FILE.read_text())

# Create agent
agent = Agent(
llm=ChatAnthropic(model="claude-sonnet-4-5"),
tools=[run_code],
system_prompt=SYSTEM_PROMPT,
dependency_overrides={get_sandbox: lambda: _sandbox},
)

# Run query
print(f"Query: {USER_PROMPT}\n")

async for event in agent.query_stream(USER_PROMPT):
match event:
case ToolCallEvent(tool=name, args=args):
print(f"[{name}] {str(args)[:100]}...")
case ToolResultEvent(result=result):
print(f" -> {str(result)[:200]}...")
case FinalResponseEvent(content=text):
print(f"\n{text}")

# Download results
download_charts(_sandbox)

finally:
_sandbox.kill()


if __name__ == "__main__":
asyncio.run(main())
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
11 changes: 11 additions & 0 deletions examples/bu-agent-sdk-python/pyproject.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
[project]
name = "bu-agent-sdk-python"
version = "0.1.0"
description = "Data analysis agent using bu-agent-sdk with E2B Code Interpreter"
readme = "README.md"
requires-python = ">=3.11"
dependencies = [
"bu-agent-sdk",
"e2b-code-interpreter",
"python-dotenv",
]