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

Structured Output Revisions #17

Open
wants to merge 32 commits into
base: dev
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 31 commits
Commits
Show all changes
32 commits
Select commit Hold shift + click to select a range
9465290
Adding utils.py and setting up openai_config.json
Aug 7, 2024
cea0b78
Changing gpt model to gp4-turbo and embedding model to text-davinci-002
Aug 7, 2024
113b48d
Creating 2 separate simulation scenarios: hide-and-seek and search-an…
Aug 7, 2024
56e4f28
updating .gitignore to not send the utils.py file to the remote branch
Aug 7, 2024
f498f8a
Setting up spawning locations for agents and personasn for the search…
Aug 7, 2024
f8eb6aa
merged dev-rebase and all of its changes onto jonathan-dev-rebase
Aug 14, 2024
625250c
Merge remote-tracking branch 'origin/chowington-search-and-rescue' in…
Sep 9, 2024
7c8d7be
Initial branch commit
LemmyTron Sep 22, 2024
68d2160
Initial commit for henry branch
LemmyTron Sep 26, 2024
fc05aeb
Merge branch 'chowington-search-and-rescue' of https://github.com/crc…
LemmyTron Sep 26, 2024
a6d560b
Merging new updates from Connor that has search and rescue simulation…
Sep 27, 2024
9d947c7
Pulled Connor's branch, updated to gpt-4o-mini, added type hinting to…
Sep 27, 2024
53c6667
Initial test simulation with modifications to Connor's branch
Sep 27, 2024
fc55356
convo parse fixed
LemmyTron Oct 10, 2024
fb1ba8c
Merge branch 'chowington-search-and-rescue' of https://github.com/crc…
LemmyTron Oct 10, 2024
d6fe1ca
merging new updates from chowington-search-and-destroy to my branch
Oct 11, 2024
24629e9
Added structured_output outline
LemmyTron Oct 11, 2024
c2a8c0d
Replaced chatgpt_safe_generate_resposne with structured output versio…
jgranda1999 Oct 11, 2024
2bf67d0
Added conversation parser
jgranda1999 Oct 11, 2024
99cbf7f
Parsers convert simulations output into txt files
denialj12 Oct 11, 2024
b0ba4ac
commit changes
LemmyTron Oct 22, 2024
e56d728
Merge remote-tracking branch 'origin/dev' into henry-dev-rebase
LemmyTron Oct 22, 2024
54b9703
add structured output to my share of functions
LemmyTron Oct 23, 2024
1546c80
fix parsing error
LemmyTron Oct 23, 2024
8adf989
Merge branch 'dev' into jonathan-dev-rebase
jgranda1999 Oct 27, 2024
71c2b99
fix structured output functions
LemmyTron Oct 27, 2024
15b5920
Merge remote-tracking branch 'origin/henry-dev-rebase' into djohan-re…
denialj12 Oct 27, 2024
5e48a51
Merge branch 'jonathan-dev-rebase' into djohan-rebase
denialj12 Oct 27, 2024
7267190
Structured Output Revisions
denialj12 Oct 27, 2024
ce9039b
Clean PR
chowington Oct 29, 2024
8d1c991
More PR cleaning
chowington Oct 29, 2024
092b6c0
Merge branch 'dev' into temporary_branch
chowington Nov 8, 2024
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
2 changes: 1 addition & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ logs/*
!logs/skip-morning_2024-05-15_13-54-44.txt

### Add simulations to keep here ###
!environment/frontend_server/storage/base_the_ville_isabella_maria_klaus/*
!environment/frontend_server/storage/base_the_ville_isabella_maria_klaus/
!environment/frontend_server/storage/base_the_ville_n25/*
!environment/frontend_server/storage/July1_the_ville_isabella_maria_klaus-step-3-*/*
!environment/frontend_server/storage/skip-morning-s-14/
Expand Down
62 changes: 62 additions & 0 deletions convo_parser.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
import os
import glob
import os
import sys
import json

def get_unique_conversations(simulation_name):
step_folder = "environment/frontend_server/storage"

# Use glob to find all files that start with the simulation_name
search_pattern = os.path.join(step_folder, f"{simulation_name}*/movement/*")
filepaths = glob.glob(search_pattern)

observed_conversations = set()
file_contents = []

# Iterate over all matching files
for filepath in filepaths:
with open(filepath, "r") as file:
data = json.load(file)
personas = data.get("persona", {})

# Loop over all personas except one, since conversations are always
# between two people
for name in list(personas.keys())[:-1]:
persona = personas[name]
chat = persona.get("chat")

if chat:
chat_string = str(chat)

