tooluniverse 1.0.6__py3-none-any.whl → 1.0.8__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 +56 -10
- tooluniverse/admetai_tool.py +8 -4
- tooluniverse/agentic_tool.py +40 -4
- tooluniverse/arxiv_tool.py +2 -6
- tooluniverse/base_tool.py +210 -25
- tooluniverse/biogrid_tool.py +118 -0
- tooluniverse/biorxiv_tool.py +35 -16
- tooluniverse/build_optimizer.py +87 -0
- tooluniverse/cache/__init__.py +3 -0
- tooluniverse/cache/memory_cache.py +99 -0
- tooluniverse/cache/result_cache_manager.py +235 -0
- tooluniverse/cache/sqlite_backend.py +257 -0
- tooluniverse/cellosaurus_tool.py +1332 -0
- tooluniverse/clinvar_tool.py +90 -0
- tooluniverse/compose_scripts/enhanced_multi_agent_literature_search.py +310 -0
- tooluniverse/compose_scripts/multi_agent_literature_search.py +794 -0
- tooluniverse/compose_scripts/tool_graph_generation.py +68 -35
- tooluniverse/compose_scripts/tool_metadata_generator.py +205 -105
- tooluniverse/compose_tool.py +93 -8
- tooluniverse/core_tool.py +46 -44
- tooluniverse/crossref_tool.py +89 -4
- tooluniverse/custom_tool.py +28 -0
- tooluniverse/data/agentic_tools.json +1271 -1179
- tooluniverse/data/alphafold_tools.json +356 -105
- tooluniverse/data/arxiv_tools.json +85 -81
- tooluniverse/data/biorxiv_tools.json +69 -64
- tooluniverse/data/cellosaurus_tools.json +260 -0
- tooluniverse/data/chembl_tools.json +27 -12
- tooluniverse/data/clinicaltrials_gov_tools.json +377 -302
- tooluniverse/data/compose_tools.json +123 -16
- tooluniverse/data/core_tools.json +104 -99
- tooluniverse/data/crossref_tools.json +131 -63
- tooluniverse/data/dailymed_tools.json +17 -3
- tooluniverse/data/dataset_tools.json +1031 -588
- tooluniverse/data/dblp_tools.json +135 -64
- tooluniverse/data/disease_target_score_tools.json +20 -10
- tooluniverse/data/doaj_tools.json +131 -87
- tooluniverse/data/drug_discovery_agents.json +292 -0
- tooluniverse/data/embedding_tools.json +362 -299
- tooluniverse/data/enrichr_tools.json +34 -27
- tooluniverse/data/europe_pmc_tools.json +107 -16
- tooluniverse/data/fatcat_tools.json +71 -66
- tooluniverse/data/fda_drug_adverse_event_tools.json +1061 -445
- tooluniverse/data/fda_drug_labeling_tools.json +6858 -6901
- tooluniverse/data/finder_tools.json +32 -37
- tooluniverse/data/gene_ontology_tools.json +19 -7
- tooluniverse/data/genomics_tools.json +174 -0
- tooluniverse/data/geo_tools.json +86 -0
- tooluniverse/data/gwas_tools.json +1720 -959
- tooluniverse/data/hal_tools.json +69 -64
- tooluniverse/data/hpa_tools.json +53 -14
- tooluniverse/data/humanbase_tools.json +51 -43
- tooluniverse/data/idmap_tools.json +76 -70
- tooluniverse/data/literature_search_tools.json +306 -0
- tooluniverse/data/markitdown_tools.json +51 -0
- tooluniverse/data/mcp_client_tools_example.json +122 -107
- tooluniverse/data/medlineplus_tools.json +50 -10
- tooluniverse/data/medrxiv_tools.json +69 -64
- tooluniverse/data/molecule_2d_tools.json +134 -0
- tooluniverse/data/molecule_3d_tools.json +164 -0
- tooluniverse/data/monarch_tools.json +112 -110
- tooluniverse/data/odphp_tools.json +389 -119
- tooluniverse/data/openaire_tools.json +89 -79
- tooluniverse/data/openalex_tools.json +96 -31
- tooluniverse/data/opentarget_tools.json +1457 -1372
- tooluniverse/data/osf_preprints_tools.json +77 -73
- tooluniverse/data/packages/bioinformatics_core_tools.json +40 -10
- tooluniverse/data/packages/cheminformatics_tools.json +20 -5
- tooluniverse/data/packages/genomics_tools.json +36 -9
- tooluniverse/data/packages/machine_learning_tools.json +36 -9
- tooluniverse/data/packages/scientific_computing_tools.json +20 -5
- tooluniverse/data/packages/single_cell_tools.json +20 -5
- tooluniverse/data/packages/structural_biology_tools.json +16 -4
- tooluniverse/data/packages/visualization_tools.json +20 -5
- tooluniverse/data/pmc_tools.json +108 -103
- tooluniverse/data/ppi_tools.json +139 -0
- tooluniverse/data/protein_structure_3d_tools.json +138 -0
- tooluniverse/data/pubchem_tools.json +37 -12
- tooluniverse/data/pubmed_tools.json +124 -58
- tooluniverse/data/pubtator_tools.json +68 -60
- tooluniverse/data/rcsb_pdb_tools.json +1532 -1221
- tooluniverse/data/semantic_scholar_tools.json +54 -22
- tooluniverse/data/special_tools.json +8 -6
- tooluniverse/data/tool_composition_tools.json +112 -82
- tooluniverse/data/unified_guideline_tools.json +909 -0
- tooluniverse/data/url_fetch_tools.json +102 -82
- tooluniverse/data/uspto_tools.json +49 -30
- tooluniverse/data/wikidata_sparql_tools.json +42 -39
- tooluniverse/data/xml_tools.json +3274 -3113
- tooluniverse/data/zenodo_tools.json +83 -76
- tooluniverse/dblp_tool.py +76 -6
- tooluniverse/dbsnp_tool.py +71 -0
- tooluniverse/default_config.py +19 -0
- tooluniverse/doaj_tool.py +76 -17
- tooluniverse/doctor.py +48 -0
- tooluniverse/ensembl_tool.py +61 -0
- tooluniverse/europe_pmc_tool.py +132 -17
- tooluniverse/exceptions.py +170 -0
- tooluniverse/execute_function.py +930 -387
- tooluniverse/fatcat_tool.py +0 -1
- tooluniverse/generate_tools.py +481 -0
- tooluniverse/genomics_gene_search_tool.py +56 -0
- tooluniverse/geo_tool.py +116 -0
- tooluniverse/gnomad_tool.py +63 -0
- tooluniverse/hal_tool.py +1 -1
- tooluniverse/llm_clients.py +101 -124
- tooluniverse/markitdown_tool.py +159 -0
- tooluniverse/mcp_client_tool.py +10 -5
- tooluniverse/mcp_tool_registry.py +4 -1
- tooluniverse/medrxiv_tool.py +32 -13
- tooluniverse/memory_manager.py +166 -0
- tooluniverse/molecule_2d_tool.py +274 -0
- tooluniverse/molecule_3d_tool.py +441 -0
- tooluniverse/odphp_tool.py +49 -14
- tooluniverse/openaire_tool.py +5 -20
- tooluniverse/openalex_tool.py +34 -0
- tooluniverse/osf_preprints_tool.py +1 -1
- tooluniverse/pmc_tool.py +54 -56
- tooluniverse/protein_structure_3d_tool.py +295 -0
- tooluniverse/pubmed_tool.py +69 -6
- tooluniverse/remote/boltz/boltz_mcp_server.py +3 -1
- tooluniverse/remote/uspto_downloader/uspto_downloader_mcp_server.py +3 -1
- tooluniverse/semantic_scholar_tool.py +40 -10
- tooluniverse/smcp.py +149 -213
- tooluniverse/smcp_server.py +97 -55
- tooluniverse/string_tool.py +112 -0
- tooluniverse/tool_registry.py +35 -3
- tooluniverse/tools/ADMETAI_predict_BBB_penetrance.py +46 -0
- tooluniverse/tools/ADMETAI_predict_CYP_interactions.py +46 -0
- tooluniverse/tools/ADMETAI_predict_bioavailability.py +46 -0
- tooluniverse/tools/ADMETAI_predict_clearance_distribution.py +49 -0
- tooluniverse/tools/ADMETAI_predict_nuclear_receptor_activity.py +49 -0
- tooluniverse/tools/ADMETAI_predict_physicochemical_properties.py +49 -0
- tooluniverse/tools/ADMETAI_predict_solubility_lipophilicity_hydration.py +49 -0
- tooluniverse/tools/ADMETAI_predict_stress_response.py +46 -0
- tooluniverse/tools/ADMETAI_predict_toxicity.py +46 -0
- tooluniverse/tools/ADMETAnalyzerAgent.py +59 -0
- tooluniverse/tools/AdvancedCodeQualityAnalyzer.py +63 -0
- tooluniverse/tools/AdverseEventICDMapper.py +46 -0
- tooluniverse/tools/AdverseEventPredictionQuestionGenerator.py +52 -0
- tooluniverse/tools/AdverseEventPredictionQuestionGeneratorWithContext.py +59 -0
- tooluniverse/tools/ArXiv_search_papers.py +63 -0
- tooluniverse/tools/ArgumentDescriptionOptimizer.py +55 -0
- tooluniverse/tools/BioRxiv_search_preprints.py +52 -0
- tooluniverse/tools/BiomarkerDiscoveryWorkflow.py +55 -0
- tooluniverse/tools/CMA_Guidelines_Search.py +52 -0
- tooluniverse/tools/CORE_search_papers.py +67 -0
- tooluniverse/tools/CallAgent.py +46 -0
- tooluniverse/tools/ChEMBL_search_similar_molecules.py +59 -0
- tooluniverse/tools/ClinVar_search_variants.py +52 -0
- tooluniverse/tools/ClinicalTrialDesignAgent.py +63 -0
- tooluniverse/tools/CodeOptimizer.py +55 -0
- tooluniverse/tools/CodeQualityAnalyzer.py +71 -0
- tooluniverse/tools/CompoundDiscoveryAgent.py +59 -0
- tooluniverse/tools/ComprehensiveDrugDiscoveryPipeline.py +49 -0
- tooluniverse/tools/Crossref_search_works.py +55 -0
- tooluniverse/tools/DBLP_search_publications.py +52 -0
- tooluniverse/tools/DOAJ_search_articles.py +55 -0
- tooluniverse/tools/DailyMed_get_spl_by_setid.py +52 -0
- tooluniverse/tools/DailyMed_search_spls.py +79 -0
- tooluniverse/tools/DataAnalysisValidityReviewer.py +49 -0
- tooluniverse/tools/DescriptionAnalyzer.py +55 -0
- tooluniverse/tools/DescriptionQualityEvaluator.py +59 -0
- tooluniverse/tools/DiseaseAnalyzerAgent.py +52 -0
- tooluniverse/tools/DomainExpertValidator.py +63 -0
- tooluniverse/tools/DrugInteractionAnalyzerAgent.py +52 -0
- tooluniverse/tools/DrugOptimizationAgent.py +63 -0
- tooluniverse/tools/DrugSafetyAnalyzer.py +59 -0
- tooluniverse/tools/Ensembl_lookup_gene_by_symbol.py +52 -0
- tooluniverse/tools/EthicalComplianceReviewer.py +49 -0
- tooluniverse/tools/EuropePMC_Guidelines_Search.py +52 -0
- tooluniverse/tools/EuropePMC_search_articles.py +52 -0
- tooluniverse/tools/ExperimentalDesignScorer.py +55 -0
- tooluniverse/tools/FAERS_count_additive_administration_routes.py +52 -0
- tooluniverse/tools/FAERS_count_additive_adverse_reactions.py +71 -0
- tooluniverse/tools/FAERS_count_additive_event_reports_by_country.py +63 -0
- tooluniverse/tools/FAERS_count_additive_reaction_outcomes.py +63 -0
- tooluniverse/tools/FAERS_count_additive_reports_by_reporter_country.py +63 -0
- tooluniverse/tools/FAERS_count_additive_seriousness_classification.py +63 -0
- tooluniverse/tools/FAERS_count_country_by_drug_event.py +63 -0
- tooluniverse/tools/FAERS_count_death_related_by_drug.py +49 -0
- tooluniverse/tools/FAERS_count_drug_routes_by_event.py +52 -0
- tooluniverse/tools/FAERS_count_drugs_by_drug_event.py +63 -0
- tooluniverse/tools/FAERS_count_outcomes_by_drug_event.py +63 -0
- tooluniverse/tools/FAERS_count_patient_age_distribution.py +49 -0
- tooluniverse/tools/FAERS_count_reactions_by_drug_event.py +71 -0
- tooluniverse/tools/FAERS_count_reportercountry_by_drug_event.py +63 -0
- tooluniverse/tools/FAERS_count_seriousness_by_drug_event.py +63 -0
- tooluniverse/tools/FDA_get_abuse_dependence_info_by_drug_name.py +55 -0
- tooluniverse/tools/FDA_get_abuse_info_by_drug_name.py +55 -0
- tooluniverse/tools/FDA_get_accessories_info_by_drug_name.py +55 -0
- tooluniverse/tools/FDA_get_active_ingredient_info_by_drug_name.py +55 -0
- tooluniverse/tools/FDA_get_adverse_reactions_by_drug_name.py +55 -0
- tooluniverse/tools/FDA_get_alarms_by_drug_name.py +55 -0
- tooluniverse/tools/FDA_get_animal_pharmacology_info_by_drug_name.py +55 -0
- tooluniverse/tools/FDA_get_assembly_installation_info_by_drug_name.py +55 -0
- tooluniverse/tools/FDA_get_boxed_warning_info_by_drug_name.py +55 -0
- tooluniverse/tools/FDA_get_brand_name_generic_name.py +52 -0
- tooluniverse/tools/FDA_get_calibration_instructions_by_drug_name.py +55 -0
- tooluniverse/tools/FDA_get_carcinogenic_mutagenic_fertility_by_drug_name.py +55 -0
- tooluniverse/tools/FDA_get_child_safety_info_by_drug_name.py +55 -0
- tooluniverse/tools/FDA_get_clinical_pharmacology_by_drug_name.py +55 -0
- tooluniverse/tools/FDA_get_clinical_studies_info_by_drug_name.py +55 -0
- tooluniverse/tools/FDA_get_contact_for_questions_info_by_drug_name.py +55 -0
- tooluniverse/tools/FDA_get_contraindications_by_drug_name.py +55 -0
- tooluniverse/tools/FDA_get_controlled_substance_DEA_schedule_info_by_drug_name.py +55 -0
- tooluniverse/tools/FDA_get_dear_health_care_provider_letter_info_by_drug_name.py +55 -0
- tooluniverse/tools/FDA_get_dependence_info_by_drug_name.py +55 -0
- tooluniverse/tools/FDA_get_disposal_info_by_drug_name.py +55 -0
- tooluniverse/tools/FDA_get_do_not_use_info_by_drug_name.py +55 -0
- tooluniverse/tools/FDA_get_document_id_by_drug_name.py +55 -0
- tooluniverse/tools/FDA_get_dosage_and_storage_information_by_drug_name.py +55 -0
- tooluniverse/tools/FDA_get_dosage_forms_and_strengths_by_drug_name.py +55 -0
- tooluniverse/tools/FDA_get_drug_generic_name.py +46 -0
- tooluniverse/tools/FDA_get_drug_interactions_by_drug_name.py +55 -0
- tooluniverse/tools/FDA_get_drug_name_by_SPL_ID.py +55 -0
- tooluniverse/tools/FDA_get_drug_name_by_adverse_reaction.py +59 -0
- tooluniverse/tools/FDA_get_drug_name_by_calibration_instructions.py +59 -0
- tooluniverse/tools/FDA_get_drug_name_by_dependence_info.py +59 -0
- tooluniverse/tools/FDA_get_drug_name_by_document_id.py +55 -0
- tooluniverse/tools/FDA_get_drug_name_by_dosage_info.py +55 -0
- tooluniverse/tools/FDA_get_drug_name_by_environmental_warning.py +59 -0
- tooluniverse/tools/FDA_get_drug_name_by_inactive_ingredient.py +59 -0
- tooluniverse/tools/FDA_get_drug_name_by_info_on_conditions_for_doctor_consultation.py +55 -0
- tooluniverse/tools/FDA_get_drug_name_by_labor_and_delivery_info.py +59 -0
- tooluniverse/tools/FDA_get_drug_name_by_microbiology.py +59 -0
- tooluniverse/tools/FDA_get_drug_name_by_other_safety_info.py +55 -0
- tooluniverse/tools/FDA_get_drug_name_by_pharmacodynamics.py +59 -0
- tooluniverse/tools/FDA_get_drug_name_by_pharmacogenomics.py +59 -0
- tooluniverse/tools/FDA_get_drug_name_by_precautions.py +55 -0
- tooluniverse/tools/FDA_get_drug_name_by_pregnancy_or_breastfeeding_info.py +59 -0
- tooluniverse/tools/FDA_get_drug_name_by_principal_display_panel.py +59 -0
- tooluniverse/tools/FDA_get_drug_name_by_reference.py +55 -0
- tooluniverse/tools/FDA_get_drug_name_by_set_id.py +55 -0
- tooluniverse/tools/FDA_get_drug_name_by_stop_use_info.py +55 -0
- tooluniverse/tools/FDA_get_drug_name_by_storage_and_handling_info.py +55 -0
- tooluniverse/tools/FDA_get_drug_name_by_warnings.py +55 -0
- tooluniverse/tools/FDA_get_drug_name_from_patient_package_insert.py +59 -0
- tooluniverse/tools/FDA_get_drug_names_by_abuse_dependence_info.py +55 -0
- tooluniverse/tools/FDA_get_drug_names_by_abuse_info.py +63 -0
- tooluniverse/tools/FDA_get_drug_names_by_accessories.py +63 -0
- tooluniverse/tools/FDA_get_drug_names_by_active_ingredient.py +63 -0
- tooluniverse/tools/FDA_get_drug_names_by_alarm.py +63 -0
- tooluniverse/tools/FDA_get_drug_names_by_animal_pharmacology_info.py +63 -0
- tooluniverse/tools/FDA_get_drug_names_by_application_number_NDC_number.py +59 -0
- tooluniverse/tools/FDA_get_drug_names_by_assembly_installation_info.py +63 -0
- tooluniverse/tools/FDA_get_drug_names_by_boxed_warning.py +63 -0
- tooluniverse/tools/FDA_get_drug_names_by_child_safety_info.py +63 -0
- tooluniverse/tools/FDA_get_drug_names_by_clinical_pharmacology.py +63 -0
- tooluniverse/tools/FDA_get_drug_names_by_clinical_studies.py +63 -0
- tooluniverse/tools/FDA_get_drug_names_by_consulting_doctor_pharmacist_info.py +63 -0
- tooluniverse/tools/FDA_get_drug_names_by_contraindications.py +63 -0
- tooluniverse/tools/FDA_get_drug_names_by_controlled_substance_DEA_schedule.py +63 -0
- tooluniverse/tools/FDA_get_drug_names_by_dear_health_care_provider_letter_info.py +63 -0
- tooluniverse/tools/FDA_get_drug_names_by_disposal_info.py +63 -0
- tooluniverse/tools/FDA_get_drug_names_by_dosage_forms_and_strengths_info.py +63 -0
- tooluniverse/tools/FDA_get_drug_names_by_drug_interactions.py +63 -0
- tooluniverse/tools/FDA_get_drug_names_by_effective_time.py +63 -0
- tooluniverse/tools/FDA_get_drug_names_by_food_safety_warnings.py +63 -0
- tooluniverse/tools/FDA_get_drug_names_by_general_precautions.py +63 -0
- tooluniverse/tools/FDA_get_drug_names_by_geriatric_use.py +63 -0
- tooluniverse/tools/FDA_get_drug_names_by_health_claim.py +63 -0
- tooluniverse/tools/FDA_get_drug_names_by_indication.py +55 -0
- tooluniverse/tools/FDA_get_drug_names_by_info_for_nursing_mothers.py +63 -0
- tooluniverse/tools/FDA_get_drug_names_by_information_for_owners_or_caregivers.py +63 -0
- tooluniverse/tools/FDA_get_drug_names_by_ingredient.py +63 -0
- tooluniverse/tools/FDA_get_drug_names_by_instructions_for_use.py +63 -0
- tooluniverse/tools/FDA_get_drug_names_by_lab_test_interference.py +63 -0
- tooluniverse/tools/FDA_get_drug_names_by_lab_tests.py +63 -0
- tooluniverse/tools/FDA_get_drug_names_by_mechanism_of_action.py +63 -0
- tooluniverse/tools/FDA_get_drug_names_by_medication_guide.py +63 -0
- tooluniverse/tools/FDA_get_drug_names_by_nonclinical_toxicology_info.py +63 -0
- tooluniverse/tools/FDA_get_drug_names_by_nonteratogenic_effects.py +63 -0
- tooluniverse/tools/FDA_get_drug_names_by_overdosage_info.py +63 -0
- tooluniverse/tools/FDA_get_drug_names_by_pediatric_use.py +63 -0
- tooluniverse/tools/FDA_get_drug_names_by_pharmacokinetics.py +63 -0
- tooluniverse/tools/FDA_get_drug_names_by_population_use.py +63 -0
- tooluniverse/tools/FDA_get_drug_names_by_pregnancy_effects_info.py +63 -0
- tooluniverse/tools/FDA_get_drug_names_by_residue_warning.py +63 -0
- tooluniverse/tools/FDA_get_drug_names_by_risk.py +63 -0
- tooluniverse/tools/FDA_get_drug_names_by_route.py +63 -0
- tooluniverse/tools/FDA_get_drug_names_by_safe_handling_warning.py +63 -0
- tooluniverse/tools/FDA_get_drug_names_by_safety_summary.py +63 -0
- tooluniverse/tools/FDA_get_drug_names_by_spl_indexing_data_elements.py +63 -0
- tooluniverse/tools/FDA_get_drug_names_by_teratogenic_effects.py +63 -0
- tooluniverse/tools/FDA_get_drug_names_by_user_safety_warning.py +63 -0
- tooluniverse/tools/FDA_get_drug_names_by_warnings_and_cautions.py +63 -0
- tooluniverse/tools/FDA_get_drugs_by_carcinogenic_mutagenic_fertility.py +63 -0
- tooluniverse/tools/FDA_get_effective_time_by_drug_name.py +55 -0
- tooluniverse/tools/FDA_get_environmental_warning_by_drug_name.py +55 -0
- tooluniverse/tools/FDA_get_general_precautions_by_drug_name.py +55 -0
- tooluniverse/tools/FDA_get_geriatric_use_info_by_drug_name.py +55 -0
- tooluniverse/tools/FDA_get_health_claims_by_drug_name.py +55 -0
- tooluniverse/tools/FDA_get_inactive_ingredient_info_by_drug_name.py +55 -0
- tooluniverse/tools/FDA_get_indications_by_drug_name.py +55 -0
- tooluniverse/tools/FDA_get_info_for_nursing_mothers_by_drug_name.py +55 -0
- tooluniverse/tools/FDA_get_info_for_patients_by_drug_name.py +55 -0
- tooluniverse/tools/FDA_get_info_on_conditions_for_doctor_consultation_by_drug_name.py +55 -0
- tooluniverse/tools/FDA_get_info_on_consulting_doctor_pharmacist_by_drug_name.py +55 -0
- tooluniverse/tools/FDA_get_information_for_owners_or_caregivers_by_drug_name.py +55 -0
- tooluniverse/tools/FDA_get_ingredients_by_drug_name.py +55 -0
- tooluniverse/tools/FDA_get_instructions_for_use_by_drug_name.py +55 -0
- tooluniverse/tools/FDA_get_lab_test_interference_info_by_drug_name.py +55 -0
- tooluniverse/tools/FDA_get_lab_tests_by_drug_name.py +55 -0
- tooluniverse/tools/FDA_get_labor_and_delivery_info_by_drug_name.py +55 -0
- tooluniverse/tools/FDA_get_manufacturer_name_NDC_number_by_drug_name.py +55 -0
- tooluniverse/tools/FDA_get_mechanism_of_action_by_drug_name.py +55 -0
- tooluniverse/tools/FDA_get_medication_guide_info_by_drug_name.py +55 -0
- tooluniverse/tools/FDA_get_microbiology_info_by_drug_name.py +55 -0
- tooluniverse/tools/FDA_get_nonclinical_toxicology_info_by_drug_name.py +55 -0
- tooluniverse/tools/FDA_get_nonteratogenic_effects_by_drug_name.py +55 -0
- tooluniverse/tools/FDA_get_other_safety_info_by_drug_name.py +55 -0
- tooluniverse/tools/FDA_get_overdosage_info_by_drug_name.py +55 -0
- tooluniverse/tools/FDA_get_patient_package_insert_from_drug_name.py +55 -0
- tooluniverse/tools/FDA_get_pediatric_use_info_by_drug_name.py +55 -0
- tooluniverse/tools/FDA_get_pharmacodynamics_by_drug_name.py +55 -0
- tooluniverse/tools/FDA_get_pharmacogenomics_info_by_drug_name.py +55 -0
- tooluniverse/tools/FDA_get_pharmacokinetics_by_drug_name.py +55 -0
- tooluniverse/tools/FDA_get_population_use_info_by_drug_name.py +55 -0
- tooluniverse/tools/FDA_get_precautions_by_drug_name.py +55 -0
- tooluniverse/tools/FDA_get_pregnancy_effects_info_by_drug_name.py +55 -0
- tooluniverse/tools/FDA_get_pregnancy_or_breastfeeding_info_by_drug_name.py +55 -0
- tooluniverse/tools/FDA_get_principal_display_panel_by_drug_name.py +55 -0
- tooluniverse/tools/FDA_get_purpose_info_by_drug_name.py +55 -0
- tooluniverse/tools/FDA_get_recent_changes_by_drug_name.py +55 -0
- tooluniverse/tools/FDA_get_reference_info_by_drug_name.py +55 -0
- tooluniverse/tools/FDA_get_residue_warning_by_drug_name.py +55 -0
- tooluniverse/tools/FDA_get_risk_info_by_drug_name.py +55 -0
- tooluniverse/tools/FDA_get_route_info_by_drug_name.py +55 -0
- tooluniverse/tools/FDA_get_safe_handling_warnings_by_drug_name.py +55 -0
- tooluniverse/tools/FDA_get_safety_summary_by_drug_name.py +55 -0
- tooluniverse/tools/FDA_get_spl_indexing_data_elements_by_drug_name.py +55 -0
- tooluniverse/tools/FDA_get_spl_unclassified_section_by_drug_name.py +55 -0
- tooluniverse/tools/FDA_get_stop_use_info_by_drug_name.py +55 -0
- tooluniverse/tools/FDA_get_storage_and_handling_info_by_drug_name.py +55 -0
- tooluniverse/tools/FDA_get_teratogenic_effects_by_drug_name.py +55 -0
- tooluniverse/tools/FDA_get_user_safety_warning_by_drug_names.py +55 -0
- tooluniverse/tools/FDA_get_warnings_and_cautions_by_drug_name.py +55 -0
- tooluniverse/tools/FDA_get_warnings_by_drug_name.py +55 -0
- tooluniverse/tools/FDA_get_when_using_info.py +55 -0
- tooluniverse/tools/FDA_retrieve_device_use_by_drug_name.py +55 -0
- tooluniverse/tools/FDA_retrieve_drug_name_by_device_use.py +59 -0
- tooluniverse/tools/FDA_retrieve_drug_names_by_patient_medication_info.py +55 -0
- tooluniverse/tools/FDA_retrieve_patient_medication_info_by_drug_name.py +55 -0
- tooluniverse/tools/Fatcat_search_scholar.py +52 -0
- tooluniverse/tools/Finish.py +44 -0
- tooluniverse/tools/GIN_Guidelines_Search.py +52 -0
- tooluniverse/tools/GO_get_annotations_for_gene.py +46 -0
- tooluniverse/tools/GO_get_genes_for_term.py +55 -0
- tooluniverse/tools/GO_get_term_by_id.py +46 -0
- tooluniverse/tools/GO_get_term_details.py +46 -0
- tooluniverse/tools/GO_search_terms.py +46 -0
- tooluniverse/tools/GWAS_search_associations_by_gene.py +52 -0
- tooluniverse/tools/HAL_search_archive.py +52 -0
- tooluniverse/tools/HPA_get_biological_processes_by_gene.py +52 -0
- tooluniverse/tools/HPA_get_cancer_prognostics_by_gene.py +49 -0
- tooluniverse/tools/HPA_get_comparative_expression_by_gene_and_cellline.py +52 -0
- tooluniverse/tools/HPA_get_comprehensive_gene_details_by_ensembl_id.py +63 -0
- tooluniverse/tools/HPA_get_contextual_biological_process_analysis.py +52 -0
- tooluniverse/tools/HPA_get_disease_expression_by_gene_tissue_disease.py +59 -0
- tooluniverse/tools/HPA_get_gene_basic_info_by_ensembl_id.py +49 -0
- tooluniverse/tools/HPA_get_gene_tsv_data_by_ensembl_id.py +49 -0
- tooluniverse/tools/HPA_get_protein_interactions_by_gene.py +49 -0
- tooluniverse/tools/HPA_get_rna_expression_by_source.py +59 -0
- tooluniverse/tools/HPA_get_rna_expression_in_specific_tissues.py +52 -0
- tooluniverse/tools/HPA_get_subcellular_location.py +46 -0
- tooluniverse/tools/HPA_search_genes_by_query.py +49 -0
- tooluniverse/tools/HypothesisGenerator.py +63 -0
- tooluniverse/tools/LabelGenerator.py +67 -0
- tooluniverse/tools/LiteratureContextReviewer.py +55 -0
- tooluniverse/tools/LiteratureSearchTool.py +49 -0
- tooluniverse/tools/LiteratureSynthesisAgent.py +59 -0
- tooluniverse/tools/MedRxiv_search_preprints.py +52 -0
- tooluniverse/tools/MedicalLiteratureReviewer.py +71 -0
- tooluniverse/tools/MedicalTermNormalizer.py +46 -0
- tooluniverse/tools/MedlinePlus_connect_lookup_by_code.py +67 -0
- tooluniverse/tools/MedlinePlus_get_genetics_condition_by_name.py +52 -0
- tooluniverse/tools/MedlinePlus_get_genetics_gene_by_name.py +52 -0
- tooluniverse/tools/MedlinePlus_get_genetics_index.py +44 -0
- tooluniverse/tools/MedlinePlus_search_topics_by_keyword.py +55 -0
- tooluniverse/tools/MethodologyRigorReviewer.py +49 -0
- tooluniverse/tools/MultiAgentLiteratureSearch.py +59 -0
- tooluniverse/tools/NICE_Clinical_Guidelines_Search.py +52 -0
- tooluniverse/tools/NICE_Guideline_Full_Text.py +46 -0
- tooluniverse/tools/NoveltySignificanceReviewer.py +59 -0
- tooluniverse/tools/OSF_search_preprints.py +59 -0
- tooluniverse/tools/OSL_get_efo_id_by_disease_name.py +46 -0
- tooluniverse/tools/OpenAIRE_search_publications.py +55 -0
- tooluniverse/tools/OpenAlex_Guidelines_Search.py +63 -0
- tooluniverse/tools/OpenTargets_drug_pharmacogenomics_data.py +52 -0
- tooluniverse/tools/OpenTargets_get_approved_indications_by_drug_chemblId.py +49 -0
- tooluniverse/tools/OpenTargets_get_associated_diseases_by_drug_chemblId.py +49 -0
- tooluniverse/tools/OpenTargets_get_associated_drugs_by_disease_efoId.py +52 -0
- tooluniverse/tools/OpenTargets_get_associated_drugs_by_target_ensemblID.py +55 -0
- tooluniverse/tools/OpenTargets_get_associated_phenotypes_by_disease_efoId.py +49 -0
- tooluniverse/tools/OpenTargets_get_associated_targets_by_disease_efoId.py +49 -0
- tooluniverse/tools/OpenTargets_get_associated_targets_by_drug_chemblId.py +49 -0
- tooluniverse/tools/OpenTargets_get_biological_mouse_models_by_ensemblID.py +49 -0
- tooluniverse/tools/OpenTargets_get_chemical_probes_by_target_ensemblID.py +49 -0
- tooluniverse/tools/OpenTargets_get_disease_ancestors_parents_by_efoId.py +49 -0
- tooluniverse/tools/OpenTargets_get_disease_descendants_children_by_efoId.py +49 -0
- tooluniverse/tools/OpenTargets_get_disease_description_by_efoId.py +49 -0
- tooluniverse/tools/OpenTargets_get_disease_id_description_by_name.py +49 -0
- tooluniverse/tools/OpenTargets_get_disease_ids_by_efoId.py +46 -0
- tooluniverse/tools/OpenTargets_get_disease_ids_by_name.py +46 -0
- tooluniverse/tools/OpenTargets_get_disease_locations_by_efoId.py +49 -0
- tooluniverse/tools/OpenTargets_get_disease_synonyms_by_efoId.py +49 -0
- tooluniverse/tools/OpenTargets_get_disease_therapeutic_areas_by_efoId.py +49 -0
- tooluniverse/tools/OpenTargets_get_diseases_phenotypes_by_target_ensembl.py +49 -0
- tooluniverse/tools/OpenTargets_get_drug_adverse_events_by_chemblId.py +52 -0
- tooluniverse/tools/OpenTargets_get_drug_approval_status_by_chemblId.py +49 -0
- tooluniverse/tools/OpenTargets_get_drug_chembId_by_generic_name.py +49 -0
- tooluniverse/tools/OpenTargets_get_drug_description_by_chemblId.py +49 -0
- tooluniverse/tools/OpenTargets_get_drug_id_description_by_name.py +49 -0
- tooluniverse/tools/OpenTargets_get_drug_indications_by_chemblId.py +49 -0
- tooluniverse/tools/OpenTargets_get_drug_mechanisms_of_action_by_chemblId.py +49 -0
- tooluniverse/tools/OpenTargets_get_drug_synonyms_by_chemblId.py +49 -0
- tooluniverse/tools/OpenTargets_get_drug_trade_names_by_chemblId.py +49 -0
- tooluniverse/tools/OpenTargets_get_drug_warnings_by_chemblId.py +49 -0
- tooluniverse/tools/OpenTargets_get_drug_withdrawn_blackbox_status_by_chemblId.py +49 -0
- tooluniverse/tools/OpenTargets_get_gene_ontology_terms_by_goID.py +49 -0
- tooluniverse/tools/OpenTargets_get_known_drugs_by_drug_chemblId.py +49 -0
- tooluniverse/tools/OpenTargets_get_parent_child_molecules_by_drug_chembl_ID.py +49 -0
- tooluniverse/tools/OpenTargets_get_publications_by_disease_efoId.py +71 -0
- tooluniverse/tools/OpenTargets_get_publications_by_drug_chemblId.py +71 -0
- tooluniverse/tools/OpenTargets_get_publications_by_target_ensemblID.py +71 -0
- tooluniverse/tools/OpenTargets_get_similar_entities_by_disease_efoId.py +55 -0
- tooluniverse/tools/OpenTargets_get_similar_entities_by_drug_chemblId.py +55 -0
- tooluniverse/tools/OpenTargets_get_similar_entities_by_target_ensemblID.py +55 -0
- tooluniverse/tools/OpenTargets_get_target_classes_by_ensemblID.py +49 -0
- tooluniverse/tools/OpenTargets_get_target_constraint_info_by_ensemblID.py +49 -0
- tooluniverse/tools/OpenTargets_get_target_enabling_packages_by_ensemblID.py +49 -0
- tooluniverse/tools/OpenTargets_get_target_gene_ontology_by_ensemblID.py +49 -0
- tooluniverse/tools/OpenTargets_get_target_genomic_location_by_ensemblID.py +49 -0
- tooluniverse/tools/OpenTargets_get_target_homologues_by_ensemblID.py +49 -0
- tooluniverse/tools/OpenTargets_get_target_id_description_by_name.py +49 -0
- tooluniverse/tools/OpenTargets_get_target_interactions_by_ensemblID.py +52 -0
- tooluniverse/tools/OpenTargets_get_target_safety_profile_by_ensemblID.py +49 -0
- tooluniverse/tools/OpenTargets_get_target_subcellular_locations_by_ensemblID.py +49 -0
- tooluniverse/tools/OpenTargets_get_target_synonyms_by_ensemblID.py +49 -0
- tooluniverse/tools/OpenTargets_get_target_tractability_by_ensemblID.py +49 -0
- tooluniverse/tools/OpenTargets_map_any_disease_id_to_all_other_ids.py +49 -0
- tooluniverse/tools/OpenTargets_multi_entity_search_by_query_string.py +59 -0
- tooluniverse/tools/OpenTargets_search_category_counts_by_query_string.py +49 -0
- tooluniverse/tools/OpenTargets_target_disease_evidence.py +52 -0
- tooluniverse/tools/OutputSummarizationComposer.py +71 -0
- tooluniverse/tools/PMC_search_papers.py +67 -0
- tooluniverse/tools/ProtocolOptimizer.py +49 -0
- tooluniverse/tools/PubChem_get_CID_by_SMILES.py +46 -0
- tooluniverse/tools/PubChem_get_CID_by_compound_name.py +46 -0
- tooluniverse/tools/PubChem_get_associated_patents_by_CID.py +46 -0
- tooluniverse/tools/PubChem_get_compound_2D_image_by_CID.py +52 -0
- tooluniverse/tools/PubChem_get_compound_properties_by_CID.py +46 -0
- tooluniverse/tools/PubChem_get_compound_synonyms_by_CID.py +46 -0
- tooluniverse/tools/PubChem_get_compound_xrefs_by_CID.py +52 -0
- tooluniverse/tools/PubChem_search_compounds_by_similarity.py +52 -0
- tooluniverse/tools/PubChem_search_compounds_by_substructure.py +49 -0
- tooluniverse/tools/PubMed_Guidelines_Search.py +55 -0
- tooluniverse/tools/PubMed_search_articles.py +55 -0
- tooluniverse/tools/PubTator3_EntityAutocomplete.py +59 -0
- tooluniverse/tools/PubTator3_LiteratureSearch.py +55 -0
- tooluniverse/tools/QuestionRephraser.py +52 -0
- tooluniverse/tools/Reactome_get_pathway_reactions.py +46 -0
- tooluniverse/tools/ReproducibilityTransparencyReviewer.py +49 -0
- tooluniverse/tools/ResultsInterpretationReviewer.py +55 -0
- tooluniverse/tools/ScientificTextSummarizer.py +59 -0
- tooluniverse/tools/SemanticScholar_search_papers.py +55 -0
- tooluniverse/tools/TRIP_Database_Guidelines_Search.py +55 -0
- tooluniverse/tools/TestCaseGenerator.py +46 -0
- tooluniverse/tools/ToolCompatibilityAnalyzer.py +59 -0
- tooluniverse/tools/ToolDescriptionOptimizer.py +67 -0
- tooluniverse/tools/ToolDiscover.py +63 -0
- tooluniverse/tools/ToolGraphComposer.py +71 -0
- tooluniverse/tools/ToolGraphGenerationPipeline.py +63 -0
- tooluniverse/tools/ToolImplementationGenerator.py +67 -0
- tooluniverse/tools/ToolMetadataGenerationPipeline.py +63 -0
- tooluniverse/tools/ToolMetadataGenerator.py +55 -0
- tooluniverse/tools/ToolMetadataStandardizer.py +52 -0
- tooluniverse/tools/ToolOptimizer.py +59 -0
- tooluniverse/tools/ToolOutputSummarizer.py +67 -0
- tooluniverse/tools/ToolQualityEvaluator.py +59 -0
- tooluniverse/tools/ToolRelationshipDetector.py +52 -0
- tooluniverse/tools/ToolSpecificationGenerator.py +67 -0
- tooluniverse/tools/ToolSpecificationOptimizer.py +63 -0
- tooluniverse/tools/Tool_Finder.py +67 -0
- tooluniverse/tools/Tool_Finder_Keyword.py +67 -0
- tooluniverse/tools/Tool_Finder_LLM.py +67 -0
- tooluniverse/tools/Tool_RAG.py +49 -0
- tooluniverse/tools/UCSC_get_genes_by_region.py +67 -0
- tooluniverse/tools/UniProt_get_alternative_names_by_accession.py +49 -0
- tooluniverse/tools/UniProt_get_disease_variants_by_accession.py +49 -0
- tooluniverse/tools/UniProt_get_entry_by_accession.py +49 -0
- tooluniverse/tools/UniProt_get_function_by_accession.py +49 -0
- tooluniverse/tools/UniProt_get_isoform_ids_by_accession.py +49 -0
- tooluniverse/tools/UniProt_get_organism_by_accession.py +49 -0
- tooluniverse/tools/UniProt_get_ptm_processing_by_accession.py +49 -0
- tooluniverse/tools/UniProt_get_recommended_name_by_accession.py +49 -0
- tooluniverse/tools/UniProt_get_sequence_by_accession.py +49 -0
- tooluniverse/tools/UniProt_get_subcellular_location_by_accession.py +49 -0
- tooluniverse/tools/Unpaywall_check_oa_status.py +52 -0
- tooluniverse/tools/WHO_Guideline_Full_Text.py +46 -0
- tooluniverse/tools/WHO_Guidelines_Search.py +52 -0
- tooluniverse/tools/Wikidata_SPARQL_query.py +52 -0
- tooluniverse/tools/WritingPresentationReviewer.py +49 -0
- tooluniverse/tools/Zenodo_search_records.py +59 -0
- tooluniverse/tools/__init__.py +1770 -0
- tooluniverse/tools/_shared_client.py +138 -0
- tooluniverse/tools/alphafold_get_annotations.py +52 -0
- tooluniverse/tools/alphafold_get_prediction.py +55 -0
- tooluniverse/tools/alphafold_get_summary.py +46 -0
- tooluniverse/tools/call_agentic_human.py +46 -0
- tooluniverse/tools/cancer_biomarkers_disease_target_score.py +52 -0
- tooluniverse/tools/cancer_gene_census_disease_target_score.py +52 -0
- tooluniverse/tools/cellosaurus_get_cell_line_info.py +55 -0
- tooluniverse/tools/cellosaurus_query_converter.py +52 -0
- tooluniverse/tools/cellosaurus_search_cell_lines.py +55 -0
- tooluniverse/tools/chembl_disease_target_score.py +52 -0
- tooluniverse/tools/convert_to_markdown.py +59 -0
- tooluniverse/tools/dbSNP_get_variant_by_rsid.py +46 -0
- tooluniverse/tools/dict_search.py +67 -0
- tooluniverse/tools/dili_search.py +67 -0
- tooluniverse/tools/diqt_search.py +67 -0
- tooluniverse/tools/disease_target_score.py +59 -0
- tooluniverse/tools/drugbank_filter_drugs_by_name.py +55 -0
- tooluniverse/tools/drugbank_full_search.py +67 -0
- tooluniverse/tools/drugbank_get_drug_basic_info_by_drug_name_or_drugbank_id.py +63 -0
- tooluniverse/tools/drugbank_get_drug_chemistry_by_drug_name_or_drugbank_id.py +63 -0
- tooluniverse/tools/drugbank_get_drug_interactions_by_drug_name_or_drugbank_id.py +63 -0
- tooluniverse/tools/drugbank_get_drug_name_and_description_by_indication.py +63 -0
- tooluniverse/tools/drugbank_get_drug_name_and_description_by_pathway_name.py +63 -0
- tooluniverse/tools/drugbank_get_drug_name_and_description_by_target_name.py +63 -0
- tooluniverse/tools/drugbank_get_drug_name_description_pharmacology_by_mechanism_of_action.py +63 -0
- tooluniverse/tools/drugbank_get_drug_pathways_and_reactions_by_drug_name_or_drugbank_id.py +63 -0
- tooluniverse/tools/drugbank_get_drug_products_by_name_or_drugbank_id.py +63 -0
- tooluniverse/tools/drugbank_get_drug_references_by_drug_name_or_drugbank_id.py +63 -0
- tooluniverse/tools/drugbank_get_indications_by_drug_name_or_drugbank_id.py +63 -0
- tooluniverse/tools/drugbank_get_pharmacology_by_drug_name_or_drugbank_id.py +63 -0
- tooluniverse/tools/drugbank_get_safety_by_drug_name_or_drugbank_id.py +63 -0
- tooluniverse/tools/drugbank_get_targets_by_drug_name_or_drugbank_id.py +63 -0
- tooluniverse/tools/drugbank_links_search.py +67 -0
- tooluniverse/tools/drugbank_vocab_filter.py +63 -0
- tooluniverse/tools/drugbank_vocab_search.py +67 -0
- tooluniverse/tools/embedding_database_add.py +63 -0
- tooluniverse/tools/embedding_database_create.py +71 -0
- tooluniverse/tools/embedding_database_load.py +63 -0
- tooluniverse/tools/embedding_database_search.py +67 -0
- tooluniverse/tools/embedding_sync_download.py +63 -0
- tooluniverse/tools/embedding_sync_upload.py +71 -0
- tooluniverse/tools/enrichr_gene_enrichment_analysis.py +52 -0
- tooluniverse/tools/europepmc_disease_target_score.py +52 -0
- tooluniverse/tools/eva_disease_target_score.py +52 -0
- tooluniverse/tools/eva_somatic_disease_target_score.py +52 -0
- tooluniverse/tools/expression_atlas_disease_target_score.py +52 -0
- tooluniverse/tools/extract_clinical_trial_adverse_events.py +59 -0
- tooluniverse/tools/extract_clinical_trial_outcomes.py +52 -0
- tooluniverse/tools/genomics_england_disease_target_score.py +52 -0
- tooluniverse/tools/get_HPO_ID_by_phenotype.py +55 -0
- tooluniverse/tools/get_albumentations_info.py +44 -0
- tooluniverse/tools/get_altair_info.py +44 -0
- tooluniverse/tools/get_anndata_info.py +49 -0
- tooluniverse/tools/get_arboreto_info.py +46 -0
- tooluniverse/tools/get_arxiv_info.py +46 -0
- tooluniverse/tools/get_ase_info.py +46 -0
- tooluniverse/tools/get_assembly_info_by_pdb_id.py +46 -0
- tooluniverse/tools/get_assembly_summary.py +46 -0
- tooluniverse/tools/get_astropy_info.py +44 -0
- tooluniverse/tools/get_binding_affinity_by_pdb_id.py +46 -0
- tooluniverse/tools/get_biopandas_info.py +49 -0
- tooluniverse/tools/get_biopython_info.py +49 -0
- tooluniverse/tools/get_bioservices_info.py +44 -0
- tooluniverse/tools/get_biotite_info.py +49 -0
- tooluniverse/tools/get_bokeh_info.py +44 -0
- tooluniverse/tools/get_brian2_info.py +44 -0
- tooluniverse/tools/get_cartopy_info.py +44 -0
- tooluniverse/tools/get_catboost_info.py +44 -0
- tooluniverse/tools/get_cellpose_info.py +49 -0
- tooluniverse/tools/get_cellrank_info.py +44 -0
- tooluniverse/tools/get_cellxgene_census_info.py +46 -0
- tooluniverse/tools/get_cftime_info.py +44 -0
- tooluniverse/tools/get_chem_comp_audit_info.py +46 -0
- tooluniverse/tools/get_chem_comp_charge_and_ambiguity.py +46 -0
- tooluniverse/tools/get_chembl_webresource_client_info.py +44 -0
- tooluniverse/tools/get_citation_info_by_pdb_id.py +46 -0
- tooluniverse/tools/get_clair3_info.py +46 -0
- tooluniverse/tools/get_clinical_trial_conditions_and_interventions.py +55 -0
- tooluniverse/tools/get_clinical_trial_descriptions.py +52 -0
- tooluniverse/tools/get_clinical_trial_eligibility_criteria.py +55 -0
- tooluniverse/tools/get_clinical_trial_locations.py +52 -0
- tooluniverse/tools/get_clinical_trial_outcome_measures.py +52 -0
- tooluniverse/tools/get_clinical_trial_references.py +52 -0
- tooluniverse/tools/get_clinical_trial_status_and_dates.py +52 -0
- tooluniverse/tools/get_cobra_info.py +46 -0
- tooluniverse/tools/get_cobrapy_info.py +46 -0
- tooluniverse/tools/get_cooler_info.py +49 -0
- tooluniverse/tools/get_core_refinement_statistics.py +46 -0
- tooluniverse/tools/get_cryosparc_tools_info.py +46 -0
- tooluniverse/tools/get_crystal_growth_conditions_by_pdb_id.py +49 -0
- tooluniverse/tools/get_crystallization_ph_by_pdb_id.py +46 -0
- tooluniverse/tools/get_crystallographic_properties_by_pdb_id.py +49 -0
- tooluniverse/tools/get_cupy_info.py +44 -0
- tooluniverse/tools/get_cyvcf2_info.py +49 -0
- tooluniverse/tools/get_dask_info.py +44 -0
- tooluniverse/tools/get_datamol_info.py +44 -0
- tooluniverse/tools/get_datashader_info.py +44 -0
- tooluniverse/tools/get_deepchem_info.py +49 -0
- tooluniverse/tools/get_deeppurpose_info.py +46 -0
- tooluniverse/tools/get_deeptools_info.py +46 -0
- tooluniverse/tools/get_deepxde_info.py +49 -0
- tooluniverse/tools/get_dendropy_info.py +44 -0
- tooluniverse/tools/get_descriptastorus_info.py +46 -0
- tooluniverse/tools/get_diffdock_info.py +46 -0
- tooluniverse/tools/get_dscribe_info.py +49 -0
- tooluniverse/tools/get_ec_number_by_entity_id.py +46 -0
- tooluniverse/tools/get_elephant_info.py +44 -0
- tooluniverse/tools/get_em_3d_fitting_and_reconstruction_details.py +49 -0
- tooluniverse/tools/get_emdb_ids_by_pdb_id.py +46 -0
- tooluniverse/tools/get_episcanpy_info.py +44 -0
- tooluniverse/tools/get_ete3_info.py +44 -0
- tooluniverse/tools/get_faiss_info.py +46 -0
- tooluniverse/tools/get_fanc_info.py +46 -0
- tooluniverse/tools/get_flask_info.py +46 -0
- tooluniverse/tools/get_flowio_info.py +46 -0
- tooluniverse/tools/get_flowkit_info.py +46 -0
- tooluniverse/tools/get_flowutils_info.py +46 -0
- tooluniverse/tools/get_freesasa_info.py +44 -0
- tooluniverse/tools/get_galpy_info.py +44 -0
- tooluniverse/tools/get_gene_name_by_entity_id.py +46 -0
- tooluniverse/tools/get_geopandas_info.py +44 -0
- tooluniverse/tools/get_gget_info.py +46 -0
- tooluniverse/tools/get_googlesearch_python_info.py +46 -0
- tooluniverse/tools/get_gseapy_info.py +49 -0
- tooluniverse/tools/get_h5py_info.py +46 -0
- tooluniverse/tools/get_harmony_pytorch_info.py +46 -0
- tooluniverse/tools/get_hmmlearn_info.py +46 -0
- tooluniverse/tools/get_holoviews_info.py +44 -0
- tooluniverse/tools/get_host_organism_by_pdb_id.py +46 -0
- tooluniverse/tools/get_htmd_info.py +44 -0
- tooluniverse/tools/get_hyperopt_info.py +49 -0
- tooluniverse/tools/get_igraph_info.py +49 -0
- tooluniverse/tools/get_imageio_info.py +44 -0
- tooluniverse/tools/get_imbalanced_learn_info.py +44 -0
- tooluniverse/tools/get_jcvi_info.py +46 -0
- tooluniverse/tools/get_joblib_info.py +44 -0
- tooluniverse/tools/get_joint_associated_diseases_by_HPO_ID_list.py +55 -0
- tooluniverse/tools/get_khmer_info.py +46 -0
- tooluniverse/tools/get_kipoiseq_info.py +44 -0
- tooluniverse/tools/get_lifelines_info.py +49 -0
- tooluniverse/tools/get_ligand_bond_count_by_pdb_id.py +46 -0
- tooluniverse/tools/get_ligand_smiles_by_chem_comp_id.py +49 -0
- tooluniverse/tools/get_lightgbm_info.py +44 -0
- tooluniverse/tools/get_loompy_info.py +46 -0
- tooluniverse/tools/get_mageck_info.py +46 -0
- tooluniverse/tools/get_matplotlib_info.py +49 -0
- tooluniverse/tools/get_mdanalysis_info.py +46 -0
- tooluniverse/tools/get_mdtraj_info.py +44 -0
- tooluniverse/tools/get_mne_info.py +44 -0
- tooluniverse/tools/get_molfeat_info.py +44 -0
- tooluniverse/tools/get_molvs_info.py +44 -0
- tooluniverse/tools/get_mordred_info.py +44 -0
- tooluniverse/tools/get_msprime_info.py +49 -0
- tooluniverse/tools/get_mudata_info.py +49 -0
- tooluniverse/tools/get_mutation_annotations_by_pdb_id.py +46 -0
- tooluniverse/tools/get_neo_info.py +44 -0
- tooluniverse/tools/get_netcdf4_info.py +44 -0
- tooluniverse/tools/get_networkx_info.py +46 -0
- tooluniverse/tools/get_nglview_info.py +44 -0
- tooluniverse/tools/get_nilearn_info.py +44 -0
- tooluniverse/tools/get_numba_info.py +46 -0
- tooluniverse/tools/get_numpy_info.py +46 -0
- tooluniverse/tools/get_oligosaccharide_descriptors_by_entity_id.py +49 -0
- tooluniverse/tools/get_openbabel_info.py +49 -0
- tooluniverse/tools/get_openchem_info.py +46 -0
- tooluniverse/tools/get_opencv_info.py +49 -0
- tooluniverse/tools/get_openmm_info.py +49 -0
- tooluniverse/tools/get_optlang_info.py +46 -0
- tooluniverse/tools/get_optuna_info.py +44 -0
- tooluniverse/tools/get_palantir_info.py +44 -0
- tooluniverse/tools/get_pandas_info.py +49 -0
- tooluniverse/tools/get_patsy_info.py +44 -0
- tooluniverse/tools/get_pdbfixer_info.py +46 -0
- tooluniverse/tools/get_phenotype_by_HPO_ID.py +46 -0
- tooluniverse/tools/get_pillow_info.py +44 -0
- tooluniverse/tools/get_plantcv_info.py +46 -0
- tooluniverse/tools/get_plip_info.py +46 -0
- tooluniverse/tools/get_plotly_info.py +44 -0
- tooluniverse/tools/get_poliastro_info.py +46 -0
- tooluniverse/tools/get_polymer_entity_annotations.py +49 -0
- tooluniverse/tools/get_polymer_entity_count_by_pdb_id.py +46 -0
- tooluniverse/tools/get_polymer_entity_ids_by_pdb_id.py +46 -0
- tooluniverse/tools/get_polymer_entity_type_by_entity_id.py +49 -0
- tooluniverse/tools/get_polymer_molecular_weight_by_entity_id.py +49 -0
- tooluniverse/tools/get_poretools_info.py +44 -0
- tooluniverse/tools/get_prody_info.py +46 -0
- tooluniverse/tools/get_protein_classification_by_pdb_id.py +49 -0
- tooluniverse/tools/get_protein_metadata_by_pdb_id.py +46 -0
- tooluniverse/tools/get_pubchempy_info.py +44 -0
- tooluniverse/tools/get_pybedtools_info.py +49 -0
- tooluniverse/tools/get_pybigwig_info.py +46 -0
- tooluniverse/tools/get_pydeseq2_info.py +46 -0
- tooluniverse/tools/get_pyensembl_info.py +44 -0
- tooluniverse/tools/get_pyephem_info.py +44 -0
- tooluniverse/tools/get_pyfaidx_info.py +49 -0
- tooluniverse/tools/get_pyfasta_info.py +44 -0
- tooluniverse/tools/get_pykalman_info.py +46 -0
- tooluniverse/tools/get_pyliftover_info.py +49 -0
- tooluniverse/tools/get_pymassspec_info.py +46 -0
- tooluniverse/tools/get_pymed_info.py +46 -0
- tooluniverse/tools/get_pymzml_info.py +46 -0
- tooluniverse/tools/get_pypdf2_info.py +46 -0
- tooluniverse/tools/get_pyranges_info.py +49 -0
- tooluniverse/tools/get_pyrosetta_info.py +44 -0
- tooluniverse/tools/get_pysam_info.py +46 -0
- tooluniverse/tools/get_pyscenic_info.py +46 -0
- tooluniverse/tools/get_pyscf_info.py +46 -0
- tooluniverse/tools/get_pyscreener_info.py +46 -0
- tooluniverse/tools/get_pytdc_info.py +46 -0
- tooluniverse/tools/get_python_libsbml_info.py +46 -0
- tooluniverse/tools/get_pytorch_info.py +49 -0
- tooluniverse/tools/get_pyvcf_info.py +44 -0
- tooluniverse/tools/get_pyvis_info.py +44 -0
- tooluniverse/tools/get_qutip_info.py +44 -0
- tooluniverse/tools/get_rasterio_info.py +44 -0
- tooluniverse/tools/get_rdkit_info.py +46 -0
- tooluniverse/tools/get_refinement_resolution_by_pdb_id.py +49 -0
- tooluniverse/tools/get_release_deposit_dates_by_pdb_id.py +49 -0
- tooluniverse/tools/get_reportlab_info.py +49 -0
- tooluniverse/tools/get_requests_info.py +49 -0
- tooluniverse/tools/get_ruptures_info.py +46 -0
- tooluniverse/tools/get_scanorama_info.py +44 -0
- tooluniverse/tools/get_scanpy_info.py +49 -0
- tooluniverse/tools/get_schnetpack_info.py +49 -0
- tooluniverse/tools/get_scholarly_info.py +46 -0
- tooluniverse/tools/get_scikit_bio_info.py +49 -0
- tooluniverse/tools/get_scikit_image_info.py +46 -0
- tooluniverse/tools/get_scikit_learn_info.py +49 -0
- tooluniverse/tools/get_scipy_info.py +46 -0
- tooluniverse/tools/get_scrublet_info.py +49 -0
- tooluniverse/tools/get_scvelo_info.py +49 -0
- tooluniverse/tools/get_scvi_tools_info.py +44 -0
- tooluniverse/tools/get_seaborn_info.py +49 -0
- tooluniverse/tools/get_sequence_by_pdb_id.py +46 -0
- tooluniverse/tools/get_sequence_lengths_by_pdb_id.py +46 -0
- tooluniverse/tools/get_sequence_positional_features_by_instance_id.py +49 -0
- tooluniverse/tools/get_skopt_info.py +44 -0
- tooluniverse/tools/get_souporcell_info.py +46 -0
- tooluniverse/tools/get_source_organism_by_pdb_id.py +46 -0
- tooluniverse/tools/get_space_group_by_pdb_id.py +46 -0
- tooluniverse/tools/get_statsmodels_info.py +49 -0
- tooluniverse/tools/get_structure_determination_software_by_pdb_id.py +49 -0
- tooluniverse/tools/get_structure_title_by_pdb_id.py +46 -0
- tooluniverse/tools/get_structure_validation_metrics_by_pdb_id.py +49 -0
- tooluniverse/tools/get_sunpy_info.py +44 -0
- tooluniverse/tools/get_sympy_info.py +46 -0
- tooluniverse/tools/get_target_cofactor_info.py +46 -0
- tooluniverse/tools/get_taxonomy_by_pdb_id.py +46 -0
- tooluniverse/tools/get_tiledb_info.py +46 -0
- tooluniverse/tools/get_tiledbsoma_info.py +46 -0
- tooluniverse/tools/get_torch_geometric_info.py +49 -0
- tooluniverse/tools/get_tqdm_info.py +46 -0
- tooluniverse/tools/get_trackpy_info.py +46 -0
- tooluniverse/tools/get_tskit_info.py +46 -0
- tooluniverse/tools/get_umap_learn_info.py +49 -0
- tooluniverse/tools/get_uniprot_accession_by_entity_id.py +49 -0
- tooluniverse/tools/get_velocyto_info.py +44 -0
- tooluniverse/tools/get_viennarna_info.py +49 -0
- tooluniverse/tools/get_webpage_text_from_url.py +52 -0
- tooluniverse/tools/get_webpage_title.py +49 -0
- tooluniverse/tools/get_xarray_info.py +44 -0
- tooluniverse/tools/get_xesmf_info.py +44 -0
- tooluniverse/tools/get_xgboost_info.py +44 -0
- tooluniverse/tools/get_zarr_info.py +44 -0
- tooluniverse/tools/gnomAD_query_variant.py +52 -0
- tooluniverse/tools/gwas_get_association_by_id.py +49 -0
- tooluniverse/tools/gwas_get_associations_for_snp.py +67 -0
- tooluniverse/tools/gwas_get_associations_for_study.py +55 -0
- tooluniverse/tools/gwas_get_associations_for_trait.py +55 -0
- tooluniverse/tools/gwas_get_snp_by_id.py +46 -0
- tooluniverse/tools/gwas_get_snps_for_gene.py +55 -0
- tooluniverse/tools/gwas_get_studies_for_trait.py +75 -0
- tooluniverse/tools/gwas_get_study_by_id.py +46 -0
- tooluniverse/tools/gwas_get_variants_for_trait.py +55 -0
- tooluniverse/tools/gwas_search_associations.py +75 -0
- tooluniverse/tools/gwas_search_snps.py +63 -0
- tooluniverse/tools/gwas_search_studies.py +75 -0
- tooluniverse/tools/humanbase_ppi_analysis.py +67 -0
- tooluniverse/tools/mesh_get_subjects_by_pharmacological_action.py +63 -0
- tooluniverse/tools/mesh_get_subjects_by_subject_id.py +63 -0
- tooluniverse/tools/mesh_get_subjects_by_subject_name.py +63 -0
- tooluniverse/tools/mesh_get_subjects_by_subject_scope_or_definition.py +63 -0
- tooluniverse/tools/odphp_itemlist.py +49 -0
- tooluniverse/tools/odphp_myhealthfinder.py +67 -0
- tooluniverse/tools/odphp_outlink_fetch.py +59 -0
- tooluniverse/tools/odphp_topicsearch.py +67 -0
- tooluniverse/tools/openalex_literature_search.py +67 -0
- tooluniverse/tools/reactome_disease_target_score.py +52 -0
- tooluniverse/tools/search_clinical_trials.py +67 -0
- tooluniverse/tools/visualize_molecule_2d.py +83 -0
- tooluniverse/tools/visualize_molecule_3d.py +91 -0
- tooluniverse/tools/visualize_protein_structure_3d.py +79 -0
- tooluniverse/ucsc_tool.py +60 -0
- tooluniverse/unified_guideline_tools.py +2328 -0
- tooluniverse/unpaywall_tool.py +0 -1
- tooluniverse/utils.py +122 -6
- tooluniverse/visualization_tool.py +897 -0
- tooluniverse/wikidata_sparql_tool.py +1 -2
- tooluniverse/zenodo_tool.py +3 -4
- {tooluniverse-1.0.6.dist-info → tooluniverse-1.0.8.dist-info}/METADATA +19 -4
- tooluniverse-1.0.8.dist-info/RECORD +891 -0
- {tooluniverse-1.0.6.dist-info → tooluniverse-1.0.8.dist-info}/entry_points.txt +3 -0
- tooluniverse/test/list_azure_openai_models.py +0 -210
- tooluniverse/test/mcp_server_test.py +0 -0
- tooluniverse/test/test_admetai_tool.py +0 -370
- tooluniverse/test/test_agentic_tool.py +0 -129
- tooluniverse/test/test_agentic_tool_azure_models.py +0 -91
- tooluniverse/test/test_alphafold_tool.py +0 -108
- tooluniverse/test/test_api_key_validation_min.py +0 -64
- tooluniverse/test/test_chem_tool.py +0 -37
- tooluniverse/test/test_claude_sdk.py +0 -93
- tooluniverse/test/test_compose_lieraturereview.py +0 -63
- tooluniverse/test/test_compose_tool.py +0 -448
- tooluniverse/test/test_dailymed.py +0 -69
- tooluniverse/test/test_dataset_tool.py +0 -200
- tooluniverse/test/test_disease_target_score.py +0 -56
- tooluniverse/test/test_drugbank_filter_examples.py +0 -179
- tooluniverse/test/test_efo.py +0 -31
- tooluniverse/test/test_enrichr_tool.py +0 -21
- tooluniverse/test/test_europe_pmc_tool.py +0 -20
- tooluniverse/test/test_fda_adv.py +0 -95
- tooluniverse/test/test_fda_drug_labeling.py +0 -91
- tooluniverse/test/test_gene_ontology_tools.py +0 -66
- tooluniverse/test/test_global_fallback.py +0 -288
- tooluniverse/test/test_gwas_tool.py +0 -139
- tooluniverse/test/test_hooks_direct.py +0 -219
- tooluniverse/test/test_hpa.py +0 -625
- tooluniverse/test/test_humanbase_tool.py +0 -20
- tooluniverse/test/test_idmap_tools.py +0 -61
- tooluniverse/test/test_list_built_in_tools.py +0 -33
- tooluniverse/test/test_mcp_server.py +0 -211
- tooluniverse/test/test_mcp_tool.py +0 -247
- tooluniverse/test/test_medlineplus.py +0 -220
- tooluniverse/test/test_odphp_tool.py +0 -166
- tooluniverse/test/test_openalex_tool.py +0 -32
- tooluniverse/test/test_openrouter_client.py +0 -288
- tooluniverse/test/test_opentargets.py +0 -28
- tooluniverse/test/test_pubchem_tool.py +0 -116
- tooluniverse/test/test_pubtator_tool.py +0 -37
- tooluniverse/test/test_rcsb_pdb_tool.py +0 -86
- tooluniverse/test/test_reactome.py +0 -54
- tooluniverse/test/test_semantic_scholar_tool.py +0 -24
- tooluniverse/test/test_software_tools.py +0 -147
- tooluniverse/test/test_stdio_hooks.py +0 -285
- tooluniverse/test/test_tool_description_optimizer.py +0 -49
- tooluniverse/test/test_tool_finder.py +0 -26
- tooluniverse/test/test_tool_finder_llm.py +0 -252
- tooluniverse/test/test_tools_find.py +0 -195
- tooluniverse/test/test_uniprot_tools.py +0 -74
- tooluniverse/test/test_uspto_tool.py +0 -72
- tooluniverse/test/test_xml_tool.py +0 -113
- tooluniverse-1.0.6.dist-info/RECORD +0 -230
- {tooluniverse-1.0.6.dist-info → tooluniverse-1.0.8.dist-info}/WHEEL +0 -0
- {tooluniverse-1.0.6.dist-info → tooluniverse-1.0.8.dist-info}/licenses/LICENSE +0 -0
- {tooluniverse-1.0.6.dist-info → tooluniverse-1.0.8.dist-info}/top_level.txt +0 -0
tooluniverse/execute_function.py
CHANGED
|
@@ -31,12 +31,26 @@ import random
|
|
|
31
31
|
import string
|
|
32
32
|
import os
|
|
33
33
|
import time
|
|
34
|
+
import hashlib
|
|
35
|
+
import warnings
|
|
36
|
+
from pathlib import Path
|
|
37
|
+
from contextlib import nullcontext
|
|
38
|
+
from typing import Any, Dict, List, Optional
|
|
34
39
|
from .utils import read_json_list, evaluate_function_call, extract_function_call_json
|
|
40
|
+
from .exceptions import (
|
|
41
|
+
ToolError,
|
|
42
|
+
ToolUnavailableError,
|
|
43
|
+
ToolValidationError,
|
|
44
|
+
ToolConfigError,
|
|
45
|
+
ToolServerError,
|
|
46
|
+
)
|
|
35
47
|
from .tool_registry import (
|
|
36
48
|
auto_discover_tools,
|
|
37
49
|
get_tool_registry,
|
|
38
50
|
register_external_tool,
|
|
39
51
|
get_tool_class_lazy,
|
|
52
|
+
get_tool_errors,
|
|
53
|
+
mark_tool_unavailable,
|
|
40
54
|
)
|
|
41
55
|
from .logging_config import (
|
|
42
56
|
get_logger,
|
|
@@ -46,6 +60,7 @@ from .logging_config import (
|
|
|
46
60
|
error,
|
|
47
61
|
set_log_level,
|
|
48
62
|
)
|
|
63
|
+
from .cache.result_cache_manager import ResultCacheManager
|
|
49
64
|
from .output_hook import HookManager
|
|
50
65
|
from .default_config import default_tool_files, get_default_hook_config
|
|
51
66
|
|
|
@@ -81,6 +96,82 @@ for _tool_name, _tool_class in sorted(tool_type_mappings.items()):
|
|
|
81
96
|
debug(f" - {_tool_name}: {_tool_class.__name__}")
|
|
82
97
|
|
|
83
98
|
|
|
99
|
+
class ToolCallable:
|
|
100
|
+
"""
|
|
101
|
+
A callable wrapper for a tool that validates kwargs and calls run_one_function.
|
|
102
|
+
|
|
103
|
+
This class provides the dynamic function interface for tools, allowing
|
|
104
|
+
them to be called like regular Python functions with keyword arguments.
|
|
105
|
+
"""
|
|
106
|
+
|
|
107
|
+
def __init__(self, engine: "ToolUniverse", tool_name: str):
|
|
108
|
+
self.engine = engine
|
|
109
|
+
self.tool_name = tool_name
|
|
110
|
+
self.schema = engine.all_tool_dict[tool_name]["parameter"]
|
|
111
|
+
self.__doc__ = engine.all_tool_dict[tool_name].get("description", tool_name)
|
|
112
|
+
|
|
113
|
+
def __call__(
|
|
114
|
+
self, *, stream_callback=None, use_cache=False, validate=True, **kwargs
|
|
115
|
+
):
|
|
116
|
+
"""
|
|
117
|
+
Execute the tool with the provided keyword arguments.
|
|
118
|
+
|
|
119
|
+
Args:
|
|
120
|
+
stream_callback: Optional callback for streaming responses
|
|
121
|
+
use_cache: Whether to use result caching
|
|
122
|
+
validate: Whether to validate parameters against schema
|
|
123
|
+
**kwargs: Tool-specific arguments
|
|
124
|
+
|
|
125
|
+
Returns:
|
|
126
|
+
Tool execution result
|
|
127
|
+
"""
|
|
128
|
+
function_call = {"name": self.tool_name, "arguments": kwargs}
|
|
129
|
+
return self.engine.run_one_function(
|
|
130
|
+
function_call,
|
|
131
|
+
stream_callback=stream_callback,
|
|
132
|
+
use_cache=use_cache,
|
|
133
|
+
validate=validate,
|
|
134
|
+
)
|
|
135
|
+
|
|
136
|
+
|
|
137
|
+
class ToolNamespace:
|
|
138
|
+
"""
|
|
139
|
+
Dynamic namespace for accessing tools as callable functions.
|
|
140
|
+
|
|
141
|
+
This class provides the `tu.tools.tool_name(**kwargs)` interface,
|
|
142
|
+
dynamically creating ToolCallable instances for each available tool.
|
|
143
|
+
"""
|
|
144
|
+
|
|
145
|
+
def __init__(self, engine: "ToolUniverse"):
|
|
146
|
+
self.engine = engine
|
|
147
|
+
|
|
148
|
+
def __getattr__(self, name: str) -> ToolCallable:
|
|
149
|
+
"""Return a ToolCallable for the requested tool name."""
|
|
150
|
+
if name in self.engine.all_tool_dict:
|
|
151
|
+
return ToolCallable(self.engine, name)
|
|
152
|
+
raise AttributeError(f"Tool '{name}' not found")
|
|
153
|
+
|
|
154
|
+
def __len__(self) -> int:
|
|
155
|
+
"""Return the number of available tools."""
|
|
156
|
+
return len(self.engine.all_tool_dict)
|
|
157
|
+
|
|
158
|
+
def __iter__(self):
|
|
159
|
+
"""Iterate over tool names."""
|
|
160
|
+
return iter(self.engine.all_tool_dict.keys())
|
|
161
|
+
|
|
162
|
+
def __contains__(self, name: str) -> bool:
|
|
163
|
+
"""Check if a tool exists."""
|
|
164
|
+
return name in self.engine.all_tool_dict
|
|
165
|
+
|
|
166
|
+
def refresh(self):
|
|
167
|
+
"""Refresh tool discovery (re-discover MCP/remote tools)."""
|
|
168
|
+
self.engine.refresh_tools()
|
|
169
|
+
|
|
170
|
+
def eager_load(self, names: Optional[List[str]] = None):
|
|
171
|
+
"""Pre-instantiate tools to reduce first-call latency."""
|
|
172
|
+
self.engine.eager_load_tools(names)
|
|
173
|
+
|
|
174
|
+
|
|
84
175
|
class ToolUniverse:
|
|
85
176
|
"""
|
|
86
177
|
A comprehensive tool management system for loading, organizing, and executing various scientific and data tools.
|
|
@@ -130,9 +221,9 @@ class ToolUniverse:
|
|
|
130
221
|
self.logger = get_logger("ToolUniverse")
|
|
131
222
|
|
|
132
223
|
# Initialize any necessary attributes here FIRST
|
|
133
|
-
self.all_tools = []
|
|
134
|
-
self.all_tool_dict = {}
|
|
135
|
-
self.tool_category_dicts = {}
|
|
224
|
+
self.all_tools: List[Dict[str, Any]] = []
|
|
225
|
+
self.all_tool_dict: Dict[str, Dict[str, Any]] = {}
|
|
226
|
+
self.tool_category_dicts: Dict[str, List[Dict[str, Any]]] = {}
|
|
136
227
|
self.tool_finder = None
|
|
137
228
|
if tool_files is None:
|
|
138
229
|
tool_files = default_tool_files
|
|
@@ -172,6 +263,46 @@ class ToolUniverse:
|
|
|
172
263
|
self.hook_manager = None
|
|
173
264
|
self.logger.debug("Output hooks disabled")
|
|
174
265
|
|
|
266
|
+
# Initialize caching configuration
|
|
267
|
+
cache_enabled = os.getenv("TOOLUNIVERSE_CACHE_ENABLED", "true").lower() in (
|
|
268
|
+
"true",
|
|
269
|
+
"1",
|
|
270
|
+
"yes",
|
|
271
|
+
)
|
|
272
|
+
persistence_enabled = os.getenv(
|
|
273
|
+
"TOOLUNIVERSE_CACHE_PERSIST", "true"
|
|
274
|
+
).lower() in ("true", "1", "yes")
|
|
275
|
+
memory_size = int(os.getenv("TOOLUNIVERSE_CACHE_MEMORY_SIZE", "256"))
|
|
276
|
+
default_ttl_env = os.getenv("TOOLUNIVERSE_CACHE_DEFAULT_TTL")
|
|
277
|
+
default_ttl = int(default_ttl_env) if default_ttl_env else None
|
|
278
|
+
singleflight_enabled = os.getenv(
|
|
279
|
+
"TOOLUNIVERSE_CACHE_SINGLEFLIGHT", "true"
|
|
280
|
+
).lower() in ("true", "1", "yes")
|
|
281
|
+
|
|
282
|
+
cache_path = os.getenv("TOOLUNIVERSE_CACHE_PATH")
|
|
283
|
+
if not cache_path and persistence_enabled:
|
|
284
|
+
base_dir = os.getenv("TOOLUNIVERSE_CACHE_DIR")
|
|
285
|
+
if not base_dir:
|
|
286
|
+
base_dir = os.path.join(str(Path.home()), ".tooluniverse")
|
|
287
|
+
os.makedirs(base_dir, exist_ok=True)
|
|
288
|
+
cache_path = os.path.join(base_dir, "cache.sqlite")
|
|
289
|
+
|
|
290
|
+
self.cache_manager = ResultCacheManager(
|
|
291
|
+
memory_size=memory_size,
|
|
292
|
+
persistent_path=cache_path if persistence_enabled else None,
|
|
293
|
+
enabled=cache_enabled,
|
|
294
|
+
persistence_enabled=persistence_enabled,
|
|
295
|
+
singleflight=singleflight_enabled,
|
|
296
|
+
default_ttl=default_ttl,
|
|
297
|
+
)
|
|
298
|
+
|
|
299
|
+
self._strict_validation = os.getenv(
|
|
300
|
+
"TOOLUNIVERSE_STRICT_VALIDATION", "false"
|
|
301
|
+
).lower() in ("true", "1", "yes")
|
|
302
|
+
|
|
303
|
+
# Initialize dynamic tools namespace
|
|
304
|
+
self.tools = ToolNamespace(self)
|
|
305
|
+
|
|
175
306
|
def register_custom_tool(self, tool_class, tool_name=None, tool_config=None):
|
|
176
307
|
"""
|
|
177
308
|
Register a custom tool class at runtime.
|
|
@@ -903,104 +1034,6 @@ class ToolUniverse:
|
|
|
903
1034
|
)
|
|
904
1035
|
self.logger.debug("_process_mcp_auto_loaders completed")
|
|
905
1036
|
|
|
906
|
-
def select_tools(
|
|
907
|
-
self,
|
|
908
|
-
include_names=None,
|
|
909
|
-
exclude_names=None,
|
|
910
|
-
include_categories=None,
|
|
911
|
-
exclude_categories=None,
|
|
912
|
-
):
|
|
913
|
-
"""
|
|
914
|
-
Select tools based on tool names and/or categories (tool_files keys).
|
|
915
|
-
|
|
916
|
-
Args:
|
|
917
|
-
include_names (list, optional): List of tool names to include. If None, include all.
|
|
918
|
-
exclude_names (list, optional): List of tool names to exclude.
|
|
919
|
-
include_categories (list, optional): List of categories (tool_files keys) to include.
|
|
920
|
-
If None, include all.
|
|
921
|
-
exclude_categories (list, optional): List of categories (tool_files keys) to exclude.
|
|
922
|
-
|
|
923
|
-
Returns:
|
|
924
|
-
list: List of selected tool configurations.
|
|
925
|
-
"""
|
|
926
|
-
selected_tools = []
|
|
927
|
-
# If categories are specified, use self.tool_category_dicts to filter
|
|
928
|
-
categories = set(self.tool_category_dicts.keys())
|
|
929
|
-
if include_categories is not None:
|
|
930
|
-
categories &= set(include_categories)
|
|
931
|
-
if exclude_categories is not None:
|
|
932
|
-
categories -= set(exclude_categories)
|
|
933
|
-
# Gather tools from selected categories
|
|
934
|
-
for cat in categories:
|
|
935
|
-
selected_tools.extend(self.tool_category_dicts[cat])
|
|
936
|
-
# Further filter by names if needed
|
|
937
|
-
if include_names is not None:
|
|
938
|
-
selected_tools = [
|
|
939
|
-
tool for tool in selected_tools if tool["name"] in include_names
|
|
940
|
-
]
|
|
941
|
-
if exclude_names is not None:
|
|
942
|
-
selected_tools = [
|
|
943
|
-
tool for tool in selected_tools if tool["name"] not in exclude_names
|
|
944
|
-
]
|
|
945
|
-
return selected_tools
|
|
946
|
-
|
|
947
|
-
def filter_tool_lists(
|
|
948
|
-
self,
|
|
949
|
-
tool_name_list,
|
|
950
|
-
tool_desc_list,
|
|
951
|
-
include_names=None,
|
|
952
|
-
exclude_names=None,
|
|
953
|
-
include_categories=None,
|
|
954
|
-
exclude_categories=None,
|
|
955
|
-
):
|
|
956
|
-
"""
|
|
957
|
-
Directly filter tool name and description lists based on names and/or categories.
|
|
958
|
-
|
|
959
|
-
This method takes existing tool name and description lists and filters them according
|
|
960
|
-
to the specified criteria using the select_tools method for category-based filtering.
|
|
961
|
-
|
|
962
|
-
Args:
|
|
963
|
-
tool_name_list (list): List of tool names to filter.
|
|
964
|
-
tool_desc_list (list): List of tool descriptions to filter (must correspond to tool_name_list).
|
|
965
|
-
include_names (list, optional): List of tool names to include.
|
|
966
|
-
exclude_names (list, optional): List of tool names to exclude.
|
|
967
|
-
include_categories (list, optional): List of categories to include.
|
|
968
|
-
exclude_categories (list, optional): List of categories to exclude.
|
|
969
|
-
|
|
970
|
-
Returns:
|
|
971
|
-
tuple: A tuple containing (filtered_tool_name_list, filtered_tool_desc_list).
|
|
972
|
-
"""
|
|
973
|
-
# Build a set of allowed tool names using select_tools for category filtering
|
|
974
|
-
allowed_names = set()
|
|
975
|
-
if any([include_names, exclude_names, include_categories, exclude_categories]):
|
|
976
|
-
filtered_tools = self.select_tools(
|
|
977
|
-
include_names=include_names,
|
|
978
|
-
exclude_names=exclude_names,
|
|
979
|
-
include_categories=include_categories,
|
|
980
|
-
exclude_categories=exclude_categories,
|
|
981
|
-
)
|
|
982
|
-
allowed_names = set(tool["name"] for tool in filtered_tools)
|
|
983
|
-
else:
|
|
984
|
-
allowed_names = set(tool_name_list)
|
|
985
|
-
|
|
986
|
-
# Filter lists by allowed_names
|
|
987
|
-
filtered_tool_name_list = []
|
|
988
|
-
filtered_tool_desc_list = []
|
|
989
|
-
for name, desc in zip(tool_name_list, tool_desc_list):
|
|
990
|
-
if name in allowed_names:
|
|
991
|
-
filtered_tool_name_list.append(name)
|
|
992
|
-
filtered_tool_desc_list.append(desc)
|
|
993
|
-
return filtered_tool_name_list, filtered_tool_desc_list
|
|
994
|
-
|
|
995
|
-
def return_all_loaded_tools(self):
|
|
996
|
-
"""
|
|
997
|
-
Return a deep copy of all loaded tools.
|
|
998
|
-
|
|
999
|
-
Returns:
|
|
1000
|
-
list: A deep copy of the all_tools list to prevent external modification.
|
|
1001
|
-
"""
|
|
1002
|
-
return copy.deepcopy(self.all_tools)
|
|
1003
|
-
|
|
1004
1037
|
def list_built_in_tools(self, mode="config", scan_all=False):
|
|
1005
1038
|
"""
|
|
1006
1039
|
List all built-in tool categories and their statistics with different modes.
|
|
@@ -1041,9 +1074,14 @@ class ToolUniverse:
|
|
|
1041
1074
|
- When scan_all=True, all JSON files in data/ and subdirectories are scanned
|
|
1042
1075
|
"""
|
|
1043
1076
|
if mode not in ["config", "type", "list_name", "list_spec"]:
|
|
1044
|
-
|
|
1045
|
-
|
|
1046
|
-
|
|
1077
|
+
# Handle invalid modes gracefully
|
|
1078
|
+
if mode is None:
|
|
1079
|
+
mode = "config" # Default to config mode
|
|
1080
|
+
else:
|
|
1081
|
+
# For invalid string modes, return error info instead of raising
|
|
1082
|
+
return {
|
|
1083
|
+
"error": f"Invalid mode '{mode}'. Must be one of: 'config', 'type', 'list_name', 'list_spec'"
|
|
1084
|
+
}
|
|
1047
1085
|
|
|
1048
1086
|
# For list_name and list_spec modes, we can return early with just the data
|
|
1049
1087
|
if mode in ["list_name", "list_spec"]:
|
|
@@ -1211,6 +1249,39 @@ class ToolUniverse:
|
|
|
1211
1249
|
|
|
1212
1250
|
return result
|
|
1213
1251
|
|
|
1252
|
+
def _read_tools_from_file(self, file_path):
|
|
1253
|
+
"""
|
|
1254
|
+
Read tools from a single JSON file with error handling.
|
|
1255
|
+
|
|
1256
|
+
Args:
|
|
1257
|
+
file_path (str): Path to the JSON file
|
|
1258
|
+
|
|
1259
|
+
Returns:
|
|
1260
|
+
list: List of tool configurations from the file
|
|
1261
|
+
"""
|
|
1262
|
+
try:
|
|
1263
|
+
tools_in_file = read_json_list(file_path)
|
|
1264
|
+
|
|
1265
|
+
# Handle different data formats
|
|
1266
|
+
if isinstance(tools_in_file, dict):
|
|
1267
|
+
# Convert dict of tools to list of tools
|
|
1268
|
+
tools_in_file = list(tools_in_file.values())
|
|
1269
|
+
elif not isinstance(tools_in_file, list):
|
|
1270
|
+
# Skip files that don't contain tool configurations
|
|
1271
|
+
return []
|
|
1272
|
+
|
|
1273
|
+
# Validate tools have required fields
|
|
1274
|
+
valid_tools = []
|
|
1275
|
+
for tool in tools_in_file:
|
|
1276
|
+
if isinstance(tool, dict) and "name" in tool:
|
|
1277
|
+
valid_tools.append(tool)
|
|
1278
|
+
|
|
1279
|
+
return valid_tools
|
|
1280
|
+
|
|
1281
|
+
except Exception as e:
|
|
1282
|
+
warning(f"Warning: Could not read tools from {file_path}: {e}")
|
|
1283
|
+
return []
|
|
1284
|
+
|
|
1214
1285
|
def _scan_predefined_files(self):
|
|
1215
1286
|
"""
|
|
1216
1287
|
Scan predefined tool files (original behavior).
|
|
@@ -1223,39 +1294,23 @@ class ToolUniverse:
|
|
|
1223
1294
|
all_tool_names = set()
|
|
1224
1295
|
|
|
1225
1296
|
# Read tools from each category file
|
|
1226
|
-
for
|
|
1227
|
-
|
|
1228
|
-
|
|
1229
|
-
|
|
1230
|
-
all_tools.extend(tools_in_category)
|
|
1231
|
-
all_tool_names.update([tool["name"] for tool in tools_in_category])
|
|
1232
|
-
except Exception as e:
|
|
1233
|
-
warning(
|
|
1234
|
-
f"Warning: Could not read tools from {category} ({file_path}): {e}"
|
|
1235
|
-
)
|
|
1297
|
+
for _category, file_path in self.tool_files.items():
|
|
1298
|
+
tools_in_category = self._read_tools_from_file(file_path)
|
|
1299
|
+
all_tools.extend(tools_in_category)
|
|
1300
|
+
all_tool_names.update([tool["name"] for tool in tools_in_category])
|
|
1236
1301
|
|
|
1237
1302
|
# Also include remote tools
|
|
1238
1303
|
try:
|
|
1239
1304
|
remote_dir = os.path.join(current_dir, "data", "remote_tools")
|
|
1240
1305
|
if os.path.isdir(remote_dir):
|
|
1241
|
-
remote_tools = []
|
|
1242
1306
|
for fname in os.listdir(remote_dir):
|
|
1243
1307
|
if not fname.lower().endswith(".json"):
|
|
1244
1308
|
continue
|
|
1245
1309
|
fpath = os.path.join(remote_dir, fname)
|
|
1246
|
-
|
|
1247
|
-
|
|
1248
|
-
|
|
1249
|
-
|
|
1250
|
-
if isinstance(tools_in_file, list):
|
|
1251
|
-
remote_tools.extend(tools_in_file)
|
|
1252
|
-
except Exception as e:
|
|
1253
|
-
warning(
|
|
1254
|
-
f"Warning: Could not read remote tools from {fpath}: {e}"
|
|
1255
|
-
)
|
|
1256
|
-
if remote_tools:
|
|
1257
|
-
all_tools.extend(remote_tools)
|
|
1258
|
-
all_tool_names.update([tool["name"] for tool in remote_tools])
|
|
1310
|
+
remote_tools = self._read_tools_from_file(fpath)
|
|
1311
|
+
if remote_tools:
|
|
1312
|
+
all_tools.extend(remote_tools)
|
|
1313
|
+
all_tool_names.update([tool["name"] for tool in remote_tools])
|
|
1259
1314
|
except Exception as e:
|
|
1260
1315
|
warning(f"Warning: Failed to scan remote tools directory: {e}")
|
|
1261
1316
|
|
|
@@ -1288,31 +1343,14 @@ class ToolUniverse:
|
|
|
1288
1343
|
|
|
1289
1344
|
self.logger.debug(f"Found {len(json_files)} JSON files to scan")
|
|
1290
1345
|
|
|
1291
|
-
# Read tools from each JSON file
|
|
1346
|
+
# Read tools from each JSON file using the common method
|
|
1292
1347
|
for json_file in json_files:
|
|
1293
|
-
|
|
1294
|
-
|
|
1295
|
-
|
|
1296
|
-
|
|
1297
|
-
if isinstance(tools_in_file, dict):
|
|
1298
|
-
# Convert dict of tools to list of tools
|
|
1299
|
-
tools_in_file = list(tools_in_file.values())
|
|
1300
|
-
elif not isinstance(tools_in_file, list):
|
|
1301
|
-
# Skip files that don't contain tool configurations
|
|
1302
|
-
continue
|
|
1303
|
-
|
|
1304
|
-
# Add tools to our collection
|
|
1305
|
-
for tool in tools_in_file:
|
|
1306
|
-
if isinstance(tool, dict) and "name" in tool:
|
|
1307
|
-
all_tools.append(tool)
|
|
1308
|
-
all_tool_names.add(tool["name"])
|
|
1309
|
-
|
|
1348
|
+
tools_in_file = self._read_tools_from_file(json_file)
|
|
1349
|
+
if tools_in_file:
|
|
1350
|
+
all_tools.extend(tools_in_file)
|
|
1351
|
+
all_tool_names.update([tool["name"] for tool in tools_in_file])
|
|
1310
1352
|
self.logger.debug(f"Loaded {len(tools_in_file)} tools from {json_file}")
|
|
1311
1353
|
|
|
1312
|
-
except Exception as e:
|
|
1313
|
-
warning(f"Warning: Could not read tools from {json_file}: {e}")
|
|
1314
|
-
continue
|
|
1315
|
-
|
|
1316
1354
|
self.logger.info(
|
|
1317
1355
|
f"Scanned {len(json_files)} JSON files, found {len(all_tools)} tools"
|
|
1318
1356
|
)
|
|
@@ -1387,63 +1425,42 @@ class ToolUniverse:
|
|
|
1387
1425
|
del tool[key]
|
|
1388
1426
|
return tool
|
|
1389
1427
|
|
|
1390
|
-
def prepare_tool_prompts(self, tool_list):
|
|
1391
|
-
"""
|
|
1392
|
-
Prepare a list of tool configurations for prompt usage.
|
|
1393
|
-
|
|
1394
|
-
Args:
|
|
1395
|
-
tool_list (list): List of tool configuration dictionaries.
|
|
1396
|
-
|
|
1397
|
-
Returns:
|
|
1398
|
-
list: List of tool configurations with only essential keys for prompting.
|
|
1399
|
-
"""
|
|
1400
|
-
copied_list = []
|
|
1401
|
-
for tool in tool_list:
|
|
1402
|
-
copied_list.append(self.prepare_one_tool_prompt(tool))
|
|
1403
|
-
return copied_list
|
|
1404
|
-
|
|
1405
|
-
def remove_keys(self, tool_list, invalid_keys):
|
|
1428
|
+
def prepare_tool_prompts(self, tool_list, mode="prompt", valid_keys=None):
|
|
1406
1429
|
"""
|
|
1407
|
-
|
|
1430
|
+
Prepare a list of tool configurations for different usage modes.
|
|
1408
1431
|
|
|
1409
1432
|
Args:
|
|
1410
1433
|
tool_list (list): List of tool configuration dictionaries.
|
|
1411
|
-
|
|
1434
|
+
mode (str): Preparation mode. Options:
|
|
1435
|
+
- 'prompt': Keep essential keys for prompting (name, description, parameter, required)
|
|
1436
|
+
- 'example': Keep extended keys for examples (name, description, parameter, required, query_schema, fields, label, type)
|
|
1437
|
+
- 'custom': Use custom valid_keys parameter
|
|
1438
|
+
valid_keys (list, optional): Custom list of keys to keep when mode='custom'.
|
|
1412
1439
|
|
|
1413
1440
|
Returns:
|
|
1414
|
-
list:
|
|
1415
|
-
"""
|
|
1416
|
-
|
|
1417
|
-
|
|
1418
|
-
|
|
1419
|
-
|
|
1420
|
-
|
|
1421
|
-
|
|
1422
|
-
|
|
1423
|
-
|
|
1424
|
-
|
|
1425
|
-
|
|
1426
|
-
|
|
1427
|
-
|
|
1428
|
-
|
|
1429
|
-
|
|
1430
|
-
|
|
1431
|
-
|
|
1432
|
-
|
|
1441
|
+
list: List of tool configurations with only specified keys.
|
|
1442
|
+
"""
|
|
1443
|
+
if mode == "prompt":
|
|
1444
|
+
valid_keys = ["name", "description", "parameter", "required"]
|
|
1445
|
+
elif mode == "example":
|
|
1446
|
+
valid_keys = [
|
|
1447
|
+
"name",
|
|
1448
|
+
"description",
|
|
1449
|
+
"parameter",
|
|
1450
|
+
"required",
|
|
1451
|
+
"query_schema",
|
|
1452
|
+
"fields",
|
|
1453
|
+
"label",
|
|
1454
|
+
"type",
|
|
1455
|
+
]
|
|
1456
|
+
elif mode == "custom":
|
|
1457
|
+
if valid_keys is None:
|
|
1458
|
+
raise ValueError("valid_keys must be provided when mode='custom'")
|
|
1459
|
+
else:
|
|
1460
|
+
raise ValueError(
|
|
1461
|
+
f"Invalid mode: {mode}. Must be 'prompt', 'example', or 'custom'"
|
|
1462
|
+
)
|
|
1433
1463
|
|
|
1434
|
-
Returns:
|
|
1435
|
-
list: Deep copy of tool list with only example-relevant keys.
|
|
1436
|
-
"""
|
|
1437
|
-
valid_keys = [
|
|
1438
|
-
"name",
|
|
1439
|
-
"description",
|
|
1440
|
-
"parameter",
|
|
1441
|
-
"required",
|
|
1442
|
-
"query_schema",
|
|
1443
|
-
"fields",
|
|
1444
|
-
"label",
|
|
1445
|
-
"type",
|
|
1446
|
-
]
|
|
1447
1464
|
copied_list = copy.deepcopy(tool_list)
|
|
1448
1465
|
for tool in copied_list:
|
|
1449
1466
|
# Create a list of keys to avoid modifying the dictionary during iteration
|
|
@@ -1472,21 +1489,6 @@ class ToolUniverse:
|
|
|
1472
1489
|
picked_tool_list.append(tool_spec)
|
|
1473
1490
|
return picked_tool_list
|
|
1474
1491
|
|
|
1475
|
-
def get_tool_by_name(self, tool_names, format="default"):
|
|
1476
|
-
"""
|
|
1477
|
-
Retrieve tool configurations by their names.
|
|
1478
|
-
|
|
1479
|
-
Args:
|
|
1480
|
-
tool_names (list): List of tool names to retrieve.
|
|
1481
|
-
format (str, optional): Output format. Options: 'default', 'openai'.
|
|
1482
|
-
If 'openai', returns OpenAI function calling format. Defaults to 'default'.
|
|
1483
|
-
|
|
1484
|
-
Returns:
|
|
1485
|
-
list: List of tool configurations for the specified names.
|
|
1486
|
-
Tools not found will be reported but not included in the result.
|
|
1487
|
-
"""
|
|
1488
|
-
return self.get_tool_specification_by_names(tool_names, format=format)
|
|
1489
|
-
|
|
1490
1492
|
def get_one_tool_by_one_name(self, tool_name, return_prompt=True):
|
|
1491
1493
|
"""
|
|
1492
1494
|
Retrieve a single tool specification by name, optionally prepared for prompting.
|
|
@@ -1521,65 +1523,58 @@ class ToolUniverse:
|
|
|
1521
1523
|
Returns:
|
|
1522
1524
|
dict or None: Tool configuration if found, None otherwise.
|
|
1523
1525
|
"""
|
|
1524
|
-
if tool_name in self.all_tool_dict:
|
|
1525
|
-
tool_config = self.all_tool_dict[tool_name]
|
|
1526
|
-
|
|
1527
|
-
if format == "openai":
|
|
1528
|
-
parameters = tool_config.get("parameter", {})
|
|
1529
|
-
if isinstance(parameters, dict):
|
|
1530
|
-
# 修复 required 字段格式
|
|
1531
|
-
if "properties" in parameters:
|
|
1532
|
-
for _prop_name, prop_config in parameters["properties"].items():
|
|
1533
|
-
if (
|
|
1534
|
-
isinstance(prop_config, dict)
|
|
1535
|
-
and "required" in prop_config
|
|
1536
|
-
):
|
|
1537
|
-
del prop_config["required"]
|
|
1538
|
-
|
|
1539
|
-
if "required" in parameters and not isinstance(
|
|
1540
|
-
parameters["required"], list
|
|
1541
|
-
):
|
|
1542
|
-
if parameters["required"] is True:
|
|
1543
|
-
required_list = []
|
|
1544
|
-
if "properties" in parameters:
|
|
1545
|
-
for prop_name, prop_config in parameters[
|
|
1546
|
-
"properties"
|
|
1547
|
-
].items():
|
|
1548
|
-
if (
|
|
1549
|
-
isinstance(prop_config, dict)
|
|
1550
|
-
and prop_config.get("required") is True
|
|
1551
|
-
):
|
|
1552
|
-
required_list.append(prop_name)
|
|
1553
|
-
parameters["required"] = required_list
|
|
1554
|
-
else:
|
|
1555
|
-
parameters["required"] = []
|
|
1556
|
-
|
|
1557
|
-
return {
|
|
1558
|
-
"name": tool_config["name"],
|
|
1559
|
-
"description": tool_config["description"],
|
|
1560
|
-
"parameters": parameters,
|
|
1561
|
-
}
|
|
1562
|
-
elif return_prompt:
|
|
1563
|
-
return self.prepare_one_tool_prompt(tool_config)
|
|
1564
|
-
else:
|
|
1565
|
-
return tool_config
|
|
1566
|
-
else:
|
|
1526
|
+
if tool_name not in self.all_tool_dict:
|
|
1567
1527
|
warning(f"Tool name {tool_name} not found in the loaded tools.")
|
|
1568
1528
|
return None
|
|
1569
1529
|
|
|
1570
|
-
|
|
1571
|
-
"""
|
|
1572
|
-
Get the description of a tool by its name.
|
|
1530
|
+
tool_config = self.all_tool_dict[tool_name]
|
|
1573
1531
|
|
|
1574
|
-
|
|
1532
|
+
if return_prompt:
|
|
1533
|
+
return self.prepare_one_tool_prompt(tool_config)
|
|
1575
1534
|
|
|
1576
|
-
|
|
1577
|
-
|
|
1535
|
+
# Process parameter schema based on format
|
|
1536
|
+
if "parameter" in tool_config and isinstance(tool_config["parameter"], dict):
|
|
1537
|
+
import copy
|
|
1578
1538
|
|
|
1579
|
-
|
|
1580
|
-
|
|
1581
|
-
|
|
1582
|
-
|
|
1539
|
+
processed_config = copy.deepcopy(tool_config)
|
|
1540
|
+
parameter_schema = processed_config["parameter"]
|
|
1541
|
+
|
|
1542
|
+
if (
|
|
1543
|
+
"properties" in parameter_schema
|
|
1544
|
+
and parameter_schema["properties"] is not None
|
|
1545
|
+
):
|
|
1546
|
+
required_properties = parameter_schema.get("required", [])
|
|
1547
|
+
|
|
1548
|
+
if format == "openai":
|
|
1549
|
+
# For OpenAI format: remove property-level required fields
|
|
1550
|
+
for _prop_name, prop_config in parameter_schema[
|
|
1551
|
+
"properties"
|
|
1552
|
+
].items():
|
|
1553
|
+
if isinstance(prop_config, dict) and "required" in prop_config:
|
|
1554
|
+
del prop_config["required"]
|
|
1555
|
+
|
|
1556
|
+
# Ensure required is a list
|
|
1557
|
+
if not isinstance(parameter_schema.get("required"), list):
|
|
1558
|
+
parameter_schema["required"] = (
|
|
1559
|
+
required_properties if required_properties else []
|
|
1560
|
+
)
|
|
1561
|
+
|
|
1562
|
+
return {
|
|
1563
|
+
"name": processed_config["name"],
|
|
1564
|
+
"description": processed_config["description"],
|
|
1565
|
+
"parameters": parameter_schema,
|
|
1566
|
+
}
|
|
1567
|
+
else:
|
|
1568
|
+
# For default format: add required fields to properties
|
|
1569
|
+
for prop_name, prop_config in parameter_schema[
|
|
1570
|
+
"properties"
|
|
1571
|
+
].items():
|
|
1572
|
+
if isinstance(prop_config, dict):
|
|
1573
|
+
prop_config["required"] = prop_name in required_properties
|
|
1574
|
+
|
|
1575
|
+
return processed_config
|
|
1576
|
+
|
|
1577
|
+
return tool_config
|
|
1583
1578
|
|
|
1584
1579
|
def get_tool_type_by_name(self, tool_name):
|
|
1585
1580
|
"""
|
|
@@ -1596,6 +1591,15 @@ class ToolUniverse:
|
|
|
1596
1591
|
"""
|
|
1597
1592
|
return self.all_tool_dict[tool_name]["type"]
|
|
1598
1593
|
|
|
1594
|
+
def call_id_gen(self):
|
|
1595
|
+
"""
|
|
1596
|
+
Generate a random call ID for function calls.
|
|
1597
|
+
|
|
1598
|
+
Returns:
|
|
1599
|
+
str: A random 9-character string composed of letters and digits.
|
|
1600
|
+
"""
|
|
1601
|
+
return "".join(random.choices(string.ascii_letters + string.digits, k=9))
|
|
1602
|
+
|
|
1599
1603
|
def tool_to_str(self, tool_list):
|
|
1600
1604
|
"""
|
|
1601
1605
|
Convert a list of tool configurations to a formatted string.
|
|
@@ -1630,14 +1634,14 @@ class ToolUniverse:
|
|
|
1630
1634
|
lst, return_message=return_message, verbose=verbose, format=format
|
|
1631
1635
|
)
|
|
1632
1636
|
|
|
1633
|
-
def
|
|
1637
|
+
def return_all_loaded_tools(self):
|
|
1634
1638
|
"""
|
|
1635
|
-
|
|
1639
|
+
Return a deep copy of all loaded tools.
|
|
1636
1640
|
|
|
1637
1641
|
Returns:
|
|
1638
|
-
|
|
1642
|
+
list: A deep copy of the all_tools list to prevent external modification.
|
|
1639
1643
|
"""
|
|
1640
|
-
return
|
|
1644
|
+
return copy.deepcopy(self.all_tools)
|
|
1641
1645
|
|
|
1642
1646
|
def run(
|
|
1643
1647
|
self,
|
|
@@ -1708,7 +1712,9 @@ class ToolUniverse:
|
|
|
1708
1712
|
error("Not a function call")
|
|
1709
1713
|
return None
|
|
1710
1714
|
|
|
1711
|
-
def run_one_function(
|
|
1715
|
+
def run_one_function(
|
|
1716
|
+
self, function_call_json, stream_callback=None, use_cache=False, validate=True
|
|
1717
|
+
):
|
|
1712
1718
|
"""
|
|
1713
1719
|
Execute a single function call.
|
|
1714
1720
|
|
|
@@ -1718,67 +1724,155 @@ class ToolUniverse:
|
|
|
1718
1724
|
|
|
1719
1725
|
Args:
|
|
1720
1726
|
function_call_json (dict): Dictionary containing function name and arguments.
|
|
1727
|
+
stream_callback (callable, optional): Callback for streaming responses.
|
|
1728
|
+
use_cache (bool, optional): Whether to use result caching. Defaults to False.
|
|
1729
|
+
validate (bool, optional): Whether to validate parameters against schema. Defaults to True.
|
|
1721
1730
|
|
|
1722
1731
|
Returns:
|
|
1723
1732
|
str or dict: Result from the tool execution, or error message if validation fails.
|
|
1724
1733
|
"""
|
|
1725
|
-
|
|
1726
|
-
|
|
1727
|
-
return (
|
|
1728
|
-
"Invalid function call: " + check_message
|
|
1729
|
-
) # + " You must correct your invalid function call!"
|
|
1730
|
-
function_name = function_call_json["name"]
|
|
1731
|
-
arguments = function_call_json["arguments"]
|
|
1734
|
+
function_name = function_call_json.get("name", "")
|
|
1735
|
+
arguments = function_call_json.get("arguments", {})
|
|
1732
1736
|
|
|
1733
|
-
#
|
|
1734
|
-
|
|
1735
|
-
|
|
1736
|
-
|
|
1737
|
-
|
|
1738
|
-
|
|
1739
|
-
|
|
1740
|
-
|
|
1741
|
-
|
|
1742
|
-
|
|
1743
|
-
|
|
1744
|
-
|
|
1745
|
-
|
|
1746
|
-
|
|
1747
|
-
|
|
1737
|
+
# Handle malformed queries gracefully
|
|
1738
|
+
if not function_name:
|
|
1739
|
+
return {"error": "Missing or empty function name"}
|
|
1740
|
+
|
|
1741
|
+
if not isinstance(arguments, dict):
|
|
1742
|
+
return {
|
|
1743
|
+
"error": f"Arguments must be a dictionary, got {type(arguments).__name__}"
|
|
1744
|
+
}
|
|
1745
|
+
|
|
1746
|
+
tool_instance = None
|
|
1747
|
+
cache_namespace = None
|
|
1748
|
+
cache_version = None
|
|
1749
|
+
cache_key = None
|
|
1750
|
+
composed_cache_key = None
|
|
1751
|
+
cache_guard = nullcontext()
|
|
1752
|
+
|
|
1753
|
+
cache_enabled = (
|
|
1754
|
+
use_cache and self.cache_manager is not None and self.cache_manager.enabled
|
|
1755
|
+
)
|
|
1756
|
+
|
|
1757
|
+
if cache_enabled:
|
|
1758
|
+
tool_instance = self._get_tool_instance(function_name, cache=True)
|
|
1759
|
+
if tool_instance and tool_instance.supports_caching():
|
|
1760
|
+
cache_namespace = tool_instance.get_cache_namespace()
|
|
1761
|
+
cache_version = tool_instance.get_cache_version()
|
|
1762
|
+
cache_key = self._make_cache_key(function_name, arguments)
|
|
1763
|
+
composed_cache_key = self.cache_manager.compose_key(
|
|
1764
|
+
cache_namespace, cache_version, cache_key
|
|
1748
1765
|
)
|
|
1749
|
-
|
|
1750
|
-
|
|
1751
|
-
|
|
1766
|
+
cached_value = self.cache_manager.get(
|
|
1767
|
+
namespace=cache_namespace,
|
|
1768
|
+
version=cache_version,
|
|
1769
|
+
cache_key=cache_key,
|
|
1752
1770
|
)
|
|
1771
|
+
if cached_value is not None:
|
|
1772
|
+
self.logger.debug(f"Cache hit for {function_name}")
|
|
1773
|
+
return cached_value
|
|
1774
|
+
cache_guard = self.cache_manager.singleflight_guard(composed_cache_key)
|
|
1753
1775
|
else:
|
|
1754
|
-
|
|
1755
|
-
|
|
1756
|
-
|
|
1757
|
-
|
|
1758
|
-
|
|
1759
|
-
|
|
1760
|
-
|
|
1761
|
-
|
|
1762
|
-
|
|
1763
|
-
|
|
1764
|
-
|
|
1765
|
-
|
|
1766
|
-
|
|
1767
|
-
|
|
1768
|
-
|
|
1769
|
-
|
|
1770
|
-
|
|
1776
|
+
cache_enabled = False
|
|
1777
|
+
|
|
1778
|
+
with cache_guard:
|
|
1779
|
+
if cache_enabled:
|
|
1780
|
+
cached_value = self.cache_manager.get(
|
|
1781
|
+
namespace=cache_namespace,
|
|
1782
|
+
version=cache_version,
|
|
1783
|
+
cache_key=cache_key,
|
|
1784
|
+
)
|
|
1785
|
+
if cached_value is not None:
|
|
1786
|
+
self.logger.debug(
|
|
1787
|
+
f"Cache hit for {function_name} (after singleflight wait)"
|
|
1788
|
+
)
|
|
1789
|
+
return cached_value
|
|
1790
|
+
|
|
1791
|
+
# Validate parameters if requested
|
|
1792
|
+
if validate:
|
|
1793
|
+
validation_error = self._validate_parameters(function_name, arguments)
|
|
1794
|
+
if validation_error:
|
|
1795
|
+
return self._create_dual_format_error(validation_error)
|
|
1796
|
+
|
|
1797
|
+
# Check function call format (existing validation)
|
|
1798
|
+
check_status, check_message = self.check_function_call(function_call_json)
|
|
1799
|
+
if check_status is False:
|
|
1800
|
+
error_msg = "Invalid function call: " + check_message
|
|
1801
|
+
return self._create_dual_format_error(
|
|
1802
|
+
ToolValidationError(
|
|
1803
|
+
error_msg, details={"check_message": check_message}
|
|
1804
|
+
)
|
|
1805
|
+
)
|
|
1771
1806
|
|
|
1772
|
-
|
|
1807
|
+
# Execute the tool
|
|
1808
|
+
tool_arguments = arguments
|
|
1809
|
+
try:
|
|
1810
|
+
if tool_instance is None:
|
|
1811
|
+
tool_instance = self._get_tool_instance(function_name, cache=True)
|
|
1812
|
+
|
|
1813
|
+
if tool_instance:
|
|
1814
|
+
result, tool_arguments = self._execute_tool_with_stream(
|
|
1815
|
+
tool_instance, arguments, stream_callback, use_cache, validate
|
|
1816
|
+
)
|
|
1817
|
+
else:
|
|
1818
|
+
error_msg = f"Tool '{function_name}' not found"
|
|
1819
|
+
return self._create_dual_format_error(
|
|
1820
|
+
ToolUnavailableError(
|
|
1821
|
+
error_msg,
|
|
1822
|
+
next_steps=[
|
|
1823
|
+
"Check tool name spelling",
|
|
1824
|
+
"Run tu.tools.refresh()",
|
|
1825
|
+
],
|
|
1826
|
+
)
|
|
1827
|
+
)
|
|
1828
|
+
except Exception as e:
|
|
1829
|
+
# Classify and return structured error
|
|
1830
|
+
classified_error = self._classify_exception(e, function_name, arguments)
|
|
1831
|
+
return self._create_dual_format_error(classified_error)
|
|
1832
|
+
|
|
1833
|
+
# Apply output hooks if enabled
|
|
1834
|
+
if self.hook_manager:
|
|
1835
|
+
context = {
|
|
1836
|
+
"tool_name": function_name,
|
|
1837
|
+
"tool_type": (
|
|
1838
|
+
tool_instance.__class__.__name__
|
|
1839
|
+
if tool_instance is not None
|
|
1840
|
+
else "unknown"
|
|
1841
|
+
),
|
|
1842
|
+
"execution_time": time.time(),
|
|
1843
|
+
"arguments": tool_arguments,
|
|
1844
|
+
}
|
|
1845
|
+
result = self.hook_manager.apply_hooks(
|
|
1846
|
+
result, function_name, tool_arguments, context
|
|
1847
|
+
)
|
|
1848
|
+
|
|
1849
|
+
# Cache result if enabled
|
|
1850
|
+
if cache_enabled and tool_instance and tool_instance.supports_caching():
|
|
1851
|
+
if cache_key is None:
|
|
1852
|
+
cache_key = self._make_cache_key(function_name, arguments)
|
|
1853
|
+
if cache_namespace is None:
|
|
1854
|
+
cache_namespace = tool_instance.get_cache_namespace()
|
|
1855
|
+
if cache_version is None:
|
|
1856
|
+
cache_version = tool_instance.get_cache_version()
|
|
1857
|
+
ttl = tool_instance.get_cache_ttl(result)
|
|
1858
|
+
self.cache_manager.set(
|
|
1859
|
+
namespace=cache_namespace,
|
|
1860
|
+
version=cache_version,
|
|
1861
|
+
cache_key=cache_key,
|
|
1862
|
+
value=result,
|
|
1863
|
+
ttl=ttl,
|
|
1864
|
+
)
|
|
1773
1865
|
|
|
1774
|
-
|
|
1775
|
-
|
|
1866
|
+
return result
|
|
1867
|
+
|
|
1868
|
+
def _execute_tool_with_stream(
|
|
1869
|
+
self, tool_instance, arguments, stream_callback, use_cache=False, validate=True
|
|
1870
|
+
):
|
|
1871
|
+
"""Invoke a tool, forwarding stream callbacks and other parameters when supported."""
|
|
1776
1872
|
|
|
1777
1873
|
tool_arguments = arguments
|
|
1778
1874
|
stream_flag_key = (
|
|
1779
|
-
getattr(tool_instance, "STREAM_FLAG_KEY", None)
|
|
1780
|
-
if stream_callback
|
|
1781
|
-
else None
|
|
1875
|
+
getattr(tool_instance, "STREAM_FLAG_KEY", None) if stream_callback else None
|
|
1782
1876
|
)
|
|
1783
1877
|
|
|
1784
1878
|
if isinstance(arguments, dict):
|
|
@@ -1791,24 +1885,30 @@ class ToolUniverse:
|
|
|
1791
1885
|
):
|
|
1792
1886
|
tool_arguments[stream_flag_key] = True
|
|
1793
1887
|
|
|
1794
|
-
|
|
1795
|
-
return tool_instance.run(tool_arguments), tool_arguments
|
|
1796
|
-
|
|
1888
|
+
# Try to pass all available parameters to the tool
|
|
1797
1889
|
try:
|
|
1798
1890
|
signature = inspect.signature(tool_instance.run)
|
|
1799
|
-
|
|
1800
|
-
|
|
1801
|
-
|
|
1802
|
-
|
|
1803
|
-
|
|
1804
|
-
|
|
1805
|
-
|
|
1806
|
-
|
|
1807
|
-
|
|
1808
|
-
|
|
1809
|
-
|
|
1810
|
-
|
|
1811
|
-
|
|
1891
|
+
params = signature.parameters
|
|
1892
|
+
|
|
1893
|
+
# Build kwargs based on what the tool accepts
|
|
1894
|
+
kwargs = {}
|
|
1895
|
+
|
|
1896
|
+
# Always include arguments as first positional argument
|
|
1897
|
+
if stream_callback is not None and "stream_callback" in params:
|
|
1898
|
+
kwargs["stream_callback"] = stream_callback
|
|
1899
|
+
if "use_cache" in params:
|
|
1900
|
+
kwargs["use_cache"] = use_cache
|
|
1901
|
+
if "validate" in params:
|
|
1902
|
+
kwargs["validate"] = validate
|
|
1903
|
+
|
|
1904
|
+
# Call with all supported parameters
|
|
1905
|
+
return tool_instance.run(tool_arguments, **kwargs), tool_arguments
|
|
1906
|
+
|
|
1907
|
+
except (ValueError, TypeError) as e:
|
|
1908
|
+
# If inspection fails or tool doesn't accept extra params,
|
|
1909
|
+
# fall back to simple execution with just arguments
|
|
1910
|
+
self.logger.debug(f"Falling back to simple run() call: {e}")
|
|
1911
|
+
return tool_instance.run(tool_arguments), tool_arguments
|
|
1812
1912
|
|
|
1813
1913
|
def toggle_hooks(self, enabled: bool):
|
|
1814
1914
|
"""
|
|
@@ -1845,65 +1945,239 @@ class ToolUniverse:
|
|
|
1845
1945
|
add_to_cache (bool, optional): Whether to cache the initialized tool. Defaults to True.
|
|
1846
1946
|
|
|
1847
1947
|
Returns:
|
|
1848
|
-
object: Initialized tool instance.
|
|
1948
|
+
object: Initialized tool instance or None if initialization fails.
|
|
1849
1949
|
|
|
1850
1950
|
Raises:
|
|
1851
1951
|
KeyError: If the tool type is not found in tool_type_mappings.
|
|
1852
1952
|
"""
|
|
1853
1953
|
global tool_type_mappings
|
|
1854
1954
|
|
|
1855
|
-
|
|
1856
|
-
|
|
1857
|
-
|
|
1858
|
-
|
|
1859
|
-
|
|
1860
|
-
|
|
1861
|
-
|
|
1862
|
-
|
|
1863
|
-
|
|
1864
|
-
|
|
1865
|
-
|
|
1866
|
-
|
|
1867
|
-
|
|
1868
|
-
|
|
1869
|
-
|
|
1870
|
-
|
|
1871
|
-
|
|
1872
|
-
|
|
1873
|
-
|
|
1874
|
-
|
|
1875
|
-
|
|
1876
|
-
|
|
1877
|
-
if "
|
|
1878
|
-
|
|
1955
|
+
try:
|
|
1956
|
+
if tool_name is not None:
|
|
1957
|
+
# Use lazy loading to get the tool class
|
|
1958
|
+
tool_class = get_tool_class_lazy(tool_name)
|
|
1959
|
+
if tool_class is None:
|
|
1960
|
+
raise KeyError(f"Tool type '{tool_name}' not found in registry")
|
|
1961
|
+
new_tool = tool_class()
|
|
1962
|
+
else:
|
|
1963
|
+
tool_type = tool["type"]
|
|
1964
|
+
tool_name = tool["name"]
|
|
1965
|
+
|
|
1966
|
+
# Use lazy loading to get the tool class
|
|
1967
|
+
tool_class = get_tool_class_lazy(tool_type)
|
|
1968
|
+
if tool_class is None:
|
|
1969
|
+
# Fallback to old method if lazy loading fails
|
|
1970
|
+
if tool_type not in tool_type_mappings:
|
|
1971
|
+
# Refresh registry and try again
|
|
1972
|
+
tool_type_mappings = get_tool_registry()
|
|
1973
|
+
if tool_type not in tool_type_mappings:
|
|
1974
|
+
raise KeyError(f"Tool type '{tool_type}' not found in registry")
|
|
1975
|
+
tool_class = tool_type_mappings[tool_type]
|
|
1976
|
+
|
|
1977
|
+
if "OpentargetToolDrugNameMatch" == tool_type:
|
|
1978
|
+
if (
|
|
1879
1979
|
"FDADrugLabelGetDrugGenericNameTool"
|
|
1880
|
-
|
|
1881
|
-
|
|
1882
|
-
drug_tool_class =
|
|
1980
|
+
not in self.callable_functions
|
|
1981
|
+
):
|
|
1982
|
+
drug_tool_class = get_tool_class_lazy(
|
|
1883
1983
|
"FDADrugLabelGetDrugGenericNameTool"
|
|
1884
|
-
|
|
1885
|
-
|
|
1886
|
-
|
|
1984
|
+
)
|
|
1985
|
+
if drug_tool_class is None:
|
|
1986
|
+
drug_tool_class = tool_type_mappings[
|
|
1987
|
+
"FDADrugLabelGetDrugGenericNameTool"
|
|
1988
|
+
]
|
|
1989
|
+
self.callable_functions[
|
|
1990
|
+
"FDADrugLabelGetDrugGenericNameTool"
|
|
1991
|
+
] = drug_tool_class()
|
|
1992
|
+
new_tool = tool_class(
|
|
1993
|
+
tool_config=tool,
|
|
1994
|
+
drug_generic_tool=self.callable_functions[
|
|
1995
|
+
"FDADrugLabelGetDrugGenericNameTool"
|
|
1996
|
+
],
|
|
1887
1997
|
)
|
|
1888
|
-
|
|
1889
|
-
tool_config=tool,
|
|
1890
|
-
|
|
1891
|
-
|
|
1892
|
-
|
|
1893
|
-
|
|
1894
|
-
|
|
1895
|
-
|
|
1896
|
-
|
|
1897
|
-
|
|
1898
|
-
|
|
1899
|
-
|
|
1900
|
-
|
|
1901
|
-
|
|
1902
|
-
|
|
1903
|
-
|
|
1904
|
-
|
|
1905
|
-
|
|
1906
|
-
|
|
1998
|
+
elif "ToolFinderEmbedding" == tool_type:
|
|
1999
|
+
new_tool = tool_class(tool_config=tool, tooluniverse=self)
|
|
2000
|
+
elif "ComposeTool" == tool_type:
|
|
2001
|
+
new_tool = tool_class(tool_config=tool, tooluniverse=self)
|
|
2002
|
+
elif "ToolFinderLLM" == tool_type:
|
|
2003
|
+
new_tool = tool_class(tool_config=tool, tooluniverse=self)
|
|
2004
|
+
elif "ToolFinderKeyword" == tool_type:
|
|
2005
|
+
new_tool = tool_class(tool_config=tool, tooluniverse=self)
|
|
2006
|
+
else:
|
|
2007
|
+
new_tool = tool_class(tool_config=tool)
|
|
2008
|
+
|
|
2009
|
+
if add_to_cache:
|
|
2010
|
+
self.callable_functions[tool_name] = new_tool
|
|
2011
|
+
return new_tool
|
|
2012
|
+
|
|
2013
|
+
except Exception as e:
|
|
2014
|
+
tool_type = tool_name if tool_name else tool.get("type")
|
|
2015
|
+
mark_tool_unavailable(tool_type, e)
|
|
2016
|
+
self.logger.warning(f"Failed to initialize '{tool_type}': {e}")
|
|
2017
|
+
return None # Return None instead of raising
|
|
2018
|
+
|
|
2019
|
+
def _get_tool_instance(self, function_name: str, cache: bool = True):
|
|
2020
|
+
"""Get or create tool instance with optional caching."""
|
|
2021
|
+
# Check cache first
|
|
2022
|
+
if function_name in self.callable_functions:
|
|
2023
|
+
return self.callable_functions[function_name]
|
|
2024
|
+
|
|
2025
|
+
# Check if known unavailable
|
|
2026
|
+
tool_errors = get_tool_errors()
|
|
2027
|
+
if function_name in tool_errors:
|
|
2028
|
+
self.logger.debug(f"Tool {function_name} is unavailable")
|
|
2029
|
+
return None
|
|
2030
|
+
|
|
2031
|
+
# Try to initialize
|
|
2032
|
+
if function_name in self.all_tool_dict:
|
|
2033
|
+
return self.init_tool(self.all_tool_dict[function_name], add_to_cache=cache)
|
|
2034
|
+
|
|
2035
|
+
return None
|
|
2036
|
+
|
|
2037
|
+
def _make_cache_key(self, function_name: str, arguments: dict) -> str:
|
|
2038
|
+
"""Generate cache key by delegating to BaseTool."""
|
|
2039
|
+
tool_instance = self._get_tool_instance(function_name, cache=False)
|
|
2040
|
+
|
|
2041
|
+
if tool_instance:
|
|
2042
|
+
return tool_instance.get_cache_key(arguments)
|
|
2043
|
+
|
|
2044
|
+
# Fallback: simple hash-based key
|
|
2045
|
+
serialized = json.dumps(
|
|
2046
|
+
{"name": function_name, "args": arguments}, sort_keys=True
|
|
2047
|
+
)
|
|
2048
|
+
return hashlib.md5(serialized.encode()).hexdigest()
|
|
2049
|
+
|
|
2050
|
+
def _validate_parameters(
|
|
2051
|
+
self, function_name: str, arguments: dict
|
|
2052
|
+
) -> Optional[ToolError]:
|
|
2053
|
+
"""Validate parameters by delegating to BaseTool."""
|
|
2054
|
+
if function_name not in self.all_tool_dict:
|
|
2055
|
+
return ToolUnavailableError(f"Tool '{function_name}' not found")
|
|
2056
|
+
|
|
2057
|
+
tool_instance = self._get_tool_instance(function_name, cache=False)
|
|
2058
|
+
if not tool_instance:
|
|
2059
|
+
return ToolConfigError("Failed to initialize tool for validation")
|
|
2060
|
+
|
|
2061
|
+
# Check if tool has validate_parameters method (for backward compatibility)
|
|
2062
|
+
if hasattr(tool_instance, "validate_parameters"):
|
|
2063
|
+
return tool_instance.validate_parameters(arguments)
|
|
2064
|
+
else:
|
|
2065
|
+
# Fallback for old-style tools without validate_parameters
|
|
2066
|
+
# Just return None (no validation) to maintain backward compatibility
|
|
2067
|
+
return None
|
|
2068
|
+
|
|
2069
|
+
def _check_basic_type(self, value: Any, expected_type: str) -> bool:
|
|
2070
|
+
"""Check if value matches expected basic type."""
|
|
2071
|
+
type_mapping = {
|
|
2072
|
+
"string": str,
|
|
2073
|
+
"integer": int,
|
|
2074
|
+
"number": (int, float),
|
|
2075
|
+
"boolean": bool,
|
|
2076
|
+
"object": dict,
|
|
2077
|
+
"array": list,
|
|
2078
|
+
}
|
|
2079
|
+
|
|
2080
|
+
if expected_type not in type_mapping:
|
|
2081
|
+
return True # Unknown type, skip validation
|
|
2082
|
+
|
|
2083
|
+
expected_python_type = type_mapping[expected_type]
|
|
2084
|
+
return isinstance(value, expected_python_type)
|
|
2085
|
+
|
|
2086
|
+
def _classify_exception(
|
|
2087
|
+
self, exception: Exception, function_name: str, arguments: dict
|
|
2088
|
+
) -> ToolError:
|
|
2089
|
+
"""Classify exception by delegating to BaseTool."""
|
|
2090
|
+
tool_instance = self._get_tool_instance(function_name, cache=False)
|
|
2091
|
+
|
|
2092
|
+
if tool_instance:
|
|
2093
|
+
return tool_instance.handle_error(exception)
|
|
2094
|
+
|
|
2095
|
+
# Fallback for tool instance creation failure
|
|
2096
|
+
return ToolServerError(f"Unexpected error calling {function_name}: {exception}")
|
|
2097
|
+
|
|
2098
|
+
def _create_dual_format_error(self, error: ToolError) -> dict:
|
|
2099
|
+
"""Create dual-format error response for backward compatibility."""
|
|
2100
|
+
return {
|
|
2101
|
+
"error": str(error), # Backward compatible string
|
|
2102
|
+
"error_details": error.to_dict(), # New structured format
|
|
2103
|
+
}
|
|
2104
|
+
|
|
2105
|
+
def refresh_tools(self):
|
|
2106
|
+
"""Refresh tool discovery (re-discover MCP/remote tools, reload configs)."""
|
|
2107
|
+
# TODO: Implement MCP tool re-discovery
|
|
2108
|
+
# For now, just reload tool configurations
|
|
2109
|
+
self.logger.info("Refreshing tool configurations...")
|
|
2110
|
+
# This could be extended to re-discover MCP tools, reload configs, etc.
|
|
2111
|
+
self.logger.info("Tool refresh completed")
|
|
2112
|
+
|
|
2113
|
+
def eager_load_tools(self, names: Optional[List[str]] = None):
|
|
2114
|
+
"""Pre-instantiate tools to reduce first-call latency."""
|
|
2115
|
+
tool_names = names or list(self.all_tool_dict.keys())
|
|
2116
|
+
self.logger.info(f"Eager loading {len(tool_names)} tools...")
|
|
2117
|
+
|
|
2118
|
+
for tool_name in tool_names:
|
|
2119
|
+
if (
|
|
2120
|
+
tool_name in self.all_tool_dict
|
|
2121
|
+
and tool_name not in self.callable_functions
|
|
2122
|
+
):
|
|
2123
|
+
try:
|
|
2124
|
+
self.init_tool(self.all_tool_dict[tool_name], add_to_cache=True)
|
|
2125
|
+
self.logger.debug(f"Eager loaded: {tool_name}")
|
|
2126
|
+
except Exception as e:
|
|
2127
|
+
self.logger.warning(f"Failed to eager load {tool_name}: {e}")
|
|
2128
|
+
|
|
2129
|
+
self.logger.info(
|
|
2130
|
+
f"Eager loading completed. {len(self.callable_functions)} tools cached."
|
|
2131
|
+
)
|
|
2132
|
+
|
|
2133
|
+
def clear_cache(self):
|
|
2134
|
+
"""Clear the result cache."""
|
|
2135
|
+
if self.cache_manager:
|
|
2136
|
+
self.cache_manager.clear()
|
|
2137
|
+
self.logger.info("Result cache cleared")
|
|
2138
|
+
|
|
2139
|
+
def get_cache_stats(self) -> Dict[str, Any]:
|
|
2140
|
+
"""Return cache statistics."""
|
|
2141
|
+
if not self.cache_manager:
|
|
2142
|
+
return {"enabled": False}
|
|
2143
|
+
return self.cache_manager.stats()
|
|
2144
|
+
|
|
2145
|
+
def dump_cache(self, namespace: Optional[str] = None):
|
|
2146
|
+
"""Iterate over cached entries (persistent layer only)."""
|
|
2147
|
+
if not self.cache_manager:
|
|
2148
|
+
return iter([])
|
|
2149
|
+
return self.cache_manager.dump(namespace=namespace)
|
|
2150
|
+
|
|
2151
|
+
def close(self):
|
|
2152
|
+
"""Release resources."""
|
|
2153
|
+
if self.cache_manager:
|
|
2154
|
+
self.cache_manager.close()
|
|
2155
|
+
|
|
2156
|
+
def __del__(self):
|
|
2157
|
+
try:
|
|
2158
|
+
self.close()
|
|
2159
|
+
except Exception:
|
|
2160
|
+
pass
|
|
2161
|
+
|
|
2162
|
+
def get_tool_health(self, tool_name: str = None) -> dict:
|
|
2163
|
+
"""Get health status for tool(s)."""
|
|
2164
|
+
tool_errors = get_tool_errors()
|
|
2165
|
+
|
|
2166
|
+
if tool_name:
|
|
2167
|
+
if tool_name in tool_errors:
|
|
2168
|
+
return tool_errors[tool_name]
|
|
2169
|
+
elif tool_name in self.all_tool_dict:
|
|
2170
|
+
return {"available": True}
|
|
2171
|
+
return {"available": False, "error": "Not found"}
|
|
2172
|
+
|
|
2173
|
+
# Summary for all tools
|
|
2174
|
+
return {
|
|
2175
|
+
"total": len(self.all_tool_dict),
|
|
2176
|
+
"available": len(self.all_tool_dict) - len(tool_errors),
|
|
2177
|
+
"unavailable": len(tool_errors),
|
|
2178
|
+
"unavailable_list": list(tool_errors.keys()),
|
|
2179
|
+
"details": tool_errors,
|
|
2180
|
+
}
|
|
1907
2181
|
|
|
1908
2182
|
def check_function_call(self, fcall_str, function_config=None, format="llama"):
|
|
1909
2183
|
"""
|
|
@@ -1986,6 +2260,66 @@ class ToolUniverse:
|
|
|
1986
2260
|
self.logger.error(f"Error exporting tool names to {output_file}: {e}")
|
|
1987
2261
|
return []
|
|
1988
2262
|
|
|
2263
|
+
def filter_tools(
|
|
2264
|
+
self,
|
|
2265
|
+
include_tools=None,
|
|
2266
|
+
exclude_tools=None,
|
|
2267
|
+
include_tool_types=None,
|
|
2268
|
+
exclude_tool_types=None,
|
|
2269
|
+
):
|
|
2270
|
+
"""
|
|
2271
|
+
Filter tools based on inclusion/exclusion criteria.
|
|
2272
|
+
|
|
2273
|
+
Args:
|
|
2274
|
+
include_tools (set, optional): Set of tool names to include
|
|
2275
|
+
exclude_tools (set, optional): Set of tool names to exclude
|
|
2276
|
+
include_tool_types (set, optional): Set of tool types to include
|
|
2277
|
+
exclude_tool_types (set, optional): Set of tool types to exclude
|
|
2278
|
+
|
|
2279
|
+
Returns:
|
|
2280
|
+
list: Filtered list of tool configurations
|
|
2281
|
+
"""
|
|
2282
|
+
if not hasattr(self, "all_tools") or not self.all_tools:
|
|
2283
|
+
self.logger.warning("No tools loaded. Call load_tools() first.")
|
|
2284
|
+
return []
|
|
2285
|
+
|
|
2286
|
+
filtered_tools = []
|
|
2287
|
+
for tool in self.all_tools:
|
|
2288
|
+
tool_name = tool.get("name", "")
|
|
2289
|
+
tool_type = tool.get("type", "")
|
|
2290
|
+
|
|
2291
|
+
# Check inclusion/exclusion criteria
|
|
2292
|
+
if include_tools and tool_name not in include_tools:
|
|
2293
|
+
continue
|
|
2294
|
+
if exclude_tools and tool_name in exclude_tools:
|
|
2295
|
+
continue
|
|
2296
|
+
if include_tool_types and tool_type not in include_tool_types:
|
|
2297
|
+
continue
|
|
2298
|
+
if exclude_tool_types and tool_type in exclude_tool_types:
|
|
2299
|
+
continue
|
|
2300
|
+
|
|
2301
|
+
filtered_tools.append(tool)
|
|
2302
|
+
|
|
2303
|
+
return filtered_tools
|
|
2304
|
+
|
|
2305
|
+
def get_required_parameters(self, tool_name):
|
|
2306
|
+
"""
|
|
2307
|
+
Get required parameters for a specific tool.
|
|
2308
|
+
|
|
2309
|
+
Args:
|
|
2310
|
+
tool_name (str): Name of the tool
|
|
2311
|
+
|
|
2312
|
+
Returns:
|
|
2313
|
+
list: List of required parameter names
|
|
2314
|
+
"""
|
|
2315
|
+
if tool_name not in self.all_tool_dict:
|
|
2316
|
+
self.logger.warning(f"Tool '{tool_name}' not found")
|
|
2317
|
+
return []
|
|
2318
|
+
|
|
2319
|
+
tool_config = self.all_tool_dict[tool_name]
|
|
2320
|
+
parameter_schema = tool_config.get("parameter", {})
|
|
2321
|
+
return parameter_schema.get("required", [])
|
|
2322
|
+
|
|
1989
2323
|
def get_available_tools(self, category_filter=None, name_only=True):
|
|
1990
2324
|
"""
|
|
1991
2325
|
Get available tools, optionally filtered by category.
|
|
@@ -2031,6 +2365,10 @@ class ToolUniverse:
|
|
|
2031
2365
|
self.logger.warning("No tools loaded. Call load_tools() first.")
|
|
2032
2366
|
return []
|
|
2033
2367
|
|
|
2368
|
+
# Handle None or empty pattern
|
|
2369
|
+
if pattern is None or pattern == "":
|
|
2370
|
+
return self.all_tools
|
|
2371
|
+
|
|
2034
2372
|
import re
|
|
2035
2373
|
|
|
2036
2374
|
flags = 0 if case_sensitive else re.IGNORECASE
|
|
@@ -2057,10 +2395,209 @@ class ToolUniverse:
|
|
|
2057
2395
|
)
|
|
2058
2396
|
return matching_tools
|
|
2059
2397
|
|
|
2398
|
+
# ============ DEPRECATED METHODS (Kept for backward compatibility) ============
|
|
2399
|
+
# These methods are deprecated and will be removed in v2.0. Use the recommended
|
|
2400
|
+
# alternatives instead. All methods below maintain backward compatibility but
|
|
2401
|
+
# issue deprecation warnings when called.
|
|
2402
|
+
|
|
2403
|
+
def get_tool_by_name(self, tool_names, format="default"):
|
|
2404
|
+
"""
|
|
2405
|
+
Retrieve tool configurations by their names.
|
|
2406
|
+
|
|
2407
|
+
DEPRECATED: Use tool_specification() instead.
|
|
2408
|
+
|
|
2409
|
+
Args:
|
|
2410
|
+
tool_names (list): List of tool names to retrieve.
|
|
2411
|
+
format (str, optional): Output format. Options: 'default', 'openai'.
|
|
2412
|
+
If 'openai', returns OpenAI function calling format. Defaults to 'default'.
|
|
2413
|
+
|
|
2414
|
+
Returns:
|
|
2415
|
+
list: List of tool configurations for the specified names.
|
|
2416
|
+
Tools not found will be reported but not included in the result.
|
|
2417
|
+
"""
|
|
2418
|
+
warnings.warn(
|
|
2419
|
+
"get_tool_by_name() is deprecated and will be removed in v2.0. "
|
|
2420
|
+
"Use tool_specification() instead.",
|
|
2421
|
+
DeprecationWarning,
|
|
2422
|
+
stacklevel=2,
|
|
2423
|
+
)
|
|
2424
|
+
return self.get_tool_specification_by_names(tool_names, format=format)
|
|
2425
|
+
|
|
2426
|
+
def get_tool_description(self, tool_name):
|
|
2427
|
+
"""
|
|
2428
|
+
Get the description of a tool by its name.
|
|
2429
|
+
|
|
2430
|
+
DEPRECATED: Use tool_specification() instead.
|
|
2431
|
+
|
|
2432
|
+
Args:
|
|
2433
|
+
tool_name (str): Name of the tool.
|
|
2434
|
+
|
|
2435
|
+
Returns:
|
|
2436
|
+
dict or None: Tool configuration if found, None otherwise.
|
|
2437
|
+
"""
|
|
2438
|
+
warnings.warn(
|
|
2439
|
+
"get_tool_description() is deprecated and will be removed in v2.0. "
|
|
2440
|
+
"Use tool_specification() instead.",
|
|
2441
|
+
DeprecationWarning,
|
|
2442
|
+
stacklevel=2,
|
|
2443
|
+
)
|
|
2444
|
+
return self.get_one_tool_by_one_name(tool_name)
|
|
2445
|
+
|
|
2446
|
+
def remove_keys(self, tool_list, invalid_keys):
|
|
2447
|
+
"""
|
|
2448
|
+
Remove specified keys from a list of tool configurations.
|
|
2449
|
+
|
|
2450
|
+
DEPRECATED: Use prepare_tool_prompts(mode='custom', valid_keys=...) instead.
|
|
2451
|
+
|
|
2452
|
+
Args:
|
|
2453
|
+
tool_list (list): List of tool configuration dictionaries.
|
|
2454
|
+
invalid_keys (list): List of keys to remove from each tool configuration.
|
|
2455
|
+
|
|
2456
|
+
Returns:
|
|
2457
|
+
list: Deep copy of tool list with specified keys removed.
|
|
2458
|
+
"""
|
|
2459
|
+
warnings.warn(
|
|
2460
|
+
"remove_keys() is deprecated and will be removed in v2.0. "
|
|
2461
|
+
"Use prepare_tool_prompts(mode='custom', valid_keys=...) instead.",
|
|
2462
|
+
DeprecationWarning,
|
|
2463
|
+
stacklevel=2,
|
|
2464
|
+
)
|
|
2465
|
+
copied_list = copy.deepcopy(tool_list)
|
|
2466
|
+
for tool in copied_list:
|
|
2467
|
+
# Create a list of keys to avoid modifying the dictionary during iteration
|
|
2468
|
+
for key in list(tool.keys()):
|
|
2469
|
+
if key in invalid_keys:
|
|
2470
|
+
del tool[key]
|
|
2471
|
+
return copied_list
|
|
2472
|
+
|
|
2473
|
+
def prepare_tool_examples(self, tool_list):
|
|
2474
|
+
"""
|
|
2475
|
+
Prepare tool configurations for example usage by keeping extended set of keys.
|
|
2476
|
+
|
|
2477
|
+
DEPRECATED: Use prepare_tool_prompts(mode='example') instead.
|
|
2478
|
+
|
|
2479
|
+
Args:
|
|
2480
|
+
tool_list (list): List of tool configuration dictionaries.
|
|
2481
|
+
|
|
2482
|
+
Returns:
|
|
2483
|
+
list: Deep copy of tool list with only example-relevant keys.
|
|
2484
|
+
"""
|
|
2485
|
+
warnings.warn(
|
|
2486
|
+
"prepare_tool_examples() is deprecated and will be removed in v2.0. "
|
|
2487
|
+
"Use prepare_tool_prompts(mode='example') instead.",
|
|
2488
|
+
DeprecationWarning,
|
|
2489
|
+
stacklevel=2,
|
|
2490
|
+
)
|
|
2491
|
+
return self.prepare_tool_prompts(tool_list, mode="example")
|
|
2492
|
+
|
|
2493
|
+
def select_tools(
|
|
2494
|
+
self,
|
|
2495
|
+
include_names=None,
|
|
2496
|
+
exclude_names=None,
|
|
2497
|
+
include_categories=None,
|
|
2498
|
+
exclude_categories=None,
|
|
2499
|
+
):
|
|
2500
|
+
"""
|
|
2501
|
+
Select tools based on tool names and/or categories (tool_files keys).
|
|
2502
|
+
|
|
2503
|
+
DEPRECATED: Use filter_tools() instead.
|
|
2504
|
+
|
|
2505
|
+
Args:
|
|
2506
|
+
include_names (list, optional): List of tool names to include. If None, include all.
|
|
2507
|
+
exclude_names (list, optional): List of tool names to exclude.
|
|
2508
|
+
include_categories (list, optional): List of categories (tool_files keys) to include.
|
|
2509
|
+
If None, include all.
|
|
2510
|
+
exclude_categories (list, optional): List of categories (tool_files keys) to exclude.
|
|
2511
|
+
|
|
2512
|
+
Returns:
|
|
2513
|
+
list: List of selected tool configurations.
|
|
2514
|
+
"""
|
|
2515
|
+
warnings.warn(
|
|
2516
|
+
"select_tools() is deprecated and will be removed in v2.0. "
|
|
2517
|
+
"Use filter_tools() instead.",
|
|
2518
|
+
DeprecationWarning,
|
|
2519
|
+
stacklevel=2,
|
|
2520
|
+
)
|
|
2521
|
+
selected_tools = []
|
|
2522
|
+
# If categories are specified, use self.tool_category_dicts to filter
|
|
2523
|
+
categories = set(self.tool_category_dicts.keys())
|
|
2524
|
+
if include_categories is not None:
|
|
2525
|
+
categories &= set(include_categories)
|
|
2526
|
+
if exclude_categories is not None:
|
|
2527
|
+
categories -= set(exclude_categories)
|
|
2528
|
+
# Gather tools from selected categories
|
|
2529
|
+
for cat in categories:
|
|
2530
|
+
selected_tools.extend(self.tool_category_dicts[cat])
|
|
2531
|
+
# Further filter by names if needed
|
|
2532
|
+
if include_names is not None:
|
|
2533
|
+
selected_tools = [
|
|
2534
|
+
tool for tool in selected_tools if tool["name"] in include_names
|
|
2535
|
+
]
|
|
2536
|
+
if exclude_names is not None:
|
|
2537
|
+
selected_tools = [
|
|
2538
|
+
tool for tool in selected_tools if tool["name"] not in exclude_names
|
|
2539
|
+
]
|
|
2540
|
+
return selected_tools
|
|
2541
|
+
|
|
2542
|
+
def filter_tool_lists(
|
|
2543
|
+
self,
|
|
2544
|
+
tool_name_list,
|
|
2545
|
+
tool_desc_list,
|
|
2546
|
+
include_names=None,
|
|
2547
|
+
exclude_names=None,
|
|
2548
|
+
include_categories=None,
|
|
2549
|
+
exclude_categories=None,
|
|
2550
|
+
):
|
|
2551
|
+
"""
|
|
2552
|
+
Directly filter tool name and description lists based on names and/or categories.
|
|
2553
|
+
|
|
2554
|
+
DEPRECATED: Use filter_tools() and manual list filtering instead.
|
|
2555
|
+
|
|
2556
|
+
Args:
|
|
2557
|
+
tool_name_list (list): List of tool names to filter.
|
|
2558
|
+
tool_desc_list (list): List of tool descriptions to filter (must correspond to tool_name_list).
|
|
2559
|
+
include_names (list, optional): List of tool names to include.
|
|
2560
|
+
exclude_names (list, optional): List of tool names to exclude.
|
|
2561
|
+
include_categories (list, optional): List of categories to include.
|
|
2562
|
+
exclude_categories (list, optional): List of categories to exclude.
|
|
2563
|
+
|
|
2564
|
+
Returns:
|
|
2565
|
+
tuple: A tuple containing (filtered_tool_name_list, filtered_tool_desc_list).
|
|
2566
|
+
"""
|
|
2567
|
+
warnings.warn(
|
|
2568
|
+
"filter_tool_lists() is deprecated and will be removed in v2.0. "
|
|
2569
|
+
"Use filter_tools() and manual list filtering instead.",
|
|
2570
|
+
DeprecationWarning,
|
|
2571
|
+
stacklevel=2,
|
|
2572
|
+
)
|
|
2573
|
+
# Build a set of allowed tool names using select_tools for category filtering
|
|
2574
|
+
allowed_names = set()
|
|
2575
|
+
if any([include_names, exclude_names, include_categories, exclude_categories]):
|
|
2576
|
+
filtered_tools = self.select_tools(
|
|
2577
|
+
include_names=include_names,
|
|
2578
|
+
exclude_names=exclude_names,
|
|
2579
|
+
include_categories=include_categories,
|
|
2580
|
+
exclude_categories=exclude_categories,
|
|
2581
|
+
)
|
|
2582
|
+
allowed_names = set(tool["name"] for tool in filtered_tools)
|
|
2583
|
+
else:
|
|
2584
|
+
allowed_names = set(tool_name_list)
|
|
2585
|
+
|
|
2586
|
+
# Filter lists by allowed_names
|
|
2587
|
+
filtered_tool_name_list = []
|
|
2588
|
+
filtered_tool_desc_list = []
|
|
2589
|
+
for name, desc in zip(tool_name_list, tool_desc_list):
|
|
2590
|
+
if name in allowed_names:
|
|
2591
|
+
filtered_tool_name_list.append(name)
|
|
2592
|
+
filtered_tool_desc_list.append(desc)
|
|
2593
|
+
return filtered_tool_name_list, filtered_tool_desc_list
|
|
2594
|
+
|
|
2060
2595
|
def load_tools_from_names_list(self, tool_names, clear_existing=True):
|
|
2061
2596
|
"""
|
|
2062
2597
|
Load only specific tools by their names.
|
|
2063
2598
|
|
|
2599
|
+
DEPRECATED: Use load_tools(include_tools=...) instead.
|
|
2600
|
+
|
|
2064
2601
|
Args:
|
|
2065
2602
|
tool_names (list): List of tool names to load
|
|
2066
2603
|
clear_existing (bool): Whether to clear existing tools first
|
|
@@ -2068,6 +2605,12 @@ class ToolUniverse:
|
|
|
2068
2605
|
Returns:
|
|
2069
2606
|
int: Number of tools successfully loaded
|
|
2070
2607
|
"""
|
|
2608
|
+
warnings.warn(
|
|
2609
|
+
"load_tools_from_names_list() is deprecated and will be removed in v2.0. "
|
|
2610
|
+
"Use load_tools(include_tools=...) instead.",
|
|
2611
|
+
DeprecationWarning,
|
|
2612
|
+
stacklevel=2,
|
|
2613
|
+
)
|
|
2071
2614
|
if clear_existing:
|
|
2072
2615
|
self.all_tools = []
|
|
2073
2616
|
self.all_tool_dict = {}
|