-
Notifications
You must be signed in to change notification settings - Fork 3.7k
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
Minimal Docker Sandbox with GPT-3.5 Execution Example #48
Conversation
Just checking some existing PRs and realize this is somewhat similar to @geohotstan's #29, with the difference being the command we run is |
I opened #29 because I saw you mention it in slack hehe 😄 |
increase timeout to avoid return too early for long running commands;
Just tweak the container a bit. Using the CodeAct idea, I also added a minimal working example (less than 100 LOC with Most of the things are working as expected, except at the end, the model did not follow the instruction to stop the interaction by outputting |
I am seeing the following error when I exit the container: penberg@vonneumann OpenDevin % python3 opendevin/sandbox/docker.py
Interactive Docker container started. Type 'exit' or use Ctrl+C to exit.
root@1149541e85f2:/# exit
Exiting...
Container killed.
Exception ignored in: <function DockerInteractive.__del__ at 0x100a02b60>
Traceback (most recent call last):
File "/Users/penberg/src/penberg/OpenDevin/opendevin/sandbox/docker.py", line 80, in __del__
File "/Users/penberg/src/penberg/OpenDevin/opendevin/sandbox/docker.py", line 70, in close
OSError: [Errno 9] Bad file descriptor |
Hey @penberg, thanks for the review! I tried to address these issues, do you mind helping me test if the "Bad file descriptor" issue goes away? My Linux setup does not throw similar errors at this moment. |
Works great now, thanks @xingyaoww! |
Thanks a bunch for this! Just a question for @xingyaoww and @rbren , how does this PR play together with #35? They seem to overlap a little, and I was wondering if it'd be necessary to combine them together to get the best of both worlds? |
Thanks @neubig! That is actually a pretty good question! I feel it ultimately comes down to the roadmap/structure of this project.
At this stage, and considering the amount of interest and potential number of contributors from the community, it might be beneficial for the project to consider both routes and work on both in parallel until some future evaluation milestones. What I think is important is how we structure the project to allow such parallel development. Here are my two cents about how we might organize this project.
Going back to these two PRs, if we eventually adopt a project structure like this, I think we can safely merge both into main, re-organize all shared components to |
There are two interesting things here that I think we should take advantage of, but might be hard to merge this PR as-is
|
…ith correct permission
I updated a few things:
Regarding @rbren's comment: I completely agree! Some of the adjustments i did above address some of these issues:
|
OK awesome, that's exactly what I'm looking for! I have a |
output_str = output_str.lstrip(user_input).lstrip() | ||
return output_str | ||
|
||
def execute(self, cmd: str) -> str: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If I'm reading this right, to run multiple commands concurrently (e.g. node server.js
and curl localhost:3000
) we'll want to instantiate multiple sandboxes with different IDs. I think that will work well.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
That's a great TODO for the next i guess! We could also consider docker run
the container in the backend, and starts multiple shell sessions to attach docker attach
to the same container so that we save some resources (but those processes could potentially interfere with each other).
self.timeout: int = timeout | ||
|
||
if container_image is None: | ||
container_image = self.CONTAINER_IMAGE |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is super helpful--I imagine folks are going to want to define custom images so that the LLM doesn't have to e.g. install nodejs or rust every time it starts a new task.
We'll probably want to make this configurable in the UI.
* minimal docker sandbox * make container_image as an argument (fall back to ubuntu); increase timeout to avoid return too early for long running commands; * add a minimal working (imperfect) example * fix typo * change default container name * attempt to fix "Bad file descriptor" error * handle ctrl+D * add Python gitignore * push sandbox to shared dockerhub for ease of use * move codeact example into research folder * add README for opendevin * change container image name to opendevin dockerhub * move folder; change example to a more general agent * update Message and Role * update docker sandbox to support mounting folder and switch to user with correct permission * make network as host * handle erorrs when attrs are not set yet * convert codeact agent into a compatible agent * add workspace to gitignore * make sure the agent interface adjustment works for langchain_agent
A minimalistic implementation of Docker Sandbox with less than 100 LOC and requires only built-in libraries. It exposes a
.execute
API to run arbitrary bash commands inside the docker container.It requires
docker
to be installed in the system, and, will potentially need some adjustment when switch to other OS. I hope it could be a potential starting point for future development.Run it:
python3 opendevin/sandbox/docker.py
Example screenshot: