Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: add E2B code interpreter #106

Open
wants to merge 7 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 1 commit
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
35 changes: 35 additions & 0 deletions crewai_tools/tools/e2b_code_interpreter_tool/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
# E2BCodeInterpreterTool

## Description
This tool is used to give an agent the ability to run arbitrary Python code. The code is executed in a secure cloud sandbox via E2B. After the code is run, the agent recieves the result of the code as well as any errors that occured during execution, which gives the agent debugging ability.

## Installation

- Get an API key from [e2b.dev](https://e2b.dev) and set it in the environment variables `E2B_API_KEY`.
- Install the [Code Interpreter Beta SDK](https://e2b.dev/docs/guide/beta-migration) along with the `crewai[tools]` package:

```
pip install e2b-code-interpreter>=0.0.11b32 'crewai[tools]'
```

## Example

Utilize the code interpreter tool to allow your agent to run Python code:

```python
from crewai import Agent
from crewai_tools import E2BCodeInterpreterTool

code_interpreter = E2BCodeInterpreterTool()
jamesmurdza marked this conversation as resolved.
Show resolved Hide resolved

Agent(
...
tools=[E2BCodeInterpreterTool()],
)

# ... Use the agent ...

code_interpreter.close()
jamesmurdza marked this conversation as resolved.
Show resolved Hide resolved
```

Futher examples are provided in the [E2B Cookbook](https://github.com/e2b-dev/e2b-cookbook).
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
import os
import json
from crewai_tools import BaseTool
from e2b_code_interpreter import CodeInterpreter

from typing import Type
from pydantic import BaseModel, Field

class E2BCodeInterpreterSchema(BaseModel):
"""Input schema for the CodeInterpreterTool, used by the agent."""

code: str = Field(
...,
description="Python3 code used to run in the Jupyter notebook cell. Non-standard packages are installed by appending !pip install [packagenames] and the Python code in one single code block.",
)

class E2BCodeInterpreterTool(BaseTool):
"""
This is a tool that runs arbitrary code in a Python Jupyter notebook.
It uses E2B to run the notebook in a secure cloud sandbox.
It requires an E2B_API_KEY to create a sandbox.
"""
name: str = "code_interpreter"
description: str = "Execute Python code in a Jupyter notebook cell and return any rich data (eg charts), stdout, stderr, and errors."
args_schema: Type[BaseModel] = E2BCodeInterpreterSchema
_code_interpreter_tool: CodeInterpreter | None = None

def __init__(self, *args, **kwargs):
# Call the superclass's init method
super().__init__(*args, **kwargs)

# Ensure that the E2B_API_KEY environment variable is set
if "E2B_API_KEY" not in os.environ:
raise Exception(
"Code Interpreter tool called while E2B_API_KEY environment variable is not set. Please get your E2B API key here https://e2b.dev/docs and set the E2B_API_KEY environment variable."
)

# Initialize the code interpreter tool
self._code_interpreter_tool = CodeInterpreter()

def _run(self, code: str) -> str:
# Execute the code using the code interpreter
execution = self._code_interpreter_tool.notebook.exec_cell(code)

# Extract relevant execution details
result = {
"results": [str(item) for item in execution.results],
"stdout": execution.logs.stdout,
"stderr": execution.logs.stderr,
"error": str(execution.error),
}

# Convert the result dictionary to a JSON string since CrewAI expects a string output
content = json.dumps(result, indent=2)

return content
jamesmurdza marked this conversation as resolved.
Show resolved Hide resolved

def close(self):
# Close the interpreter tool when done
self._code_interpreter_tool.kill()