[go: up one dir, main page]

Skip to content

Commit

Permalink
Abstraction that allows us to develop different agents, frontend, bac…
Browse files Browse the repository at this point in the history
…kend, and evaluation in parallel (All-Hands-AI#68)

* move agent to langchains_agent

* remove old .env

* remove the old agent folder

* add preliminary version of Agent abstraction

* add preliminary version of the main.py

* merge controlloop and main into a Agent class

* add init

* fix json import

* fix missing arg

* get langchains_agent working after abstraction

* rename `research` to `agenthub`

* rename: rename research to agenthub

---------

Co-authored-by: huybery <huybery@gmail.com>
  • Loading branch information
xingyaoww and huybery authored Mar 20, 2024
1 parent f99f4eb commit 0380070
Show file tree
Hide file tree
Showing 140 changed files with 296 additions and 131 deletions.
9 changes: 0 additions & 9 deletions agent/build-and-run.sh

This file was deleted.

6 changes: 0 additions & 6 deletions agent/lib/actions/__init__.py

This file was deleted.

18 changes: 0 additions & 18 deletions agent/lib/controlloop.py

This file was deleted.

83 changes: 0 additions & 83 deletions agent/main.py

This file was deleted.

6 changes: 6 additions & 0 deletions agenthub/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
# Agent Framework Research

In this folder, there may exist multiple implementations of `Agent` that will be used by the

For example, `agenthub/langchain_agent`, `agenthub/metagpt_agent`, `agenthub/codeact_agent`, etc.
Contributors from different backgrounds and interests can choose to contribute to any (or all!) of these directions.
1 change: 1 addition & 0 deletions agenthub/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
from . import langchains_agent
File renamed without changes.
5 changes: 1 addition & 4 deletions agent/Dockerfile → agenthub/langchains_agent/Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -14,10 +14,7 @@ WORKDIR /app
COPY requirements.txt ./requirements.txt
RUN python -m pip install -r requirements.txt

COPY lib ./lib
COPY main.py ./main.py

WORKDIR /workspace

CMD ["python", "/app/main.py", "/workspace"]
CMD ["python", "/app/opendevin/main.py", "/workspace"]

3 changes: 2 additions & 1 deletion agent/README.md → agenthub/langchains_agent/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,5 +3,6 @@ This is currently a standalone utility. It will need to be integrated into OpenD

## Usage
```bash
./build-and-run.sh "write a bash script that prints 'hello world'"
# Run this in project root
./agenthub/langchains_agent/build-and-run.sh "write a bash script that prints 'hello world'"
```
File renamed without changes.
111 changes: 111 additions & 0 deletions agenthub/langchains_agent/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,111 @@
import os
import argparse

from opendevin.agent import Agent, Message

from agenthub.langchains_agent.utils.agent import Agent as LangchainsAgentImpl
from agenthub.langchains_agent.utils.event import Event

INITIAL_THOUGHTS = [
"I exist!",
"Hmm...looks like I can type in a command line prompt",
"Looks like I have a web browser too!",
"Here's what I want to do: $TASK",
"How am I going to get there though?",
"It seems like I have some kind of short term memory.",
"Each of my thoughts seems to be stored in a numbered list.",
"It seems whatever I say next will be added to the list.",
"But no one has perfect short-term memory. My list of thoughts will be summarized and condensed over time, losing information in the process.",
"Fortunately I have long term memory!",
"I can just say RECALL, followed by the thing I want to remember. And then related thoughts just spill out!",
"Sometimes they're random thoughts that don't really have to do with what I wanted to remember. But usually they're exactly what I need!",
"Let's try it out!",
"RECALL what it is I want to do",
"Here's what I want to do: $TASK",
"How am I going to get there though?",
"Neat! And it looks like it's easy for me to use the command line too! I just have to say RUN followed by the command I want to run. The command output just jumps into my head!",
'RUN echo "hello world"',
"hello world",
"Cool! I bet I can read and edit files too.",
"RUN echo \"console.log('hello world')\" > test.js",
"",
"I just created test.js. I'll try and run it now.",
"RUN node test.js",
"hello world",
"it works!",
"And if I want to use the browser, I just need to say BROWSE, followed by a website I want to visit, or an action I want to take on the current site",
"Let's try that...",
"BROWSE google.com",
'<form><input type="text"></input><button type="submit"></button></form>',
"Very cool. Now to accomplish my task.",
"I'll need a strategy. And as I make progress, I'll need to keep refining that strategy. I'll need to set goals, and break them into sub-goals.",
"In between actions, I must always take some time to think, strategize, and set new goals. I should never take two actions in a row.",
"OK so my task is to $TASK. I haven't made any progress yet. Where should I start?",
"It seems like there might be an existing project here. I should probably start by running `ls` to see what's here.",
]


class LangchainsAgent(Agent):

def _run_loop(self, agent: LangchainsAgentImpl, max_iterations=100):
# TODO: make it add a Message to the history for each turn / event
for i in range(max_iterations):
print("STEP", i, flush=True)
log_events = agent.get_background_logs()
for event in log_events:
print(event, flush=True)
action = agent.get_next_action()
if action.action == "finish":
print("Done!", flush=True)
break
print(action, flush=True)
print("---", flush=True)
out = agent.maybe_perform_latest_action()
print(out, flush=True)
print("==============", flush=True)

def run(self) -> None:
"""
Starts the execution of the assigned instruction. This method should
be implemented by subclasses to define the specific execution logic.
"""
agent = LangchainsAgentImpl(self.instruction)
next_is_output = False
for thought in INITIAL_THOUGHTS:
thought = thought.replace("$TASK", self.instruction)
if next_is_output:
event = Event("output", {"output": thought})
next_is_output = False
else:
if thought.startswith("RUN"):
command = thought.split("RUN ")[1]
event = Event("run", {"command": command})
next_is_output = True
elif thought.startswith("RECALL"):
query = thought.split("RECALL ")[1]
event = Event("recall", {"query": query})
next_is_output = True
elif thought.startswith("BROWSE"):
url = thought.split("BROWSE ")[1]
event = Event("browse", {"url": url})
next_is_output = True
else:
event = Event("think", {"thought": thought})

agent.add_event(event)
self._run_loop(agent, self.max_steps)

# Set the agent's completion status to True
self._complete = True

def chat(self, message: str) -> None:
"""
Optional method for interactive communication with the agent during its execution. Implementations
can use this method to modify the agent's behavior or state based on chat inputs.
Parameters:
- message (str): The chat message or command.
"""
raise NotImplementedError

Agent.register("LangchainsAgent", LangchainsAgent)
19 changes: 19 additions & 0 deletions agenthub/langchains_agent/build-and-run.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
#!/bin/bash
set -eo pipefail

rm -rf `pwd`/workspace
mkdir -p `pwd`/workspace

pushd agenthub/langchains_agent
docker build -t control-loop .
popd
docker run \
-e DEBUG=$DEBUG \
-e OPENAI_API_KEY=$OPENAI_API_KEY \
-u `id -u`:`id -g` \
-v `pwd`/workspace:/workspace \
-v `pwd`:/app:ro \
-e PYTHONPATH=/app \
control-loop \
python /app/opendevin/main.py -d /workspace -t "${1}"

File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
6 changes: 6 additions & 0 deletions agenthub/langchains_agent/utils/actions/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
from .run import run
from .kill import kill
from .browse import browse
from .write import write
from .read import read

File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
import select

from lib.monologue import Monologue
from lib.memory import LongTermMemory
from lib.event import Event
import lib.llm as llm
from agenthub.langchains_agent.utils.monologue import Monologue
from agenthub.langchains_agent.utils.memory import LongTermMemory
from agenthub.langchains_agent.utils.event import Event
import agenthub.langchains_agent.utils.llm as llm

MAX_OUTPUT_LENGTH = 5000
MAX_MONOLOGUE_LENGTH = 20000
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import os
import json
import lib.actions as actions
import agenthub.langchains_agent.utils.actions as actions

class Event:
def __init__(self, action, args):
Expand Down
File renamed without changes.
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import os

import lib.json as json
from . import json

if os.getenv("DEBUG"):
from langchain.globals import set_debug
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import os
import lib.json as json
from . import json

import chromadb

Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import lib.json as json
from lib.event import Event
import agenthub.langchains_agent.utils.json as json
from agenthub.langchains_agent.utils.event import Event

import lib.llm as llm
import agenthub.langchains_agent.utils.llm as llm

class Monologue:
def __init__(self):
Expand Down
Loading

0 comments on commit 0380070

Please sign in to comment.