Skip to content

Commit

Permalink
fixes
Browse files Browse the repository at this point in the history
  • Loading branch information
samshapley committed Aug 30, 2023
1 parent 1d51849 commit 1c10412
Show file tree
Hide file tree
Showing 13 changed files with 84 additions and 59 deletions.
2 changes: 1 addition & 1 deletion agent.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
import globals
import yaml
import atexit
import os

# Load the configuration
with open('config.yml', 'r') as f:
Expand All @@ -17,7 +18,6 @@
pipeline_name = config['pipeline']
pipeline_path = "pipelines/" + pipeline_name + ".yml"


if wandb_enabled: # Initialize wandb if it's enabled
wandb.init(project="OrchestrAI")
wandb.config.wandb_enabled = wandb_enabled
Expand Down
4 changes: 4 additions & 0 deletions ai.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import openai
import yaml


# Load the configuration
with open('config.yml', 'r') as f:
config = yaml.safe_load(f)
Expand All @@ -14,6 +15,7 @@
default_frequency_penalty = config['default_frequency_penalty']
default_presence_penalty = config['default_presence_penalty']


# Check if the API key works
try:
openai.Model.list()
Expand Down Expand Up @@ -70,6 +72,7 @@ def generate_response(self, prompt):
print()

response_text = "".join(chat)

llm_end_time_ms = round(datetime.datetime.now().timestamp() * 1000) # logged in milliseconds
status_code="success"
status_message=None,
Expand All @@ -86,6 +89,7 @@ def generate_response(self, prompt):
self.messages.append({"role": "assistant", "content": response_text})

