aiagents4pharma 1.44.0__py3-none-any.whl → 1.45.1__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- aiagents4pharma/__init__.py +2 -2
- aiagents4pharma/talk2aiagents4pharma/.dockerignore +13 -0
- aiagents4pharma/talk2aiagents4pharma/Dockerfile +105 -0
- aiagents4pharma/talk2aiagents4pharma/README.md +1 -0
- aiagents4pharma/talk2aiagents4pharma/__init__.py +4 -5
- aiagents4pharma/talk2aiagents4pharma/agents/__init__.py +3 -2
- aiagents4pharma/talk2aiagents4pharma/agents/main_agent.py +24 -23
- aiagents4pharma/talk2aiagents4pharma/configs/__init__.py +2 -2
- aiagents4pharma/talk2aiagents4pharma/configs/agents/__init__.py +2 -2
- aiagents4pharma/talk2aiagents4pharma/configs/agents/main_agent/default.yaml +2 -2
- aiagents4pharma/talk2aiagents4pharma/configs/config.yaml +1 -1
- aiagents4pharma/talk2aiagents4pharma/docker-compose/cpu/.env.example +23 -0
- aiagents4pharma/talk2aiagents4pharma/docker-compose/cpu/docker-compose.yml +93 -0
- aiagents4pharma/talk2aiagents4pharma/docker-compose/gpu/.env.example +23 -0
- aiagents4pharma/talk2aiagents4pharma/docker-compose/gpu/docker-compose.yml +108 -0
- aiagents4pharma/talk2aiagents4pharma/install.md +127 -0
- aiagents4pharma/talk2aiagents4pharma/states/__init__.py +3 -2
- aiagents4pharma/talk2aiagents4pharma/states/state_talk2aiagents4pharma.py +5 -3
- aiagents4pharma/talk2aiagents4pharma/tests/__init__.py +2 -2
- aiagents4pharma/talk2aiagents4pharma/tests/test_main_agent.py +72 -50
- aiagents4pharma/talk2biomodels/.dockerignore +13 -0
- aiagents4pharma/talk2biomodels/Dockerfile +104 -0
- aiagents4pharma/talk2biomodels/README.md +1 -0
- aiagents4pharma/talk2biomodels/__init__.py +4 -8
- aiagents4pharma/talk2biomodels/agents/__init__.py +3 -2
- aiagents4pharma/talk2biomodels/agents/t2b_agent.py +47 -42
- aiagents4pharma/talk2biomodels/api/__init__.py +4 -5
- aiagents4pharma/talk2biomodels/api/kegg.py +14 -10
- aiagents4pharma/talk2biomodels/api/ols.py +13 -10
- aiagents4pharma/talk2biomodels/api/uniprot.py +7 -6
- aiagents4pharma/talk2biomodels/configs/__init__.py +3 -4
- aiagents4pharma/talk2biomodels/configs/agents/__init__.py +2 -2
- aiagents4pharma/talk2biomodels/configs/agents/t2b_agent/__init__.py +2 -2
- aiagents4pharma/talk2biomodels/configs/agents/t2b_agent/default.yaml +1 -1
- aiagents4pharma/talk2biomodels/configs/config.yaml +1 -1
- aiagents4pharma/talk2biomodels/configs/tools/__init__.py +4 -5
- aiagents4pharma/talk2biomodels/configs/tools/ask_question/__init__.py +2 -2
- aiagents4pharma/talk2biomodels/configs/tools/ask_question/default.yaml +1 -2
- aiagents4pharma/talk2biomodels/configs/tools/custom_plotter/__init__.py +2 -2
- aiagents4pharma/talk2biomodels/configs/tools/custom_plotter/default.yaml +1 -1
- aiagents4pharma/talk2biomodels/configs/tools/get_annotation/__init__.py +2 -2
- aiagents4pharma/talk2biomodels/configs/tools/get_annotation/default.yaml +1 -1
- aiagents4pharma/talk2biomodels/install.md +63 -0
- aiagents4pharma/talk2biomodels/models/__init__.py +4 -4
- aiagents4pharma/talk2biomodels/models/basico_model.py +36 -28
- aiagents4pharma/talk2biomodels/models/sys_bio_model.py +13 -10
- aiagents4pharma/talk2biomodels/states/__init__.py +3 -2
- aiagents4pharma/talk2biomodels/states/state_talk2biomodels.py +12 -8
- aiagents4pharma/talk2biomodels/tests/BIOMD0000000449_url.xml +1585 -0
- aiagents4pharma/talk2biomodels/tests/__init__.py +2 -2
- aiagents4pharma/talk2biomodels/tests/article_on_model_537.pdf +0 -0
- aiagents4pharma/talk2biomodels/tests/test_api.py +18 -14
- aiagents4pharma/talk2biomodels/tests/test_ask_question.py +8 -9
- aiagents4pharma/talk2biomodels/tests/test_basico_model.py +15 -9
- aiagents4pharma/talk2biomodels/tests/test_get_annotation.py +54 -55
- aiagents4pharma/talk2biomodels/tests/test_getmodelinfo.py +28 -27
- aiagents4pharma/talk2biomodels/tests/test_integration.py +21 -33
- aiagents4pharma/talk2biomodels/tests/test_load_biomodel.py +14 -11
- aiagents4pharma/talk2biomodels/tests/test_param_scan.py +21 -20
- aiagents4pharma/talk2biomodels/tests/test_query_article.py +129 -29
- aiagents4pharma/talk2biomodels/tests/test_search_models.py +9 -13
- aiagents4pharma/talk2biomodels/tests/test_simulate_model.py +16 -15
- aiagents4pharma/talk2biomodels/tests/test_steady_state.py +12 -22
- aiagents4pharma/talk2biomodels/tests/test_sys_bio_model.py +33 -29
- aiagents4pharma/talk2biomodels/tools/__init__.py +15 -12
- aiagents4pharma/talk2biomodels/tools/ask_question.py +42 -32
- aiagents4pharma/talk2biomodels/tools/custom_plotter.py +51 -43
- aiagents4pharma/talk2biomodels/tools/get_annotation.py +99 -75
- aiagents4pharma/talk2biomodels/tools/get_modelinfo.py +57 -51
- aiagents4pharma/talk2biomodels/tools/load_arguments.py +52 -32
- aiagents4pharma/talk2biomodels/tools/load_biomodel.py +8 -2
- aiagents4pharma/talk2biomodels/tools/parameter_scan.py +107 -90
- aiagents4pharma/talk2biomodels/tools/query_article.py +14 -13
- aiagents4pharma/talk2biomodels/tools/search_models.py +37 -26
- aiagents4pharma/talk2biomodels/tools/simulate_model.py +47 -37
- aiagents4pharma/talk2biomodels/tools/steady_state.py +76 -58
- aiagents4pharma/talk2biomodels/tools/utils.py +4 -3
- aiagents4pharma/talk2cells/README.md +1 -0
- aiagents4pharma/talk2cells/__init__.py +4 -5
- aiagents4pharma/talk2cells/agents/__init__.py +3 -2
- aiagents4pharma/talk2cells/agents/scp_agent.py +21 -19
- aiagents4pharma/talk2cells/states/__init__.py +3 -2
- aiagents4pharma/talk2cells/states/state_talk2cells.py +4 -2
- aiagents4pharma/talk2cells/tests/scp_agent/test_scp_agent.py +8 -9
- aiagents4pharma/talk2cells/tools/__init__.py +3 -2
- aiagents4pharma/talk2cells/tools/scp_agent/__init__.py +4 -4
- aiagents4pharma/talk2cells/tools/scp_agent/display_studies.py +5 -3
- aiagents4pharma/talk2cells/tools/scp_agent/search_studies.py +21 -22
- aiagents4pharma/talk2knowledgegraphs/.dockerignore +13 -0
- aiagents4pharma/talk2knowledgegraphs/Dockerfile +103 -0
- aiagents4pharma/talk2knowledgegraphs/README.md +1 -0
- aiagents4pharma/talk2knowledgegraphs/__init__.py +4 -7
- aiagents4pharma/talk2knowledgegraphs/agents/__init__.py +3 -2
- aiagents4pharma/talk2knowledgegraphs/agents/t2kg_agent.py +40 -30
- aiagents4pharma/talk2knowledgegraphs/configs/__init__.py +3 -6
- aiagents4pharma/talk2knowledgegraphs/configs/agents/t2kg_agent/__init__.py +2 -2
- aiagents4pharma/talk2knowledgegraphs/configs/agents/t2kg_agent/default.yaml +8 -8
- aiagents4pharma/talk2knowledgegraphs/configs/app/__init__.py +3 -2
- aiagents4pharma/talk2knowledgegraphs/configs/app/frontend/__init__.py +2 -2
- aiagents4pharma/talk2knowledgegraphs/configs/app/frontend/default.yaml +1 -1
- aiagents4pharma/talk2knowledgegraphs/configs/config.yaml +1 -1
- aiagents4pharma/talk2knowledgegraphs/configs/tools/__init__.py +4 -5
- aiagents4pharma/talk2knowledgegraphs/configs/tools/graphrag_reasoning/__init__.py +2 -2
- aiagents4pharma/talk2knowledgegraphs/configs/tools/graphrag_reasoning/default.yaml +1 -1
- aiagents4pharma/talk2knowledgegraphs/configs/tools/subgraph_extraction/__init__.py +2 -2
- aiagents4pharma/talk2knowledgegraphs/configs/tools/subgraph_extraction/default.yaml +1 -1
- aiagents4pharma/talk2knowledgegraphs/configs/tools/subgraph_summarization/__init__.py +2 -2
- aiagents4pharma/talk2knowledgegraphs/configs/tools/subgraph_summarization/default.yaml +1 -1
- aiagents4pharma/talk2knowledgegraphs/configs/utils/enrichments/ols_terms/default.yaml +1 -1
- aiagents4pharma/talk2knowledgegraphs/configs/utils/enrichments/reactome_pathways/default.yaml +1 -1
- aiagents4pharma/talk2knowledgegraphs/configs/utils/enrichments/uniprot_proteins/default.yaml +1 -1
- aiagents4pharma/talk2knowledgegraphs/configs/utils/pubchem_utils/default.yaml +1 -1
- aiagents4pharma/talk2knowledgegraphs/datasets/__init__.py +4 -6
- aiagents4pharma/talk2knowledgegraphs/datasets/biobridge_primekg.py +115 -67
- aiagents4pharma/talk2knowledgegraphs/datasets/dataset.py +2 -0
- aiagents4pharma/talk2knowledgegraphs/datasets/primekg.py +35 -24
- aiagents4pharma/talk2knowledgegraphs/datasets/starkqa_primekg.py +29 -21
- aiagents4pharma/talk2knowledgegraphs/docker-compose/cpu/.env.example +23 -0
- aiagents4pharma/talk2knowledgegraphs/docker-compose/cpu/docker-compose.yml +93 -0
- aiagents4pharma/talk2knowledgegraphs/docker-compose/gpu/.env.example +23 -0
- aiagents4pharma/talk2knowledgegraphs/docker-compose/gpu/docker-compose.yml +108 -0
- aiagents4pharma/talk2knowledgegraphs/entrypoint.sh +190 -0
- aiagents4pharma/talk2knowledgegraphs/install.md +140 -0
- aiagents4pharma/talk2knowledgegraphs/milvus_data_dump.py +31 -65
- aiagents4pharma/talk2knowledgegraphs/states/__init__.py +3 -2
- aiagents4pharma/talk2knowledgegraphs/states/state_talk2knowledgegraphs.py +1 -0
- aiagents4pharma/talk2knowledgegraphs/tests/test_agents_t2kg_agent.py +65 -40
- aiagents4pharma/talk2knowledgegraphs/tests/test_datasets_biobridge_primekg.py +54 -48
- aiagents4pharma/talk2knowledgegraphs/tests/test_datasets_dataset.py +4 -0
- aiagents4pharma/talk2knowledgegraphs/tests/test_datasets_primekg.py +17 -4
- aiagents4pharma/talk2knowledgegraphs/tests/test_datasets_starkqa_primekg.py +33 -24
- aiagents4pharma/talk2knowledgegraphs/tests/test_tools_graphrag_reasoning.py +116 -69
- aiagents4pharma/talk2knowledgegraphs/tests/test_tools_milvus_multimodal_subgraph_extraction.py +334 -216
- aiagents4pharma/talk2knowledgegraphs/tests/test_tools_multimodal_subgraph_extraction.py +22 -15
- aiagents4pharma/talk2knowledgegraphs/tests/test_tools_subgraph_extraction.py +19 -12
- aiagents4pharma/talk2knowledgegraphs/tests/test_tools_subgraph_summarization.py +95 -48
- aiagents4pharma/talk2knowledgegraphs/tests/test_utils_embeddings_embeddings.py +4 -0
- aiagents4pharma/talk2knowledgegraphs/tests/test_utils_embeddings_huggingface.py +5 -0
- aiagents4pharma/talk2knowledgegraphs/tests/test_utils_embeddings_nim_molmim.py +13 -18
- aiagents4pharma/talk2knowledgegraphs/tests/test_utils_embeddings_ollama.py +10 -3
- aiagents4pharma/talk2knowledgegraphs/tests/test_utils_enrichments_enrichments.py +4 -3
- aiagents4pharma/talk2knowledgegraphs/tests/test_utils_enrichments_ollama.py +3 -2
- aiagents4pharma/talk2knowledgegraphs/tests/test_utils_enrichments_ols.py +1 -0
- aiagents4pharma/talk2knowledgegraphs/tests/test_utils_enrichments_pubchem.py +9 -4
- aiagents4pharma/talk2knowledgegraphs/tests/test_utils_enrichments_reactome.py +6 -6
- aiagents4pharma/talk2knowledgegraphs/tests/test_utils_enrichments_uniprot.py +4 -0
- aiagents4pharma/talk2knowledgegraphs/tests/test_utils_extractions_milvus_multimodal_pcst.py +160 -97
- aiagents4pharma/talk2knowledgegraphs/tests/test_utils_kg_utils.py +3 -4
- aiagents4pharma/talk2knowledgegraphs/tests/test_utils_pubchem_utils.py +87 -13
- aiagents4pharma/talk2knowledgegraphs/tools/__init__.py +10 -7
- aiagents4pharma/talk2knowledgegraphs/tools/graphrag_reasoning.py +15 -20
- aiagents4pharma/talk2knowledgegraphs/tools/milvus_multimodal_subgraph_extraction.py +145 -142
- aiagents4pharma/talk2knowledgegraphs/tools/multimodal_subgraph_extraction.py +92 -90
- aiagents4pharma/talk2knowledgegraphs/tools/subgraph_extraction.py +25 -37
- aiagents4pharma/talk2knowledgegraphs/tools/subgraph_summarization.py +10 -13
- aiagents4pharma/talk2knowledgegraphs/utils/__init__.py +4 -7
- aiagents4pharma/talk2knowledgegraphs/utils/embeddings/__init__.py +4 -7
- aiagents4pharma/talk2knowledgegraphs/utils/embeddings/embeddings.py +4 -0
- aiagents4pharma/talk2knowledgegraphs/utils/embeddings/huggingface.py +11 -14
- aiagents4pharma/talk2knowledgegraphs/utils/embeddings/nim_molmim.py +7 -7
- aiagents4pharma/talk2knowledgegraphs/utils/embeddings/ollama.py +12 -6
- aiagents4pharma/talk2knowledgegraphs/utils/embeddings/sentence_transformer.py +8 -6
- aiagents4pharma/talk2knowledgegraphs/utils/enrichments/__init__.py +9 -6
- aiagents4pharma/talk2knowledgegraphs/utils/enrichments/enrichments.py +1 -0
- aiagents4pharma/talk2knowledgegraphs/utils/enrichments/ollama.py +15 -9
- aiagents4pharma/talk2knowledgegraphs/utils/enrichments/ols_terms.py +23 -20
- aiagents4pharma/talk2knowledgegraphs/utils/enrichments/pubchem_strings.py +12 -10
- aiagents4pharma/talk2knowledgegraphs/utils/enrichments/reactome_pathways.py +16 -10
- aiagents4pharma/talk2knowledgegraphs/utils/enrichments/uniprot_proteins.py +26 -18
- aiagents4pharma/talk2knowledgegraphs/utils/extractions/__init__.py +4 -5
- aiagents4pharma/talk2knowledgegraphs/utils/extractions/milvus_multimodal_pcst.py +14 -34
- aiagents4pharma/talk2knowledgegraphs/utils/extractions/multimodal_pcst.py +53 -47
- aiagents4pharma/talk2knowledgegraphs/utils/extractions/pcst.py +18 -14
- aiagents4pharma/talk2knowledgegraphs/utils/kg_utils.py +22 -23
- aiagents4pharma/talk2knowledgegraphs/utils/pubchem_utils.py +11 -10
- aiagents4pharma/talk2scholars/.dockerignore +13 -0
- aiagents4pharma/talk2scholars/Dockerfile +104 -0
- aiagents4pharma/talk2scholars/README.md +1 -0
- aiagents4pharma/talk2scholars/agents/__init__.py +1 -5
- aiagents4pharma/talk2scholars/agents/main_agent.py +6 -4
- aiagents4pharma/talk2scholars/agents/paper_download_agent.py +5 -4
- aiagents4pharma/talk2scholars/agents/pdf_agent.py +4 -2
- aiagents4pharma/talk2scholars/agents/s2_agent.py +2 -2
- aiagents4pharma/talk2scholars/agents/zotero_agent.py +10 -11
- aiagents4pharma/talk2scholars/configs/__init__.py +1 -3
- aiagents4pharma/talk2scholars/configs/agents/talk2scholars/__init__.py +1 -4
- aiagents4pharma/talk2scholars/configs/agents/talk2scholars/main_agent/default.yaml +1 -1
- aiagents4pharma/talk2scholars/configs/agents/talk2scholars/pdf_agent/default.yaml +1 -1
- aiagents4pharma/talk2scholars/configs/agents/talk2scholars/s2_agent/default.yaml +8 -8
- aiagents4pharma/talk2scholars/configs/agents/talk2scholars/zotero_agent/default.yaml +7 -7
- aiagents4pharma/talk2scholars/configs/tools/__init__.py +8 -6
- aiagents4pharma/talk2scholars/docker-compose/cpu/.env.example +21 -0
- aiagents4pharma/talk2scholars/docker-compose/cpu/docker-compose.yml +90 -0
- aiagents4pharma/talk2scholars/docker-compose/gpu/.env.example +21 -0
- aiagents4pharma/talk2scholars/docker-compose/gpu/docker-compose.yml +105 -0
- aiagents4pharma/talk2scholars/install.md +122 -0
- aiagents4pharma/talk2scholars/state/state_talk2scholars.py +8 -8
- aiagents4pharma/talk2scholars/tests/{test_main_agent.py → test_agents_main_agent.py} +41 -23
- aiagents4pharma/talk2scholars/tests/{test_paper_download_agent.py → test_agents_paper_agents_download_agent.py} +10 -16
- aiagents4pharma/talk2scholars/tests/{test_pdf_agent.py → test_agents_pdf_agent.py} +6 -10
- aiagents4pharma/talk2scholars/tests/{test_s2_agent.py → test_agents_s2_agent.py} +8 -16
- aiagents4pharma/talk2scholars/tests/{test_zotero_agent.py → test_agents_zotero_agent.py} +5 -7
- aiagents4pharma/talk2scholars/tests/{test_s2_display_dataframe.py → test_s2_tools_display_dataframe.py} +6 -7
- aiagents4pharma/talk2scholars/tests/{test_s2_query_dataframe.py → test_s2_tools_query_dataframe.py} +5 -15
- aiagents4pharma/talk2scholars/tests/{test_paper_downloader.py → test_tools_paper_downloader.py} +25 -63
- aiagents4pharma/talk2scholars/tests/{test_question_and_answer_tool.py → test_tools_question_and_answer_tool.py} +2 -6
- aiagents4pharma/talk2scholars/tests/{test_s2_multi.py → test_tools_s2_multi.py} +5 -5
- aiagents4pharma/talk2scholars/tests/{test_s2_retrieve.py → test_tools_s2_retrieve.py} +2 -1
- aiagents4pharma/talk2scholars/tests/{test_s2_search.py → test_tools_s2_search.py} +5 -5
- aiagents4pharma/talk2scholars/tests/{test_s2_single.py → test_tools_s2_single.py} +5 -5
- aiagents4pharma/talk2scholars/tests/{test_arxiv_downloader.py → test_utils_arxiv_downloader.py} +16 -25
- aiagents4pharma/talk2scholars/tests/{test_base_paper_downloader.py → test_utils_base_paper_downloader.py} +25 -47
- aiagents4pharma/talk2scholars/tests/{test_biorxiv_downloader.py → test_utils_biorxiv_downloader.py} +14 -42
- aiagents4pharma/talk2scholars/tests/{test_medrxiv_downloader.py → test_utils_medrxiv_downloader.py} +15 -49
- aiagents4pharma/talk2scholars/tests/{test_nvidia_nim_reranker.py → test_utils_nvidia_nim_reranker.py} +6 -16
- aiagents4pharma/talk2scholars/tests/{test_pdf_answer_formatter.py → test_utils_pdf_answer_formatter.py} +1 -0
- aiagents4pharma/talk2scholars/tests/{test_pdf_batch_processor.py → test_utils_pdf_batch_processor.py} +6 -15
- aiagents4pharma/talk2scholars/tests/{test_pdf_collection_manager.py → test_utils_pdf_collection_manager.py} +34 -11
- aiagents4pharma/talk2scholars/tests/{test_pdf_document_processor.py → test_utils_pdf_document_processor.py} +2 -3
- aiagents4pharma/talk2scholars/tests/{test_pdf_generate_answer.py → test_utils_pdf_generate_answer.py} +3 -6
- aiagents4pharma/talk2scholars/tests/{test_pdf_gpu_detection.py → test_utils_pdf_gpu_detection.py} +5 -16
- aiagents4pharma/talk2scholars/tests/{test_pdf_rag_pipeline.py → test_utils_pdf_rag_pipeline.py} +7 -17
- aiagents4pharma/talk2scholars/tests/{test_pdf_retrieve_chunks.py → test_utils_pdf_retrieve_chunks.py} +4 -11
- aiagents4pharma/talk2scholars/tests/{test_pdf_singleton_manager.py → test_utils_pdf_singleton_manager.py} +26 -23
- aiagents4pharma/talk2scholars/tests/{test_pdf_vector_normalization.py → test_utils_pdf_vector_normalization.py} +1 -1
- aiagents4pharma/talk2scholars/tests/{test_pdf_vector_store.py → test_utils_pdf_vector_store.py} +27 -55
- aiagents4pharma/talk2scholars/tests/{test_pubmed_downloader.py → test_utils_pubmed_downloader.py} +31 -91
- aiagents4pharma/talk2scholars/tests/{test_read_helper_utils.py → test_utils_read_helper_utils.py} +2 -6
- aiagents4pharma/talk2scholars/tests/{test_s2_utils_ext_ids.py → test_utils_s2_utils_ext_ids.py} +5 -15
- aiagents4pharma/talk2scholars/tests/{test_zotero_human_in_the_loop.py → test_utils_zotero_human_in_the_loop.py} +6 -13
- aiagents4pharma/talk2scholars/tests/{test_zotero_path.py → test_utils_zotero_path.py} +53 -45
- aiagents4pharma/talk2scholars/tests/{test_zotero_read.py → test_utils_zotero_read.py} +30 -91
- aiagents4pharma/talk2scholars/tests/{test_zotero_write.py → test_utils_zotero_write.py} +6 -16
- aiagents4pharma/talk2scholars/tools/__init__.py +1 -4
- aiagents4pharma/talk2scholars/tools/paper_download/paper_downloader.py +20 -35
- aiagents4pharma/talk2scholars/tools/paper_download/utils/__init__.py +7 -5
- aiagents4pharma/talk2scholars/tools/paper_download/utils/arxiv_downloader.py +9 -11
- aiagents4pharma/talk2scholars/tools/paper_download/utils/base_paper_downloader.py +14 -21
- aiagents4pharma/talk2scholars/tools/paper_download/utils/biorxiv_downloader.py +14 -22
- aiagents4pharma/talk2scholars/tools/paper_download/utils/medrxiv_downloader.py +11 -13
- aiagents4pharma/talk2scholars/tools/paper_download/utils/pubmed_downloader.py +14 -28
- aiagents4pharma/talk2scholars/tools/pdf/question_and_answer.py +4 -8
- aiagents4pharma/talk2scholars/tools/pdf/utils/__init__.py +16 -14
- aiagents4pharma/talk2scholars/tools/pdf/utils/answer_formatter.py +4 -4
- aiagents4pharma/talk2scholars/tools/pdf/utils/batch_processor.py +15 -17
- aiagents4pharma/talk2scholars/tools/pdf/utils/collection_manager.py +2 -2
- aiagents4pharma/talk2scholars/tools/pdf/utils/document_processor.py +5 -5
- aiagents4pharma/talk2scholars/tools/pdf/utils/generate_answer.py +4 -4
- aiagents4pharma/talk2scholars/tools/pdf/utils/get_vectorstore.py +2 -6
- aiagents4pharma/talk2scholars/tools/pdf/utils/gpu_detection.py +5 -9
- aiagents4pharma/talk2scholars/tools/pdf/utils/nvidia_nim_reranker.py +4 -4
- aiagents4pharma/talk2scholars/tools/pdf/utils/paper_loader.py +2 -2
- aiagents4pharma/talk2scholars/tools/pdf/utils/rag_pipeline.py +6 -15
- aiagents4pharma/talk2scholars/tools/pdf/utils/retrieve_chunks.py +7 -15
- aiagents4pharma/talk2scholars/tools/pdf/utils/singleton_manager.py +2 -2
- aiagents4pharma/talk2scholars/tools/pdf/utils/tool_helper.py +3 -4
- aiagents4pharma/talk2scholars/tools/pdf/utils/vector_normalization.py +8 -17
- aiagents4pharma/talk2scholars/tools/pdf/utils/vector_store.py +17 -33
- aiagents4pharma/talk2scholars/tools/s2/__init__.py +8 -6
- aiagents4pharma/talk2scholars/tools/s2/display_dataframe.py +3 -7
- aiagents4pharma/talk2scholars/tools/s2/multi_paper_rec.py +7 -6
- aiagents4pharma/talk2scholars/tools/s2/query_dataframe.py +5 -12
- aiagents4pharma/talk2scholars/tools/s2/retrieve_semantic_scholar_paper_id.py +2 -4
- aiagents4pharma/talk2scholars/tools/s2/search.py +6 -6
- aiagents4pharma/talk2scholars/tools/s2/single_paper_rec.py +5 -3
- aiagents4pharma/talk2scholars/tools/s2/utils/__init__.py +1 -3
- aiagents4pharma/talk2scholars/tools/s2/utils/multi_helper.py +12 -18
- aiagents4pharma/talk2scholars/tools/s2/utils/search_helper.py +11 -18
- aiagents4pharma/talk2scholars/tools/s2/utils/single_helper.py +11 -16
- aiagents4pharma/talk2scholars/tools/zotero/__init__.py +1 -4
- aiagents4pharma/talk2scholars/tools/zotero/utils/__init__.py +1 -4
- aiagents4pharma/talk2scholars/tools/zotero/utils/read_helper.py +21 -39
- aiagents4pharma/talk2scholars/tools/zotero/utils/review_helper.py +2 -6
- aiagents4pharma/talk2scholars/tools/zotero/utils/write_helper.py +8 -11
- aiagents4pharma/talk2scholars/tools/zotero/utils/zotero_path.py +4 -12
- aiagents4pharma/talk2scholars/tools/zotero/utils/zotero_pdf_downloader.py +13 -27
- aiagents4pharma/talk2scholars/tools/zotero/zotero_read.py +4 -7
- aiagents4pharma/talk2scholars/tools/zotero/zotero_review.py +8 -10
- aiagents4pharma/talk2scholars/tools/zotero/zotero_write.py +3 -2
- {aiagents4pharma-1.44.0.dist-info → aiagents4pharma-1.45.1.dist-info}/METADATA +115 -51
- aiagents4pharma-1.45.1.dist-info/RECORD +324 -0
- {aiagents4pharma-1.44.0.dist-info → aiagents4pharma-1.45.1.dist-info}/WHEEL +1 -2
- aiagents4pharma-1.44.0.dist-info/RECORD +0 -293
- aiagents4pharma-1.44.0.dist-info/top_level.txt +0 -1
- /aiagents4pharma/talk2scholars/tests/{test_state.py → test_states_state.py} +0 -0
- /aiagents4pharma/talk2scholars/tests/{test_pdf_paper_loader.py → test_utils_pdf_paper_loader.py} +0 -0
- /aiagents4pharma/talk2scholars/tests/{test_tool_helper_utils.py → test_utils_tool_helper_utils.py} +0 -0
- /aiagents4pharma/talk2scholars/tests/{test_zotero_pdf_downloader_utils.py → test_utils_zotero_pdf_downloader_utils.py} +0 -0
- {aiagents4pharma-1.44.0.dist-info → aiagents4pharma-1.45.1.dist-info}/licenses/LICENSE +0 -0
aiagents4pharma/talk2knowledgegraphs/tests/test_tools_milvus_multimodal_subgraph_extraction.py
CHANGED
@@ -4,15 +4,19 @@ Test cases for tools/milvus_multimodal_subgraph_extraction.py
|
|
4
4
|
|
5
5
|
import importlib
|
6
6
|
import unittest
|
7
|
-
from unittest.mock import
|
7
|
+
from unittest.mock import MagicMock, patch
|
8
|
+
|
8
9
|
import numpy as np
|
9
10
|
import pandas as pd
|
11
|
+
|
10
12
|
from ..tools.milvus_multimodal_subgraph_extraction import MultimodalSubgraphExtractionTool
|
11
13
|
|
14
|
+
|
12
15
|
class TestMultimodalSubgraphExtractionTool(unittest.TestCase):
|
13
16
|
"""
|
14
17
|
Test cases for MultimodalSubgraphExtractionTool (Milvus)
|
15
18
|
"""
|
19
|
+
|
16
20
|
def setUp(self):
|
17
21
|
self.tool = MultimodalSubgraphExtractionTool()
|
18
22
|
self.state = {
|
@@ -37,15 +41,16 @@ class TestMultimodalSubgraphExtractionTool(unittest.TestCase):
|
|
37
41
|
self.cfg.search_metric_type = "L2"
|
38
42
|
self.cfg.node_colors_dict = {"gene/protein": "red"}
|
39
43
|
|
40
|
-
@patch(
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
+
@patch(
|
45
|
+
"aiagents4pharma.talk2knowledgegraphs.tools."
|
46
|
+
"milvus_multimodal_subgraph_extraction.Collection"
|
47
|
+
)
|
48
|
+
@patch(
|
49
|
+
"aiagents4pharma.talk2knowledgegraphs.tools."
|
50
|
+
"milvus_multimodal_subgraph_extraction.MultimodalPCSTPruning"
|
51
|
+
)
|
44
52
|
@patch("pymilvus.connections")
|
45
|
-
def test_extract_multimodal_subgraph_wo_doc(self,
|
46
|
-
mock_connections,
|
47
|
-
mock_pcst,
|
48
|
-
mock_collection):
|
53
|
+
def test_extract_multimodal_subgraph_wo_doc(self, mock_connections, mock_pcst, mock_collection):
|
49
54
|
"""
|
50
55
|
Test the multimodal subgraph extraction tool for only text as modality.
|
51
56
|
"""
|
@@ -63,36 +68,42 @@ class TestMultimodalSubgraphExtractionTool(unittest.TestCase):
|
|
63
68
|
colls["nodes"] = MagicMock()
|
64
69
|
colls["nodes"] = MagicMock()
|
65
70
|
colls["nodes"].query.return_value = [
|
66
|
-
{
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
71
|
+
{
|
72
|
+
"node_index": 0,
|
73
|
+
"node_id": "id1",
|
74
|
+
"node_name": "JAK1",
|
75
|
+
"node_type": "gene/protein",
|
76
|
+
"feat": "featA",
|
77
|
+
"feat_emb": [0.1, 0.2, 0.3],
|
78
|
+
"desc": "descA",
|
79
|
+
"desc_emb": [0.1, 0.2, 0.3],
|
80
|
+
},
|
81
|
+
{
|
82
|
+
"node_index": 1,
|
83
|
+
"node_id": "id2",
|
84
|
+
"node_name": "JAK2",
|
85
|
+
"node_type": "gene/protein",
|
86
|
+
"feat": "featB",
|
87
|
+
"feat_emb": [0.4, 0.5, 0.6],
|
88
|
+
"desc": "descB",
|
89
|
+
"desc_emb": [0.4, 0.5, 0.6],
|
90
|
+
},
|
82
91
|
]
|
83
92
|
colls["nodes"].load.return_value = None
|
84
93
|
|
85
94
|
colls["edges"] = MagicMock()
|
86
95
|
colls["edges"].query.return_value = [
|
87
|
-
{
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
+
{
|
97
|
+
"triplet_index": 0,
|
98
|
+
"head_id": "id1",
|
99
|
+
"head_index": 0,
|
100
|
+
"tail_id": "id2",
|
101
|
+
"tail_index": 1,
|
102
|
+
"edge_type": "gene/protein,ppi,gene/protein",
|
103
|
+
"display_relation": "ppi",
|
104
|
+
"feat": "featC",
|
105
|
+
"feat_emb": [0.7, 0.8, 0.9],
|
106
|
+
}
|
96
107
|
]
|
97
108
|
colls["edges"].load.return_value = None
|
98
109
|
|
@@ -105,30 +116,39 @@ class TestMultimodalSubgraphExtractionTool(unittest.TestCase):
|
|
105
116
|
if "edges" in name:
|
106
117
|
return colls["edges"]
|
107
118
|
return None
|
119
|
+
|
108
120
|
mock_collection.side_effect = collection_side_effect
|
109
121
|
|
110
122
|
# Mock MultimodalPCSTPruning
|
111
123
|
mock_pcst_instance = MagicMock()
|
112
124
|
mock_pcst_instance.extract_subgraph.return_value = {
|
113
125
|
"nodes": pd.Series([1, 2]),
|
114
|
-
"edges": pd.Series([0])
|
126
|
+
"edges": pd.Series([0]),
|
115
127
|
}
|
116
128
|
mock_pcst.return_value = mock_pcst_instance
|
117
129
|
|
118
130
|
# Patch hydra.compose to return config objects
|
119
|
-
with
|
120
|
-
|
121
|
-
|
122
|
-
|
131
|
+
with (
|
132
|
+
patch(
|
133
|
+
"aiagents4pharma.talk2knowledgegraphs.tools."
|
134
|
+
"milvus_multimodal_subgraph_extraction.hydra.initialize"
|
135
|
+
),
|
136
|
+
patch(
|
137
|
+
"aiagents4pharma.talk2knowledgegraphs.tools."
|
138
|
+
"milvus_multimodal_subgraph_extraction.hydra.compose"
|
139
|
+
) as mock_compose,
|
140
|
+
):
|
123
141
|
mock_compose.return_value = MagicMock()
|
124
142
|
mock_compose.return_value.app.frontend = self.cfg_db
|
125
143
|
mock_compose.return_value.tools.multimodal_subgraph_extraction = self.cfg
|
126
144
|
|
127
145
|
response = self.tool.invoke(
|
128
|
-
input={
|
129
|
-
|
130
|
-
|
131
|
-
|
146
|
+
input={
|
147
|
+
"prompt": self.prompt,
|
148
|
+
"tool_call_id": "subgraph_extraction_tool",
|
149
|
+
"state": self.state,
|
150
|
+
"arg_data": self.arg_data,
|
151
|
+
}
|
132
152
|
)
|
133
153
|
|
134
154
|
# Check tool message
|
@@ -146,36 +166,47 @@ class TestMultimodalSubgraphExtractionTool(unittest.TestCase):
|
|
146
166
|
self.assertGreater(len(dic_extracted_graph["graph_dict"]["edges"]), 0)
|
147
167
|
self.assertIsInstance(dic_extracted_graph["graph_text"], str)
|
148
168
|
# Check if the nodes are in the graph_text
|
149
|
-
self.assertTrue(
|
150
|
-
|
151
|
-
|
152
|
-
|
153
|
-
|
169
|
+
self.assertTrue(
|
170
|
+
all(
|
171
|
+
n[0] in dic_extracted_graph["graph_text"].replace('"', "")
|
172
|
+
for subgraph_nodes in dic_extracted_graph["graph_dict"]["nodes"]
|
173
|
+
for n in subgraph_nodes
|
174
|
+
)
|
175
|
+
)
|
154
176
|
# Check if the edges are in the graph_text
|
155
|
-
self.assertTrue(
|
156
|
-
|
157
|
-
|
158
|
-
|
159
|
-
|
160
|
-
|
161
|
-
|
177
|
+
self.assertTrue(
|
178
|
+
all(
|
179
|
+
",".join([str(e[0])] + str(e[2]["label"][0]).split(",") + [str(e[1])])
|
180
|
+
in dic_extracted_graph["graph_text"]
|
181
|
+
.replace('"', "")
|
182
|
+
.replace("[", "")
|
183
|
+
.replace("]", "")
|
184
|
+
.replace("'", "")
|
185
|
+
for subgraph_edges in dic_extracted_graph["graph_dict"]["edges"]
|
186
|
+
for e in subgraph_edges
|
187
|
+
)
|
188
|
+
)
|
162
189
|
|
163
190
|
# Another test for unknown collection
|
164
191
|
result = collection_side_effect("unknown")
|
165
192
|
self.assertIsNone(result)
|
166
193
|
|
167
|
-
@patch(
|
168
|
-
|
169
|
-
|
170
|
-
|
171
|
-
@patch(
|
172
|
-
|
194
|
+
@patch(
|
195
|
+
"aiagents4pharma.talk2knowledgegraphs.tools."
|
196
|
+
"milvus_multimodal_subgraph_extraction.Collection"
|
197
|
+
)
|
198
|
+
@patch(
|
199
|
+
"aiagents4pharma.talk2knowledgegraphs.tools."
|
200
|
+
"milvus_multimodal_subgraph_extraction.pd.read_excel"
|
201
|
+
)
|
202
|
+
@patch(
|
203
|
+
"aiagents4pharma.talk2knowledgegraphs.tools."
|
204
|
+
"milvus_multimodal_subgraph_extraction.MultimodalPCSTPruning"
|
205
|
+
)
|
173
206
|
@patch("pymilvus.connections")
|
174
|
-
def test_extract_multimodal_subgraph_w_doc(
|
175
|
-
|
176
|
-
|
177
|
-
mock_read_excel,
|
178
|
-
mock_collection):
|
207
|
+
def test_extract_multimodal_subgraph_w_doc(
|
208
|
+
self, mock_connections, mock_pcst, mock_read_excel, mock_collection
|
209
|
+
):
|
179
210
|
"""
|
180
211
|
Test the multimodal subgraph extraction tool for text as modality, plus genes.
|
181
212
|
"""
|
@@ -183,17 +214,12 @@ class TestMultimodalSubgraphExtractionTool(unittest.TestCase):
|
|
183
214
|
mock_connections.has_connection.return_value = True
|
184
215
|
|
185
216
|
# With uploaded_files (with doc)
|
186
|
-
self.state["uploaded_files"] = [
|
187
|
-
{"file_type": "multimodal", "file_path": "dummy.xlsx"}
|
188
|
-
]
|
217
|
+
self.state["uploaded_files"] = [{"file_type": "multimodal", "file_path": "dummy.xlsx"}]
|
189
218
|
self.state["embedding_model"].embed_query.return_value = [0.1, 0.2, 0.3]
|
190
219
|
self.state["selections"] = {"gene/protein": ["JAK1", "JAK2"]}
|
191
220
|
|
192
221
|
# Mock pd.read_excel to return a dict of DataFrames
|
193
|
-
df = pd.DataFrame({
|
194
|
-
"name": ["JAK1", "JAK2"],
|
195
|
-
"node_type": ["gene/protein", "gene/protein"]
|
196
|
-
})
|
222
|
+
df = pd.DataFrame({"name": ["JAK1", "JAK2"], "node_type": ["gene/protein", "gene/protein"]})
|
197
223
|
mock_read_excel.return_value = {"gene/protein": df}
|
198
224
|
|
199
225
|
# Mock Collection for nodes and edges
|
@@ -201,36 +227,42 @@ class TestMultimodalSubgraphExtractionTool(unittest.TestCase):
|
|
201
227
|
colls["nodes"] = MagicMock()
|
202
228
|
colls["nodes"] = MagicMock()
|
203
229
|
colls["nodes"].query.return_value = [
|
204
|
-
{
|
205
|
-
|
206
|
-
|
207
|
-
|
208
|
-
|
209
|
-
|
210
|
-
|
211
|
-
|
212
|
-
|
213
|
-
|
214
|
-
|
215
|
-
|
216
|
-
|
217
|
-
|
218
|
-
|
219
|
-
|
230
|
+
{
|
231
|
+
"node_index": 0,
|
232
|
+
"node_id": "id1",
|
233
|
+
"node_name": "JAK1",
|
234
|
+
"node_type": "gene/protein",
|
235
|
+
"feat": "featA",
|
236
|
+
"feat_emb": [0.1, 0.2, 0.3],
|
237
|
+
"desc": "descA",
|
238
|
+
"desc_emb": [0.1, 0.2, 0.3],
|
239
|
+
},
|
240
|
+
{
|
241
|
+
"node_index": 1,
|
242
|
+
"node_id": "id2",
|
243
|
+
"node_name": "JAK2",
|
244
|
+
"node_type": "gene/protein",
|
245
|
+
"feat": "featB",
|
246
|
+
"feat_emb": [0.4, 0.5, 0.6],
|
247
|
+
"desc": "descB",
|
248
|
+
"desc_emb": [0.4, 0.5, 0.6],
|
249
|
+
},
|
220
250
|
]
|
221
251
|
colls["nodes"].load.return_value = None
|
222
252
|
|
223
253
|
colls["edges"] = MagicMock()
|
224
254
|
colls["edges"].query.return_value = [
|
225
|
-
{
|
226
|
-
|
227
|
-
|
228
|
-
|
229
|
-
|
230
|
-
|
231
|
-
|
232
|
-
|
233
|
-
|
255
|
+
{
|
256
|
+
"triplet_index": 0,
|
257
|
+
"head_id": "id1",
|
258
|
+
"head_index": 0,
|
259
|
+
"tail_id": "id2",
|
260
|
+
"tail_index": 1,
|
261
|
+
"edge_type": "gene/protein,ppi,gene/protein",
|
262
|
+
"display_relation": "ppi",
|
263
|
+
"feat": "featC",
|
264
|
+
"feat_emb": [0.7, 0.8, 0.9],
|
265
|
+
}
|
234
266
|
]
|
235
267
|
colls["edges"].load.return_value = None
|
236
268
|
|
@@ -243,30 +275,39 @@ class TestMultimodalSubgraphExtractionTool(unittest.TestCase):
|
|
243
275
|
if "edges" in name:
|
244
276
|
return colls["edges"]
|
245
277
|
return None
|
278
|
+
|
246
279
|
mock_collection.side_effect = collection_side_effect
|
247
280
|
|
248
281
|
# Mock MultimodalPCSTPruning
|
249
282
|
mock_pcst_instance = MagicMock()
|
250
283
|
mock_pcst_instance.extract_subgraph.return_value = {
|
251
284
|
"nodes": pd.Series([1, 2]),
|
252
|
-
"edges": pd.Series([0])
|
285
|
+
"edges": pd.Series([0]),
|
253
286
|
}
|
254
287
|
mock_pcst.return_value = mock_pcst_instance
|
255
288
|
|
256
289
|
# Patch hydra.compose to return config objects
|
257
|
-
with
|
258
|
-
|
259
|
-
|
260
|
-
|
290
|
+
with (
|
291
|
+
patch(
|
292
|
+
"aiagents4pharma.talk2knowledgegraphs.tools."
|
293
|
+
"milvus_multimodal_subgraph_extraction.hydra.initialize"
|
294
|
+
),
|
295
|
+
patch(
|
296
|
+
"aiagents4pharma.talk2knowledgegraphs.tools."
|
297
|
+
"milvus_multimodal_subgraph_extraction.hydra.compose"
|
298
|
+
) as mock_compose,
|
299
|
+
):
|
261
300
|
mock_compose.return_value = MagicMock()
|
262
301
|
mock_compose.return_value.app.frontend = self.cfg_db
|
263
302
|
mock_compose.return_value.tools.multimodal_subgraph_extraction = self.cfg
|
264
303
|
|
265
304
|
response = self.tool.invoke(
|
266
|
-
input={
|
267
|
-
|
268
|
-
|
269
|
-
|
305
|
+
input={
|
306
|
+
"prompt": self.prompt,
|
307
|
+
"tool_call_id": "subgraph_extraction_tool",
|
308
|
+
"state": self.state,
|
309
|
+
"arg_data": self.arg_data,
|
310
|
+
}
|
270
311
|
)
|
271
312
|
|
272
313
|
# Check tool message
|
@@ -284,19 +325,26 @@ class TestMultimodalSubgraphExtractionTool(unittest.TestCase):
|
|
284
325
|
self.assertGreater(len(dic_extracted_graph["graph_dict"]["edges"]), 0)
|
285
326
|
self.assertIsInstance(dic_extracted_graph["graph_text"], str)
|
286
327
|
# Check if the nodes are in the graph_text
|
287
|
-
self.assertTrue(
|
288
|
-
|
289
|
-
|
290
|
-
|
291
|
-
|
328
|
+
self.assertTrue(
|
329
|
+
all(
|
330
|
+
n[0] in dic_extracted_graph["graph_text"].replace('"', "")
|
331
|
+
for subgraph_nodes in dic_extracted_graph["graph_dict"]["nodes"]
|
332
|
+
for n in subgraph_nodes
|
333
|
+
)
|
334
|
+
)
|
292
335
|
# Check if the edges are in the graph_text
|
293
|
-
self.assertTrue(
|
294
|
-
|
295
|
-
|
296
|
-
|
297
|
-
|
298
|
-
|
299
|
-
|
336
|
+
self.assertTrue(
|
337
|
+
all(
|
338
|
+
",".join([str(e[0])] + str(e[2]["label"][0]).split(",") + [str(e[1])])
|
339
|
+
in dic_extracted_graph["graph_text"]
|
340
|
+
.replace('"', "")
|
341
|
+
.replace("[", "")
|
342
|
+
.replace("]", "")
|
343
|
+
.replace("'", "")
|
344
|
+
for subgraph_edges in dic_extracted_graph["graph_dict"]["edges"]
|
345
|
+
for e in subgraph_edges
|
346
|
+
)
|
347
|
+
)
|
300
348
|
|
301
349
|
# Another test for unknown collection
|
302
350
|
result = collection_side_effect("unknown")
|
@@ -307,84 +355,100 @@ class TestMultimodalSubgraphExtractionTool(unittest.TestCase):
|
|
307
355
|
Test the multimodal subgraph extraction tool for only text as modality,
|
308
356
|
simulating GPU (cudf/cupy) environment.
|
309
357
|
"""
|
310
|
-
module_name =
|
311
|
-
"milvus_multimodal_subgraph_extraction"
|
358
|
+
module_name = (
|
359
|
+
"aiagents4pharma.talk2knowledgegraphs.tools." + "milvus_multimodal_subgraph_extraction"
|
360
|
+
)
|
312
361
|
with patch.dict("sys.modules", {"cupy": np, "cudf": pd}):
|
313
362
|
mod = importlib.reload(importlib.import_module(module_name))
|
314
363
|
# Patch Collection and MultimodalPCSTPruning after reload
|
315
|
-
with
|
316
|
-
|
317
|
-
|
364
|
+
with (
|
365
|
+
patch(f"{module_name}.Collection") as mock_collection,
|
366
|
+
patch(f"{module_name}.MultimodalPCSTPruning") as mock_pcst,
|
367
|
+
patch("pymilvus.connections") as mock_connections,
|
368
|
+
):
|
318
369
|
# Setup mocks as in the original test
|
319
370
|
mock_connections.has_connection.return_value = True
|
320
371
|
colls = {}
|
321
372
|
colls["nodes"] = MagicMock()
|
322
373
|
colls["nodes"].query.return_value = [
|
323
|
-
{
|
324
|
-
|
325
|
-
|
326
|
-
|
327
|
-
|
328
|
-
|
329
|
-
|
330
|
-
|
331
|
-
|
332
|
-
|
333
|
-
|
334
|
-
|
335
|
-
|
336
|
-
|
337
|
-
|
338
|
-
|
374
|
+
{
|
375
|
+
"node_index": 0,
|
376
|
+
"node_id": "id1",
|
377
|
+
"node_name": "JAK1",
|
378
|
+
"node_type": "gene/protein",
|
379
|
+
"feat": "featA",
|
380
|
+
"feat_emb": [0.1, 0.2, 0.3],
|
381
|
+
"desc": "descA",
|
382
|
+
"desc_emb": [0.1, 0.2, 0.3],
|
383
|
+
},
|
384
|
+
{
|
385
|
+
"node_index": 1,
|
386
|
+
"node_id": "id2",
|
387
|
+
"node_name": "JAK2",
|
388
|
+
"node_type": "gene/protein",
|
389
|
+
"feat": "featB",
|
390
|
+
"feat_emb": [0.4, 0.5, 0.6],
|
391
|
+
"desc": "descB",
|
392
|
+
"desc_emb": [0.4, 0.5, 0.6],
|
393
|
+
},
|
339
394
|
]
|
340
395
|
colls["nodes"].load.return_value = None
|
341
396
|
colls["edges"] = MagicMock()
|
342
397
|
colls["edges"].query.return_value = [
|
343
|
-
{
|
344
|
-
|
345
|
-
|
346
|
-
|
347
|
-
|
348
|
-
|
349
|
-
|
350
|
-
|
351
|
-
|
398
|
+
{
|
399
|
+
"triplet_index": 0,
|
400
|
+
"head_id": "id1",
|
401
|
+
"head_index": 0,
|
402
|
+
"tail_id": "id2",
|
403
|
+
"tail_index": 1,
|
404
|
+
"edge_type": "gene/protein,ppi,gene/protein",
|
405
|
+
"display_relation": "ppi",
|
406
|
+
"feat": "featC",
|
407
|
+
"feat_emb": [0.7, 0.8, 0.9],
|
408
|
+
}
|
352
409
|
]
|
353
410
|
colls["edges"].load.return_value = None
|
411
|
+
|
354
412
|
def collection_side_effect(name):
|
355
413
|
if "nodes" in name:
|
356
414
|
return colls["nodes"]
|
357
415
|
if "edges" in name:
|
358
416
|
return colls["edges"]
|
359
417
|
return None
|
418
|
+
|
360
419
|
mock_collection.side_effect = collection_side_effect
|
361
420
|
mock_pcst_instance = MagicMock()
|
362
421
|
mock_pcst_instance.extract_subgraph.return_value = {
|
363
422
|
"nodes": pd.Series([1, 2]),
|
364
|
-
"edges": pd.Series([0])
|
423
|
+
"edges": pd.Series([0]),
|
365
424
|
}
|
366
425
|
mock_pcst.return_value = mock_pcst_instance
|
367
426
|
# Setup config mocks
|
368
|
-
tool_cls =
|
427
|
+
tool_cls = mod.MultimodalSubgraphExtractionTool
|
369
428
|
tool = tool_cls()
|
370
429
|
|
371
430
|
# Patch hydra.compose
|
372
|
-
with
|
373
|
-
|
431
|
+
with (
|
432
|
+
patch(f"{module_name}.hydra.initialize"),
|
433
|
+
patch(f"{module_name}.hydra.compose") as mock_compose,
|
434
|
+
):
|
374
435
|
mock_compose.return_value = MagicMock()
|
375
436
|
mock_compose.return_value.app.frontend = self.cfg_db
|
376
437
|
mock_compose.return_value.tools.multimodal_subgraph_extraction = self.cfg
|
377
438
|
self.state["embedding_model"].embed_query.return_value = [0.1, 0.2, 0.3]
|
378
439
|
self.state["selections"] = {}
|
379
440
|
response = tool.invoke(
|
380
|
-
input={
|
381
|
-
|
382
|
-
|
383
|
-
|
441
|
+
input={
|
442
|
+
"prompt": self.prompt,
|
443
|
+
"tool_call_id": "subgraph_extraction_tool",
|
444
|
+
"state": self.state,
|
445
|
+
"arg_data": self.arg_data,
|
446
|
+
}
|
384
447
|
)
|
385
448
|
# Check tool message
|
386
|
-
self.assertEqual(
|
387
|
-
|
449
|
+
self.assertEqual(
|
450
|
+
response.update["messages"][-1].tool_call_id, "subgraph_extraction_tool"
|
451
|
+
)
|
388
452
|
dic_extracted_graph = response.update["dic_extracted_graph"][0]
|
389
453
|
self.assertIsInstance(dic_extracted_graph, dict)
|
390
454
|
self.assertEqual(dic_extracted_graph["name"], self.arg_data["extraction_name"])
|
@@ -395,18 +459,25 @@ class TestMultimodalSubgraphExtractionTool(unittest.TestCase):
|
|
395
459
|
self.assertGreater(len(dic_extracted_graph["graph_dict"]["nodes"]), 0)
|
396
460
|
self.assertGreater(len(dic_extracted_graph["graph_dict"]["edges"]), 0)
|
397
461
|
self.assertIsInstance(dic_extracted_graph["graph_text"], str)
|
398
|
-
self.assertTrue(
|
399
|
-
|
400
|
-
|
401
|
-
|
402
|
-
|
403
|
-
|
404
|
-
|
405
|
-
|
406
|
-
|
407
|
-
|
408
|
-
|
409
|
-
|
462
|
+
self.assertTrue(
|
463
|
+
all(
|
464
|
+
n[0] in dic_extracted_graph["graph_text"].replace('"', "")
|
465
|
+
for subgraph_nodes in dic_extracted_graph["graph_dict"]["nodes"]
|
466
|
+
for n in subgraph_nodes
|
467
|
+
)
|
468
|
+
)
|
469
|
+
self.assertTrue(
|
470
|
+
all(
|
471
|
+
",".join([str(e[0])] + str(e[2]["label"][0]).split(",") + [str(e[1])])
|
472
|
+
in dic_extracted_graph["graph_text"]
|
473
|
+
.replace('"', "")
|
474
|
+
.replace("[", "")
|
475
|
+
.replace("]", "")
|
476
|
+
.replace("'", "")
|
477
|
+
for subgraph_edges in dic_extracted_graph["graph_dict"]["edges"]
|
478
|
+
for e in subgraph_edges
|
479
|
+
)
|
480
|
+
)
|
410
481
|
|
411
482
|
# Another test for unknown collection
|
412
483
|
result = collection_side_effect("unknown")
|
@@ -439,15 +510,18 @@ class TestMultimodalSubgraphExtractionTool(unittest.TestCase):
|
|
439
510
|
# In CPU mode, should return the input as-is
|
440
511
|
self.assertEqual(result, [1.0, 2.0, 3.0])
|
441
512
|
|
442
|
-
@patch(
|
443
|
-
|
444
|
-
|
445
|
-
|
513
|
+
@patch(
|
514
|
+
"aiagents4pharma.talk2knowledgegraphs.tools."
|
515
|
+
"milvus_multimodal_subgraph_extraction.Collection"
|
516
|
+
)
|
517
|
+
@patch(
|
518
|
+
"aiagents4pharma.talk2knowledgegraphs.tools."
|
519
|
+
"milvus_multimodal_subgraph_extraction.MultimodalPCSTPruning"
|
520
|
+
)
|
446
521
|
@patch("pymilvus.connections")
|
447
|
-
def test_extract_multimodal_subgraph_no_vector_processing(
|
448
|
-
|
449
|
-
|
450
|
-
mock_collection):
|
522
|
+
def test_extract_multimodal_subgraph_no_vector_processing(
|
523
|
+
self, mock_connections, mock_pcst, mock_collection
|
524
|
+
):
|
451
525
|
"""Test when vector_processing config is not present."""
|
452
526
|
# Mock Milvus connection utilities
|
453
527
|
mock_connections.has_connection.return_value = True
|
@@ -460,16 +534,27 @@ class TestMultimodalSubgraphExtractionTool(unittest.TestCase):
|
|
460
534
|
colls = {}
|
461
535
|
colls["nodes"] = MagicMock()
|
462
536
|
colls["nodes"].query.return_value = [
|
463
|
-
{
|
464
|
-
|
465
|
-
|
537
|
+
{
|
538
|
+
"node_index": 0,
|
539
|
+
"node_id": "id1",
|
540
|
+
"node_name": "JAK1",
|
541
|
+
"node_type": "gene/protein",
|
542
|
+
"feat": "featA",
|
543
|
+
"feat_emb": [0.1, 0.2, 0.3],
|
544
|
+
"desc": "descA",
|
545
|
+
"desc_emb": [0.1, 0.2, 0.3],
|
546
|
+
}
|
466
547
|
]
|
467
548
|
colls["nodes"].load.return_value = None
|
468
549
|
|
469
550
|
colls["edges"] = MagicMock()
|
470
551
|
colls["edges"].query.return_value = [
|
471
|
-
{
|
472
|
-
|
552
|
+
{
|
553
|
+
"triplet_index": 0,
|
554
|
+
"head_id": "id1",
|
555
|
+
"tail_id": "id2",
|
556
|
+
"edge_type": "gene/protein,ppi,gene/protein",
|
557
|
+
}
|
473
558
|
]
|
474
559
|
colls["edges"].load.return_value = None
|
475
560
|
|
@@ -479,13 +564,14 @@ class TestMultimodalSubgraphExtractionTool(unittest.TestCase):
|
|
479
564
|
if "edges" in name:
|
480
565
|
return colls["edges"]
|
481
566
|
return None
|
567
|
+
|
482
568
|
mock_collection.side_effect = collection_side_effect
|
483
569
|
|
484
570
|
# Mock MultimodalPCSTPruning
|
485
571
|
mock_pcst_instance = MagicMock()
|
486
572
|
mock_pcst_instance.extract_subgraph.return_value = {
|
487
573
|
"nodes": pd.Series([1]),
|
488
|
-
"edges": pd.Series([0])
|
574
|
+
"edges": pd.Series([0]),
|
489
575
|
}
|
490
576
|
mock_pcst.return_value = mock_pcst_instance
|
491
577
|
|
@@ -503,20 +589,29 @@ class TestMultimodalSubgraphExtractionTool(unittest.TestCase):
|
|
503
589
|
del cfg_no_vector_processing.vector_processing
|
504
590
|
|
505
591
|
# Patch hydra.compose to return config without vector_processing
|
506
|
-
with
|
507
|
-
|
508
|
-
|
509
|
-
|
592
|
+
with (
|
593
|
+
patch(
|
594
|
+
"aiagents4pharma.talk2knowledgegraphs.tools."
|
595
|
+
"milvus_multimodal_subgraph_extraction.hydra.initialize"
|
596
|
+
),
|
597
|
+
patch(
|
598
|
+
"aiagents4pharma.talk2knowledgegraphs.tools."
|
599
|
+
"milvus_multimodal_subgraph_extraction.hydra.compose"
|
600
|
+
) as mock_compose,
|
601
|
+
):
|
510
602
|
mock_compose.return_value = MagicMock()
|
511
603
|
mock_compose.return_value.app.frontend = self.cfg_db
|
512
|
-
mock_compose.return_value.tools.multimodal_subgraph_extraction =
|
604
|
+
mock_compose.return_value.tools.multimodal_subgraph_extraction = (
|
513
605
|
cfg_no_vector_processing
|
606
|
+
)
|
514
607
|
|
515
608
|
response = self.tool.invoke(
|
516
|
-
input={
|
517
|
-
|
518
|
-
|
519
|
-
|
609
|
+
input={
|
610
|
+
"prompt": self.prompt,
|
611
|
+
"tool_call_id": "subgraph_extraction_tool",
|
612
|
+
"state": self.state,
|
613
|
+
"arg_data": self.arg_data,
|
614
|
+
}
|
520
615
|
)
|
521
616
|
|
522
617
|
# Verify the test completed successfully
|
@@ -530,15 +625,18 @@ class TestMultimodalSubgraphExtractionTool(unittest.TestCase):
|
|
530
625
|
result = collection_side_effect("unknown_collection")
|
531
626
|
self.assertIsNone(result)
|
532
627
|
|
533
|
-
@patch(
|
534
|
-
|
535
|
-
|
536
|
-
|
628
|
+
@patch(
|
629
|
+
"aiagents4pharma.talk2knowledgegraphs.tools."
|
630
|
+
"milvus_multimodal_subgraph_extraction.Collection"
|
631
|
+
)
|
632
|
+
@patch(
|
633
|
+
"aiagents4pharma.talk2knowledgegraphs.tools."
|
634
|
+
"milvus_multimodal_subgraph_extraction.MultimodalPCSTPruning"
|
635
|
+
)
|
537
636
|
@patch("pymilvus.connections")
|
538
|
-
def test_extract_multimodal_subgraph_dynamic_metrics_disabled(
|
539
|
-
|
540
|
-
|
541
|
-
mock_collection):
|
637
|
+
def test_extract_multimodal_subgraph_dynamic_metrics_disabled(
|
638
|
+
self, mock_connections, mock_pcst, mock_collection
|
639
|
+
):
|
542
640
|
"""Test when dynamic_metrics is disabled."""
|
543
641
|
# Mock Milvus connection utilities
|
544
642
|
mock_connections.has_connection.return_value = True
|
@@ -551,16 +649,27 @@ class TestMultimodalSubgraphExtractionTool(unittest.TestCase):
|
|
551
649
|
colls = {}
|
552
650
|
colls["nodes"] = MagicMock()
|
553
651
|
colls["nodes"].query.return_value = [
|
554
|
-
{
|
555
|
-
|
556
|
-
|
652
|
+
{
|
653
|
+
"node_index": 0,
|
654
|
+
"node_id": "id1",
|
655
|
+
"node_name": "JAK1",
|
656
|
+
"node_type": "gene/protein",
|
657
|
+
"feat": "featA",
|
658
|
+
"feat_emb": [0.1, 0.2, 0.3],
|
659
|
+
"desc": "descA",
|
660
|
+
"desc_emb": [0.1, 0.2, 0.3],
|
661
|
+
}
|
557
662
|
]
|
558
663
|
colls["nodes"].load.return_value = None
|
559
664
|
|
560
665
|
colls["edges"] = MagicMock()
|
561
666
|
colls["edges"].query.return_value = [
|
562
|
-
{
|
563
|
-
|
667
|
+
{
|
668
|
+
"triplet_index": 0,
|
669
|
+
"head_id": "id1",
|
670
|
+
"tail_id": "id2",
|
671
|
+
"edge_type": "gene/protein,ppi,gene/protein",
|
672
|
+
}
|
564
673
|
]
|
565
674
|
colls["edges"].load.return_value = None
|
566
675
|
|
@@ -570,13 +679,14 @@ class TestMultimodalSubgraphExtractionTool(unittest.TestCase):
|
|
570
679
|
if "edges" in name:
|
571
680
|
return colls["edges"]
|
572
681
|
return None
|
682
|
+
|
573
683
|
mock_collection.side_effect = collection_side_effect
|
574
684
|
|
575
685
|
# Mock MultimodalPCSTPruning
|
576
686
|
mock_pcst_instance = MagicMock()
|
577
687
|
mock_pcst_instance.extract_subgraph.return_value = {
|
578
688
|
"nodes": pd.Series([1]),
|
579
|
-
"edges": pd.Series([0])
|
689
|
+
"edges": pd.Series([0]),
|
580
690
|
}
|
581
691
|
mock_pcst.return_value = mock_pcst_instance
|
582
692
|
|
@@ -595,19 +705,27 @@ class TestMultimodalSubgraphExtractionTool(unittest.TestCase):
|
|
595
705
|
cfg_dynamic_disabled.vector_processing.dynamic_metrics = False
|
596
706
|
|
597
707
|
# Patch hydra.compose to return config with dynamic_metrics disabled
|
598
|
-
with
|
599
|
-
|
600
|
-
|
601
|
-
|
708
|
+
with (
|
709
|
+
patch(
|
710
|
+
"aiagents4pharma.talk2knowledgegraphs.tools."
|
711
|
+
"milvus_multimodal_subgraph_extraction.hydra.initialize"
|
712
|
+
),
|
713
|
+
patch(
|
714
|
+
"aiagents4pharma.talk2knowledgegraphs.tools."
|
715
|
+
"milvus_multimodal_subgraph_extraction.hydra.compose"
|
716
|
+
) as mock_compose,
|
717
|
+
):
|
602
718
|
mock_compose.return_value = MagicMock()
|
603
719
|
mock_compose.return_value.app.frontend = self.cfg_db
|
604
720
|
mock_compose.return_value.tools.multimodal_subgraph_extraction = cfg_dynamic_disabled
|
605
721
|
|
606
722
|
response = self.tool.invoke(
|
607
|
-
input={
|
608
|
-
|
609
|
-
|
610
|
-
|
723
|
+
input={
|
724
|
+
"prompt": self.prompt,
|
725
|
+
"tool_call_id": "subgraph_extraction_tool",
|
726
|
+
"state": self.state,
|
727
|
+
"arg_data": self.arg_data,
|
728
|
+
}
|
611
729
|
)
|
612
730
|
|
613
731
|
# Verify the test completed successfully
|