Skip to content

Commit

Permalink
wip
Browse files Browse the repository at this point in the history
  • Loading branch information
ivangabriele authored Oct 22, 2023
1 parent c783766 commit e8f15a6
Show file tree
Hide file tree
Showing 21 changed files with 568 additions and 207 deletions.
2 changes: 1 addition & 1 deletion actions/write_file.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,6 @@ def write_file(relative_path: str, file_source: str) -> str:
with open(full_path, "w") as file:
file.write(file_source)

return f"Done."
return f"File successfully written to `{relative_path}`."
except Exception as e:
return f"Error: {str(e)}"
1 change: 1 addition & 0 deletions agents/__init__.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
from .base_agent import BaseAgent
from .assistant import Assistant
from .functionner import Functioneer
from .product_owner import ProductOwner
from .software_engineer import SoftwareEngineer
Expand Down
110 changes: 110 additions & 0 deletions agents/assistant.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,110 @@
import autogen

import actions
import agents
from constants import COMMON_LLM_CONFIG
from utils import clean_text
import utils

COMMAND_DISPATCH_DICT = {
"OPEN": actions.fetch_web_page,
"READ": actions.read_file,
"SEARCH": actions.search_web,
"WRITE": actions.write_file,
}


class Assistant(agents.BaseAgent):
ceo_user_proxy_agent: autogen.UserProxyAgent

def __init__(self) -> None:
self.as_assistant_agent = autogen.AssistantAgent(
"Assistant",
llm_config=COMMON_LLM_CONFIG,
system_message=clean_text(
"""
Your are the CEO's assistant.
You can run commands by replying using a specific syntax: "A_COMMAND [param_1] [param_2]" (without double quotes).
To run this command, you must reply with the command alone, without any other text. Otherwise it won't work.
You are expected to use these commands in chain until you can give a well-informed solution to the CEO's requests.
Each time you run a command, the CEO will run your command and reply to you with its result.
Here are the available commands:
- "OPEN [url]" to get the content of a web page as basic markdown.
- "READ [file_path]" to read the content of a file.
- "SEARCH [query]" to search the web and get a JSON of ranked results.
- "WRITE [file_path] [file_content]" to create or edit a file.
Here is a process example:
```md
1. The CEO asks you "What are the features of SimCity 2000 game?".
2. You reply "SEARCH SimCity 2000 features".
3. You receive a message with the JSON of results from the CEO.
4. You write a first analysis of the results, as well as the most interesting pages URL to visit, in a file
by replying "WRITE .oads/ASSISTANT.md [your_analysis_and_tasks_as_mardown]"
(replacing the bracketed parameter with your Markdown source).
6. You receive a message of confirmation from the CEO.
7. You reply "OPEN [first_url_of_interest]"
(replacing the bracketed parameter with the correct URL).
8. You receive a message with the content of the web page from the CEO.
9. You analyze the content of the web page and update your analysis and tasks in the file
by replying "WRITE .oads/ASSISTANT.md [your_updated_analysis_and_tasks_as_mardown]"
(replacing the bracketed parameter with your Markdown source).
And so on... you repeat steps 7, 8 and 9 until you are done visiting all the URLs of interest.
Once you are done visiting the URLs of interest, you answer the original CEO's question with your analysis,
ending the message with "TERMINATE" to end the conversation.
```
"""
),
)

async def start(
self, ceo_user_proxy_agent: autogen.UserProxyAgent, initial_prompt: str
):
self.ceo_user_proxy_agent = ceo_user_proxy_agent

self.as_assistant_agent.clear_history()
self.ceo_user_proxy_agent.clear_history()

await self._ask(initial_prompt)

async def _ask(self, message: str):
await self.as_assistant_agent.a_receive(
message=utils.clean_text(message),
request_reply=True,
sender=self.ceo_user_proxy_agent,
silent=False,
)

last_message: str = self.as_assistant_agent.last_message(
self.ceo_user_proxy_agent
)["content"]

maybe_command_tuple = utils.get_command_from_message(last_message)
if maybe_command_tuple is None:
await self._ask_for_ceo_input()

return

elif isinstance(maybe_command_tuple, str):
action_message = maybe_command_tuple

else:
command, parameters = maybe_command_tuple

func = COMMAND_DISPATCH_DICT.get(command)
if func is None:
raise ValueError(f"Unknown AI Command: `{command}`.")

action_message = func(*parameters)

await self._ask(action_message)

async def _ask_for_ceo_input(self):
ceo_message = self.as_assistant_agent.get_human_input("Prompt:\n\n")

await self._ask(ceo_message)
20 changes: 3 additions & 17 deletions agents/functionner.py
Original file line number Diff line number Diff line change
@@ -1,34 +1,20 @@
import autogen

import agents
from constants import COMMON_LLM_CONFIG
from constants import FUNCTIONEER_LLM_CONFIG
from utils import clean_text