# Add unique conversations
if chat_string not in observed_conversations:
observed_conversations.add(chat_string)
file_contents.append(data)
break

return file_contents

def write_conversations_to_file(conversations, simulation_name):
output_directory = "logs/conversations"
if not os.path.exists(output_directory):
os.makedirs(output_directory)
output_filename = f"{simulation_name}_highlights.json"
full_path = os.path.join(output_directory, output_filename);
with open(full_path, "w") as file:
for conversation in conversations:
json.dump(conversation, file, indent=4)

if __name__ == "__main__":
if len(sys.argv) < 2:
print("Please provide the simulation name as a command line argument.")
sys.exit(1)

simulation_name = sys.argv[1]
unique_conversations = get_unique_conversations(simulation_name)

if unique_conversations:
write_conversations_to_file(unique_conversations, simulation_name)
print(f"Unique conversations written to {simulation_name}_highlights.txt")
else:
print("No unique conversations found.")
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
"age": 20,
"innate": "kind, inquisitive, passionate",
"learned": "Klaus Mueller is a student at Oak Hill College studying sociology. He is passionate about social justice and loves to explore different perspectives.",
"currently": "Klaus Mueller is writing a research paper on the effects of gentrification in low-income communities. Klauss is thinking about whom to vote for in the upcoming town election. He knows that Adam Smith and Isabella Rodriguez are running for the office of town mayor. The election takes place next week.",
"currently": "Klaus Mueller is writing a research paper on the effects of gentrification in low-income communities. Klaus is thinking about whom to vote for in the upcoming town election. He knows that Adam Smith and Isabella Rodriguez are running for the office of town mayor. The election takes place next week.",
"lifestyle": "Klaus Mueller goes to bed around 11pm, awakes up around 7am, eats dinner around 5pm.",
"living_area": "the Ville:Dorm for Oak Hill College:Klaus Mueller's room",
"concept_forget": 100,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
"age": 20,
"innate": "kind, inquisitive, passionate",
"learned": "Klaus Mueller is a student at Oak Hill College studying sociology. He is passionate about social justice and loves to explore different perspectives.",
"currently": "Klaus Mueller is writing a research paper on the effects of gentrification in low-income communities. Klauss is thinking about whom to vote for in the upcoming town election. He knows that Adam Smith and Isabella Rodriguez are running for the office of town mayor. The election takes place next week.",
"currently": "Klaus Mueller is writing a research paper on the effects of gentrification in low-income communities. Klaus is thinking about whom to vote for in the upcoming town election. He knows that Adam Smith and Isabella Rodriguez are running for the office of town mayor. The election takes place next week.",
"lifestyle": "Klaus Mueller goes to bed around 11pm, awakes up around 7am, eats dinner around 5pm.",
"living_area": "the Ville:Dorm for Oak Hill College:Klaus Mueller's room",
"concept_forget": 100,
Expand Down
2 changes: 1 addition & 1 deletion nlp/openai_convo_summary.py
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ def main():
print(file_chunks[0])

