-
Notifications
You must be signed in to change notification settings - Fork 2
Expand file tree
/
Copy pathretriever.py
More file actions
207 lines (151 loc) · 7.48 KB
/
Copy pathretriever.py
File metadata and controls
207 lines (151 loc) · 7.48 KB
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
190
191
192
193
194
195
196
197
198
199
200
201
202
203
import json
import os
import re
# from scrapegraphai.graphs import SmartScraperGraph
from drugagent.LLM import complete_text_fast
from drugagent.utils import extract_jsons
current_script_dir = os.path.dirname(os.path.abspath(__file__))
doc_dir = os.path.join(current_script_dir, 'doc')
# IMPORTANT: As the documentations collected for case study is relatively short, we didn't use RAG based method to save resources. We suggest using the SmartScraperGraph library for RAG if needed.
# doc search function modified from https://github.com/SageMindAI/autogen-agi/blob/master/agents/agent_functions.py
def update_tools_json(tool_data, workdir):
tools_file = os.path.join(workdir, "tools.json")
# Check if tools.json exists
if os.path.exists(tools_file):
with open(tools_file, 'r') as file:
try:
tools = json.load(file)
if not isinstance(tools, list):
tools = [] # Reset to empty list if data is invalid
except json.JSONDecodeError:
tools = [] # Reset to empty list if file is not a valid JSON
else:
tools = [] # If file does not exist, initialize as an empty list
tools.append(tool_data)
with open(tools_file, 'w') as file:
json.dump(tools, file, indent=4)
ARCHIVE_AGENT_MATCH_DOMAIN_PROMPT = """You are an expert at finding a matching domain based on a DOMAIN_DESCRIPTION. Given the following DOMAIN_DESCRIPTION and list of AVAILABLE_DOMAINS, please respond with a JSON array of the form:
[
{{
"domain": <the name of the matching domain file or "None">,
"domain_description": <the description of the matching domain or "None">
"analysis": <your analysis of how closesly the domain matches the given DOMAIN_DESCRIPTION>,
"rating": <the rating of the similarity of the domain from 1 to 10>
}},
{{
"domain": <the name of the matching domain file or "None">,
"domain_description": <the description of the matching domain or "None">
"analysis": <your analysis of how closesly the domain matches the given DOMAIN_DESCRIPTION>,
"rating": <the rating of the similarity of the domain from 1 to 10>
}},
...
]
IMPORTANT: Be very critical about your analysis and ratings. If an important keyword is missing in the domain description, it should be rated low. If the domain description is not very similar to the domain, it should be rated low. If the domain description is not similar to the domain at all, it should be rated very low.
DOMAIN_DESCRIPTION:
---------------
{domain_description}
---------------
QUESTION:
---------------
{question}
---------------
AVAILABLE_DOMAINS:
---------------
{available_domains}
---------------
JSON_ARRAY_RESPONSE:
"""
GENERATE_ANSWER_TEMPLATE = """You are an expert with access to the following document. It may or may not be relevant to answering the question.
Question: {question}
Idea Context: {idea}
Document: {doc}
Your goal is to answer the question based on your knowledge and the information provided in the document. Please format your response in JSON as follows:
{{
"Import": "How to import this tool?",
"Parameter": "What are the parameters of the tool if it is a function? Please describe them in plain text, not additional JSON.",
"Usage": "How to use it? Include input types, output types, and provide an example if applicable. Describe them in plain text, not additional JSON."
}}
*Note*: You are allowed to return only one tool. Choose the most relevant tool based on the research idea instead of using the entire document.
"""
example_json = """
{{
"Import": "How to import this tool?",
"Parameter": "What are the parameters of the tool? Describe them in plain text, not additional JSON.",
"Usage": "How to use it? Include input types, output types, and provide an example if applicable. Describe them in plain text, not additional JSON."
}}
"""
def consult_archive_agent_for_tool(domain_description, name, question, research_problem="", curr_idea="",
doc_dir=doc_dir,
work_dir=".", **kwargs):
failure_prompt = f"Domain not found for domain description: {domain_description} and question: {question}. The Archive Agent cannot help on your question."
# Load the JSON metadata file
with open(os.path.join(doc_dir, "doc_info.json"), 'r') as f:
doc_info = json.load(f)
# Prepare the domain descriptions by reading the actual content from each file
domain_descriptions = [
{
"domain_name": doc.get("name"),
"domain_description": doc.get("description")
}
for doc in doc_info
]
# Build the string of all domain descriptions
str_desc = "\n".join(
[f"Domain: {desc['domain_name']}\n\nDescription:\n{'*' * 50}\n{desc['domain_description']}\n{'*' * 50}\n"
for desc in domain_descriptions]
)
# Format the prompt for ARCHIVE_AGENT_MATCH_DOMAIN_PROMPT
find_domain_query = ARCHIVE_AGENT_MATCH_DOMAIN_PROMPT.format(
domain_description=domain_description,
available_domains=str_desc,
question=question
)
domain_response = complete_text_fast(find_domain_query, log_file=None)
try:
domain_response = extract_jsons(domain_response)
domain_response = sorted(domain_response, key=lambda x: int(x["rating"]), reverse=True)
top_domain = domain_response[0]
except:
return failure_prompt
DOMAIN_RESPONSE_THRESHOLD = 5
if top_domain["rating"] < DOMAIN_RESPONSE_THRESHOLD:
return failure_prompt
# Retrieve domain content
domain_name = top_domain["domain"]
file_path = os.path.join(doc_dir, domain_name)
with open(file_path, 'r') as f:
file_content = f.read()
prompt = GENERATE_ANSWER_TEMPLATE.format(question=question, doc=file_content, idea=curr_idea)
result = complete_text_fast(prompt, log_file=None)
# Hallucination check
hallucination_prompt = f"""
You are a grader assessing whether 1. the retrieved doc is highly relevant to the user question and 2. The answer is grounded in / supported by retrieved facts.
Question: {question}
Retrieved Facts:
{file_content}
Generated Result:
{result}
Give a binary score 'yes' or 'no' without explanation. 'Yes' means that 1. the retrieved doc is highly relevant to the user question and 2. The answer is grounded in / supported by retrieved facts.
"""
evaluation = complete_text_fast(hallucination_prompt, log_file=None)
if re.search(r'\bno\b', evaluation):
return failure_prompt
for attempt in range(5):
try:
tool_data = extract_jsons(result)[0]
tool_data['name'] = name
break
except Exception as e:
if attempt == 4:
print("Failed to parse JSON after 5 attempts.")
return "Failed to create tool due to format error. Please try again."
print("Using LLM to reformat the response...")
result = complete_text_fast(
prompt=f"The following response could not be parsed as JSON:\n{result}\n"
f"Please format this response as a valid JSON according to this example:\n{example_json}\n"
f"Provide only the corrected JSON output.",
log_file=None
)
# Update tools json file with the correct tool data
update_tools_json(tool_data, work_dir)
return json.dumps(tool_data, indent=4)