tooluniverse 0.1.4__py3-none-any.whl → 1.0.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 +340 -4
- tooluniverse/admetai_tool.py +84 -0
- tooluniverse/agentic_tool.py +563 -0
- tooluniverse/alphafold_tool.py +96 -0
- tooluniverse/base_tool.py +129 -6
- tooluniverse/boltz_tool.py +207 -0
- tooluniverse/chem_tool.py +192 -0
- tooluniverse/compose_scripts/__init__.py +1 -0
- tooluniverse/compose_scripts/biomarker_discovery.py +293 -0
- tooluniverse/compose_scripts/comprehensive_drug_discovery.py +186 -0
- tooluniverse/compose_scripts/drug_safety_analyzer.py +89 -0
- tooluniverse/compose_scripts/literature_tool.py +34 -0
- tooluniverse/compose_scripts/output_summarizer.py +279 -0
- tooluniverse/compose_scripts/tool_description_optimizer.py +681 -0
- tooluniverse/compose_scripts/tool_discover.py +705 -0
- tooluniverse/compose_scripts/tool_graph_composer.py +448 -0
- tooluniverse/compose_tool.py +371 -0
- tooluniverse/ctg_tool.py +1002 -0
- tooluniverse/custom_tool.py +81 -0
- tooluniverse/dailymed_tool.py +108 -0
- tooluniverse/data/admetai_tools.json +155 -0
- tooluniverse/data/agentic_tools.json +1156 -0
- tooluniverse/data/alphafold_tools.json +87 -0
- tooluniverse/data/boltz_tools.json +9 -0
- tooluniverse/data/chembl_tools.json +16 -0
- tooluniverse/data/clait_tools.json +108 -0
- tooluniverse/data/clinicaltrials_gov_tools.json +326 -0
- tooluniverse/data/compose_tools.json +202 -0
- tooluniverse/data/dailymed_tools.json +70 -0
- tooluniverse/data/dataset_tools.json +646 -0
- tooluniverse/data/disease_target_score_tools.json +712 -0
- tooluniverse/data/efo_tools.json +17 -0
- tooluniverse/data/embedding_tools.json +319 -0
- tooluniverse/data/enrichr_tools.json +31 -0
- tooluniverse/data/europe_pmc_tools.json +22 -0
- tooluniverse/data/expert_feedback_tools.json +10 -0
- tooluniverse/data/fda_drug_adverse_event_tools.json +491 -0
- tooluniverse/data/fda_drug_labeling_tools.json +544 -168
- tooluniverse/data/fda_drugs_with_brand_generic_names_for_tool.py +76929 -148860
- tooluniverse/data/finder_tools.json +209 -0
- tooluniverse/data/gene_ontology_tools.json +113 -0
- tooluniverse/data/gwas_tools.json +1082 -0
- tooluniverse/data/hpa_tools.json +333 -0
- tooluniverse/data/humanbase_tools.json +47 -0
- tooluniverse/data/idmap_tools.json +74 -0
- tooluniverse/data/mcp_client_tools_example.json +113 -0
- tooluniverse/data/mcpautoloadertool_defaults.json +28 -0
- tooluniverse/data/medlineplus_tools.json +141 -0
- tooluniverse/data/monarch_tools.json +1 -1
- tooluniverse/data/openalex_tools.json +36 -0
- tooluniverse/data/opentarget_tools.json +82 -58
- tooluniverse/data/output_summarization_tools.json +101 -0
- tooluniverse/data/packages/bioinformatics_core_tools.json +1756 -0
- tooluniverse/data/packages/categorized_tools.txt +206 -0
- tooluniverse/data/packages/cheminformatics_tools.json +347 -0
- tooluniverse/data/packages/earth_sciences_tools.json +74 -0
- tooluniverse/data/packages/genomics_tools.json +776 -0
- tooluniverse/data/packages/image_processing_tools.json +38 -0
- tooluniverse/data/packages/machine_learning_tools.json +789 -0
- tooluniverse/data/packages/neuroscience_tools.json +62 -0
- tooluniverse/data/packages/original_tools.txt +0 -0
- tooluniverse/data/packages/physics_astronomy_tools.json +62 -0
- tooluniverse/data/packages/scientific_computing_tools.json +560 -0
- tooluniverse/data/packages/single_cell_tools.json +453 -0
- tooluniverse/data/packages/software_tools.json +4954 -0
- tooluniverse/data/packages/structural_biology_tools.json +396 -0
- tooluniverse/data/packages/visualization_tools.json +399 -0
- tooluniverse/data/pubchem_tools.json +215 -0
- tooluniverse/data/pubtator_tools.json +68 -0
- tooluniverse/data/rcsb_pdb_tools.json +1332 -0
- tooluniverse/data/reactome_tools.json +19 -0
- tooluniverse/data/semantic_scholar_tools.json +26 -0
- tooluniverse/data/special_tools.json +2 -25
- tooluniverse/data/tool_composition_tools.json +88 -0
- tooluniverse/data/toolfinderkeyword_defaults.json +34 -0
- tooluniverse/data/txagent_client_tools.json +9 -0
- tooluniverse/data/uniprot_tools.json +211 -0
- tooluniverse/data/url_fetch_tools.json +94 -0
- tooluniverse/data/uspto_downloader_tools.json +9 -0
- tooluniverse/data/uspto_tools.json +811 -0
- tooluniverse/data/xml_tools.json +3275 -0
- tooluniverse/dataset_tool.py +296 -0
- tooluniverse/default_config.py +165 -0
- tooluniverse/efo_tool.py +42 -0
- tooluniverse/embedding_database.py +630 -0
- tooluniverse/embedding_sync.py +396 -0
- tooluniverse/enrichr_tool.py +266 -0
- tooluniverse/europe_pmc_tool.py +52 -0
- tooluniverse/execute_function.py +1775 -95
- tooluniverse/extended_hooks.py +444 -0
- tooluniverse/gene_ontology_tool.py +194 -0
- tooluniverse/graphql_tool.py +158 -36
- tooluniverse/gwas_tool.py +358 -0
- tooluniverse/hpa_tool.py +1645 -0
- tooluniverse/humanbase_tool.py +389 -0
- tooluniverse/logging_config.py +254 -0
- tooluniverse/mcp_client_tool.py +764 -0
- tooluniverse/mcp_integration.py +413 -0
- tooluniverse/mcp_tool_registry.py +925 -0
- tooluniverse/medlineplus_tool.py +337 -0
- tooluniverse/openalex_tool.py +228 -0
- tooluniverse/openfda_adv_tool.py +283 -0
- tooluniverse/openfda_tool.py +393 -160
- tooluniverse/output_hook.py +1122 -0
- tooluniverse/package_tool.py +195 -0
- tooluniverse/pubchem_tool.py +158 -0
- tooluniverse/pubtator_tool.py +168 -0
- tooluniverse/rcsb_pdb_tool.py +38 -0
- tooluniverse/reactome_tool.py +108 -0
- tooluniverse/remote/boltz/boltz_mcp_server.py +50 -0
- tooluniverse/remote/depmap_24q2/depmap_24q2_mcp_tool.py +442 -0
- tooluniverse/remote/expert_feedback/human_expert_mcp_tools.py +2013 -0
- tooluniverse/remote/expert_feedback/simple_test.py +23 -0
- tooluniverse/remote/expert_feedback/start_web_interface.py +188 -0
- tooluniverse/remote/expert_feedback/web_only_interface.py +0 -0
- tooluniverse/remote/expert_feedback_mcp/human_expert_mcp_server.py +1611 -0
- tooluniverse/remote/expert_feedback_mcp/simple_test.py +34 -0
- tooluniverse/remote/expert_feedback_mcp/start_web_interface.py +91 -0
- tooluniverse/remote/immune_compass/compass_tool.py +327 -0
- tooluniverse/remote/pinnacle/pinnacle_tool.py +328 -0
- tooluniverse/remote/transcriptformer/transcriptformer_tool.py +586 -0
- tooluniverse/remote/uspto_downloader/uspto_downloader_mcp_server.py +61 -0
- tooluniverse/remote/uspto_downloader/uspto_downloader_tool.py +120 -0
- tooluniverse/remote_tool.py +99 -0
- tooluniverse/restful_tool.py +53 -30
- tooluniverse/scripts/generate_tool_graph.py +408 -0
- tooluniverse/scripts/visualize_tool_graph.py +829 -0
- tooluniverse/semantic_scholar_tool.py +62 -0
- tooluniverse/smcp.py +2452 -0
- tooluniverse/smcp_server.py +975 -0
- tooluniverse/test/mcp_server_test.py +0 -0
- tooluniverse/test/test_admetai_tool.py +370 -0
- tooluniverse/test/test_agentic_tool.py +129 -0
- tooluniverse/test/test_alphafold_tool.py +71 -0
- tooluniverse/test/test_chem_tool.py +37 -0
- tooluniverse/test/test_compose_lieraturereview.py +63 -0
- tooluniverse/test/test_compose_tool.py +448 -0
- tooluniverse/test/test_dailymed.py +69 -0
- tooluniverse/test/test_dataset_tool.py +200 -0
- tooluniverse/test/test_disease_target_score.py +56 -0
- tooluniverse/test/test_drugbank_filter_examples.py +179 -0
- tooluniverse/test/test_efo.py +31 -0
- tooluniverse/test/test_enrichr_tool.py +21 -0
- tooluniverse/test/test_europe_pmc_tool.py +20 -0
- tooluniverse/test/test_fda_adv.py +95 -0
- tooluniverse/test/test_fda_drug_labeling.py +91 -0
- tooluniverse/test/test_gene_ontology_tools.py +66 -0
- tooluniverse/test/test_gwas_tool.py +139 -0
- tooluniverse/test/test_hpa.py +625 -0
- tooluniverse/test/test_humanbase_tool.py +20 -0
- tooluniverse/test/test_idmap_tools.py +61 -0
- tooluniverse/test/test_mcp_server.py +211 -0
- tooluniverse/test/test_mcp_tool.py +247 -0
- tooluniverse/test/test_medlineplus.py +220 -0
- tooluniverse/test/test_openalex_tool.py +32 -0
- tooluniverse/test/test_opentargets.py +28 -0
- tooluniverse/test/test_pubchem_tool.py +116 -0
- tooluniverse/test/test_pubtator_tool.py +37 -0
- tooluniverse/test/test_rcsb_pdb_tool.py +86 -0
- tooluniverse/test/test_reactome.py +54 -0
- tooluniverse/test/test_semantic_scholar_tool.py +24 -0
- tooluniverse/test/test_software_tools.py +147 -0
- tooluniverse/test/test_tool_description_optimizer.py +49 -0
- tooluniverse/test/test_tool_finder.py +26 -0
- tooluniverse/test/test_tool_finder_llm.py +252 -0
- tooluniverse/test/test_tools_find.py +195 -0
- tooluniverse/test/test_uniprot_tools.py +74 -0
- tooluniverse/test/test_uspto_tool.py +72 -0
- tooluniverse/test/test_xml_tool.py +113 -0
- tooluniverse/tool_finder_embedding.py +267 -0
- tooluniverse/tool_finder_keyword.py +693 -0
- tooluniverse/tool_finder_llm.py +699 -0
- tooluniverse/tool_graph_web_ui.py +955 -0
- tooluniverse/tool_registry.py +416 -0
- tooluniverse/uniprot_tool.py +155 -0
- tooluniverse/url_tool.py +253 -0
- tooluniverse/uspto_tool.py +240 -0
- tooluniverse/utils.py +369 -41
- tooluniverse/xml_tool.py +369 -0
- tooluniverse-1.0.0.dist-info/METADATA +377 -0
- tooluniverse-1.0.0.dist-info/RECORD +186 -0
- {tooluniverse-0.1.4.dist-info → tooluniverse-1.0.0.dist-info}/WHEEL +1 -1
- tooluniverse-1.0.0.dist-info/entry_points.txt +9 -0
- tooluniverse-0.1.4.dist-info/METADATA +0 -141
- tooluniverse-0.1.4.dist-info/RECORD +0 -18
- {tooluniverse-0.1.4.dist-info → tooluniverse-1.0.0.dist-info}/licenses/LICENSE +0 -0
- {tooluniverse-0.1.4.dist-info → tooluniverse-1.0.0.dist-info}/top_level.txt +0 -0
|
@@ -0,0 +1,408 @@
|
|
|
1
|
+
#!/usr/bin/env python3
|
|
2
|
+
"""
|
|
3
|
+
Tool Graph Generator Script
|
|
4
|
+
|
|
5
|
+
This script generates a compatibility graph for all tools in ToolUniverse.
|
|
6
|
+
It uses the ToolCompatibilityAnalyzer and ToolGraphComposer to analyze tool relationships.
|
|
7
|
+
|
|
8
|
+
Usage:
|
|
9
|
+
python generate_tool_graph.py [options]
|
|
10
|
+
|
|
11
|
+
Examples:
|
|
12
|
+
# Quick analysis with limited tools
|
|
13
|
+
python generate_tool_graph.py --quick --max-tools 5
|
|
14
|
+
|
|
15
|
+
# Detailed analysis of specific categories
|
|
16
|
+
python generate_tool_graph.py --categories pubchem,chembl --analysis-depth detailed
|
|
17
|
+
|
|
18
|
+
# Full comprehensive analysis (may take hours)
|
|
19
|
+
python generate_tool_graph.py --analysis-depth comprehensive --force-rebuild
|
|
20
|
+
"""
|
|
21
|
+
|
|
22
|
+
import argparse
|
|
23
|
+
import json
|
|
24
|
+
import os
|
|
25
|
+
import sys
|
|
26
|
+
import time
|
|
27
|
+
from datetime import datetime
|
|
28
|
+
from pathlib import Path
|
|
29
|
+
|
|
30
|
+
# Add parent directories to path for imports
|
|
31
|
+
script_dir = Path(__file__).parent
|
|
32
|
+
tooluniverse_dir = script_dir.parent
|
|
33
|
+
src_dir = tooluniverse_dir.parent
|
|
34
|
+
sys.path.insert(0, str(src_dir))
|
|
35
|
+
|
|
36
|
+
from tooluniverse import ToolUniverse # noqa: E402
|
|
37
|
+
|
|
38
|
+
|
|
39
|
+
def parse_arguments():
|
|
40
|
+
"""Parse command line arguments."""
|
|
41
|
+
|
|
42
|
+
parser = argparse.ArgumentParser(
|
|
43
|
+
description="Generate tool compatibility graph for ToolUniverse",
|
|
44
|
+
formatter_class=argparse.RawDescriptionHelpFormatter,
|
|
45
|
+
epilog="""
|
|
46
|
+
Examples:
|
|
47
|
+
%(prog)s --quick --max-tools 10
|
|
48
|
+
%(prog)s --categories pubchem,chembl,europepmc
|
|
49
|
+
%(prog)s --analysis-depth comprehensive --output ./full_graph
|
|
50
|
+
%(prog)s --force-rebuild --min-score 80
|
|
51
|
+
""",
|
|
52
|
+
)
|
|
53
|
+
|
|
54
|
+
# Output options
|
|
55
|
+
parser.add_argument(
|
|
56
|
+
"--output",
|
|
57
|
+
"-o",
|
|
58
|
+
type=str,
|
|
59
|
+
default="./tool_composition_graph",
|
|
60
|
+
help="Output path for graph files (default: ./tool_composition_graph)",
|
|
61
|
+
)
|
|
62
|
+
|
|
63
|
+
parser.add_argument(
|
|
64
|
+
"--force-rebuild",
|
|
65
|
+
"-f",
|
|
66
|
+
action="store_true",
|
|
67
|
+
help="Force rebuild even if cached graph exists",
|
|
68
|
+
)
|
|
69
|
+
|
|
70
|
+
# Analysis options
|
|
71
|
+
parser.add_argument(
|
|
72
|
+
"--analysis-depth",
|
|
73
|
+
"-d",
|
|
74
|
+
choices=["quick", "detailed", "comprehensive"],
|
|
75
|
+
default="detailed",
|
|
76
|
+
help="Analysis depth (default: detailed)",
|
|
77
|
+
)
|
|
78
|
+
|
|
79
|
+
parser.add_argument(
|
|
80
|
+
"--min-score",
|
|
81
|
+
"-s",
|
|
82
|
+
type=int,
|
|
83
|
+
default=60,
|
|
84
|
+
help="Minimum compatibility score for edges (0-100, default: 60)",
|
|
85
|
+
)
|
|
86
|
+
|
|
87
|
+
# Tool selection options
|
|
88
|
+
parser.add_argument(
|
|
89
|
+
"--categories",
|
|
90
|
+
"-c",
|
|
91
|
+
type=str,
|
|
92
|
+
help="Comma-separated list of tool categories to include (e.g., 'pubchem,chembl')",
|
|
93
|
+
)
|
|
94
|
+
|
|
95
|
+
parser.add_argument(
|
|
96
|
+
"--exclude-categories",
|
|
97
|
+
"-e",
|
|
98
|
+
type=str,
|
|
99
|
+
default="tool_finder,special_tools",
|
|
100
|
+
help="Comma-separated list of categories to exclude (default: tool_finder,special_tools)",
|
|
101
|
+
)
|
|
102
|
+
|
|
103
|
+
parser.add_argument(
|
|
104
|
+
"--max-tools",
|
|
105
|
+
"-m",
|
|
106
|
+
type=int,
|
|
107
|
+
default=50,
|
|
108
|
+
help="Maximum tools per category (default: 50)",
|
|
109
|
+
)
|
|
110
|
+
|
|
111
|
+
# Convenience options
|
|
112
|
+
parser.add_argument(
|
|
113
|
+
"--quick",
|
|
114
|
+
"-q",
|
|
115
|
+
action="store_true",
|
|
116
|
+
help="Quick mode: use quick analysis and limit to 10 tools per category",
|
|
117
|
+
)
|
|
118
|
+
|
|
119
|
+
parser.add_argument("--verbose", "-v", action="store_true", help="Verbose output")
|
|
120
|
+
|
|
121
|
+
parser.add_argument(
|
|
122
|
+
"--dry-run",
|
|
123
|
+
action="store_true",
|
|
124
|
+
help="Show what would be analyzed without actually running",
|
|
125
|
+
)
|
|
126
|
+
|
|
127
|
+
return parser.parse_args()
|
|
128
|
+
|
|
129
|
+
|
|
130
|
+
def setup_analysis_parameters(args):
|
|
131
|
+
"""Setup analysis parameters based on arguments."""
|
|
132
|
+
|
|
133
|
+
# Handle quick mode
|
|
134
|
+
if args.quick:
|
|
135
|
+
analysis_depth = "quick"
|
|
136
|
+
max_tools = 10
|
|
137
|
+
min_score = 70 # Higher threshold for quick mode
|
|
138
|
+
else:
|
|
139
|
+
analysis_depth = args.analysis_depth
|
|
140
|
+
max_tools = args.max_tools
|
|
141
|
+
min_score = args.min_score
|
|
142
|
+
|
|
143
|
+
# Handle category selection
|
|
144
|
+
if args.categories:
|
|
145
|
+
include_categories = [cat.strip() for cat in args.categories.split(",")]
|
|
146
|
+
exclude_categories = []
|
|
147
|
+
else:
|
|
148
|
+
include_categories = None
|
|
149
|
+
exclude_categories = [cat.strip() for cat in args.exclude_categories.split(",")]
|
|
150
|
+
|
|
151
|
+
return {
|
|
152
|
+
"output_path": args.output,
|
|
153
|
+
"analysis_depth": analysis_depth,
|
|
154
|
+
"min_compatibility_score": min_score,
|
|
155
|
+
"exclude_categories": exclude_categories,
|
|
156
|
+
"include_categories": include_categories,
|
|
157
|
+
"max_tools_per_category": max_tools,
|
|
158
|
+
"force_rebuild": args.force_rebuild,
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
|
|
162
|
+
def preview_analysis(tooluniverse, parameters):
|
|
163
|
+
"""Show what tools would be analyzed without running the analysis."""
|
|
164
|
+
|
|
165
|
+
print("Analysis Preview")
|
|
166
|
+
print("=" * 50)
|
|
167
|
+
print(f"Analysis Depth: {parameters['analysis_depth']}")
|
|
168
|
+
print(f"Min Compatibility Score: {parameters['min_compatibility_score']}")
|
|
169
|
+
print(f"Max Tools per Category: {parameters['max_tools_per_category']}")
|
|
170
|
+
print(f"Output Path: {parameters['output_path']}")
|
|
171
|
+
print()
|
|
172
|
+
|
|
173
|
+
# Show categories and tool counts
|
|
174
|
+
categories = tooluniverse.tool_category_dicts
|
|
175
|
+
exclude_set = set(parameters.get("exclude_categories", []))
|
|
176
|
+
include_set = (
|
|
177
|
+
set(parameters.get("include_categories", []))
|
|
178
|
+
if parameters.get("include_categories")
|
|
179
|
+
else None
|
|
180
|
+
)
|
|
181
|
+
|
|
182
|
+
total_tools = 0
|
|
183
|
+
selected_categories = []
|
|
184
|
+
|
|
185
|
+
for category, tools in categories.items():
|
|
186
|
+
# Apply category filtering
|
|
187
|
+
if include_set and category not in include_set:
|
|
188
|
+
continue
|
|
189
|
+
if category in exclude_set:
|
|
190
|
+
continue
|
|
191
|
+
|
|
192
|
+
tool_count = min(len(tools), parameters["max_tools_per_category"])
|
|
193
|
+
total_tools += tool_count
|
|
194
|
+
selected_categories.append((category, tool_count, len(tools)))
|
|
195
|
+
|
|
196
|
+
print("Selected Categories:")
|
|
197
|
+
for category, selected_count, total_count in selected_categories:
|
|
198
|
+
status = (
|
|
199
|
+
f"({selected_count}/{total_count})"
|
|
200
|
+
if selected_count < total_count
|
|
201
|
+
else f"({total_count})"
|
|
202
|
+
)
|
|
203
|
+
print(f" {category}: {status}")
|
|
204
|
+
|
|
205
|
+
print(f"\nTotal tools to analyze: {total_tools}")
|
|
206
|
+
print(f"Estimated tool pairs: {total_tools * (total_tools - 1)}")
|
|
207
|
+
|
|
208
|
+
# Time estimates
|
|
209
|
+
if parameters["analysis_depth"] == "quick":
|
|
210
|
+
est_time_per_pair = 2 # seconds
|
|
211
|
+
elif parameters["analysis_depth"] == "detailed":
|
|
212
|
+
est_time_per_pair = 5 # seconds
|
|
213
|
+
else: # comprehensive
|
|
214
|
+
est_time_per_pair = 10 # seconds
|
|
215
|
+
|
|
216
|
+
total_pairs = total_tools * (total_tools - 1)
|
|
217
|
+
est_total_time = total_pairs * est_time_per_pair
|
|
218
|
+
|
|
219
|
+
print("\nEstimated Analysis Time:")
|
|
220
|
+
print(f" Per pair: ~{est_time_per_pair} seconds")
|
|
221
|
+
print(f" Total: ~{est_total_time // 3600}h {(est_total_time % 3600) // 60}m")
|
|
222
|
+
|
|
223
|
+
return total_tools > 0
|
|
224
|
+
|
|
225
|
+
|
|
226
|
+
def run_graph_generation(tooluniverse, parameters, verbose=False):
|
|
227
|
+
"""Run the graph generation process."""
|
|
228
|
+
|
|
229
|
+
print("Starting Tool Graph Generation")
|
|
230
|
+
print("=" * 50)
|
|
231
|
+
|
|
232
|
+
start_time = time.time()
|
|
233
|
+
|
|
234
|
+
try:
|
|
235
|
+
# Prepare arguments for ToolGraphComposer
|
|
236
|
+
composer_args = {
|
|
237
|
+
"output_path": parameters["output_path"],
|
|
238
|
+
"analysis_depth": parameters["analysis_depth"],
|
|
239
|
+
"min_compatibility_score": parameters["min_compatibility_score"],
|
|
240
|
+
"exclude_categories": parameters["exclude_categories"],
|
|
241
|
+
"max_tools_per_category": parameters["max_tools_per_category"],
|
|
242
|
+
"force_rebuild": parameters["force_rebuild"],
|
|
243
|
+
}
|
|
244
|
+
|
|
245
|
+
# Add include_categories if specified
|
|
246
|
+
if parameters.get("include_categories"):
|
|
247
|
+
# For include_categories, we need to modify exclude_categories
|
|
248
|
+
all_categories = set(tooluniverse.tool_category_dicts.keys())
|
|
249
|
+
include_set = set(parameters["include_categories"])
|
|
250
|
+
composer_args["exclude_categories"] = list(all_categories - include_set)
|
|
251
|
+
|
|
252
|
+
if verbose:
|
|
253
|
+
print("Composer arguments:")
|
|
254
|
+
print(json.dumps(composer_args, indent=2))
|
|
255
|
+
print()
|
|
256
|
+
|
|
257
|
+
# Run the composition
|
|
258
|
+
result = tooluniverse.run(
|
|
259
|
+
json.dumps([{"name": "ToolGraphComposer", "arguments": composer_args}])
|
|
260
|
+
)
|
|
261
|
+
|
|
262
|
+
# Handle result formatting
|
|
263
|
+
if isinstance(result, list) and len(result) > 0:
|
|
264
|
+
result = result[0]
|
|
265
|
+
|
|
266
|
+
end_time = time.time()
|
|
267
|
+
duration = end_time - start_time
|
|
268
|
+
|
|
269
|
+
# Display results
|
|
270
|
+
print("Graph Generation Complete!")
|
|
271
|
+
print("-" * 30)
|
|
272
|
+
print(
|
|
273
|
+
f"Duration: {duration // 3600:.0f}h {(duration % 3600) // 60:.0f}m {duration % 60:.1f}s"
|
|
274
|
+
)
|
|
275
|
+
|
|
276
|
+
if isinstance(result, dict):
|
|
277
|
+
if result.get("status") == "success":
|
|
278
|
+
print("✅ Status: Success")
|
|
279
|
+
|
|
280
|
+
# Show files created
|
|
281
|
+
if "graph_files" in result:
|
|
282
|
+
print("\nGenerated Files:")
|
|
283
|
+
for format_type, file_path in result["graph_files"].items():
|
|
284
|
+
if os.path.exists(file_path):
|
|
285
|
+
file_size = os.path.getsize(file_path)
|
|
286
|
+
print(
|
|
287
|
+
f" {format_type.upper()}: {file_path} ({file_size:,} bytes)"
|
|
288
|
+
)
|
|
289
|
+
|
|
290
|
+
# Show statistics
|
|
291
|
+
if "statistics" in result:
|
|
292
|
+
stats = result["statistics"]
|
|
293
|
+
print("\nGraph Statistics:")
|
|
294
|
+
print(f" Tools Analyzed: {result.get('tools_analyzed', 'N/A')}")
|
|
295
|
+
print(f" Nodes: {stats.get('total_nodes', 'N/A')}")
|
|
296
|
+
print(f" Edges: {stats.get('total_edges', 'N/A')}")
|
|
297
|
+
print(f" Edge Density: {stats.get('edge_density', 0):.3f}")
|
|
298
|
+
|
|
299
|
+
if "compatibility_scores" in stats:
|
|
300
|
+
scores = stats["compatibility_scores"]
|
|
301
|
+
print(
|
|
302
|
+
f" Avg Compatibility Score: {scores.get('average', 0):.1f}"
|
|
303
|
+
)
|
|
304
|
+
print(f" High-Quality Edges: {scores.get('count_high', 0)}")
|
|
305
|
+
|
|
306
|
+
if "automation_ready_percentage" in stats:
|
|
307
|
+
print(
|
|
308
|
+
f" Automation Ready: {stats['automation_ready_percentage']:.1f}%"
|
|
309
|
+
)
|
|
310
|
+
|
|
311
|
+
return True
|
|
312
|
+
else:
|
|
313
|
+
print("❌ Status: Failed")
|
|
314
|
+
print(f"Error: {result.get('message', 'Unknown error')}")
|
|
315
|
+
return False
|
|
316
|
+
else:
|
|
317
|
+
print("❌ Unexpected result format")
|
|
318
|
+
print(result)
|
|
319
|
+
return False
|
|
320
|
+
|
|
321
|
+
except Exception as e:
|
|
322
|
+
print(f"❌ Error during graph generation: {e}")
|
|
323
|
+
if verbose:
|
|
324
|
+
import traceback
|
|
325
|
+
|
|
326
|
+
traceback.print_exc()
|
|
327
|
+
return False
|
|
328
|
+
|
|
329
|
+
|
|
330
|
+
def main():
|
|
331
|
+
"""Main function."""
|
|
332
|
+
|
|
333
|
+
args = parse_arguments()
|
|
334
|
+
|
|
335
|
+
print("ToolUniverse Graph Generator")
|
|
336
|
+
print("=" * 60)
|
|
337
|
+
print(f"Timestamp: {datetime.now().strftime('%Y-%m-%d %H:%M:%S')}")
|
|
338
|
+
print()
|
|
339
|
+
|
|
340
|
+
# Initialize ToolUniverse
|
|
341
|
+
if args.verbose:
|
|
342
|
+
print("Initializing ToolUniverse...")
|
|
343
|
+
|
|
344
|
+
try:
|
|
345
|
+
tu = ToolUniverse()
|
|
346
|
+
tu.load_tools()
|
|
347
|
+
|
|
348
|
+
if args.verbose:
|
|
349
|
+
print(f"Loaded {len(tu.all_tool_dict)} tools")
|
|
350
|
+
print(f"Categories: {len(tu.tool_category_dicts)}")
|
|
351
|
+
print()
|
|
352
|
+
|
|
353
|
+
except Exception as e:
|
|
354
|
+
print(f"❌ Failed to initialize ToolUniverse: {e}")
|
|
355
|
+
return 1
|
|
356
|
+
|
|
357
|
+
# Setup parameters
|
|
358
|
+
parameters = setup_analysis_parameters(args)
|
|
359
|
+
|
|
360
|
+
# Show preview
|
|
361
|
+
if not preview_analysis(tu, parameters):
|
|
362
|
+
print("❌ No tools selected for analysis. Check your category filters.")
|
|
363
|
+
return 1
|
|
364
|
+
|
|
365
|
+
# Dry run mode
|
|
366
|
+
if args.dry_run:
|
|
367
|
+
print(
|
|
368
|
+
"\n✅ Dry run complete. Use --force-rebuild to actually generate the graph."
|
|
369
|
+
)
|
|
370
|
+
return 0
|
|
371
|
+
|
|
372
|
+
# Confirmation for large analyses
|
|
373
|
+
total_categories = len(
|
|
374
|
+
[
|
|
375
|
+
cat
|
|
376
|
+
for cat in tu.tool_category_dicts.keys()
|
|
377
|
+
if cat not in parameters.get("exclude_categories", [])
|
|
378
|
+
]
|
|
379
|
+
)
|
|
380
|
+
|
|
381
|
+
if (
|
|
382
|
+
not args.quick
|
|
383
|
+
and total_categories > 5
|
|
384
|
+
and parameters["max_tools_per_category"] > 20
|
|
385
|
+
):
|
|
386
|
+
response = input("\nThis may take a very long time. Continue? (y/N): ")
|
|
387
|
+
if response.lower() != "y":
|
|
388
|
+
print("Cancelled.")
|
|
389
|
+
return 0
|
|
390
|
+
|
|
391
|
+
print("\n" + "=" * 60)
|
|
392
|
+
|
|
393
|
+
# Run the generation
|
|
394
|
+
success = run_graph_generation(tu, parameters, verbose=args.verbose)
|
|
395
|
+
|
|
396
|
+
if success:
|
|
397
|
+
print("\n🎉 Graph generation completed successfully!")
|
|
398
|
+
print(f"Files saved to: {parameters['output_path']}.*")
|
|
399
|
+
print("\nTo visualize the graph, run:")
|
|
400
|
+
print(f"python visualize_tool_graph.py {parameters['output_path']}.json")
|
|
401
|
+
return 0
|
|
402
|
+
else:
|
|
403
|
+
print("\n❌ Graph generation failed.")
|
|
404
|
+
return 1
|
|
405
|
+
|
|
406
|
+
|
|
407
|
+
if __name__ == "__main__":
|
|
408
|
+
sys.exit(main())
|