tooluniverse 0.1.0__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Potentially problematic release.
This version of tooluniverse might be problematic. Click here for more details.
- tooluniverse/__init__.py +17 -0
- tooluniverse/base_tool.py +32 -0
- tooluniverse/data/__init__.py +0 -0
- tooluniverse/data/fda_drug_labeling_tools.json +6529 -0
- tooluniverse/data/fda_drugs_with_brand_generic_names_for_tool.py +201670 -0
- tooluniverse/data/monarch_tools.json +118 -0
- tooluniverse/data/opentarget_tools.json +1415 -0
- tooluniverse/data/special_tools.json +48 -0
- tooluniverse/execute_function.py +216 -0
- tooluniverse/graphql_tool.py +122 -0
- tooluniverse/openfda_tool.py +421 -0
- tooluniverse/restful_tool.py +95 -0
- tooluniverse/utils.py +172 -0
- tooluniverse-0.1.0.dist-info/METADATA +54 -0
- tooluniverse-0.1.0.dist-info/RECORD +17 -0
- tooluniverse-0.1.0.dist-info/WHEEL +5 -0
- tooluniverse-0.1.0.dist-info/top_level.txt +1 -0
tooluniverse/utils.py
ADDED
|
@@ -0,0 +1,172 @@
|
|
|
1
|
+
import yaml
|
|
2
|
+
import json
|
|
3
|
+
|
|
4
|
+
|
|
5
|
+
def yaml_to_dict(yaml_file_path):
|
|
6
|
+
"""
|
|
7
|
+
Convert a YAML file to a dictionary.
|
|
8
|
+
|
|
9
|
+
Args:
|
|
10
|
+
yaml_file_path (str): Path to the YAML file.
|
|
11
|
+
|
|
12
|
+
Returns:
|
|
13
|
+
dict: Dictionary representation of the YAML file content.
|
|
14
|
+
"""
|
|
15
|
+
try:
|
|
16
|
+
with open(yaml_file_path, 'r') as file:
|
|
17
|
+
yaml_dict = yaml.safe_load(file)
|
|
18
|
+
return yaml_dict
|
|
19
|
+
except FileNotFoundError:
|
|
20
|
+
print(f"File not found: {yaml_file_path}")
|
|
21
|
+
except yaml.YAMLError as exc:
|
|
22
|
+
print(f"Error in YAML file: {exc}")
|
|
23
|
+
|
|
24
|
+
|
|
25
|
+
def read_json_list(file_path):
|
|
26
|
+
"""
|
|
27
|
+
Reads a list of JSON objects from a file.
|
|
28
|
+
|
|
29
|
+
Parameters:
|
|
30
|
+
file_path (str): The path to the JSON file.
|
|
31
|
+
|
|
32
|
+
Returns:
|
|
33
|
+
list: A list of dictionaries containing the JSON objects.
|
|
34
|
+
"""
|
|
35
|
+
with open(file_path, 'r') as file:
|
|
36
|
+
data = json.load(file)
|
|
37
|
+
return data
|
|
38
|
+
|
|
39
|
+
|
|
40
|
+
def evaluate_function_call(tool_definition, function_call):
|
|
41
|
+
# Map for type conversion
|
|
42
|
+
type_map = {
|
|
43
|
+
"string": str,
|
|
44
|
+
"integer": int,
|
|
45
|
+
"number": float,
|
|
46
|
+
"boolean": bool,
|
|
47
|
+
"array": list,
|
|
48
|
+
"object": dict
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
# Check if the function name matches
|
|
52
|
+
if tool_definition["name"] != function_call["name"]:
|
|
53
|
+
return False, "Function name does not match."
|
|
54
|
+
|
|
55
|
+
# Check if all required parameters are present
|
|
56
|
+
required_params = [key for key, value in tool_definition["parameter"]
|
|
57
|
+
["properties"].items() if value.get("required", False)]
|
|
58
|
+
missing_params = [
|
|
59
|
+
param for param in required_params if param not in function_call["arguments"]]
|
|
60
|
+
if missing_params:
|
|
61
|
+
return False, f"Missing required parameters: {missing_params}"
|
|
62
|
+
|
|
63
|
+
# Check if all provided parameters are valid and their data types are correct
|
|
64
|
+
valid_params = tool_definition["parameter"]["properties"]
|
|
65
|
+
invalid_params = []
|
|
66
|
+
type_mismatches = []
|
|
67
|
+
|
|
68
|
+
for param, value in function_call["arguments"].items():
|
|
69
|
+
if param not in valid_params:
|
|
70
|
+
invalid_params.append(param)
|
|
71
|
+
else:
|
|
72
|
+
expected_type = valid_params[param]["type"]
|
|
73
|
+
if expected_type not in type_map:
|
|
74
|
+
return False, f"Unsupported parameter type: {expected_type}"
|
|
75
|
+
if not isinstance(value, type_map[expected_type]):
|
|
76
|
+
type_mismatches.append(
|
|
77
|
+
(param, expected_type, type(value).__name__))
|
|
78
|
+
|
|
79
|
+
if invalid_params:
|
|
80
|
+
return False, f"Invalid parameters provided: {invalid_params}"
|
|
81
|
+
|
|
82
|
+
if type_mismatches:
|
|
83
|
+
return False, f"Type mismatches: {type_mismatches}"
|
|
84
|
+
|
|
85
|
+
return True, "Function call is valid."
|
|
86
|
+
|
|
87
|
+
def evaluate_function_call_from_toolbox(toolbox, function_call):
|
|
88
|
+
tool_name = function_call["name"]
|
|
89
|
+
this_tool_dec = toolbox.get_one_tool_by_one_name(tool_name)
|
|
90
|
+
if this_tool_dec is None:
|
|
91
|
+
return False, "Tool not found."
|
|
92
|
+
results, results_message = evaluate_function_call(this_tool_dec, function_call)
|
|
93
|
+
return results, results_message
|
|
94
|
+
|
|
95
|
+
|
|
96
|
+
def compare_function_calls(pred_function_call, gt_function_call, compare_arguments=True, compare_value=True):
|
|
97
|
+
# Extracting the name and arguments from the predicted function call
|
|
98
|
+
pred_name = pred_function_call["name"]
|
|
99
|
+
pred_arguments = pred_function_call["arguments"]
|
|
100
|
+
|
|
101
|
+
# Extracting the name and arguments from the ground truth function call
|
|
102
|
+
gt_name = gt_function_call["name"]
|
|
103
|
+
gt_arguments = gt_function_call["arguments"]
|
|
104
|
+
|
|
105
|
+
# Compare function names
|
|
106
|
+
if pred_name != gt_name:
|
|
107
|
+
return False, "Function names do not match."
|
|
108
|
+
|
|
109
|
+
if compare_arguments:
|
|
110
|
+
# Compare arguments
|
|
111
|
+
if set(pred_arguments.keys()) != set(gt_arguments.keys()):
|
|
112
|
+
missing_in_pred = set(gt_arguments.keys()) - set(pred_arguments.keys())
|
|
113
|
+
missing_in_gt = set(pred_arguments.keys()) - set(gt_arguments.keys())
|
|
114
|
+
return False, f"Argument keys do not match. Missing in predicted: {missing_in_pred}, Missing in ground truth: {missing_in_gt}"
|
|
115
|
+
if compare_value:
|
|
116
|
+
# Compare argument values
|
|
117
|
+
mismatched_values = []
|
|
118
|
+
for key in pred_arguments:
|
|
119
|
+
if pred_arguments[key] != gt_arguments[key]:
|
|
120
|
+
mismatched_values.append((key, pred_arguments[key], gt_arguments[key]))
|
|
121
|
+
|
|
122
|
+
if mismatched_values:
|
|
123
|
+
return False, f"Argument values do not match: {mismatched_values}"
|
|
124
|
+
|
|
125
|
+
return True, "Function calls match."
|
|
126
|
+
|
|
127
|
+
|
|
128
|
+
def extract_function_call_json(lst, return_message=False, verbose=True):
|
|
129
|
+
if type(lst) is dict:
|
|
130
|
+
if return_message:
|
|
131
|
+
return lst, ""
|
|
132
|
+
return lst
|
|
133
|
+
result_str = ''.join(lst)
|
|
134
|
+
if verbose:
|
|
135
|
+
print("\033[1;34mPossible LLM outputs for function call:\033[0m", result_str)
|
|
136
|
+
try:
|
|
137
|
+
function_call_json = json.loads(result_str.strip())
|
|
138
|
+
if return_message:
|
|
139
|
+
return function_call_json, ""
|
|
140
|
+
return function_call_json
|
|
141
|
+
except json.JSONDecodeError:
|
|
142
|
+
try:
|
|
143
|
+
index_start = result_str.find(
|
|
144
|
+
'[TOOL_CALLS]')
|
|
145
|
+
index_end = result_str.find('</s>')
|
|
146
|
+
if index_end == -1:
|
|
147
|
+
index_end = result_str.find('<|eom_id|>')
|
|
148
|
+
if index_end == -1:
|
|
149
|
+
function_call_str = result_str[index_start+ len('[TOOL_CALLS]'):]
|
|
150
|
+
else:
|
|
151
|
+
function_call_str = result_str[index_start+ len('[TOOL_CALLS]'):index_end]
|
|
152
|
+
# print("function_call_str", function_call_str)
|
|
153
|
+
function_call_json = json.loads(function_call_str.strip())
|
|
154
|
+
if return_message:
|
|
155
|
+
message = result_str[:index_start]
|
|
156
|
+
return function_call_json, message
|
|
157
|
+
return function_call_json
|
|
158
|
+
except json.JSONDecodeError:
|
|
159
|
+
try:
|
|
160
|
+
print("Multiple function calls not implemented for 'llama' format.")
|
|
161
|
+
index_start = result_str.find(
|
|
162
|
+
'<functioncall>') + len('<functioncall>')
|
|
163
|
+
index_end = result_str.find('</functioncall>')
|
|
164
|
+
function_call_str = result_str[index_start:index_end]
|
|
165
|
+
# function_call_str = function_call_str.replace("'", '"')
|
|
166
|
+
function_call_json = json.loads(function_call_str.strip())
|
|
167
|
+
return function_call_json
|
|
168
|
+
except json.JSONDecodeError as e:
|
|
169
|
+
print("Not a function call:", e)
|
|
170
|
+
if return_message:
|
|
171
|
+
return None, result_str
|
|
172
|
+
return None
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
Metadata-Version: 2.2
|
|
2
|
+
Name: tooluniverse
|
|
3
|
+
Version: 0.1.0
|
|
4
|
+
Summary: A collection of biomedical tools designed for use by Agentic AI.
|
|
5
|
+
Home-page: https://github.com/mims-harvard/TxAgent
|
|
6
|
+
Author: Shanghua Gao
|
|
7
|
+
Author-email: shanghuagao@gmail.com
|
|
8
|
+
Requires-Python: >=3.6
|
|
9
|
+
Description-Content-Type: text/markdown
|
|
10
|
+
Requires-Dist: requests
|
|
11
|
+
Requires-Dist: numpy
|
|
12
|
+
Requires-Dist: graphql
|
|
13
|
+
|
|
14
|
+
# ToolUniverse
|
|
15
|
+
|
|
16
|
+
ToolUniverse is a collection of biomedical tools designed for use by Agentic AI.
|
|
17
|
+
|
|
18
|
+
# Install
|
|
19
|
+
|
|
20
|
+
### Local install
|
|
21
|
+
|
|
22
|
+
```
|
|
23
|
+
python -m pip install . --no-cache-dir
|
|
24
|
+
```
|
|
25
|
+
|
|
26
|
+
### Install from PIP
|
|
27
|
+
|
|
28
|
+
```
|
|
29
|
+
pip install tooluniverse
|
|
30
|
+
```
|
|
31
|
+
|
|
32
|
+
### Usage
|
|
33
|
+
|
|
34
|
+
Get all tools
|
|
35
|
+
|
|
36
|
+
```
|
|
37
|
+
from tooluniverse import ToolUniverse
|
|
38
|
+
tooluni = ToolUniverse()
|
|
39
|
+
tooluni.load_tools()
|
|
40
|
+
tool_name_list, tool_desc_list = tooluni.refresh_tool_name_desc()
|
|
41
|
+
print(tool_name_list)
|
|
42
|
+
print(tool_desc_list)
|
|
43
|
+
```
|
|
44
|
+
|
|
45
|
+
Function call to a tool
|
|
46
|
+
|
|
47
|
+
```
|
|
48
|
+
from tooluniverse import ToolUniverse
|
|
49
|
+
tooluni = ToolUniverse()
|
|
50
|
+
tooluni.load_tools()
|
|
51
|
+
tooluni.refresh_tool_name_desc()
|
|
52
|
+
query = {"name": "get_indications_by_drug_name", "arguments": {"drug_name": "KISUNLA"}}
|
|
53
|
+
tooluni.run(query)
|
|
54
|
+
```
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
tooluniverse/__init__.py,sha256=j44hf13WM50HQJRi7aloeTG6y6872wJtfX8ydsaiJFI,652
|
|
2
|
+
tooluniverse/base_tool.py,sha256=WMGgr02lhEsVzHgt7NIeynXQ2wZtu97yZI-lQWOSoSs,1145
|
|
3
|
+
tooluniverse/execute_function.py,sha256=HC3i4B_ATakUgGnDBiT7w2Zdd2Cpa3UCcx8wzoevH1k,9790
|
|
4
|
+
tooluniverse/graphql_tool.py,sha256=FpyP70ZiQkd031crECAhZ7CbXBor8x6S-n48VICnxVs,5086
|
|
5
|
+
tooluniverse/openfda_tool.py,sha256=SPs4skPqwaC2RaZvqD1LA31VeQmMl4bOh7CkTpJKM5U,21017
|
|
6
|
+
tooluniverse/restful_tool.py,sha256=5HoTyCSd507D4Qjcqjd16o8Y4BFZ02Zm4cGuczIXWdw,4078
|
|
7
|
+
tooluniverse/utils.py,sha256=zh1IopojPBIJzK_8eGytTmWlPckluQQZTpiCQONw-pY,6416
|
|
8
|
+
tooluniverse/data/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
9
|
+
tooluniverse/data/fda_drug_labeling_tools.json,sha256=iRYkuNk6ohCbNELMbfPghtlCGthjzZch_9Ukr-yjaJI,209383
|
|
10
|
+
tooluniverse/data/fda_drugs_with_brand_generic_names_for_tool.py,sha256=Clb7kQpPaXPTT_rdDLoinfwF8JbrdRaBis-0TYcT0BU,6510589
|
|
11
|
+
tooluniverse/data/monarch_tools.json,sha256=I5KvamNZRvkKBaKbM6Ypo333m-RejQhqScX8h-uket4,3567
|
|
12
|
+
tooluniverse/data/opentarget_tools.json,sha256=nNvl-vYqS8nLfyIvHO40Fsnx6HJxwInUuS0mrrh6xmY,66201
|
|
13
|
+
tooluniverse/data/special_tools.json,sha256=tOI0TFpdjZBEE5Af1Vc4CeXQ0gAkz39xho9hDVBYR70,1518
|
|
14
|
+
tooluniverse-0.1.0.dist-info/METADATA,sha256=YuX65va7z43zUCVyD6PwZFp4A0R59Y7t3jRqgqQJcVo,1088
|
|
15
|
+
tooluniverse-0.1.0.dist-info/WHEEL,sha256=jB7zZ3N9hIM9adW7qlTAyycLYW9npaWKLRzaoVcLKcM,91
|
|
16
|
+
tooluniverse-0.1.0.dist-info/top_level.txt,sha256=zZ8YeCJ5FAkEwdd_mxsFtSCQMBDgBdxrrmHo3RNBiWs,13
|
|
17
|
+
tooluniverse-0.1.0.dist-info/RECORD,,
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
tooluniverse
|