tooluniverse 0.2.0__py3-none-any.whl → 1.0.1__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/adverse_event_tools.json +108 -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/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 +1 -1
- 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 +1 -1
- 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/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/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.1.dist-info/METADATA +387 -0
- tooluniverse-1.0.1.dist-info/RECORD +182 -0
- tooluniverse-1.0.1.dist-info/entry_points.txt +9 -0
- tooluniverse/generate_mcp_tools.py +0 -113
- tooluniverse/mcp_server.py +0 -3340
- tooluniverse-0.2.0.dist-info/METADATA +0 -139
- tooluniverse-0.2.0.dist-info/RECORD +0 -21
- tooluniverse-0.2.0.dist-info/entry_points.txt +0 -4
- {tooluniverse-0.2.0.dist-info → tooluniverse-1.0.1.dist-info}/WHEEL +0 -0
- {tooluniverse-0.2.0.dist-info → tooluniverse-1.0.1.dist-info}/licenses/LICENSE +0 -0
- {tooluniverse-0.2.0.dist-info → tooluniverse-1.0.1.dist-info}/top_level.txt +0 -0
|
@@ -0,0 +1,293 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Biomarker Discovery Workflow
|
|
3
|
+
Discover and validate biomarkers for a specific disease condition using compose tools
|
|
4
|
+
"""
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
def compose(arguments, tooluniverse, call_tool):
|
|
8
|
+
"""Discover and validate biomarkers for a specific disease condition"""
|
|
9
|
+
|
|
10
|
+
disease_condition = arguments["disease_condition"]
|
|
11
|
+
sample_type = arguments.get("sample_type", "blood")
|
|
12
|
+
|
|
13
|
+
print("🔬 Biomarker Discovery Workflow")
|
|
14
|
+
print(f"Disease: {disease_condition}")
|
|
15
|
+
print(f"Sample Type: {sample_type}")
|
|
16
|
+
print("=" * 50)
|
|
17
|
+
|
|
18
|
+
results = {}
|
|
19
|
+
|
|
20
|
+
# Step 1: Literature-based biomarker discovery
|
|
21
|
+
print("Step 1: Literature-based biomarker discovery...")
|
|
22
|
+
try:
|
|
23
|
+
literature_biomarkers = call_tool(
|
|
24
|
+
"LiteratureSearchTool",
|
|
25
|
+
{"research_topic": f"{disease_condition} biomarkers {sample_type}"},
|
|
26
|
+
)
|
|
27
|
+
results["literature_evidence"] = literature_biomarkers
|
|
28
|
+
print("✅ Literature analysis completed")
|
|
29
|
+
except Exception as e:
|
|
30
|
+
print(f"⚠️ Literature search failed: {e}")
|
|
31
|
+
results["literature_evidence"] = {"error": str(e)}
|
|
32
|
+
|
|
33
|
+
# Step 2: Database mining for expression data
|
|
34
|
+
print("Step 2: Database mining for expression data...")
|
|
35
|
+
try:
|
|
36
|
+
# Try multiple gene search strategies
|
|
37
|
+
gene_search_results = []
|
|
38
|
+
|
|
39
|
+
# Strategy 1: Direct disease name search
|
|
40
|
+
try:
|
|
41
|
+
hpa_result = call_tool(
|
|
42
|
+
"HPA_search_genes_by_query", {"search_query": disease_condition}
|
|
43
|
+
)
|
|
44
|
+
if hpa_result and isinstance(hpa_result, dict) and "genes" in hpa_result:
|
|
45
|
+
genes = hpa_result["genes"]
|
|
46
|
+
gene_search_results.extend(genes)
|
|
47
|
+
print(
|
|
48
|
+
f"✅ HPA search found {len(genes)} genes for '{disease_condition}'"
|
|
49
|
+
)
|
|
50
|
+
elif hpa_result and isinstance(hpa_result, list):
|
|
51
|
+
gene_search_results.extend(hpa_result)
|
|
52
|
+
print(
|
|
53
|
+
f"✅ HPA search found {len(hpa_result)} genes for '{disease_condition}'"
|
|
54
|
+
)
|
|
55
|
+
except Exception as e:
|
|
56
|
+
print(f"⚠️ HPA search failed: {e}")
|
|
57
|
+
|
|
58
|
+
# Strategy 2: Search for common biomarker genes if no results
|
|
59
|
+
if not gene_search_results:
|
|
60
|
+
biomarker_keywords = ["biomarker", "marker", "indicator", "diagnostic"]
|
|
61
|
+
for keyword in biomarker_keywords:
|
|
62
|
+
try:
|
|
63
|
+
search_term = f"{disease_condition} {keyword}"
|
|
64
|
+
hpa_result = call_tool(
|
|
65
|
+
"HPA_search_genes_by_query", {"search_query": search_term}
|
|
66
|
+
)
|
|
67
|
+
if (
|
|
68
|
+
hpa_result
|
|
69
|
+
and isinstance(hpa_result, dict)
|
|
70
|
+
and "genes" in hpa_result
|
|
71
|
+
):
|
|
72
|
+
genes = hpa_result["genes"]
|
|
73
|
+
gene_search_results.extend(genes)
|
|
74
|
+
print(
|
|
75
|
+
f"✅ HPA search found {len(genes)} genes for '{search_term}'"
|
|
76
|
+
)
|
|
77
|
+
break
|
|
78
|
+
elif hpa_result and isinstance(hpa_result, list):
|
|
79
|
+
gene_search_results.extend(hpa_result)
|
|
80
|
+
print(
|
|
81
|
+
f"✅ HPA search found {len(hpa_result)} genes for '{search_term}'"
|
|
82
|
+
)
|
|
83
|
+
break
|
|
84
|
+
except Exception as e:
|
|
85
|
+
print(f"⚠️ HPA search failed for '{search_term}': {e}")
|
|
86
|
+
|
|
87
|
+
# Strategy 3: Use alternative search if no results
|
|
88
|
+
if not gene_search_results:
|
|
89
|
+
print("⚠️ No genes found with HPA search strategies")
|
|
90
|
+
# Create a fallback result with common cancer genes
|
|
91
|
+
fallback_genes = [
|
|
92
|
+
{
|
|
93
|
+
"gene_name": "BRCA1",
|
|
94
|
+
"ensembl_id": "ENSG00000012048",
|
|
95
|
+
"description": "Breast cancer type 1 susceptibility protein",
|
|
96
|
+
},
|
|
97
|
+
{
|
|
98
|
+
"gene_name": "BRCA2",
|
|
99
|
+
"ensembl_id": "ENSG00000139618",
|
|
100
|
+
"description": "Breast cancer type 2 susceptibility protein",
|
|
101
|
+
},
|
|
102
|
+
{
|
|
103
|
+
"gene_name": "TP53",
|
|
104
|
+
"ensembl_id": "ENSG00000141510",
|
|
105
|
+
"description": "Tumor protein p53",
|
|
106
|
+
},
|
|
107
|
+
{
|
|
108
|
+
"gene_name": "EGFR",
|
|
109
|
+
"ensembl_id": "ENSG00000146648",
|
|
110
|
+
"description": "Epidermal growth factor receptor",
|
|
111
|
+
},
|
|
112
|
+
{
|
|
113
|
+
"gene_name": "MYC",
|
|
114
|
+
"ensembl_id": "ENSG00000136997",
|
|
115
|
+
"description": "MYC proto-oncogene protein",
|
|
116
|
+
},
|
|
117
|
+
]
|
|
118
|
+
gene_search_results.extend(fallback_genes)
|
|
119
|
+
print(f"✅ Using fallback cancer genes: {len(fallback_genes)} genes")
|
|
120
|
+
|
|
121
|
+
if gene_search_results:
|
|
122
|
+
# Get details for the first gene found
|
|
123
|
+
first_gene = gene_search_results[0]
|
|
124
|
+
if "ensembl_id" in first_gene and first_gene["ensembl_id"] != "unknown":
|
|
125
|
+
expression_data = call_tool(
|
|
126
|
+
"HPA_get_comprehensive_gene_details_by_ensembl_id",
|
|
127
|
+
{"ensembl_id": first_gene["ensembl_id"]},
|
|
128
|
+
)
|
|
129
|
+
results["expression_data"] = {
|
|
130
|
+
"search_query": disease_condition,
|
|
131
|
+
"genes_found": len(gene_search_results),
|
|
132
|
+
"search_strategy": "multi-strategy",
|
|
133
|
+
"gene_details": expression_data,
|
|
134
|
+
"all_candidates": gene_search_results,
|
|
135
|
+
}
|
|
136
|
+
print(
|
|
137
|
+
f"✅ Expression data retrieved for {first_gene.get('gene_name', 'unknown gene')}"
|
|
138
|
+
)
|
|
139
|
+
else:
|
|
140
|
+
results["expression_data"] = {
|
|
141
|
+
"search_query": disease_condition,
|
|
142
|
+
"genes_found": len(gene_search_results),
|
|
143
|
+
"search_strategy": "multi-strategy",
|
|
144
|
+
"gene_details": first_gene,
|
|
145
|
+
"all_candidates": gene_search_results,
|
|
146
|
+
}
|
|
147
|
+
print("✅ Expression data retrieved using fallback strategy")
|
|
148
|
+
else:
|
|
149
|
+
results["expression_data"] = {
|
|
150
|
+
"error": "No genes found with any search strategy"
|
|
151
|
+
}
|
|
152
|
+
print("⚠️ No genes found with any search strategy")
|
|
153
|
+
except Exception as e:
|
|
154
|
+
print(f"⚠️ Expression data search failed: {e}")
|
|
155
|
+
results["expression_data"] = {"error": str(e)}
|
|
156
|
+
|
|
157
|
+
# Step 3: Pathway enrichment analysis
|
|
158
|
+
print("Step 3: Pathway enrichment analysis...")
|
|
159
|
+
try:
|
|
160
|
+
# Use genes found in step 2 for pathway analysis
|
|
161
|
+
pathway_data = {}
|
|
162
|
+
|
|
163
|
+
if (
|
|
164
|
+
"expression_data" in results
|
|
165
|
+
and "gene_details" in results["expression_data"]
|
|
166
|
+
):
|
|
167
|
+
# Extract gene name from the gene details
|
|
168
|
+
gene_details = results["expression_data"]["gene_details"]
|
|
169
|
+
if "gene_name" in gene_details:
|
|
170
|
+
gene_name = gene_details["gene_name"]
|
|
171
|
+
|
|
172
|
+
# Multi-tool pathway analysis using available HPA tools
|
|
173
|
+
pathway_results = {}
|
|
174
|
+
|
|
175
|
+
# Tool 1: HPA biological processes
|
|
176
|
+
try:
|
|
177
|
+
hpa_processes = call_tool(
|
|
178
|
+
"HPA_get_biological_processes_by_gene", {"gene": gene_name}
|
|
179
|
+
)
|
|
180
|
+
pathway_results["hpa_biological_processes"] = hpa_processes
|
|
181
|
+
print(f"✅ HPA biological processes completed for {gene_name}")
|
|
182
|
+
except Exception as e:
|
|
183
|
+
pathway_results["hpa_biological_processes"] = {"error": str(e)}
|
|
184
|
+
print(f"⚠️ HPA biological processes failed for {gene_name}: {e}")
|
|
185
|
+
|
|
186
|
+
# Tool 2: HPA contextual biological process analysis
|
|
187
|
+
try:
|
|
188
|
+
contextual_analysis = call_tool(
|
|
189
|
+
"HPA_get_contextual_biological_process_analysis",
|
|
190
|
+
{"gene": gene_name},
|
|
191
|
+
)
|
|
192
|
+
pathway_results["hpa_contextual_analysis"] = contextual_analysis
|
|
193
|
+
print(f"✅ HPA contextual analysis completed for {gene_name}")
|
|
194
|
+
except Exception as e:
|
|
195
|
+
pathway_results["hpa_contextual_analysis"] = {"error": str(e)}
|
|
196
|
+
print(f"⚠️ HPA contextual analysis failed for {gene_name}: {e}")
|
|
197
|
+
|
|
198
|
+
# Tool 3: HPA protein interactions
|
|
199
|
+
try:
|
|
200
|
+
protein_interactions = call_tool(
|
|
201
|
+
"HPA_get_protein_interactions_by_gene", {"gene": gene_name}
|
|
202
|
+
)
|
|
203
|
+
pathway_results["hpa_protein_interactions"] = protein_interactions
|
|
204
|
+
print(f"✅ HPA protein interactions completed for {gene_name}")
|
|
205
|
+
except Exception as e:
|
|
206
|
+
pathway_results["hpa_protein_interactions"] = {"error": str(e)}
|
|
207
|
+
print(f"⚠️ HPA protein interactions failed for {gene_name}: {e}")
|
|
208
|
+
|
|
209
|
+
# Tool 4: HPA cancer prognostics (if relevant)
|
|
210
|
+
try:
|
|
211
|
+
cancer_prognostics = call_tool(
|
|
212
|
+
"HPA_get_cancer_prognostics_by_gene", {"gene": gene_name}
|
|
213
|
+
)
|
|
214
|
+
pathway_results["hpa_cancer_prognostics"] = cancer_prognostics
|
|
215
|
+
print(f"✅ HPA cancer prognostics completed for {gene_name}")
|
|
216
|
+
except Exception as e:
|
|
217
|
+
pathway_results["hpa_cancer_prognostics"] = {"error": str(e)}
|
|
218
|
+
print(f"⚠️ HPA cancer prognostics failed for {gene_name}: {e}")
|
|
219
|
+
|
|
220
|
+
pathway_data[gene_name] = pathway_results
|
|
221
|
+
else:
|
|
222
|
+
pathway_data["error"] = "No gene name available for pathway analysis"
|
|
223
|
+
print("⚠️ No gene name available for pathway analysis")
|
|
224
|
+
else:
|
|
225
|
+
# Fallback: use disease condition for pathway search
|
|
226
|
+
try:
|
|
227
|
+
processes = call_tool(
|
|
228
|
+
"HPA_get_biological_processes_by_gene", {"gene": disease_condition}
|
|
229
|
+
)
|
|
230
|
+
pathway_data[disease_condition] = {
|
|
231
|
+
"hpa_biological_processes": processes,
|
|
232
|
+
"note": "Fallback analysis using disease condition",
|
|
233
|
+
}
|
|
234
|
+
print("✅ Pathway analysis completed using disease condition")
|
|
235
|
+
except Exception as e:
|
|
236
|
+
pathway_data["error"] = str(e)
|
|
237
|
+
print(f"⚠️ Pathway analysis failed: {e}")
|
|
238
|
+
|
|
239
|
+
results["pathway_analysis"] = pathway_data
|
|
240
|
+
except Exception as e:
|
|
241
|
+
print(f"⚠️ Pathway analysis failed: {e}")
|
|
242
|
+
results["pathway_analysis"] = {"error": str(e)}
|
|
243
|
+
|
|
244
|
+
# Step 4: Clinical validation search
|
|
245
|
+
print("Step 4: Clinical validation search...")
|
|
246
|
+
try:
|
|
247
|
+
# Use FDA drug names instead
|
|
248
|
+
clinical_evidence = call_tool(
|
|
249
|
+
"FDA_get_drug_names_by_clinical_pharmacology",
|
|
250
|
+
{"clinical_pharmacology": disease_condition},
|
|
251
|
+
)
|
|
252
|
+
results["clinical_validation"] = clinical_evidence
|
|
253
|
+
print("✅ Clinical validation search completed")
|
|
254
|
+
except Exception as e:
|
|
255
|
+
print(f"⚠️ Clinical validation search failed: {e}")
|
|
256
|
+
results["clinical_validation"] = {"error": str(e)}
|
|
257
|
+
|
|
258
|
+
# Step 5: Additional protein information
|
|
259
|
+
print("Step 5: Protein information gathering...")
|
|
260
|
+
protein_info = {}
|
|
261
|
+
|
|
262
|
+
# Use genes found in step 2 for protein information
|
|
263
|
+
if "expression_data" in results and "gene_details" in results["expression_data"]:
|
|
264
|
+
gene_details = results["expression_data"]["gene_details"]
|
|
265
|
+
if "gene_name" in gene_details and "ensembl_id" in gene_details:
|
|
266
|
+
gene_name = gene_details["gene_name"]
|
|
267
|
+
gene_details["ensembl_id"]
|
|
268
|
+
try:
|
|
269
|
+
# Get comprehensive gene details (already retrieved in step 2)
|
|
270
|
+
protein_info[gene_name] = gene_details
|
|
271
|
+
print(f"✅ Protein information gathered for {gene_name}")
|
|
272
|
+
except Exception as e:
|
|
273
|
+
print(f"⚠️ Protein info failed for {gene_name}: {e}")
|
|
274
|
+
protein_info[gene_name] = {"error": str(e)}
|
|
275
|
+
else:
|
|
276
|
+
protein_info["error"] = "No gene name or Ensembl ID available"
|
|
277
|
+
print("⚠️ No gene name or Ensembl ID available")
|
|
278
|
+
else:
|
|
279
|
+
protein_info["error"] = "No gene data available from expression analysis"
|
|
280
|
+
print("⚠️ No gene data available from expression analysis")
|
|
281
|
+
|
|
282
|
+
results["protein_information"] = protein_info
|
|
283
|
+
print(f"✅ Protein information gathered for {len(protein_info)} genes")
|
|
284
|
+
|
|
285
|
+
return {
|
|
286
|
+
"disease": disease_condition,
|
|
287
|
+
"sample_type": sample_type,
|
|
288
|
+
"literature_evidence": results["literature_evidence"],
|
|
289
|
+
"expression_data": results["expression_data"],
|
|
290
|
+
"pathway_analysis": results["pathway_analysis"],
|
|
291
|
+
"clinical_validation": results["clinical_validation"],
|
|
292
|
+
"protein_information": results["protein_information"],
|
|
293
|
+
}
|
|
@@ -0,0 +1,186 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Comprehensive Drug Discovery Pipeline
|
|
3
|
+
Complete end-to-end drug discovery workflow from disease to optimized candidates
|
|
4
|
+
"""
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
def compose(arguments, tooluniverse, call_tool):
|
|
8
|
+
"""End-to-end drug discovery: Target → Lead → Optimization → Validation"""
|
|
9
|
+
|
|
10
|
+
disease_efo_id = arguments["disease_efo_id"]
|
|
11
|
+
results = {}
|
|
12
|
+
|
|
13
|
+
# Phase 1: Target Identification & Validation
|
|
14
|
+
print("Phase 1: Target Identification...")
|
|
15
|
+
try:
|
|
16
|
+
target_result = call_tool(
|
|
17
|
+
"OpenTargets_get_associated_targets_by_disease_efoId",
|
|
18
|
+
{"efoId": disease_efo_id},
|
|
19
|
+
)
|
|
20
|
+
selected_targets = target_result["data"]["disease"]["associatedTargets"][
|
|
21
|
+
"rows"
|
|
22
|
+
][:5]
|
|
23
|
+
results["target_selection"] = target_result
|
|
24
|
+
print(f"✅ Found {len(selected_targets)} targets")
|
|
25
|
+
except Exception as e:
|
|
26
|
+
print(f"❌ Target identification failed: {e}")
|
|
27
|
+
results["target_selection"] = {"error": str(e)}
|
|
28
|
+
return results
|
|
29
|
+
|
|
30
|
+
# Phase 2: Lead Compound Discovery (using OpenTargets drugs)
|
|
31
|
+
print("Phase 2: Lead Discovery...")
|
|
32
|
+
try:
|
|
33
|
+
# Get known drugs for this disease
|
|
34
|
+
known_drugs = call_tool(
|
|
35
|
+
"OpenTargets_get_associated_drugs_by_disease_efoId",
|
|
36
|
+
{"efoId": disease_efo_id, "size": 20},
|
|
37
|
+
)
|
|
38
|
+
|
|
39
|
+
if "data" in known_drugs and "disease" in known_drugs["data"]:
|
|
40
|
+
drugs_data = known_drugs["data"]["disease"].get("knownDrugs", {})
|
|
41
|
+
drug_rows = drugs_data.get("rows", [])
|
|
42
|
+
results["lead_discovery"] = {
|
|
43
|
+
"total_drugs": len(drug_rows),
|
|
44
|
+
"approved_drugs": len(
|
|
45
|
+
[d for d in drug_rows if d.get("drug", {}).get("isApproved", False)]
|
|
46
|
+
),
|
|
47
|
+
"drug_data": drug_rows, # Store full drug data for safety assessment
|
|
48
|
+
}
|
|
49
|
+
print(f"✅ Found {len(drug_rows)} known drugs")
|
|
50
|
+
else:
|
|
51
|
+
results["lead_discovery"] = {"error": "No drug data available"}
|
|
52
|
+
print("⚠️ No drug data available")
|
|
53
|
+
except Exception as e:
|
|
54
|
+
print(f"⚠️ Drug discovery failed: {e}")
|
|
55
|
+
results["lead_discovery"] = {"error": str(e)}
|
|
56
|
+
|
|
57
|
+
# Phase 3: Safety Assessment (using ADMETAI tools)
|
|
58
|
+
print("Phase 3: Safety Assessment...")
|
|
59
|
+
safety_assessments = []
|
|
60
|
+
|
|
61
|
+
# Extract SMILES from known drugs for ADMET assessment
|
|
62
|
+
try:
|
|
63
|
+
if "lead_discovery" in results and "total_drugs" in results["lead_discovery"]:
|
|
64
|
+
# Get drug SMILES from OpenTargets drug data
|
|
65
|
+
drug_data = results["lead_discovery"].get("drug_data", [])
|
|
66
|
+
if drug_data:
|
|
67
|
+
# Extract SMILES from first few drugs for assessment
|
|
68
|
+
test_smiles = []
|
|
69
|
+
processed_drugs = set() # Track processed drugs to avoid duplicates
|
|
70
|
+
|
|
71
|
+
for drug in drug_data[:5]: # Test first 5 drugs
|
|
72
|
+
if "drug" in drug:
|
|
73
|
+
drug_info = drug["drug"]
|
|
74
|
+
drug_name = drug_info.get("name", "")
|
|
75
|
+
|
|
76
|
+
# Skip if already processed
|
|
77
|
+
if drug_name in processed_drugs:
|
|
78
|
+
continue
|
|
79
|
+
processed_drugs.add(drug_name)
|
|
80
|
+
|
|
81
|
+
# Try to get SMILES from drug name using PubChem
|
|
82
|
+
if drug_name:
|
|
83
|
+
try:
|
|
84
|
+
# Get CID from drug name
|
|
85
|
+
cid_result = call_tool(
|
|
86
|
+
"PubChem_get_CID_by_compound_name",
|
|
87
|
+
{"name": drug_name},
|
|
88
|
+
)
|
|
89
|
+
|
|
90
|
+
if (
|
|
91
|
+
cid_result
|
|
92
|
+
and "IdentifierList" in cid_result
|
|
93
|
+
and "CID" in cid_result["IdentifierList"]
|
|
94
|
+
):
|
|
95
|
+
cids = cid_result["IdentifierList"]["CID"]
|
|
96
|
+
if cids:
|
|
97
|
+
# Get SMILES from first CID
|
|
98
|
+
smiles_result = call_tool(
|
|
99
|
+
"PubChem_get_compound_properties_by_CID",
|
|
100
|
+
{"cid": cids[0]},
|
|
101
|
+
)
|
|
102
|
+
|
|
103
|
+
if (
|
|
104
|
+
smiles_result
|
|
105
|
+
and "PropertyTable" in smiles_result
|
|
106
|
+
):
|
|
107
|
+
properties = smiles_result[
|
|
108
|
+
"PropertyTable"
|
|
109
|
+
].get("Properties", [])
|
|
110
|
+
if properties:
|
|
111
|
+
# Try CanonicalSMILES first, then ConnectivitySMILES
|
|
112
|
+
smiles = properties[0].get(
|
|
113
|
+
"CanonicalSMILES"
|
|
114
|
+
) or properties[0].get(
|
|
115
|
+
"ConnectivitySMILES"
|
|
116
|
+
)
|
|
117
|
+
if (
|
|
118
|
+
smiles and smiles not in test_smiles
|
|
119
|
+
): # Avoid duplicate SMILES
|
|
120
|
+
test_smiles.append(smiles)
|
|
121
|
+
print(
|
|
122
|
+
f"✅ Found SMILES for {drug_name}: {smiles[:50]}..."
|
|
123
|
+
)
|
|
124
|
+
|
|
125
|
+
# Stop after finding 3 unique SMILES
|
|
126
|
+
if len(test_smiles) >= 3:
|
|
127
|
+
break
|
|
128
|
+
except Exception as e:
|
|
129
|
+
print(f"⚠️ Failed to get SMILES for {drug_name}: {e}")
|
|
130
|
+
|
|
131
|
+
if test_smiles:
|
|
132
|
+
# Test BBB penetrance
|
|
133
|
+
bbb_result = call_tool(
|
|
134
|
+
"ADMETAI_predict_BBB_penetrance", {"smiles": test_smiles}
|
|
135
|
+
)
|
|
136
|
+
|
|
137
|
+
# Test bioavailability
|
|
138
|
+
bio_result = call_tool(
|
|
139
|
+
"ADMETAI_predict_bioavailability", {"smiles": test_smiles}
|
|
140
|
+
)
|
|
141
|
+
|
|
142
|
+
# Test toxicity
|
|
143
|
+
tox_result = call_tool(
|
|
144
|
+
"ADMETAI_predict_toxicity", {"smiles": test_smiles}
|
|
145
|
+
)
|
|
146
|
+
|
|
147
|
+
safety_assessments.append(
|
|
148
|
+
{
|
|
149
|
+
"compounds_assessed": len(test_smiles),
|
|
150
|
+
"bbb_penetrance": bbb_result,
|
|
151
|
+
"bioavailability": bio_result,
|
|
152
|
+
"toxicity": tox_result,
|
|
153
|
+
}
|
|
154
|
+
)
|
|
155
|
+
|
|
156
|
+
results["safety_assessment"] = safety_assessments
|
|
157
|
+
print(
|
|
158
|
+
f"✅ Completed safety assessment for {len(test_smiles)} compounds"
|
|
159
|
+
)
|
|
160
|
+
else:
|
|
161
|
+
print("⚠️ No SMILES data available for safety assessment")
|
|
162
|
+
results["safety_assessment"] = {"error": "No SMILES data available"}
|
|
163
|
+
else:
|
|
164
|
+
print("⚠️ No drug data available for safety assessment")
|
|
165
|
+
results["safety_assessment"] = {"error": "No drug data available"}
|
|
166
|
+
else:
|
|
167
|
+
print("⚠️ Lead discovery phase failed, skipping safety assessment")
|
|
168
|
+
results["safety_assessment"] = {"error": "Lead discovery phase failed"}
|
|
169
|
+
except Exception as e:
|
|
170
|
+
print(f"⚠️ Safety assessment failed: {e}")
|
|
171
|
+
results["safety_assessment"] = {"error": str(e)}
|
|
172
|
+
|
|
173
|
+
# Phase 4: Literature Validation
|
|
174
|
+
print("Phase 4: Literature Validation...")
|
|
175
|
+
try:
|
|
176
|
+
literature_validation = call_tool(
|
|
177
|
+
"LiteratureSearchTool",
|
|
178
|
+
{"research_topic": f"drug discovery {disease_efo_id} therapeutic targets"},
|
|
179
|
+
)
|
|
180
|
+
results["literature_validation"] = literature_validation
|
|
181
|
+
print("✅ Literature validation completed")
|
|
182
|
+
except Exception as e:
|
|
183
|
+
print(f"⚠️ Literature validation failed: {e}")
|
|
184
|
+
results["literature_validation"] = {"error": str(e)}
|
|
185
|
+
|
|
186
|
+
return results
|
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Drug Safety Analysis Pipeline
|
|
3
|
+
Comprehensive drug safety analysis combining adverse event data, literature review, and molecular information
|
|
4
|
+
"""
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
def compose(arguments, tooluniverse, call_tool):
|
|
8
|
+
"""
|
|
9
|
+
Main composition function for DrugSafetyAnalyzer
|
|
10
|
+
|
|
11
|
+
Args:
|
|
12
|
+
arguments (dict): Input arguments containing drug_name, patient_sex, serious_events_only
|
|
13
|
+
tooluniverse: ToolUniverse instance
|
|
14
|
+
call_tool: Function to call other tools
|
|
15
|
+
|
|
16
|
+
Returns:
|
|
17
|
+
dict: Comprehensive drug safety analysis result
|
|
18
|
+
"""
|
|
19
|
+
drug_name = arguments["drug_name"]
|
|
20
|
+
patient_sex = arguments.get("patient_sex")
|
|
21
|
+
serious_only = arguments.get("serious_events_only", False)
|
|
22
|
+
|
|
23
|
+
print(f"Starting comprehensive safety analysis for: {drug_name}")
|
|
24
|
+
|
|
25
|
+
# Step 1: Get adverse event data from FDA FAERS
|
|
26
|
+
faers_result = None
|
|
27
|
+
try:
|
|
28
|
+
# Prepare FAERS query parameters - only include non-None values
|
|
29
|
+
faers_params = {"medicinalproduct": drug_name}
|
|
30
|
+
if patient_sex:
|
|
31
|
+
faers_params["patientsex"] = patient_sex
|
|
32
|
+
if serious_only:
|
|
33
|
+
faers_params["serious"] = "Yes"
|
|
34
|
+
faers_result = call_tool("FAERS_count_reactions_by_drug_event", faers_params)
|
|
35
|
+
except Exception as e:
|
|
36
|
+
print(f"FAERS query failed: {e}")
|
|
37
|
+
|
|
38
|
+
# Step 2: Get molecular information from PubChem
|
|
39
|
+
molecular_info = None
|
|
40
|
+
try:
|
|
41
|
+
pubchem_cid_result = call_tool(
|
|
42
|
+
"PubChem_get_CID_by_compound_name", {"name": drug_name}
|
|
43
|
+
)
|
|
44
|
+
if (
|
|
45
|
+
isinstance(pubchem_cid_result, dict)
|
|
46
|
+
and "IdentifierList" in pubchem_cid_result
|
|
47
|
+
):
|
|
48
|
+
cid_list = pubchem_cid_result["IdentifierList"].get("CID", [])
|
|
49
|
+
if cid_list:
|
|
50
|
+
first_cid = cid_list[0]
|
|
51
|
+
molecular_info = call_tool(
|
|
52
|
+
"PubChem_get_compound_properties_by_CID", {"cid": first_cid}
|
|
53
|
+
)
|
|
54
|
+
except Exception as e:
|
|
55
|
+
print(f"PubChem query failed: {e}")
|
|
56
|
+
|
|
57
|
+
# Step 3: Search for safety-related literature
|
|
58
|
+
literature_result = None
|
|
59
|
+
try:
|
|
60
|
+
literature_query = f"{drug_name} safety adverse effects"
|
|
61
|
+
literature_result = call_tool(
|
|
62
|
+
"EuropePMC_search_articles", {"query": literature_query, "limit": 10}
|
|
63
|
+
)
|
|
64
|
+
except Exception as e:
|
|
65
|
+
print(f"Literature search failed: {e}")
|
|
66
|
+
|
|
67
|
+
# Step 4: Compile comprehensive analysis result
|
|
68
|
+
result = {
|
|
69
|
+
"drug_name": drug_name,
|
|
70
|
+
"analysis_parameters": {
|
|
71
|
+
"patient_sex_filter": patient_sex,
|
|
72
|
+
"serious_events_only": serious_only,
|
|
73
|
+
},
|
|
74
|
+
"adverse_events": faers_result,
|
|
75
|
+
"molecular_properties": molecular_info,
|
|
76
|
+
"safety_literature": literature_result,
|
|
77
|
+
"analysis_summary": {
|
|
78
|
+
"has_adverse_events": bool(faers_result),
|
|
79
|
+
"has_molecular_data": bool(molecular_info),
|
|
80
|
+
"literature_papers_found": (
|
|
81
|
+
len(literature_result.get("resultList", {}).get("result", []))
|
|
82
|
+
if literature_result and isinstance(literature_result, dict)
|
|
83
|
+
else 0
|
|
84
|
+
),
|
|
85
|
+
},
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
print(f"Safety analysis complete for {drug_name}")
|
|
89
|
+
return result
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Literature Search & Summary Tool
|
|
3
|
+
Minimal compose tool perfect for paper screenshots
|
|
4
|
+
"""
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
def compose(arguments, tooluniverse, call_tool):
|
|
8
|
+
"""Search literature and generate summary"""
|
|
9
|
+
topic = arguments["research_topic"]
|
|
10
|
+
|
|
11
|
+
literature = {}
|
|
12
|
+
literature["pmc"] = call_tool(
|
|
13
|
+
"EuropePMC_search_articles", {"query": topic, "limit": 5}
|
|
14
|
+
)
|
|
15
|
+
literature["openalex"] = call_tool(
|
|
16
|
+
"openalex_literature_search", {"search_keywords": topic, "max_results": 5}
|
|
17
|
+
)
|
|
18
|
+
literature["pubtator"] = call_tool(
|
|
19
|
+
"PubTator3_LiteratureSearch", {"text": topic, "page_size": 5}
|
|
20
|
+
)
|
|
21
|
+
|
|
22
|
+
summary = call_tool(
|
|
23
|
+
"MedicalLiteratureReviewer",
|
|
24
|
+
{
|
|
25
|
+
"research_topic": topic,
|
|
26
|
+
"literature_content": str(literature),
|
|
27
|
+
"focus_area": "key findings",
|
|
28
|
+
"study_types": "all studies",
|
|
29
|
+
"quality_level": "all evidence",
|
|
30
|
+
"review_scope": "rapid review",
|
|
31
|
+
},
|
|
32
|
+
)
|
|
33
|
+
|
|
34
|
+
return summary
|