response = client.chat.completions.create(
model="gpt-4",
model="gpt-4o-mini",
messages=[
{
"role": "system",
Expand Down
59 changes: 59 additions & 0 deletions print_all_sim.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
import os
import json
import re
import sys

def get_unique_conversations(simulation_name):
sim_folder = os.path.join("environment", "frontend_server", "storage", "base_search_and_rescue")

regex_name = re.compile(re.escape(simulation_name + '-'))
for file_name in os.listdir(sim_folder):
step=0
output = []
if regex_name.search(file_name):
step_folder = os.path.join(sim_folder, file_name, "movement")
for filename in os.listdir(step_folder):
filepath = os.path.join(step_folder, filename)
output.append(f"Step {str(step)}:")
try:
with open(filepath, "r") as file:
data = json.load(file)
for k, v in data.items():
output.append(k)
if k == 'persona':
for key, value in v.items():
output.append(f' {key}')
for attribute, val in value.items():
if attribute != 'chat' or (attribute == 'chat' and val is None):
output.append(f' {attribute}: {val}')
else:
output.append(f' {attribute}:')
for convo in val:
output.append(f' {convo[0]}: {convo[1]}')
else:
for key, value in v.items():
output.append(f' {key}: {value}')
output.append('\n')
except json.JSONDecodeError:
continue
except Exception as e:
print(f"Error processing file {filename}: {e}")
continue
step+=1

output_filename = os.path.join(sim_folder, file_name, f"output_0-{file_name.split('-')[5]}.txt", )
with open(output_filename, "w") as output_file:
output_file.write('\n'.join(output))


if __name__ == "__main__":
if len(sys.argv) < 2:
print("Please provide the simulation name as a command line argument.")
sys.exit(1)

simulation_name = sys.argv[1]
'''
unique_conversations = get_unique_conversations(simulation_name)
print(json.dumps(unique_conversations, indent=2))
'''
get_unique_conversations(simulation_name)
Original file line number Diff line number Diff line change
Expand Up @@ -176,7 +176,7 @@ def agent_chat_v2(maze, init_persona, target_persona):
focal_points = [f"{target_persona.scratch.name}"]
retrieved = new_retrieve(init_persona, focal_points, 50)
relationship = generate_summarize_agent_relationship(init_persona, target_persona, retrieved)
print ("-------- relationshopadsjfhkalsdjf", relationship)
print ("-------- relationship", relationship)
last_chat = ""
for i in curr_chat[-4:]:
last_chat += ": ".join(i) + "\n"
Expand Down
84 changes: 71 additions & 13 deletions reverie/backend_server/persona/prompt_template/gpt_structure.py
Original file line number Diff line number Diff line change
Expand Up @@ -188,7 +188,40 @@ def ChatGPT_request(prompt):
traceback.print_exc()
return "LLM ERROR"

def ChatGPT_structured_request(prompt, response_format):
"""
Given a prompt and a dictionary of GPT parameters, make a request to OpenAI
server and returns the response.
ARGS:
prompt: a str prompt
gpt_parameter: a python dictionary with the keys indicating the names of
the parameter and the values indicating the parameter
values.
RETURNS:
a str of GPT-3's response.
"""
# temp_sleep()
print("--- ChatGPT_request() ---")
print("Prompt:", prompt)

try:
completion = client.beta.chat.completions.parse(
model=openai_config["model"],
response_format=response_format,
messages=[{"role": "user", "content": prompt}]
)
content = completion.choices[0].message.content
print("Response content:", content)
cost_logger.update_cost(
completion, input_cost=openai_config["model-costs"]["input"], output_cost=openai_config["model-costs"]["output"]
)
return content

except Exception as e:
print(f"Error: {e}")
traceback.print_exc()
return "LLM ERROR"

# def GPT4_safe_generate_response(
# prompt,
# example_output,
Expand Down Expand Up @@ -234,7 +267,6 @@ def ChatGPT_request(prompt):

# return False


def ChatGPT_safe_generate_response(
prompt,
example_output,
Expand All @@ -246,26 +278,51 @@ def ChatGPT_safe_generate_response(
verbose=False,
):
if func_validate and func_clean_up:
# prompt = 'GPT-3 Prompt:\n"""\n' + prompt + '\n"""\n'
prompt = '"""\n' + prompt + '\n"""\n'
prompt += (
f"Output the response to the prompt above in json. {special_instruction}\n"
)
prompt += "Example output json:\n"
prompt += '{"output": "' + str(example_output) + '"}'
# Constructing the new prompt using the structured output format
prompt_structure = {
"model": "gpt-4o-2024-08-06",
"messages": [
{
"role": "system",
"content": special_instruction
},
{
"role": "user",
"content": prompt
}
],
"response_format": {
"type": "json_schema",
"json_schema": {
"name": "output_response",
"strict": True,
"schema": {
"type": "object",
"properties": {
"output": {
"type": "string"
}
},
"required": ["output"],
"additionalProperties": False
}
}
}
}

if verbose:
print("LLM PROMPT")
print(prompt)
print("LLM PROMPT STRUCTURE")
print(json.dumps(prompt_structure, indent=2))

for i in range(repeat):
try:
chatgpt_response = ChatGPT_request(prompt)
chatgpt_response = ChatGPT_request(json.dumps(prompt_structure))
if not chatgpt_response:
raise Exception("No valid response from LLM.")
curr_gpt_response = chatgpt_response.strip()
end_index = curr_gpt_response.rfind("}") + 1
curr_gpt_response = curr_gpt_response[:end_index]
print(curr_gpt_response)
curr_gpt_response = json.loads(curr_gpt_response)["output"]

if verbose:
Expand Down Expand Up @@ -491,8 +548,9 @@ def generate_structured_response(
prompt=prompt
):
return func_clean_up(curr_gpt_response, prompt=prompt)
print("Response validation failed.")
except:
print("Response validation failed.", func_validate(curr_gpt_response,
prompt=prompt), curr_gpt_response.decision)
except Exception as e:
print("Could not process response.")
if verbose:
print("---- repeat count: ", i, curr_gpt_response)
Expand Down
Loading