Spaces:
Sleeping
Sleeping
File size: 5,867 Bytes
a72140d | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 | from openai import OpenAI
import json
import os
from tqdm import tqdm
import sys
import copy
from utils import extract_planning, content_to_json, extract_code_from_content, print_response, print_log_cost, load_accumulated_cost, save_accumulated_cost, read_python_files
import argparse
parser = argparse.ArgumentParser()
parser.add_argument('--paper_name',type=str)
parser.add_argument('--gpt_version',type=str, default="o3-mini")
parser.add_argument('--paper_format',type=str, default="JSON", choices=["JSON", "LaTeX"])
parser.add_argument('--pdf_json_path', type=str) # json format
parser.add_argument('--pdf_latex_path', type=str) # latex format
parser.add_argument('--output_dir',type=str, default="")
parser.add_argument('--output_repo_dir',type=str, default="")
args = parser.parse_args()
client = OpenAI(api_key = os.environ["OPENAI_API_KEY"])
paper_name = args.paper_name
gpt_version = args.gpt_version
paper_format = args.paper_format
pdf_json_path = args.pdf_json_path
pdf_latex_path = args.pdf_latex_path
output_dir = args.output_dir
output_repo_dir = args.output_repo_dir
if paper_format == "JSON":
with open(f'{pdf_json_path}') as f:
paper_content = json.load(f)
elif paper_format == "LaTeX":
with open(f'{pdf_latex_path}') as f:
paper_content = f.read()
else:
print(f"[ERROR] Invalid paper format. Please select either 'JSON' or 'LaTeX.")
sys.exit(0)
with open(f'{output_dir}/planning_config.yaml') as f:
config_yaml = f.read()
context_lst = extract_planning(f'{output_dir}/planning_trajectories.json')
# 0: overview, 1: detailed, 2: PRD
# file_list = content_to_json(context_lst[1])
task_list = content_to_json(context_lst[2])
todo_file_lst = task_list['Task list']
done_file_lst = ['config.yaml']
done_file_dict = {}
code_msg = [
{"role": "system", "content": f"""You are an expert researcher and software engineer with a deep understanding of experimental design and reproducibility in scientific research.
You will receive configuration file named "config.yaml", and implmented code repository.
Your task is to write a Bash script that can run the given repository from scratch. The script should create and activate the required environment, install all dependencies, and include the commands needed to execute the main file or entry point. Make sure the script is self-contained and can be executed without any manual setup.
Write code with triple quoto."""}]
def get_write_msg(todo_file_name, done_file_lst):
code_files = ""
for done_file in done_file_lst:
if done_file.endswith(".yaml"): continue
code_files += f"""
```python
{done_file_dict[done_file]}
```
"""
write_msg=[
{'role': 'user', "content": f"""# Context
## Configuration file
```yaml
{config_yaml}
```
-----
## Code Files
{code_files}
-----
# Format example
## Code: {todo_file_name}
```python
## {todo_file_name}
...
```
-----
# Instruction
Based on the code files, follow "Format example", write the code.
We have {done_file_lst}.
Next, you must write only the "{todo_file_name}".
## Code: {todo_file_name}"""}]
return write_msg
def api_call(msg):
if "o3-mini" in gpt_version or "o4-mini" in gpt_version:
completion = client.chat.completions.create(
model=gpt_version,
reasoning_effort="high",
messages=msg
)
else:
completion = client.chat.completions.create(
model=gpt_version,
messages=msg
)
return completion
artifact_output_dir=f'{output_dir}/coding_artifacts'
os.makedirs(artifact_output_dir, exist_ok=True)
python_dict = read_python_files(output_repo_dir)
for todo_idx, todo_file_name in enumerate(tqdm(todo_file_lst)):
if todo_file_name == "config.yaml":
continue
done_file_dict[todo_file_name] = python_dict[todo_file_name]
done_file_lst.append(todo_file_name)
total_accumulated_cost = load_accumulated_cost(f"{output_dir}/accumulated_cost.json")
for todo_idx, todo_file_name in enumerate(["reproduce.sh"]):
responses = []
trajectories = copy.deepcopy(code_msg)
current_stage = f"[CODING] {todo_file_name}"
print(current_stage)
if todo_file_name == "config.yaml":
continue
instruction_msg = get_write_msg(todo_file_name, done_file_lst)
trajectories.extend(instruction_msg)
completion = api_call(trajectories)
# print(completion.choices[0].message)
# response
completion_json = json.loads(completion.model_dump_json())
responses.append(completion_json)
# trajectories
message = completion.choices[0].message
trajectories.append({'role': message.role, 'content': message.content})
done_file_lst.append(todo_file_name)
# save
# save_dir_name = f"{paper_name}_repo"
os.makedirs(f'{output_repo_dir}', exist_ok=True)
save_todo_file_name = todo_file_name.replace("/", "_")
# print and logging
print_response(completion_json)
temp_total_accumulated_cost = print_log_cost(completion_json, gpt_version, current_stage, output_dir, total_accumulated_cost)
total_accumulated_cost = temp_total_accumulated_cost
# save artifacts
with open(f'{artifact_output_dir}/{save_todo_file_name}_coding.txt', 'w') as f:
f.write(completion_json['choices'][0]['message']['content'])
# extract code save
code = extract_code_from_content(message.content)
if len(code) == 0:
code = message.content
done_file_dict[todo_file_name] = code
if save_todo_file_name != todo_file_name:
todo_file_dir = '/'.join(todo_file_name.split("/")[:-1])
os.makedirs(f"{output_repo_dir}/{todo_file_dir}", exist_ok=True)
with open(f"{output_repo_dir}/{todo_file_name}", 'w') as f:
f.write(code)
save_accumulated_cost(f"{output_dir}/accumulated_cost.json", total_accumulated_cost)
|