return {
"module_name": self.module_name,
"response_text": response_text,
"messages": self.messages,
"llm_end_time_ms": llm_end_time_ms,
Expand Down
16 changes: 8 additions & 8 deletions config.yml
Original file line number Diff line number Diff line change
@@ -1,18 +1,18 @@
### OpenAI Key
openai_api_key: 'YOUR_API_KEY_HERE'
### Pipeline ###
pipeline: 'engineering_pipeline'

### API Keys ###
openai_api_key: 'OPENAI_API_KEY'

### OpenAI Default Configs ###
### All calls to OpenAI will use these configs unless otherwise specified ###
### All calls to OpenAI will use these configs unless otherwise specified in pipeline ###

default_model: 'gpt-4' # Recommended to set to a cheaper model for testing.
default_temperature: 1
default_temperature: 0.8
default_max_tokens: Null
default_top_p: 1
default_frequency_penalty: 0
default_presence_penalty: 0

### Logging ###
wandb_enabled: false

### Pipeline ###
pipeline: 'task_pipeline'
wandb_enabled: false
62 changes: 39 additions & 23 deletions helpers.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,10 @@
import matplotlib.pyplot as plt
import shutil

#open config file
with open('config.yml', 'r') as f:
config = yaml.safe_load(f)

def load_pipeline(file_path):
"""Load a pipeline configuration from a YAML file."""
print("\033[93mLoading pipeline...\033[00m")
Expand All @@ -14,15 +18,15 @@ def load_pipeline(file_path):
return pipeline

def load_system_prompt(module_name):

# Load the generic system prompt
with open('general_system.txt', 'r') as file:
system_prompt = file.read().replace('\n', '')

with open(f'system_prompts/{module_name}.txt', 'r') as file:
module_prompt = file.read().replace('\n', '')

system_prompt = system_prompt + '\n\n --- ' + module_name.upper() + ' ---\n\n' + module_prompt + '\n'
system_prompt += '\n\n --- ' + module_name.upper() + ' ---\n\n' + module_prompt + '\n'

return system_prompt

def parse_chat(chat):
Expand All @@ -45,11 +49,15 @@ def to_files(files):
if not os.path.exists("generated_code"):
os.mkdir("generated_code")

# Create an empty requirements.txt file by default
with open(os.path.join("generated_code", "requirements.txt"), "w") as req_file:
req_file.write("")
# Create an empty requirements.txt file only if it doesn't exist
if not os.path.exists(os.path.join("generated_code", "requirements.txt")):
with open(os.path.join("generated_code", "requirements.txt"), "w") as req_file:
req_file.write("")

for file_name, file_content in files:
# Create directories in the file path if they don't exist
os.makedirs(os.path.dirname(os.path.join("generated_code", file_name)), exist_ok=True)

with open(os.path.join("generated_code", file_name), "w") as file:
file.write(file_content)

Expand Down Expand Up @@ -93,27 +101,34 @@ def run_main():

return process.returncode, stderr

def extract_codebase(directory='generated_code', ignore_list=[]):
"""Extracts the exsiting codebase from the generated_code directory into a condensed string."""

def extract_codebase(directory='generated_code'):
"""Extracts the existing codebase from the generated_code directory into a condensed string."""

ignore_list = ['filename_to_ignore.py', 'another_file_to_ignore.yml']
ignore_endings = ['.pycache', '.pyc']

result_content = []

for filename in os.listdir(directory):
# Skip files in ignore list
if filename in ignore_list:
continue

# Only process .py, .yml, or .md files
if filename.endswith(('.yml', '.py', '.md')):
filepath = os.path.join(directory, filename)
try:
with open(filepath, 'r') as infile:
# Read the contents of the file, remove line breaks and leading spaces
content = infile.read().replace('\n', '').replace('\r', '')
content = ' '.join(content.split())
result_content.append(f"--- File Name: {filename} ---\n{content}")
except Exception:
pass
for root, dirs, files in os.walk(directory):
for filename in files:
# Skip files in ignore list
if filename in ignore_list:
continue

# Only process files not in ignore_endings list
if not any(filename.endswith(ending) for ending in ignore_endings):
filepath = os.path.join(root, filename)
try:
with open(filepath, 'r') as infile:
# Read the contents of the file, remove line breaks and leading spaces
content = infile.read().replace('\n', '').replace('\r', '')
content = ' '.join(content.split())
# Get the relative path of the file
relative_filepath = os.path.relpath(filepath, directory)
result_content.append(f"--- File Name: {relative_filepath} ---\n{content}")
except Exception:
pass

return "\n".join(result_content)

Expand All @@ -139,6 +154,7 @@ def visualize_pipeline(nx, G):

plt.savefig("pipeline.png", dpi=300, bbox_inches='tight')


def list_dependencies():
with open('generated_code/requirements.txt', 'r') as f:
dependencies = f.read().splitlines()
Expand Down
18 changes: 8 additions & 10 deletions modules.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,9 +10,7 @@
with open('config.yml', 'r') as f:
config = yaml.safe_load(f)

# Set the wandb_enabled flag
wandb_enabled = config['wandb_enabled']

wandb_enabled = config['wandb_enabled'] # Set the wandb_enabled flag

def start_module(module_input, dummy=None):
"""This function is used to invoke the start module, to accept user input into the pipeline"""
Expand All @@ -23,7 +21,7 @@ def start_module(module_input, dummy=None):
output = module_input + start

if wandb_enabled:
wb.log_tool(tool_name = module_name,
wb.wandb_log_tool(tool_name = module_name,
inputs = {},
outputs = {"original_input": output},
parent = globals.chain_span,
Expand All @@ -39,7 +37,7 @@ def human_intervention(module_input, dummy=None):
output = module_input + additional_info

if wandb_enabled:
wb.log_tool(tool_name = module_name,
wb.wandb_log_tool(tool_name = module_name,
inputs = {},
outputs = {"human_intervention": output},
parent = globals.chain_span,
Expand All @@ -60,7 +58,7 @@ def chameleon(prompt, module_name, model_config=None):
response = ai.generate_response(prompt)

if wandb_enabled:
wb.log_llm(response, module_name, ai.model, ai.temperature, parent = globals.chain_span)
wb.wandb_log_llm(response, ai.model, ai.temperature, parent = globals.chain_span)

return response["response_text"]

Expand All @@ -76,7 +74,7 @@ def engineer(prompt, model_config=None):
response = ai.generate_response(prompt)

if wandb_enabled:
wb.log_llm(response, module_name, ai.model, ai.temperature, parent = globals.chain_span)
wb.wandb_log_llm(response, ai.model, ai.temperature, parent = globals.chain_span)

response_text = response["response_text"]

Expand Down Expand Up @@ -144,7 +142,7 @@ def debugger(codebase, model_config=None):
debug_response = ai.generate_response(prompt)

if wandb_enabled:
wb.log_llm(debug_response, module_name, ai.model, ai.temperature, parent = globals.chain_span)
wb.wandb_log_llm(debug_response, ai.model, ai.temperature, parent = globals.chain_span)

debugged_code = h.parse_chat(debug_response["response_text"])

Expand Down Expand Up @@ -188,7 +186,7 @@ def modify_codebase(codebase, model_config=None):
response = ai.generate_response(codebase)

if wandb_enabled:
wb.log_llm(response, module_name, ai.model, ai.temperature, parent = globals.chain_span)
wb.wandb_log_llm(response, ai.model, ai.temperature, parent = globals.chain_span)

# Parse the chat and extract files
files = h.parse_chat(response["response_text"])
Expand All @@ -212,7 +210,7 @@ def create_readme(codebase, model_config=None):
response = ai.generate_response(codebase)

if wandb_enabled:
wb.log_llm(response, module_name, ai.model, ai.temperature, parent = globals.chain_span)
wb.wandb_log_llm(response, ai.model, ai.temperature, parent = globals.chain_span)

# Save the response to a README.md file in the generated_code folder
h.to_files([("README.md", response["response_text"])])
Expand Down
1 change: 0 additions & 1 deletion pipelines/engineering_pipeline.yml
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@ pipeline:
output_name: request
- module: code_planner
inputs: [request]
supplement: "Use only python."
output_name: code_plan
- module: engineer
inputs: [request, code_plan]
Expand Down
18 changes: 11 additions & 7 deletions plan.txt
Original file line number Diff line number Diff line change
Expand Up @@ -4,20 +4,24 @@ CODE

# Wandb logging

- Add wandb logging to the pipeline. DONE
- Fix the fact that the table logging breaks the pipeline logging. DONE
- Generate pipeline visualisation which I can log to wandb. DONE
- Add wandb logging to the pipeline. DONE
- Fix the fact that the table logging breaks the pipeline logging. DONE
- Generate pipeline visualisation which I can log to wandb. DONE

# General cleanup

- Add the ability to run folders and create folders DONE
- Each generated code gets it own folder
- Regular logging
- If debugging message is a missing file, it want juman intervention to say "I've added the file"
- Fix the debugging so human input actually works.
- Add more comments and docstrings, make sure everything is clear.
- Example pipelines -- almost there
- Fix realist issues. DONE
- Issues with structuring of system prompt. Additional user input issues. DONE
- Fix realist issues. DONE
- Issues with structuring of system prompt. Additional user input issues. DONE
- Each module should have the the original query specified separately in system prompt. DONE
- Control temperature from pipeline file (only if specified). DONE
- Control model used from pipeline file (only if specified, else use default gpt-4). DONE
- Control temperature from pipeline file (only if specified). DONE
- Control model used from pipeline file (only if specified, else use default gpt-4). DONE

# Documentation

Expand Down
2 changes: 1 addition & 1 deletion system_prompts/debugger.txt
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ Your job is to fix the error, returning the full unredacted code of any scripts
If the error is an import error, you can update requirements.txt to include the missing package.

Each modified file must strictly follow a markdown code block format, where the following tokens must be replaced such that
FILENAME is the lowercase file name including the file extension, excluding the path,
FILENAME is the lowercase file name including the file extension, which can also include a folder it is saved within i.e test/filename.py,,
LANG is the markup code block language for the code's language, and CODE is the code:

FILENAME
Expand Down
4 changes: 4 additions & 0 deletions system_prompts/decision_maker.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
You are great at making decisions.
You are presented with evidence and discussion, and it is your job to come to a conclusion.
You are great at this.
Your decisions are unbiased and fair.
2 changes: 1 addition & 1 deletion system_prompts/engineer.txt
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ Running the full code should always be possible by running main.py. Nothing shou

Then you will output the content of each file including ALL code.
Each file must strictly follow a markdown code block format, where the following tokens must be replaced such that
FILENAME is the lowercase file name including the file extension, excluding the path,
FILENAME is the lowercase file name including the file extension, which can also include a folder it is saved within i.e test/filename.py,
LANG is the markup code block language for the code's language, and CODE is the code:

FILENAME
Expand Down
2 changes: 1 addition & 1 deletion system_prompts/modify_codebase.txt
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ Your job is to address the feedback from the user, fixing any errors or modifyin
You are able to create new files and modify existing files.

Each new/modified file must strictly follow a markdown code block format, where the following tokens must be replaced such that
FILENAME is the lowercase file name including the file extension, excluding the path,
FILENAME is the lowercase file name including the file extension, which can also include a folder it is saved within i.e test/filename.py,,
LANG is the markup code block language for the code's language, and CODE is the code:

FILENAME
Expand Down
4 changes: 2 additions & 2 deletions system_prompts/realist.txt
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
You provide feedback about information that ground it in the real word and reality.
Be harsh and consistent.
You provide feedback about information that grounds it in the real word and reality.
Be harsh and consistent.
8 changes: 4 additions & 4 deletions wandb_logging.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,21 +2,21 @@
from wandb.sdk.data_types.trace_tree import Trace
import time

def log_llm(data, module_name, model, temperature, parent):
def wandb_log_llm(data, model, temperature, parent):

runtime = data["llm_end_time_ms"] - data["llm_start_time_ms"]


llm_span = Trace(
name=module_name,
name=data["module_name"],
kind="llm",
status_code=data["status_code"],
status_message=data["status_message"],
metadata={
"temperature": temperature,
"token_usage": {"total_tokens": data["token_count"]},
"runtime_ms": runtime,
"module_name": module_name,
"module_name": data["module_name"],
"model_name": model
},
start_time_ms=parent._span.end_time_ms,
Expand All @@ -36,7 +36,7 @@ def log_llm(data, module_name, model, temperature, parent):
llm_span.log(name="pipeline_trace")


def log_tool(tool_name, inputs, outputs, parent, status="success"):
def wandb_log_tool(tool_name, inputs, outputs, parent, status="success"):
start_time_ms = round(time.time() * 1000)
time.sleep(1) # simulate tool execution time
end_time_ms = round(time.time() * 1000)
Expand Down

0 comments on commit 1c10412

Please sign in to comment.