tooluniverse 1.0.3__py3-none-any.whl → 1.0.4__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/agentic_tool.py +262 -330
- tooluniverse/compose_scripts/output_summarizer.py +21 -15
- tooluniverse/data/output_summarization_tools.json +2 -2
- tooluniverse/llm_clients.py +369 -0
- tooluniverse/output_hook.py +92 -3
- tooluniverse/smcp_server.py +19 -13
- tooluniverse/test/list_azure_openai_models.py +210 -0
- tooluniverse/test/test_agentic_tool_azure_models.py +91 -0
- tooluniverse/test/test_api_key_validation_min.py +64 -0
- tooluniverse/test/test_global_fallback.py +288 -0
- tooluniverse/test/test_hooks_direct.py +219 -0
- tooluniverse/test/test_stdio_hooks.py +285 -0
- {tooluniverse-1.0.3.dist-info → tooluniverse-1.0.4.dist-info}/METADATA +2 -1
- {tooluniverse-1.0.3.dist-info → tooluniverse-1.0.4.dist-info}/RECORD +18 -11
- {tooluniverse-1.0.3.dist-info → tooluniverse-1.0.4.dist-info}/WHEEL +0 -0
- {tooluniverse-1.0.3.dist-info → tooluniverse-1.0.4.dist-info}/entry_points.txt +0 -0
- {tooluniverse-1.0.3.dist-info → tooluniverse-1.0.4.dist-info}/licenses/LICENSE +0 -0
- {tooluniverse-1.0.3.dist-info → tooluniverse-1.0.4.dist-info}/top_level.txt +0 -0
|
@@ -0,0 +1,219 @@
|
|
|
1
|
+
#!/usr/bin/env python3
|
|
2
|
+
"""
|
|
3
|
+
简化的 MCP stdio 模式 hooks 测试
|
|
4
|
+
直接测试工具调用功能
|
|
5
|
+
"""
|
|
6
|
+
import subprocess
|
|
7
|
+
import sys
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
def test_tool_call_directly(hooks_enabled=False):
|
|
11
|
+
"""直接测试工具调用"""
|
|
12
|
+
print(f"\n{'='*60}")
|
|
13
|
+
print(f"测试模式: {'开启 hooks' if hooks_enabled else '关闭 hooks'}")
|
|
14
|
+
print(f"{'='*60}")
|
|
15
|
+
|
|
16
|
+
# 构建命令
|
|
17
|
+
cmd = [
|
|
18
|
+
sys.executable,
|
|
19
|
+
"-c",
|
|
20
|
+
f"""
|
|
21
|
+
import sys
|
|
22
|
+
import time
|
|
23
|
+
sys.path.insert(0, 'src')
|
|
24
|
+
from tooluniverse.execute_function import ToolUniverse
|
|
25
|
+
|
|
26
|
+
# 创建 ToolUniverse 实例
|
|
27
|
+
tooluniverse = ToolUniverse()
|
|
28
|
+
|
|
29
|
+
# 配置 hooks
|
|
30
|
+
if {hooks_enabled}:
|
|
31
|
+
print("启用 hooks...")
|
|
32
|
+
tooluniverse.toggle_hooks(True)
|
|
33
|
+
else:
|
|
34
|
+
print("禁用 hooks...")
|
|
35
|
+
tooluniverse.toggle_hooks(False)
|
|
36
|
+
|
|
37
|
+
# 加载工具
|
|
38
|
+
print("加载工具...")
|
|
39
|
+
tooluniverse.load_tools()
|
|
40
|
+
|
|
41
|
+
# 测试工具调用
|
|
42
|
+
function_call = {{
|
|
43
|
+
"name": "OpenTargets_get_target_gene_ontology_by_ensemblID",
|
|
44
|
+
"arguments": {{"ensemblId": "ENSG00000012048"}}
|
|
45
|
+
}}
|
|
46
|
+
|
|
47
|
+
print("开始工具调用...")
|
|
48
|
+
start_time = time.time()
|
|
49
|
+
result = tooluniverse.run_one_function(function_call)
|
|
50
|
+
end_time = time.time()
|
|
51
|
+
|
|
52
|
+
response_time = end_time - start_time
|
|
53
|
+
result_str = str(result)
|
|
54
|
+
result_length = len(result_str)
|
|
55
|
+
|
|
56
|
+
print(f"工具调用完成")
|
|
57
|
+
print(f"响应时间: {{response_time:.2f}} 秒")
|
|
58
|
+
print(f"响应长度: {{result_length}} 字符")
|
|
59
|
+
print(f"响应类型: {{type(result)}}")
|
|
60
|
+
|
|
61
|
+
# 检查是否是摘要
|
|
62
|
+
if "summary" in result_str.lower() or "摘要" in result_str:
|
|
63
|
+
print("✅ 检测到摘要内容")
|
|
64
|
+
else:
|
|
65
|
+
print("📄 原始内容(未摘要)")
|
|
66
|
+
|
|
67
|
+
# 输出结果的前200个字符
|
|
68
|
+
print(f"结果预览: {{result_str[:200]}}...")
|
|
69
|
+
""",
|
|
70
|
+
]
|
|
71
|
+
|
|
72
|
+
print(f"启动命令: {' '.join(cmd[:3])} ...")
|
|
73
|
+
|
|
74
|
+
# 启动进程
|
|
75
|
+
process = subprocess.Popen(
|
|
76
|
+
cmd,
|
|
77
|
+
stdin=subprocess.PIPE,
|
|
78
|
+
stdout=subprocess.PIPE,
|
|
79
|
+
stderr=subprocess.PIPE,
|
|
80
|
+
text=True,
|
|
81
|
+
bufsize=0,
|
|
82
|
+
)
|
|
83
|
+
|
|
84
|
+
try:
|
|
85
|
+
# 等待执行完成
|
|
86
|
+
stdout, stderr = process.communicate(timeout=60)
|
|
87
|
+
|
|
88
|
+
print("标准输出:")
|
|
89
|
+
print(stdout)
|
|
90
|
+
|
|
91
|
+
if stderr:
|
|
92
|
+
print("标准错误:")
|
|
93
|
+
print(stderr)
|
|
94
|
+
|
|
95
|
+
# 解析结果
|
|
96
|
+
lines = stdout.split("\n")
|
|
97
|
+
response_time = None
|
|
98
|
+
result_length = None
|
|
99
|
+
is_summary = False
|
|
100
|
+
|
|
101
|
+
for line in lines:
|
|
102
|
+
if "响应时间:" in line:
|
|
103
|
+
try:
|
|
104
|
+
response_time = float(line.split(":")[1].strip().split()[0])
|
|
105
|
+
except (ValueError, IndexError):
|
|
106
|
+
pass
|
|
107
|
+
elif "响应长度:" in line:
|
|
108
|
+
try:
|
|
109
|
+
result_length = int(line.split(":")[1].strip().split()[0])
|
|
110
|
+
except (ValueError, IndexError):
|
|
111
|
+
pass
|
|
112
|
+
elif "检测到摘要内容" in line:
|
|
113
|
+
is_summary = True
|
|
114
|
+
|
|
115
|
+
return {
|
|
116
|
+
"hooks_enabled": hooks_enabled,
|
|
117
|
+
"response_time": response_time,
|
|
118
|
+
"result_length": result_length,
|
|
119
|
+
"is_summary": is_summary,
|
|
120
|
+
"success": process.returncode == 0,
|
|
121
|
+
"stdout": stdout,
|
|
122
|
+
"stderr": stderr,
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
except subprocess.TimeoutExpired:
|
|
126
|
+
print("❌ 测试超时")
|
|
127
|
+
process.kill()
|
|
128
|
+
return {
|
|
129
|
+
"hooks_enabled": hooks_enabled,
|
|
130
|
+
"response_time": None,
|
|
131
|
+
"result_length": None,
|
|
132
|
+
"is_summary": False,
|
|
133
|
+
"success": False,
|
|
134
|
+
"error": "超时",
|
|
135
|
+
}
|
|
136
|
+
except Exception as e:
|
|
137
|
+
print(f"❌ 测试失败: {e}")
|
|
138
|
+
return {
|
|
139
|
+
"hooks_enabled": hooks_enabled,
|
|
140
|
+
"response_time": None,
|
|
141
|
+
"result_length": None,
|
|
142
|
+
"is_summary": False,
|
|
143
|
+
"success": False,
|
|
144
|
+
"error": str(e),
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
|
|
148
|
+
def main():
|
|
149
|
+
"""主函数"""
|
|
150
|
+
print("MCP stdio 模式 hooks 直接测试")
|
|
151
|
+
print("测试工具: OpenTargets_get_target_gene_ontology_by_ensemblID")
|
|
152
|
+
print("测试参数: ensemblId=ENSG00000012048")
|
|
153
|
+
|
|
154
|
+
# 测试关闭 hooks
|
|
155
|
+
result_no_hooks = test_tool_call_directly(hooks_enabled=False)
|
|
156
|
+
|
|
157
|
+
# 测试开启 hooks
|
|
158
|
+
result_with_hooks = test_tool_call_directly(hooks_enabled=True)
|
|
159
|
+
|
|
160
|
+
# 对比结果
|
|
161
|
+
print(f"\n{'='*60}")
|
|
162
|
+
print("测试结果对比")
|
|
163
|
+
print(f"{'='*60}")
|
|
164
|
+
|
|
165
|
+
print("关闭 hooks:")
|
|
166
|
+
if result_no_hooks["success"]:
|
|
167
|
+
print(
|
|
168
|
+
f" ✅ 成功 - 响应时间: {result_no_hooks['response_time']:.2f}s, 长度: {result_no_hooks['result_length']} 字符"
|
|
169
|
+
)
|
|
170
|
+
if result_no_hooks["is_summary"]:
|
|
171
|
+
print(" 📄 检测到摘要内容")
|
|
172
|
+
else:
|
|
173
|
+
print(" 📄 原始内容(未摘要)")
|
|
174
|
+
else:
|
|
175
|
+
print(f" ❌ 失败 - {result_no_hooks.get('error', '未知错误')}")
|
|
176
|
+
|
|
177
|
+
print("开启 hooks:")
|
|
178
|
+
if result_with_hooks["success"]:
|
|
179
|
+
print(
|
|
180
|
+
f" ✅ 成功 - 响应时间: {result_with_hooks['response_time']:.2f}s, 长度: {result_with_hooks['result_length']} 字符"
|
|
181
|
+
)
|
|
182
|
+
if result_with_hooks["is_summary"]:
|
|
183
|
+
print(" ✅ 检测到摘要内容")
|
|
184
|
+
else:
|
|
185
|
+
print(" 📄 原始内容(未摘要)")
|
|
186
|
+
else:
|
|
187
|
+
print(f" ❌ 失败 - {result_with_hooks.get('error', '未知错误')}")
|
|
188
|
+
|
|
189
|
+
# 性能对比
|
|
190
|
+
if result_no_hooks["success"] and result_with_hooks["success"]:
|
|
191
|
+
time_diff = (
|
|
192
|
+
result_with_hooks["response_time"] - result_no_hooks["response_time"]
|
|
193
|
+
)
|
|
194
|
+
length_diff = (
|
|
195
|
+
result_with_hooks["result_length"] - result_no_hooks["result_length"]
|
|
196
|
+
)
|
|
197
|
+
|
|
198
|
+
print("\n性能对比:")
|
|
199
|
+
print(
|
|
200
|
+
f" 时间差异: {time_diff:+.2f}s ({'hooks 更慢' if time_diff > 0 else 'hooks 更快'})"
|
|
201
|
+
)
|
|
202
|
+
print(
|
|
203
|
+
f" 长度差异: {length_diff:+d} 字符 ({'hooks 更长' if length_diff > 0 else 'hooks 更短'})"
|
|
204
|
+
)
|
|
205
|
+
|
|
206
|
+
if abs(time_diff) < 5.0:
|
|
207
|
+
print(" ✅ 时间差异在可接受范围内")
|
|
208
|
+
else:
|
|
209
|
+
print(" ⚠️ 时间差异较大,需要进一步优化")
|
|
210
|
+
|
|
211
|
+
# 检查 hooks 是否生效
|
|
212
|
+
if result_with_hooks["is_summary"] and not result_no_hooks["is_summary"]:
|
|
213
|
+
print(" ✅ Hooks 功能正常工作")
|
|
214
|
+
elif result_with_hooks["is_summary"] == result_no_hooks["is_summary"]:
|
|
215
|
+
print(" ⚠️ Hooks 功能可能未生效")
|
|
216
|
+
|
|
217
|
+
|
|
218
|
+
if __name__ == "__main__":
|
|
219
|
+
main()
|
|
@@ -0,0 +1,285 @@
|
|
|
1
|
+
#!/usr/bin/env python3
|
|
2
|
+
"""
|
|
3
|
+
测试 MCP stdio 模式下关闭和开启 hooks 的情况
|
|
4
|
+
"""
|
|
5
|
+
import subprocess
|
|
6
|
+
import json
|
|
7
|
+
import time
|
|
8
|
+
import sys
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
def run_stdio_test(hooks_enabled=False):
|
|
12
|
+
"""运行 stdio 测试"""
|
|
13
|
+
print(f"\n{'='*60}")
|
|
14
|
+
print(f"测试模式: {'开启 hooks' if hooks_enabled else '关闭 hooks'}")
|
|
15
|
+
print(f"{'='*60}")
|
|
16
|
+
|
|
17
|
+
# 构建命令
|
|
18
|
+
cmd = [
|
|
19
|
+
sys.executable,
|
|
20
|
+
"-c",
|
|
21
|
+
f"""
|
|
22
|
+
import sys
|
|
23
|
+
sys.path.insert(0, 'src')
|
|
24
|
+
from tooluniverse.smcp_server import run_stdio_server
|
|
25
|
+
sys.argv = ['tooluniverse-stdio'] + (['--hooks'] if {hooks_enabled} else [])
|
|
26
|
+
run_stdio_server()
|
|
27
|
+
""",
|
|
28
|
+
]
|
|
29
|
+
|
|
30
|
+
print(f"启动命令: {' '.join(cmd[:3])} ...")
|
|
31
|
+
|
|
32
|
+
# 启动服务器进程
|
|
33
|
+
process = subprocess.Popen(
|
|
34
|
+
cmd,
|
|
35
|
+
stdin=subprocess.PIPE,
|
|
36
|
+
stdout=subprocess.PIPE,
|
|
37
|
+
stderr=subprocess.PIPE,
|
|
38
|
+
text=True,
|
|
39
|
+
bufsize=0,
|
|
40
|
+
)
|
|
41
|
+
|
|
42
|
+
try:
|
|
43
|
+
# 等待服务器启动并读取启动日志
|
|
44
|
+
time.sleep(3)
|
|
45
|
+
|
|
46
|
+
# 读取并丢弃启动日志
|
|
47
|
+
print("读取启动日志...")
|
|
48
|
+
while True:
|
|
49
|
+
line = process.stdout.readline()
|
|
50
|
+
if not line:
|
|
51
|
+
break
|
|
52
|
+
print(f"启动日志: {line.strip()}")
|
|
53
|
+
if "Starting SMCP ToolUniverse Server" in line:
|
|
54
|
+
break
|
|
55
|
+
|
|
56
|
+
# 发送初始化请求
|
|
57
|
+
init_request = {
|
|
58
|
+
"jsonrpc": "2.0",
|
|
59
|
+
"id": 1,
|
|
60
|
+
"method": "initialize",
|
|
61
|
+
"params": {
|
|
62
|
+
"protocolVersion": "2024-11-05",
|
|
63
|
+
"capabilities": {},
|
|
64
|
+
"clientInfo": {"name": "test-client", "version": "1.0.0"},
|
|
65
|
+
},
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
print("发送初始化请求...")
|
|
69
|
+
process.stdin.write(json.dumps(init_request) + "\n")
|
|
70
|
+
process.stdin.flush()
|
|
71
|
+
|
|
72
|
+
# 读取初始化响应
|
|
73
|
+
init_response = process.stdout.readline()
|
|
74
|
+
print(f"初始化响应: {init_response.strip()}")
|
|
75
|
+
|
|
76
|
+
# 发送 tools/list 请求
|
|
77
|
+
list_request = {"jsonrpc": "2.0", "id": 2, "method": "tools/list"}
|
|
78
|
+
|
|
79
|
+
print("发送 tools/list 请求...")
|
|
80
|
+
process.stdin.write(json.dumps(list_request) + "\n")
|
|
81
|
+
process.stdin.flush()
|
|
82
|
+
|
|
83
|
+
# 读取 tools/list 响应
|
|
84
|
+
list_response = process.stdout.readline()
|
|
85
|
+
print(f"tools/list 响应长度: {len(list_response)} 字符")
|
|
86
|
+
|
|
87
|
+
# 发送测试工具调用请求
|
|
88
|
+
test_request = {
|
|
89
|
+
"jsonrpc": "2.0",
|
|
90
|
+
"id": 3,
|
|
91
|
+
"method": "tools/call",
|
|
92
|
+
"params": {
|
|
93
|
+
"name": "OpenTargets_get_target_gene_ontology_by_ensemblID",
|
|
94
|
+
"arguments": {"ensemblId": "ENSG00000012048"},
|
|
95
|
+
},
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
print("发送测试工具调用请求...")
|
|
99
|
+
process.stdin.write(json.dumps(test_request) + "\n")
|
|
100
|
+
process.stdin.flush()
|
|
101
|
+
|
|
102
|
+
# 读取工具调用响应(可能需要等待更长时间)
|
|
103
|
+
print("等待工具调用响应...")
|
|
104
|
+
start_time = time.time()
|
|
105
|
+
|
|
106
|
+
# 读取多行响应,直到找到 JSON 响应
|
|
107
|
+
tool_response = ""
|
|
108
|
+
timeout = 30 # 30秒超时
|
|
109
|
+
while time.time() - start_time < timeout:
|
|
110
|
+
line = process.stdout.readline()
|
|
111
|
+
if not line:
|
|
112
|
+
time.sleep(0.1)
|
|
113
|
+
continue
|
|
114
|
+
|
|
115
|
+
tool_response += line
|
|
116
|
+
print(f"收到响应行: {repr(line)}")
|
|
117
|
+
|
|
118
|
+
# 检查是否是 JSON 响应
|
|
119
|
+
try:
|
|
120
|
+
json.loads(line.strip())
|
|
121
|
+
break
|
|
122
|
+
except json.JSONDecodeError:
|
|
123
|
+
continue
|
|
124
|
+
|
|
125
|
+
end_time = time.time()
|
|
126
|
+
response_time = end_time - start_time
|
|
127
|
+
response_length = len(tool_response)
|
|
128
|
+
|
|
129
|
+
print(f"工具调用响应时间: {response_time:.2f} 秒")
|
|
130
|
+
print(f"工具调用响应长度: {response_length} 字符")
|
|
131
|
+
print(f"原始响应内容: {repr(tool_response)}")
|
|
132
|
+
|
|
133
|
+
# 尝试解析 JSON 响应
|
|
134
|
+
json_response = None
|
|
135
|
+
for line in tool_response.split("\n"):
|
|
136
|
+
if line.strip().startswith('{"jsonrpc"'):
|
|
137
|
+
try:
|
|
138
|
+
json_response = json.loads(line.strip())
|
|
139
|
+
break
|
|
140
|
+
except json.JSONDecodeError:
|
|
141
|
+
continue
|
|
142
|
+
|
|
143
|
+
if json_response:
|
|
144
|
+
print("✅ 成功解析 JSON 响应")
|
|
145
|
+
print(f"响应 ID: {json_response.get('id')}")
|
|
146
|
+
if "result" in json_response:
|
|
147
|
+
print("✅ 工具调用成功")
|
|
148
|
+
elif "error" in json_response:
|
|
149
|
+
print(f"❌ 工具调用失败: {json_response['error']}")
|
|
150
|
+
else:
|
|
151
|
+
print("⚠️ 未找到有效的 JSON 响应")
|
|
152
|
+
|
|
153
|
+
# 继续等待实际的工具调用响应
|
|
154
|
+
print("等待工具调用完成...")
|
|
155
|
+
time.sleep(5) # 等待工具执行完成
|
|
156
|
+
|
|
157
|
+
# 读取工具调用的实际响应
|
|
158
|
+
actual_response = ""
|
|
159
|
+
while True:
|
|
160
|
+
line = process.stdout.readline()
|
|
161
|
+
if not line:
|
|
162
|
+
break
|
|
163
|
+
actual_response += line
|
|
164
|
+
print(f"工具响应行: {repr(line)}")
|
|
165
|
+
|
|
166
|
+
# 检查是否是 JSON 响应
|
|
167
|
+
try:
|
|
168
|
+
json.loads(line.strip())
|
|
169
|
+
break
|
|
170
|
+
except json.JSONDecodeError:
|
|
171
|
+
continue
|
|
172
|
+
|
|
173
|
+
if actual_response:
|
|
174
|
+
print(f"工具调用实际响应长度: {len(actual_response)} 字符")
|
|
175
|
+
|
|
176
|
+
# 尝试解析工具调用响应
|
|
177
|
+
tool_json_response = None
|
|
178
|
+
for line in actual_response.split("\n"):
|
|
179
|
+
if line.strip().startswith('{"jsonrpc"'):
|
|
180
|
+
try:
|
|
181
|
+
tool_json_response = json.loads(line.strip())
|
|
182
|
+
break
|
|
183
|
+
except json.JSONDecodeError:
|
|
184
|
+
continue
|
|
185
|
+
|
|
186
|
+
if tool_json_response and "result" in tool_json_response:
|
|
187
|
+
result_content = tool_json_response["result"]
|
|
188
|
+
if "content" in result_content:
|
|
189
|
+
content_text = str(result_content["content"])
|
|
190
|
+
content_length = len(content_text)
|
|
191
|
+
print(f"工具响应内容长度: {content_length} 字符")
|
|
192
|
+
|
|
193
|
+
# 检查是否是摘要
|
|
194
|
+
if "summary" in content_text.lower() or "摘要" in content_text:
|
|
195
|
+
print("✅ 检测到摘要内容")
|
|
196
|
+
else:
|
|
197
|
+
print("📄 原始内容(未摘要)")
|
|
198
|
+
else:
|
|
199
|
+
print("⚠️ 工具响应中没有 content 字段")
|
|
200
|
+
else:
|
|
201
|
+
print("⚠️ 无法解析工具调用响应")
|
|
202
|
+
|
|
203
|
+
return {
|
|
204
|
+
"hooks_enabled": hooks_enabled,
|
|
205
|
+
"response_time": response_time,
|
|
206
|
+
"response_length": response_length,
|
|
207
|
+
"success": True,
|
|
208
|
+
}
|
|
209
|
+
|
|
210
|
+
except Exception as e:
|
|
211
|
+
print(f"❌ 测试失败: {e}")
|
|
212
|
+
return {
|
|
213
|
+
"hooks_enabled": hooks_enabled,
|
|
214
|
+
"response_time": None,
|
|
215
|
+
"response_length": None,
|
|
216
|
+
"success": False,
|
|
217
|
+
"error": str(e),
|
|
218
|
+
}
|
|
219
|
+
finally:
|
|
220
|
+
# 清理进程
|
|
221
|
+
try:
|
|
222
|
+
process.terminate()
|
|
223
|
+
process.wait(timeout=5)
|
|
224
|
+
except Exception:
|
|
225
|
+
process.kill()
|
|
226
|
+
|
|
227
|
+
|
|
228
|
+
def main():
|
|
229
|
+
"""主函数"""
|
|
230
|
+
print("MCP stdio 模式 hooks 测试")
|
|
231
|
+
print("测试工具: OpenTargets_get_target_gene_ontology_by_ensemblID")
|
|
232
|
+
print("测试参数: ensemblId=ENSG00000012048")
|
|
233
|
+
|
|
234
|
+
# 测试关闭 hooks
|
|
235
|
+
result_no_hooks = run_stdio_test(hooks_enabled=False)
|
|
236
|
+
|
|
237
|
+
# 测试开启 hooks
|
|
238
|
+
result_with_hooks = run_stdio_test(hooks_enabled=True)
|
|
239
|
+
|
|
240
|
+
# 对比结果
|
|
241
|
+
print(f"\n{'='*60}")
|
|
242
|
+
print("测试结果对比")
|
|
243
|
+
print(f"{'='*60}")
|
|
244
|
+
|
|
245
|
+
print("关闭 hooks:")
|
|
246
|
+
if result_no_hooks["success"]:
|
|
247
|
+
print(
|
|
248
|
+
f" ✅ 成功 - 响应时间: {result_no_hooks['response_time']:.2f}s, 长度: {result_no_hooks['response_length']} 字符"
|
|
249
|
+
)
|
|
250
|
+
else:
|
|
251
|
+
print(f" ❌ 失败 - {result_no_hooks.get('error', '未知错误')}")
|
|
252
|
+
|
|
253
|
+
print("开启 hooks:")
|
|
254
|
+
if result_with_hooks["success"]:
|
|
255
|
+
print(
|
|
256
|
+
f" ✅ 成功 - 响应时间: {result_with_hooks['response_time']:.2f}s, 长度: {result_with_hooks['response_length']} 字符"
|
|
257
|
+
)
|
|
258
|
+
else:
|
|
259
|
+
print(f" ❌ 失败 - {result_with_hooks.get('error', '未知错误')}")
|
|
260
|
+
|
|
261
|
+
# 性能对比
|
|
262
|
+
if result_no_hooks["success"] and result_with_hooks["success"]:
|
|
263
|
+
time_diff = (
|
|
264
|
+
result_with_hooks["response_time"] - result_no_hooks["response_time"]
|
|
265
|
+
)
|
|
266
|
+
length_diff = (
|
|
267
|
+
result_with_hooks["response_length"] - result_no_hooks["response_length"]
|
|
268
|
+
)
|
|
269
|
+
|
|
270
|
+
print("\n性能对比:")
|
|
271
|
+
print(
|
|
272
|
+
f" 时间差异: {time_diff:+.2f}s ({'hooks 更慢' if time_diff > 0 else 'hooks 更快'})"
|
|
273
|
+
)
|
|
274
|
+
print(
|
|
275
|
+
f" 长度差异: {length_diff:+d} 字符 ({'hooks 更长' if length_diff > 0 else 'hooks 更短'})"
|
|
276
|
+
)
|
|
277
|
+
|
|
278
|
+
if abs(time_diff) < 1.0:
|
|
279
|
+
print(" ✅ 时间差异在可接受范围内")
|
|
280
|
+
else:
|
|
281
|
+
print(" ⚠️ 时间差异较大,需要进一步优化")
|
|
282
|
+
|
|
283
|
+
|
|
284
|
+
if __name__ == "__main__":
|
|
285
|
+
main()
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: tooluniverse
|
|
3
|
-
Version: 1.0.
|
|
3
|
+
Version: 1.0.4
|
|
4
4
|
Summary: A comprehensive collection of scientific tools for Agentic AI, offering integration with the ToolUniverse SDK and MCP Server to support advanced scientific workflows.
|
|
5
5
|
Author-email: Shanghua Gao <shanghuagao@gmail.com>
|
|
6
6
|
Project-URL: Homepage, https://github.com/mims-harvard/TxAgent
|
|
@@ -18,6 +18,7 @@ Requires-Dist: networkx>=3.4.0
|
|
|
18
18
|
Requires-Dist: openai>=1.107.0
|
|
19
19
|
Requires-Dist: pyyaml>=6.0.0
|
|
20
20
|
Requires-Dist: google-genai>=1.36.0
|
|
21
|
+
Requires-Dist: google-generativeai>=0.7.2
|
|
21
22
|
Requires-Dist: mcp[cli]>=1.9.3
|
|
22
23
|
Requires-Dist: fastmcp>=2.12.0
|
|
23
24
|
Requires-Dist: xmltodict>=1.0.0
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
tooluniverse/__init__.py,sha256=DXdZsB6gSGAubWpPjZDJZGo_PeH8l3BeJ-NeKsuY5Co,13944
|
|
2
2
|
tooluniverse/admetai_tool.py,sha256=nEfq7dwvFqjDryKv3nivGoBSRap6LT7_m76iMu72Q6E,3009
|
|
3
|
-
tooluniverse/agentic_tool.py,sha256=
|
|
3
|
+
tooluniverse/agentic_tool.py,sha256=y8M_6LzTGxrpndLms_M9-ycC10Ppp0S3EphExl5RrBo,20645
|
|
4
4
|
tooluniverse/alphafold_tool.py,sha256=NkKQttC0MfuetCTTcWTFEG2MdhyKwy3jb5TR4odiqAw,4658
|
|
5
5
|
tooluniverse/base_tool.py,sha256=uA-wGrs1drEJJbIp24YfWWWWfNGeMqEQo1tI6r3csEg,5664
|
|
6
6
|
tooluniverse/boltz_tool.py,sha256=Kfcymeu6FRRpWLw7dWhEON4PUBTsHuBiTAPJlYH5ZGs,7930
|
|
@@ -23,6 +23,7 @@ tooluniverse/graphql_tool.py,sha256=y7ztNyb9hn4OdSGKhLsHev_snkNgbAwJZL8ZGHm0LEk,
|
|
|
23
23
|
tooluniverse/gwas_tool.py,sha256=hq4VhB93DhczZo0xRGjGS9AtdKWL0O_XQy3eoV_fi8E,12351
|
|
24
24
|
tooluniverse/hpa_tool.py,sha256=siRA0usQ0Rggloy3VL1b56QlytabndXS8Xzc9H3uWs8,64998
|
|
25
25
|
tooluniverse/humanbase_tool.py,sha256=xojNboYvFrW_LAzOzKaexp6tvyGSbUazpMfOvX5ETXY,15006
|
|
26
|
+
tooluniverse/llm_clients.py,sha256=UPcK0H68ryEDdkuKgu17QNroIXmYa6eUu8XNfwHSmkM,14630
|
|
26
27
|
tooluniverse/logging_config.py,sha256=SWM8TCrv0RZJZbC8NNwy8h04V9BvqSVyzwJFcW43eFI,7212
|
|
27
28
|
tooluniverse/mcp_client_tool.py,sha256=R2WWAbnjzCFEKfeddTvtZTSZqtnvKRayV2ha2xdV9EU,28741
|
|
28
29
|
tooluniverse/mcp_integration.py,sha256=9VtFDFbcVIuKO_sd1gFrOd-R0r6uxlYRjdsOKiqV1zs,13912
|
|
@@ -31,7 +32,7 @@ tooluniverse/medlineplus_tool.py,sha256=__D7W2Khl05WllMnoV4Owv3pyl5EXS1lzEJmAE7P
|
|
|
31
32
|
tooluniverse/openalex_tool.py,sha256=cR6K4ycFTarXxkNM_Rm2ULNu3K4QJX0ukK-7YVZiLcg,8066
|
|
32
33
|
tooluniverse/openfda_adv_tool.py,sha256=t5kffba0iNDVtFHYPtfLW8ql4dKLaWwdcFnE9cNmNWE,10168
|
|
33
34
|
tooluniverse/openfda_tool.py,sha256=AetafmFr1IygGAL8p1-URsNahVdN52tN0FvToTlkcMw,27425
|
|
34
|
-
tooluniverse/output_hook.py,sha256=
|
|
35
|
+
tooluniverse/output_hook.py,sha256=2f95WFXA9DC6-HV4uJb8ZJAF-VmlmM2DPVvG2up_4EE,46279
|
|
35
36
|
tooluniverse/package_tool.py,sha256=Ri-TPc_jTY3olHjPsMkEe2z45vknM7yynjtMXkh3Le8,8294
|
|
36
37
|
tooluniverse/pubchem_tool.py,sha256=14C_5uz0RNzv5HaSAXHlq13TZLtlkhmJhr7RrjI91Yk,6415
|
|
37
38
|
tooluniverse/pubtator_tool.py,sha256=WdFufeT3hY2lCq6vb9SLF44UYJ48PiZ1mf4bSfpI7mg,7151
|
|
@@ -41,7 +42,7 @@ tooluniverse/remote_tool.py,sha256=ywb5xaJBqOT38_r5FBVoF3QFQDcLvfOH5AQrT-g7Fcs,3
|
|
|
41
42
|
tooluniverse/restful_tool.py,sha256=H7alq_vO3G4iVgZIZrrWh9vq2ForJN52Fl7_QOq7yaM,4409
|
|
42
43
|
tooluniverse/semantic_scholar_tool.py,sha256=3gMHF-ReyNsP74oV7LzphhkhjYOX44F4JpnvIafaWPY,1970
|
|
43
44
|
tooluniverse/smcp.py,sha256=D53npbXtNLN4snGpFyzU-jqyMVYt4MrpoA3DVNlStHo,99797
|
|
44
|
-
tooluniverse/smcp_server.py,sha256=
|
|
45
|
+
tooluniverse/smcp_server.py,sha256=MfpamnRfn0P1YImIkmdIri7U_z4v2HOI0-NsBB3OySI,34598
|
|
45
46
|
tooluniverse/tool_finder_embedding.py,sha256=O0WMCT6z7a_pDDew04QtpyPk_qzfGCX_647rsrBs0ug,11239
|
|
46
47
|
tooluniverse/tool_finder_keyword.py,sha256=_Nt4-C1RranoywTk8vi6MePWPoNqFwOhafMDiTYl_SU,23480
|
|
47
48
|
tooluniverse/tool_finder_llm.py,sha256=W63BDow6ioWQJgkpuhS3f0f4lb48uT_Jzc_bTqhBKE8,27361
|
|
@@ -57,7 +58,7 @@ tooluniverse/compose_scripts/biomarker_discovery.py,sha256=Im7SO1boySOVAcOz5JtuN
|
|
|
57
58
|
tooluniverse/compose_scripts/comprehensive_drug_discovery.py,sha256=k5aoTkC5bTneM9asOuYKz0dCwewVv2kWOXUdS_CAoOc,8588
|
|
58
59
|
tooluniverse/compose_scripts/drug_safety_analyzer.py,sha256=4lmGYY8a4T4WbeHIUG1aAtxowk3SFnJNEtndCTmnJfk,3164
|
|
59
60
|
tooluniverse/compose_scripts/literature_tool.py,sha256=8-NITTQHj6vdn-vo_d0W8l6Ed8bvDTkDOJ7yvhaE-lI,976
|
|
60
|
-
tooluniverse/compose_scripts/output_summarizer.py,sha256=
|
|
61
|
+
tooluniverse/compose_scripts/output_summarizer.py,sha256=dCT9GAcplaaIWuOjF9uJTVer7z-xbclb2V9tqR1BPAY,10331
|
|
61
62
|
tooluniverse/compose_scripts/tool_description_optimizer.py,sha256=L6Kd8e6Af8pD6dy8jrFzJq5jq-QNbg72gkQktn8IDBE,32175
|
|
62
63
|
tooluniverse/compose_scripts/tool_discover.py,sha256=RKzCmhDWzDCsAl2KCcEQRNH96mOf_2bTQOH2EVGvpC8,24976
|
|
63
64
|
tooluniverse/compose_scripts/tool_graph_composer.py,sha256=lmGeN94Mc9SZCeYo8ez55tKYLS1-dI3JDm-onKB5DZA,15566
|
|
@@ -95,7 +96,7 @@ tooluniverse/data/medlineplus_tools.json,sha256=Jxy4Mqw6l6VYKfQ1sS54iR5SdDJFqVSr
|
|
|
95
96
|
tooluniverse/data/monarch_tools.json,sha256=-uyhy-FlYBCmP0_biespZcuBHwcvOPmxX4gNYnTmgMU,3568
|
|
96
97
|
tooluniverse/data/openalex_tools.json,sha256=6y-1rqRAwR8dzxT3E5sroTdzfl4OVJMxdLSPcIBb-vQ,1736
|
|
97
98
|
tooluniverse/data/opentarget_tools.json,sha256=IZGLUbQWC--u_DSNoGGMtI9V9YFxucHB1ESqglJWCY8,67795
|
|
98
|
-
tooluniverse/data/output_summarization_tools.json,sha256=
|
|
99
|
+
tooluniverse/data/output_summarization_tools.json,sha256=9BxZAkzexsDp8jGMKUHW3LIRThZjleRjYRvk0y-bxEs,3944
|
|
99
100
|
tooluniverse/data/pubchem_tools.json,sha256=_q3sov5n2fGhBT43gzfqSjsjT1uc_itiF9HT2UV3jFU,12695
|
|
100
101
|
tooluniverse/data/pubtator_tools.json,sha256=WkcP3DFlC6EcL9zf2KMrDITC0_fYPNTu60by0RJBdVI,2511
|
|
101
102
|
tooluniverse/data/rcsb_pdb_tools.json,sha256=gKY8Y9QDN4-3ILc2KFLGdPFXG1M9LhXMAPFQtwnP7Bg,47767
|
|
@@ -138,10 +139,13 @@ tooluniverse/remote/uspto_downloader/uspto_downloader_tool.py,sha256=hkDmSVh2-KE
|
|
|
138
139
|
tooluniverse/scripts/filter_tool_files.py,sha256=IZZIeSmBfHKntno790er1hQHSDcrxfdIHZwZ-Lvq7I4,6415
|
|
139
140
|
tooluniverse/scripts/generate_tool_graph.py,sha256=X_TpGcJ29CFH49Djzsz4gs8VvjDe0CcF6KFWU_hJHDI,12727
|
|
140
141
|
tooluniverse/scripts/visualize_tool_graph.py,sha256=4USGnUVdffJfOxourBKELldGhhk5HV7ZeHHREhyKqOc,25812
|
|
142
|
+
tooluniverse/test/list_azure_openai_models.py,sha256=lemS5fSmt1jdJ04dwL--YUJ50Fc9E2G1LpUG8nKfaTg,7680
|
|
141
143
|
tooluniverse/test/mcp_server_test.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
142
144
|
tooluniverse/test/test_admetai_tool.py,sha256=Z_J-LjPgvqsdWpHvXwq24rt2e3Pg3IIp6t4XWUmBPoA,31991
|
|
143
145
|
tooluniverse/test/test_agentic_tool.py,sha256=vMU6uxU0rB6DaYL105XY4euU9VOWWXR3c-qGzMzhHkU,5803
|
|
146
|
+
tooluniverse/test/test_agentic_tool_azure_models.py,sha256=2T3R_rm2jZ-tVe8b_3RI2CvYxY9mq0Yq28hEi1LtFas,2460
|
|
144
147
|
tooluniverse/test/test_alphafold_tool.py,sha256=Hj-ITZqWO-U8OVNveVtmLVACiOAzwUYh1COwjcIaxrQ,3459
|
|
148
|
+
tooluniverse/test/test_api_key_validation_min.py,sha256=esWQywax1fSLvinZ_LXbLVVqUxstqmlkIV0ZfAj7sPg,1976
|
|
145
149
|
tooluniverse/test/test_chem_tool.py,sha256=N_ARBvouWyJMgWL1yMXSg1w407fBB-CZxJysFVRE6uY,1589
|
|
146
150
|
tooluniverse/test/test_compose_lieraturereview.py,sha256=qNkgXHXJm7Ekiw9e0mcgtqs1z5c-MeE3qy0RoexF9Tg,1956
|
|
147
151
|
tooluniverse/test/test_compose_tool.py,sha256=reRhUWhSuWwuorWF0jbDQHhIEd14UTq_GDSe0Wwl0v4,16607
|
|
@@ -155,7 +159,9 @@ tooluniverse/test/test_europe_pmc_tool.py,sha256=zcd-1aTB25Vkm-FOfGXyqTRBPKoeVOn
|
|
|
155
159
|
tooluniverse/test/test_fda_adv.py,sha256=kP9YvZ1i8TzL-oDMwaQvvuryAEsp2yaD60ViAj0B3Sw,8141
|
|
156
160
|
tooluniverse/test/test_fda_drug_labeling.py,sha256=O655Pcvyx9_d_grHSIYqYVxprvqpy_Ih4Ax43tLM1Xc,7875
|
|
157
161
|
tooluniverse/test/test_gene_ontology_tools.py,sha256=b9adyK5s7EF3Ij_onp8RAfNH7UgC3vsVgZwbEBxQ8Ek,2364
|
|
162
|
+
tooluniverse/test/test_global_fallback.py,sha256=AEvDUJwMPgvvLusTnxuEESsRjvMGgYLoR4h3bdYIYR4,10845
|
|
158
163
|
tooluniverse/test/test_gwas_tool.py,sha256=_VXaf8K_1uO-oKlacJP6VTt4u5cjtX3w92G_eQBucvE,4961
|
|
164
|
+
tooluniverse/test/test_hooks_direct.py,sha256=T_mzUYASXfhPX2S_3j9CCD9AHXXkVloup36_3EDKgSo,6389
|
|
159
165
|
tooluniverse/test/test_hpa.py,sha256=53lx0rXx0-aT1LRm9IEeBbV5cXaYlp3Ol5bmeRz10Hc,30006
|
|
160
166
|
tooluniverse/test/test_humanbase_tool.py,sha256=4KQnaehJwGtePEwb5my3yldZnMWQHfvCGEpzm-AWLH0,564
|
|
161
167
|
tooluniverse/test/test_idmap_tools.py,sha256=bP_AKhZG1lX9vQKrrrzuZ1iXIMWIWjAriB66pbFCE5M,1743
|
|
@@ -171,6 +177,7 @@ tooluniverse/test/test_rcsb_pdb_tool.py,sha256=bLI5zSWSZiyTmG_yyLf3mkroI6MZVnnp9
|
|
|
171
177
|
tooluniverse/test/test_reactome.py,sha256=X3lV4z5sjYnpO3ntH6wc9DluKHgB6GL0z5j7YavFrtA,1784
|
|
172
178
|
tooluniverse/test/test_semantic_scholar_tool.py,sha256=7ZQOIqivfIMc7yPCzGwWGrxNphvYHK_fZAlrdUAEzKE,705
|
|
173
179
|
tooluniverse/test/test_software_tools.py,sha256=fJeS_9k-cysYzsic75QrQAC_bNxWRVk_vazoldNz0KA,5781
|
|
180
|
+
tooluniverse/test/test_stdio_hooks.py,sha256=UDuZCOM7Rcz2hYQdCFwJDXgoth5qLMlHLMxp55pYNVQ,9187
|
|
174
181
|
tooluniverse/test/test_tool_description_optimizer.py,sha256=CuuxSYfb8kHjz9fHmJ8bGhpAIAmqIvUb6mYrt1H5F64,1320
|
|
175
182
|
tooluniverse/test/test_tool_finder.py,sha256=6piRAEMR-9dKr2zaurRZd4dqZLpDMbach4jrq1fgP-c,741
|
|
176
183
|
tooluniverse/test/test_tool_finder_llm.py,sha256=nZTYavGePiNt5Z2smmNLhkO3dz-_P_RcUTv8J1vDzVs,8997
|
|
@@ -178,9 +185,9 @@ tooluniverse/test/test_tools_find.py,sha256=vP9EV04iXXmejoY2rDhEM0Yc9uHEO2qEmd8s
|
|
|
178
185
|
tooluniverse/test/test_uniprot_tools.py,sha256=V0x7aQjjlE-wS5alFWviHNwC3saHiEE5pMMqAcbokaw,2582
|
|
179
186
|
tooluniverse/test/test_uspto_tool.py,sha256=y2VQBMbiHCTAmvXhBosHrc1innstUl9UMWNoPaBv-RY,2311
|
|
180
187
|
tooluniverse/test/test_xml_tool.py,sha256=tx-w_psZ801C2kM6aDbBzR8QV3Vgu1p2zP6zExhjpVs,3602
|
|
181
|
-
tooluniverse-1.0.
|
|
182
|
-
tooluniverse-1.0.
|
|
183
|
-
tooluniverse-1.0.
|
|
184
|
-
tooluniverse-1.0.
|
|
185
|
-
tooluniverse-1.0.
|
|
186
|
-
tooluniverse-1.0.
|
|
188
|
+
tooluniverse-1.0.4.dist-info/licenses/LICENSE,sha256=Unq9Y3buGL9J0vFop03FYZiVweytt1xdgLIh2n9ck2c,1115
|
|
189
|
+
tooluniverse-1.0.4.dist-info/METADATA,sha256=724WaE2RW8W6CIVl-IM0-ud7iVvjQr66cqWWMm4R0Wg,18404
|
|
190
|
+
tooluniverse-1.0.4.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
|
|
191
|
+
tooluniverse-1.0.4.dist-info/entry_points.txt,sha256=Z_znqzUc_XR9ZIXViavqNAwBkwM4XYfC9h7LoBbAAog,600
|
|
192
|
+
tooluniverse-1.0.4.dist-info/top_level.txt,sha256=zZ8YeCJ5FAkEwdd_mxsFtSCQMBDgBdxrrmHo3RNBiWs,13
|
|
193
|
+
tooluniverse-1.0.4.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|