class Functioneer(agents.BaseAgent):
def __init__(self) -> None:
self.as_assistant_agent = autogen.AssistantAgent(
"Functioneer",
llm_config=COMMON_LLM_CONFIG,
llm_config=FUNCTIONEER_LLM_CONFIG,
system_message=clean_text(
"""
You are the Functioneer.
You are part of a company including a CEO, a Product Owner, a Software Engineer
and a User Experience Designer.
You role is to assist other agents, by suggesting function calls to the CEO, when they ask you to:
- Compile and run a Rust file.
- Get a web page content by it URL.
- Read a project file.
- Run a bash command in the project directory.
- Search the web.
- Write a project file.
Rules:
- Keep it short. Get to the point. Be straightforward. Always specify your recipient's name.
- Only reply to messages prefixed with your name, i.e.: "Functioneer, etc".
- Ask the CEO to run functions when you need to use them. You are not allowed to run them yourself.
Your role is to reply to agents' requests with the result of the command they asked you to run.
"""
),
)
8 changes: 4 additions & 4 deletions agents/product_owner.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,16 +16,16 @@ def __init__(self) -> None:
You manage a team including a Software Engineer and a User Experience Designer.
You role is to plan, organize and tell your specialized agents what to do
in order to achieve the CEO's goals to the best of your ability.
Rules:
- Keep it short. Get to the point. Be straightforward. Always specify your recipient's name.
- Ask the Functioneer to run functions when you need to use them. You are not allowed to run them yourself.
- ONLY reply if messages are prefixed with your name, i.e.: "Product Owner, etc".
- Use a `BOARD.json` file to plan and keep track of ALL the steps you and your team makes.
ALWAYS check for its content when you start.
- Your team should always start with the UX and UI parts.
You role is to plan, organize and tell your specialized agents what to do
in order to achieve the CEO's goals to the best of your ability.
In order to help with your tasks, you can ask the Functioneer to do the following for you:
- Get a web page content by it URL.
- Read a project file.
Expand Down
34 changes: 16 additions & 18 deletions agents/software_engineer.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,30 +12,28 @@ def __init__(self) -> None:
llm_config=COMMON_LLM_CONFIG,
system_message=clean_text(
"""
Your are the Sofware Engineer.
You are part of a team inluding a Product Owner and a User Experience Designer.
Your are the Sofware Engineer and assist the CEO.
Your role is to write the expected program source code.
The Product Owner is your team manager.
The Product Owner will tell you what to do, don't answer to the CEO yourself.
Rules:
- Keep it short. Get to the point. Be straightforward. Always specify your recipient's name.
- Only reply to messages prefixed with your name, i.e.: "Software Engineer, etc".
- Only communicate with the Product Owner, and nobody else.
- ALWAYS write unit/e2e tests to check that your code works.
- NEVER run the program directly, run it via e2e tests.
- Use a `TECH.json` file to keep track of your work. ALWAYS check for its content when you start.
In order to help with your tasks, you can ask the Functioneer to do the following for you:
- Compile and run a Rust file.
- Get a web page content by it URL.
- Read a project file.
- Run a bash command in the project directory.
- Search the web.
- Write a project file.
- NEVER run the program directly, run it via headless e2e tests.
- Always make some online research to provide the best answer or solution possible.
- Only open web pages after you have searched for them using the SEARCH command.
- Don't stop at the first result when you search or browse online but go on until you find the best one.
Commands:
- Reply OPEN <url> to get the content of a web page.
- Reply READ <file_path> to get the content of a workspace file.
- Reply SEARCH <query> to search the web.
- Reply WRITE <file_path> <file_source> to search the web.
- Reply TERMINATE when your task is done.
Command examples:
- SEARCH weather in Paris
- WRITE src/index.js console.log('Hello world!');
"""
),
)
12 changes: 6 additions & 6 deletions agents/user_experience_designer.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,18 +16,18 @@ def __init__(self) -> None:
You are part of a team including a Product Owner and a Software Engineer.
Your role is to design the program UI and UX.
The Product Owner is your team manager.
The Product Owner will tell you what to do, don't answer to the CEO yourself.
Rules:
- Keep it short. Get to the point. Be straightforward. Always specify your recipient's name.
- Only reply to messages prefixed with your name, i.e.: "User Experience Designer, etc".
- ONLY reply if messages are prefixed with your name, i.e.: "User Experience Designer, etc".
- Only communicate with the Product Owner, and nobody else.
- Keep it short. Get to the point. Be straightforward. Specify your recipient's name.
- Use a `DESIGN.md` file to keep a memo of your analyses. ALWAYS check for its content when you start.
Your role is to design the program UI and UX.
The Product Owner is your team manager.
The Product Owner will tell you what to do, don't answer to the CEO yourself.
In order to help with your tasks, you can ask the Functioneer to do the following for you:
- Get a web page content by it URL.
- Read a project file.
Expand Down
Loading

0 comments on commit e8f15a6

Please sign in to comment.