aiagents4pharma 1.43.0__py3-none-any.whl → 1.45.0__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (290) hide show
  1. aiagents4pharma/__init__.py +2 -2
  2. aiagents4pharma/talk2aiagents4pharma/.dockerignore +13 -0
  3. aiagents4pharma/talk2aiagents4pharma/Dockerfile +105 -0
  4. aiagents4pharma/talk2aiagents4pharma/README.md +1 -0
  5. aiagents4pharma/talk2aiagents4pharma/__init__.py +4 -5
  6. aiagents4pharma/talk2aiagents4pharma/agents/__init__.py +3 -2
  7. aiagents4pharma/talk2aiagents4pharma/agents/main_agent.py +24 -23
  8. aiagents4pharma/talk2aiagents4pharma/configs/__init__.py +2 -2
  9. aiagents4pharma/talk2aiagents4pharma/configs/agents/__init__.py +2 -2
  10. aiagents4pharma/talk2aiagents4pharma/configs/agents/main_agent/default.yaml +2 -2
  11. aiagents4pharma/talk2aiagents4pharma/configs/config.yaml +1 -1
  12. aiagents4pharma/talk2aiagents4pharma/docker-compose/cpu/.env.example +23 -0
  13. aiagents4pharma/talk2aiagents4pharma/docker-compose/cpu/docker-compose.yml +93 -0
  14. aiagents4pharma/talk2aiagents4pharma/docker-compose/gpu/.env.example +23 -0
  15. aiagents4pharma/talk2aiagents4pharma/docker-compose/gpu/docker-compose.yml +108 -0
  16. aiagents4pharma/talk2aiagents4pharma/install.md +127 -0
  17. aiagents4pharma/talk2aiagents4pharma/states/__init__.py +3 -2
  18. aiagents4pharma/talk2aiagents4pharma/states/state_talk2aiagents4pharma.py +5 -3
  19. aiagents4pharma/talk2aiagents4pharma/tests/__init__.py +2 -2
  20. aiagents4pharma/talk2aiagents4pharma/tests/test_main_agent.py +72 -50
  21. aiagents4pharma/talk2biomodels/.dockerignore +13 -0
  22. aiagents4pharma/talk2biomodels/Dockerfile +104 -0
  23. aiagents4pharma/talk2biomodels/README.md +1 -0
  24. aiagents4pharma/talk2biomodels/__init__.py +4 -8
  25. aiagents4pharma/talk2biomodels/agents/__init__.py +3 -2
  26. aiagents4pharma/talk2biomodels/agents/t2b_agent.py +47 -42
  27. aiagents4pharma/talk2biomodels/api/__init__.py +4 -5
  28. aiagents4pharma/talk2biomodels/api/kegg.py +14 -10
  29. aiagents4pharma/talk2biomodels/api/ols.py +13 -10
  30. aiagents4pharma/talk2biomodels/api/uniprot.py +7 -6
  31. aiagents4pharma/talk2biomodels/configs/__init__.py +3 -4
  32. aiagents4pharma/talk2biomodels/configs/agents/__init__.py +2 -2
  33. aiagents4pharma/talk2biomodels/configs/agents/t2b_agent/__init__.py +2 -2
  34. aiagents4pharma/talk2biomodels/configs/agents/t2b_agent/default.yaml +1 -1
  35. aiagents4pharma/talk2biomodels/configs/config.yaml +1 -1
  36. aiagents4pharma/talk2biomodels/configs/tools/__init__.py +4 -5
  37. aiagents4pharma/talk2biomodels/configs/tools/ask_question/__init__.py +2 -2
  38. aiagents4pharma/talk2biomodels/configs/tools/ask_question/default.yaml +1 -2
  39. aiagents4pharma/talk2biomodels/configs/tools/custom_plotter/__init__.py +2 -2
  40. aiagents4pharma/talk2biomodels/configs/tools/custom_plotter/default.yaml +1 -1
  41. aiagents4pharma/talk2biomodels/configs/tools/get_annotation/__init__.py +2 -2
  42. aiagents4pharma/talk2biomodels/configs/tools/get_annotation/default.yaml +1 -1
  43. aiagents4pharma/talk2biomodels/install.md +63 -0
  44. aiagents4pharma/talk2biomodels/models/__init__.py +4 -4
  45. aiagents4pharma/talk2biomodels/models/basico_model.py +36 -28
  46. aiagents4pharma/talk2biomodels/models/sys_bio_model.py +13 -10
  47. aiagents4pharma/talk2biomodels/states/__init__.py +3 -2
  48. aiagents4pharma/talk2biomodels/states/state_talk2biomodels.py +12 -8
  49. aiagents4pharma/talk2biomodels/tests/BIOMD0000000449_url.xml +1585 -0
  50. aiagents4pharma/talk2biomodels/tests/__init__.py +2 -2
  51. aiagents4pharma/talk2biomodels/tests/article_on_model_537.pdf +0 -0
  52. aiagents4pharma/talk2biomodels/tests/test_api.py +18 -14
  53. aiagents4pharma/talk2biomodels/tests/test_ask_question.py +8 -9
  54. aiagents4pharma/talk2biomodels/tests/test_basico_model.py +15 -9
  55. aiagents4pharma/talk2biomodels/tests/test_get_annotation.py +54 -55
  56. aiagents4pharma/talk2biomodels/tests/test_getmodelinfo.py +28 -27
  57. aiagents4pharma/talk2biomodels/tests/test_integration.py +21 -33
  58. aiagents4pharma/talk2biomodels/tests/test_load_biomodel.py +14 -11
  59. aiagents4pharma/talk2biomodels/tests/test_param_scan.py +21 -20
  60. aiagents4pharma/talk2biomodels/tests/test_query_article.py +129 -29
  61. aiagents4pharma/talk2biomodels/tests/test_search_models.py +9 -13
  62. aiagents4pharma/talk2biomodels/tests/test_simulate_model.py +16 -15
  63. aiagents4pharma/talk2biomodels/tests/test_steady_state.py +12 -22
  64. aiagents4pharma/talk2biomodels/tests/test_sys_bio_model.py +33 -29
  65. aiagents4pharma/talk2biomodels/tools/__init__.py +15 -12
  66. aiagents4pharma/talk2biomodels/tools/ask_question.py +42 -32
  67. aiagents4pharma/talk2biomodels/tools/custom_plotter.py +51 -43
  68. aiagents4pharma/talk2biomodels/tools/get_annotation.py +99 -75
  69. aiagents4pharma/talk2biomodels/tools/get_modelinfo.py +57 -51
  70. aiagents4pharma/talk2biomodels/tools/load_arguments.py +52 -32
  71. aiagents4pharma/talk2biomodels/tools/load_biomodel.py +8 -2
  72. aiagents4pharma/talk2biomodels/tools/parameter_scan.py +107 -90
  73. aiagents4pharma/talk2biomodels/tools/query_article.py +14 -13
  74. aiagents4pharma/talk2biomodels/tools/search_models.py +37 -26
  75. aiagents4pharma/talk2biomodels/tools/simulate_model.py +47 -37
  76. aiagents4pharma/talk2biomodels/tools/steady_state.py +76 -58
  77. aiagents4pharma/talk2biomodels/tools/utils.py +4 -3
  78. aiagents4pharma/talk2cells/README.md +1 -0
  79. aiagents4pharma/talk2cells/__init__.py +4 -5
  80. aiagents4pharma/talk2cells/agents/__init__.py +3 -2
  81. aiagents4pharma/talk2cells/agents/scp_agent.py +21 -19
  82. aiagents4pharma/talk2cells/states/__init__.py +3 -2
  83. aiagents4pharma/talk2cells/states/state_talk2cells.py +4 -2
  84. aiagents4pharma/talk2cells/tests/scp_agent/test_scp_agent.py +8 -9
  85. aiagents4pharma/talk2cells/tools/__init__.py +3 -2
  86. aiagents4pharma/talk2cells/tools/scp_agent/__init__.py +4 -4
  87. aiagents4pharma/talk2cells/tools/scp_agent/display_studies.py +5 -3
  88. aiagents4pharma/talk2cells/tools/scp_agent/search_studies.py +21 -22
  89. aiagents4pharma/talk2knowledgegraphs/.dockerignore +13 -0
  90. aiagents4pharma/talk2knowledgegraphs/Dockerfile +103 -0
  91. aiagents4pharma/talk2knowledgegraphs/README.md +1 -0
  92. aiagents4pharma/talk2knowledgegraphs/__init__.py +4 -7
  93. aiagents4pharma/talk2knowledgegraphs/agents/__init__.py +3 -2
  94. aiagents4pharma/talk2knowledgegraphs/agents/t2kg_agent.py +40 -30
  95. aiagents4pharma/talk2knowledgegraphs/configs/__init__.py +3 -6
  96. aiagents4pharma/talk2knowledgegraphs/configs/agents/t2kg_agent/__init__.py +2 -2
  97. aiagents4pharma/talk2knowledgegraphs/configs/agents/t2kg_agent/default.yaml +8 -8
  98. aiagents4pharma/talk2knowledgegraphs/configs/app/__init__.py +3 -2
  99. aiagents4pharma/talk2knowledgegraphs/configs/app/frontend/__init__.py +2 -2
  100. aiagents4pharma/talk2knowledgegraphs/configs/app/frontend/default.yaml +1 -1
  101. aiagents4pharma/talk2knowledgegraphs/configs/config.yaml +1 -1
  102. aiagents4pharma/talk2knowledgegraphs/configs/tools/__init__.py +4 -5
  103. aiagents4pharma/talk2knowledgegraphs/configs/tools/graphrag_reasoning/__init__.py +2 -2
  104. aiagents4pharma/talk2knowledgegraphs/configs/tools/graphrag_reasoning/default.yaml +1 -1
  105. aiagents4pharma/talk2knowledgegraphs/configs/tools/multimodal_subgraph_extraction/default.yaml +17 -2
  106. aiagents4pharma/talk2knowledgegraphs/configs/tools/subgraph_extraction/__init__.py +2 -2
  107. aiagents4pharma/talk2knowledgegraphs/configs/tools/subgraph_extraction/default.yaml +1 -1
  108. aiagents4pharma/talk2knowledgegraphs/configs/tools/subgraph_summarization/__init__.py +2 -2
  109. aiagents4pharma/talk2knowledgegraphs/configs/tools/subgraph_summarization/default.yaml +1 -1
  110. aiagents4pharma/talk2knowledgegraphs/configs/utils/enrichments/ols_terms/default.yaml +1 -1
  111. aiagents4pharma/talk2knowledgegraphs/configs/utils/enrichments/reactome_pathways/default.yaml +1 -1
  112. aiagents4pharma/talk2knowledgegraphs/configs/utils/enrichments/uniprot_proteins/default.yaml +1 -1
  113. aiagents4pharma/talk2knowledgegraphs/configs/utils/pubchem_utils/default.yaml +1 -1
  114. aiagents4pharma/talk2knowledgegraphs/datasets/__init__.py +4 -6
  115. aiagents4pharma/talk2knowledgegraphs/datasets/biobridge_primekg.py +115 -67
  116. aiagents4pharma/talk2knowledgegraphs/datasets/dataset.py +2 -0
  117. aiagents4pharma/talk2knowledgegraphs/datasets/primekg.py +35 -24
  118. aiagents4pharma/talk2knowledgegraphs/datasets/starkqa_primekg.py +29 -21
  119. aiagents4pharma/talk2knowledgegraphs/docker-compose/cpu/.env.example +23 -0
  120. aiagents4pharma/talk2knowledgegraphs/docker-compose/cpu/docker-compose.yml +93 -0
  121. aiagents4pharma/talk2knowledgegraphs/docker-compose/gpu/.env.example +23 -0
  122. aiagents4pharma/talk2knowledgegraphs/docker-compose/gpu/docker-compose.yml +108 -0
  123. aiagents4pharma/talk2knowledgegraphs/entrypoint.sh +190 -0
  124. aiagents4pharma/talk2knowledgegraphs/install.md +140 -0
  125. aiagents4pharma/talk2knowledgegraphs/milvus_data_dump.py +31 -65
  126. aiagents4pharma/talk2knowledgegraphs/states/__init__.py +3 -2
  127. aiagents4pharma/talk2knowledgegraphs/states/state_talk2knowledgegraphs.py +1 -0
  128. aiagents4pharma/talk2knowledgegraphs/tests/test_agents_t2kg_agent.py +65 -40
  129. aiagents4pharma/talk2knowledgegraphs/tests/test_datasets_biobridge_primekg.py +54 -48
  130. aiagents4pharma/talk2knowledgegraphs/tests/test_datasets_dataset.py +4 -0
  131. aiagents4pharma/talk2knowledgegraphs/tests/test_datasets_primekg.py +17 -4
  132. aiagents4pharma/talk2knowledgegraphs/tests/test_datasets_starkqa_primekg.py +33 -24
  133. aiagents4pharma/talk2knowledgegraphs/tests/test_tools_graphrag_reasoning.py +116 -69
  134. aiagents4pharma/talk2knowledgegraphs/tests/test_tools_milvus_multimodal_subgraph_extraction.py +736 -413
  135. aiagents4pharma/talk2knowledgegraphs/tests/test_tools_multimodal_subgraph_extraction.py +22 -15
  136. aiagents4pharma/talk2knowledgegraphs/tests/test_tools_subgraph_extraction.py +19 -12
  137. aiagents4pharma/talk2knowledgegraphs/tests/test_tools_subgraph_summarization.py +95 -48
  138. aiagents4pharma/talk2knowledgegraphs/tests/test_utils_embeddings_embeddings.py +4 -0
  139. aiagents4pharma/talk2knowledgegraphs/tests/test_utils_embeddings_huggingface.py +5 -0
  140. aiagents4pharma/talk2knowledgegraphs/tests/test_utils_embeddings_nim_molmim.py +13 -18
  141. aiagents4pharma/talk2knowledgegraphs/tests/test_utils_embeddings_ollama.py +10 -3
  142. aiagents4pharma/talk2knowledgegraphs/tests/test_utils_enrichments_enrichments.py +4 -3
  143. aiagents4pharma/talk2knowledgegraphs/tests/test_utils_enrichments_ollama.py +3 -2
  144. aiagents4pharma/talk2knowledgegraphs/tests/test_utils_enrichments_ols.py +1 -0
  145. aiagents4pharma/talk2knowledgegraphs/tests/test_utils_enrichments_pubchem.py +9 -4
  146. aiagents4pharma/talk2knowledgegraphs/tests/test_utils_enrichments_reactome.py +6 -6
  147. aiagents4pharma/talk2knowledgegraphs/tests/test_utils_enrichments_uniprot.py +4 -0
  148. aiagents4pharma/talk2knowledgegraphs/tests/test_utils_extractions_milvus_multimodal_pcst.py +442 -42
  149. aiagents4pharma/talk2knowledgegraphs/tests/test_utils_kg_utils.py +3 -4
  150. aiagents4pharma/talk2knowledgegraphs/tests/test_utils_pubchem_utils.py +10 -6
  151. aiagents4pharma/talk2knowledgegraphs/tools/__init__.py +10 -7
  152. aiagents4pharma/talk2knowledgegraphs/tools/graphrag_reasoning.py +15 -20
  153. aiagents4pharma/talk2knowledgegraphs/tools/milvus_multimodal_subgraph_extraction.py +245 -205
  154. aiagents4pharma/talk2knowledgegraphs/tools/multimodal_subgraph_extraction.py +92 -90
  155. aiagents4pharma/talk2knowledgegraphs/tools/subgraph_extraction.py +25 -37
  156. aiagents4pharma/talk2knowledgegraphs/tools/subgraph_summarization.py +10 -13
  157. aiagents4pharma/talk2knowledgegraphs/utils/__init__.py +4 -7
  158. aiagents4pharma/talk2knowledgegraphs/utils/embeddings/__init__.py +4 -7
  159. aiagents4pharma/talk2knowledgegraphs/utils/embeddings/embeddings.py +4 -0
  160. aiagents4pharma/talk2knowledgegraphs/utils/embeddings/huggingface.py +11 -14
  161. aiagents4pharma/talk2knowledgegraphs/utils/embeddings/nim_molmim.py +7 -7
  162. aiagents4pharma/talk2knowledgegraphs/utils/embeddings/ollama.py +12 -6
  163. aiagents4pharma/talk2knowledgegraphs/utils/embeddings/sentence_transformer.py +8 -6
  164. aiagents4pharma/talk2knowledgegraphs/utils/enrichments/__init__.py +9 -6
  165. aiagents4pharma/talk2knowledgegraphs/utils/enrichments/enrichments.py +1 -0
  166. aiagents4pharma/talk2knowledgegraphs/utils/enrichments/ollama.py +15 -9
  167. aiagents4pharma/talk2knowledgegraphs/utils/enrichments/ols_terms.py +23 -20
  168. aiagents4pharma/talk2knowledgegraphs/utils/enrichments/pubchem_strings.py +12 -10
  169. aiagents4pharma/talk2knowledgegraphs/utils/enrichments/reactome_pathways.py +16 -10
  170. aiagents4pharma/talk2knowledgegraphs/utils/enrichments/uniprot_proteins.py +26 -18
  171. aiagents4pharma/talk2knowledgegraphs/utils/extractions/__init__.py +4 -5
  172. aiagents4pharma/talk2knowledgegraphs/utils/extractions/milvus_multimodal_pcst.py +218 -81
  173. aiagents4pharma/talk2knowledgegraphs/utils/extractions/multimodal_pcst.py +53 -47
  174. aiagents4pharma/talk2knowledgegraphs/utils/extractions/pcst.py +18 -14
  175. aiagents4pharma/talk2knowledgegraphs/utils/kg_utils.py +22 -23
  176. aiagents4pharma/talk2knowledgegraphs/utils/pubchem_utils.py +11 -10
  177. aiagents4pharma/talk2scholars/.dockerignore +13 -0
  178. aiagents4pharma/talk2scholars/Dockerfile +104 -0
  179. aiagents4pharma/talk2scholars/README.md +1 -0
  180. aiagents4pharma/talk2scholars/agents/__init__.py +1 -5
  181. aiagents4pharma/talk2scholars/agents/main_agent.py +6 -4
  182. aiagents4pharma/talk2scholars/agents/paper_download_agent.py +5 -4
  183. aiagents4pharma/talk2scholars/agents/pdf_agent.py +4 -2
  184. aiagents4pharma/talk2scholars/agents/s2_agent.py +2 -2
  185. aiagents4pharma/talk2scholars/agents/zotero_agent.py +10 -11
  186. aiagents4pharma/talk2scholars/configs/__init__.py +1 -3
  187. aiagents4pharma/talk2scholars/configs/agents/talk2scholars/__init__.py +1 -4
  188. aiagents4pharma/talk2scholars/configs/agents/talk2scholars/main_agent/default.yaml +1 -1
  189. aiagents4pharma/talk2scholars/configs/agents/talk2scholars/pdf_agent/default.yaml +1 -1
  190. aiagents4pharma/talk2scholars/configs/agents/talk2scholars/s2_agent/default.yaml +8 -8
  191. aiagents4pharma/talk2scholars/configs/agents/talk2scholars/zotero_agent/default.yaml +7 -7
  192. aiagents4pharma/talk2scholars/configs/tools/__init__.py +8 -6
  193. aiagents4pharma/talk2scholars/docker-compose/cpu/.env.example +21 -0
  194. aiagents4pharma/talk2scholars/docker-compose/cpu/docker-compose.yml +90 -0
  195. aiagents4pharma/talk2scholars/docker-compose/gpu/.env.example +21 -0
  196. aiagents4pharma/talk2scholars/docker-compose/gpu/docker-compose.yml +105 -0
  197. aiagents4pharma/talk2scholars/install.md +122 -0
  198. aiagents4pharma/talk2scholars/state/state_talk2scholars.py +8 -8
  199. aiagents4pharma/talk2scholars/tests/{test_main_agent.py → test_agents_main_agent.py} +41 -23
  200. aiagents4pharma/talk2scholars/tests/{test_paper_download_agent.py → test_agents_paper_agents_download_agent.py} +10 -16
  201. aiagents4pharma/talk2scholars/tests/{test_pdf_agent.py → test_agents_pdf_agent.py} +6 -10
  202. aiagents4pharma/talk2scholars/tests/{test_s2_agent.py → test_agents_s2_agent.py} +8 -16
  203. aiagents4pharma/talk2scholars/tests/{test_zotero_agent.py → test_agents_zotero_agent.py} +5 -7
  204. aiagents4pharma/talk2scholars/tests/{test_s2_display_dataframe.py → test_s2_tools_display_dataframe.py} +6 -7
  205. aiagents4pharma/talk2scholars/tests/{test_s2_query_dataframe.py → test_s2_tools_query_dataframe.py} +5 -15
  206. aiagents4pharma/talk2scholars/tests/{test_paper_downloader.py → test_tools_paper_downloader.py} +25 -63
  207. aiagents4pharma/talk2scholars/tests/{test_question_and_answer_tool.py → test_tools_question_and_answer_tool.py} +2 -6
  208. aiagents4pharma/talk2scholars/tests/{test_s2_multi.py → test_tools_s2_multi.py} +5 -5
  209. aiagents4pharma/talk2scholars/tests/{test_s2_retrieve.py → test_tools_s2_retrieve.py} +2 -1
  210. aiagents4pharma/talk2scholars/tests/{test_s2_search.py → test_tools_s2_search.py} +5 -5
  211. aiagents4pharma/talk2scholars/tests/{test_s2_single.py → test_tools_s2_single.py} +5 -5
  212. aiagents4pharma/talk2scholars/tests/{test_arxiv_downloader.py → test_utils_arxiv_downloader.py} +16 -25
  213. aiagents4pharma/talk2scholars/tests/{test_base_paper_downloader.py → test_utils_base_paper_downloader.py} +25 -47
  214. aiagents4pharma/talk2scholars/tests/{test_biorxiv_downloader.py → test_utils_biorxiv_downloader.py} +14 -42
  215. aiagents4pharma/talk2scholars/tests/{test_medrxiv_downloader.py → test_utils_medrxiv_downloader.py} +15 -49
  216. aiagents4pharma/talk2scholars/tests/{test_nvidia_nim_reranker.py → test_utils_nvidia_nim_reranker.py} +6 -16
  217. aiagents4pharma/talk2scholars/tests/{test_pdf_answer_formatter.py → test_utils_pdf_answer_formatter.py} +1 -0
  218. aiagents4pharma/talk2scholars/tests/{test_pdf_batch_processor.py → test_utils_pdf_batch_processor.py} +6 -15
  219. aiagents4pharma/talk2scholars/tests/{test_pdf_collection_manager.py → test_utils_pdf_collection_manager.py} +34 -11
  220. aiagents4pharma/talk2scholars/tests/{test_pdf_document_processor.py → test_utils_pdf_document_processor.py} +2 -3
  221. aiagents4pharma/talk2scholars/tests/{test_pdf_generate_answer.py → test_utils_pdf_generate_answer.py} +3 -6
  222. aiagents4pharma/talk2scholars/tests/{test_pdf_gpu_detection.py → test_utils_pdf_gpu_detection.py} +5 -16
  223. aiagents4pharma/talk2scholars/tests/{test_pdf_rag_pipeline.py → test_utils_pdf_rag_pipeline.py} +7 -17
  224. aiagents4pharma/talk2scholars/tests/{test_pdf_retrieve_chunks.py → test_utils_pdf_retrieve_chunks.py} +4 -11
  225. aiagents4pharma/talk2scholars/tests/{test_pdf_singleton_manager.py → test_utils_pdf_singleton_manager.py} +26 -23
  226. aiagents4pharma/talk2scholars/tests/{test_pdf_vector_normalization.py → test_utils_pdf_vector_normalization.py} +1 -1
  227. aiagents4pharma/talk2scholars/tests/{test_pdf_vector_store.py → test_utils_pdf_vector_store.py} +27 -55
  228. aiagents4pharma/talk2scholars/tests/{test_pubmed_downloader.py → test_utils_pubmed_downloader.py} +31 -91
  229. aiagents4pharma/talk2scholars/tests/{test_read_helper_utils.py → test_utils_read_helper_utils.py} +2 -6
  230. aiagents4pharma/talk2scholars/tests/{test_s2_utils_ext_ids.py → test_utils_s2_utils_ext_ids.py} +5 -15
  231. aiagents4pharma/talk2scholars/tests/{test_zotero_human_in_the_loop.py → test_utils_zotero_human_in_the_loop.py} +6 -13
  232. aiagents4pharma/talk2scholars/tests/{test_zotero_path.py → test_utils_zotero_path.py} +53 -45
  233. aiagents4pharma/talk2scholars/tests/{test_zotero_read.py → test_utils_zotero_read.py} +30 -91
  234. aiagents4pharma/talk2scholars/tests/{test_zotero_write.py → test_utils_zotero_write.py} +6 -16
  235. aiagents4pharma/talk2scholars/tools/__init__.py +1 -4
  236. aiagents4pharma/talk2scholars/tools/paper_download/paper_downloader.py +20 -35
  237. aiagents4pharma/talk2scholars/tools/paper_download/utils/__init__.py +7 -5
  238. aiagents4pharma/talk2scholars/tools/paper_download/utils/arxiv_downloader.py +9 -11
  239. aiagents4pharma/talk2scholars/tools/paper_download/utils/base_paper_downloader.py +14 -21
  240. aiagents4pharma/talk2scholars/tools/paper_download/utils/biorxiv_downloader.py +14 -22
  241. aiagents4pharma/talk2scholars/tools/paper_download/utils/medrxiv_downloader.py +11 -13
  242. aiagents4pharma/talk2scholars/tools/paper_download/utils/pubmed_downloader.py +14 -28
  243. aiagents4pharma/talk2scholars/tools/pdf/question_and_answer.py +4 -8
  244. aiagents4pharma/talk2scholars/tools/pdf/utils/__init__.py +16 -14
  245. aiagents4pharma/talk2scholars/tools/pdf/utils/answer_formatter.py +4 -4
  246. aiagents4pharma/talk2scholars/tools/pdf/utils/batch_processor.py +15 -17
  247. aiagents4pharma/talk2scholars/tools/pdf/utils/collection_manager.py +2 -2
  248. aiagents4pharma/talk2scholars/tools/pdf/utils/document_processor.py +5 -5
  249. aiagents4pharma/talk2scholars/tools/pdf/utils/generate_answer.py +4 -4
  250. aiagents4pharma/talk2scholars/tools/pdf/utils/get_vectorstore.py +2 -6
  251. aiagents4pharma/talk2scholars/tools/pdf/utils/gpu_detection.py +5 -9
  252. aiagents4pharma/talk2scholars/tools/pdf/utils/nvidia_nim_reranker.py +4 -4
  253. aiagents4pharma/talk2scholars/tools/pdf/utils/paper_loader.py +2 -2
  254. aiagents4pharma/talk2scholars/tools/pdf/utils/rag_pipeline.py +6 -15
  255. aiagents4pharma/talk2scholars/tools/pdf/utils/retrieve_chunks.py +7 -15
  256. aiagents4pharma/talk2scholars/tools/pdf/utils/singleton_manager.py +2 -2
  257. aiagents4pharma/talk2scholars/tools/pdf/utils/tool_helper.py +3 -4
  258. aiagents4pharma/talk2scholars/tools/pdf/utils/vector_normalization.py +8 -17
  259. aiagents4pharma/talk2scholars/tools/pdf/utils/vector_store.py +17 -33
  260. aiagents4pharma/talk2scholars/tools/s2/__init__.py +8 -6
  261. aiagents4pharma/talk2scholars/tools/s2/display_dataframe.py +3 -7
  262. aiagents4pharma/talk2scholars/tools/s2/multi_paper_rec.py +7 -6
  263. aiagents4pharma/talk2scholars/tools/s2/query_dataframe.py +5 -12
  264. aiagents4pharma/talk2scholars/tools/s2/retrieve_semantic_scholar_paper_id.py +2 -4
  265. aiagents4pharma/talk2scholars/tools/s2/search.py +6 -6
  266. aiagents4pharma/talk2scholars/tools/s2/single_paper_rec.py +5 -3
  267. aiagents4pharma/talk2scholars/tools/s2/utils/__init__.py +1 -3
  268. aiagents4pharma/talk2scholars/tools/s2/utils/multi_helper.py +12 -18
  269. aiagents4pharma/talk2scholars/tools/s2/utils/search_helper.py +11 -18
  270. aiagents4pharma/talk2scholars/tools/s2/utils/single_helper.py +11 -16
  271. aiagents4pharma/talk2scholars/tools/zotero/__init__.py +1 -4
  272. aiagents4pharma/talk2scholars/tools/zotero/utils/__init__.py +1 -4
  273. aiagents4pharma/talk2scholars/tools/zotero/utils/read_helper.py +21 -39
  274. aiagents4pharma/talk2scholars/tools/zotero/utils/review_helper.py +2 -6
  275. aiagents4pharma/talk2scholars/tools/zotero/utils/write_helper.py +8 -11
  276. aiagents4pharma/talk2scholars/tools/zotero/utils/zotero_path.py +4 -12
  277. aiagents4pharma/talk2scholars/tools/zotero/utils/zotero_pdf_downloader.py +13 -27
  278. aiagents4pharma/talk2scholars/tools/zotero/zotero_read.py +4 -7
  279. aiagents4pharma/talk2scholars/tools/zotero/zotero_review.py +8 -10
  280. aiagents4pharma/talk2scholars/tools/zotero/zotero_write.py +3 -2
  281. {aiagents4pharma-1.43.0.dist-info → aiagents4pharma-1.45.0.dist-info}/METADATA +115 -50
  282. aiagents4pharma-1.45.0.dist-info/RECORD +324 -0
  283. {aiagents4pharma-1.43.0.dist-info → aiagents4pharma-1.45.0.dist-info}/WHEEL +1 -2
  284. aiagents4pharma-1.43.0.dist-info/RECORD +0 -293
  285. aiagents4pharma-1.43.0.dist-info/top_level.txt +0 -1
  286. /aiagents4pharma/talk2scholars/tests/{test_state.py → test_states_state.py} +0 -0
  287. /aiagents4pharma/talk2scholars/tests/{test_pdf_paper_loader.py → test_utils_pdf_paper_loader.py} +0 -0
  288. /aiagents4pharma/talk2scholars/tests/{test_tool_helper_utils.py → test_utils_tool_helper_utils.py} +0 -0
  289. /aiagents4pharma/talk2scholars/tests/{test_zotero_pdf_downloader_utils.py → test_utils_zotero_pdf_downloader_utils.py} +0 -0
  290. {aiagents4pharma-1.43.0.dist-info → aiagents4pharma-1.45.0.dist-info}/licenses/LICENSE +0 -0
@@ -5,6 +5,7 @@ Test cases for utils/enrichments/reactome_pathways.py
5
5
  """
6
6
 
7
7
  import pytest
8
+
8
9
  from ..utils.enrichments.reactome_pathways import EnrichmentWithReactome
9
10
 
10
11
  # In this test, we will consider 2 examples:
@@ -18,26 +19,25 @@ FIRST_PATHWAY = "Cyclic GMP-AMP (cGAMP) synthase (cGAS) was identified as a cyto
18
19
  SECOND_PATHWAY = "The P2RX7 (P2X7, P2Z) trimer binds ATP,"
19
20
  # The expected description of pathway R-HSA-1234567 is None.
20
21
 
22
+
21
23
  @pytest.fixture(name="enrich_obj")
22
24
  def fixture_uniprot_config():
23
25
  """Return a dictionary with the configuration for Reactome enrichment."""
24
26
  return EnrichmentWithReactome()
25
27
 
28
+
26
29
  def test_enrich_documents(enrich_obj):
27
30
  """Test the enrich_documents method."""
28
- reactome_pathways = ["R-HSA-3244647",
29
- "R-HSA-9905952",
30
- "R-HSA-1234567"]
31
+ reactome_pathways = ["R-HSA-3244647", "R-HSA-9905952", "R-HSA-1234567"]
31
32
  descriptions = enrich_obj.enrich_documents(reactome_pathways)
32
33
  assert descriptions[0].startswith(FIRST_PATHWAY)
33
34
  assert descriptions[1].startswith(SECOND_PATHWAY)
34
35
  assert descriptions[2] is None
35
36
 
37
+
36
38
  def test_enrich_documents_with_rag(enrich_obj):
37
39
  """Test the enrich_documents_with_rag method."""
38
- reactome_pathways = ["R-HSA-3244647",
39
- "R-HSA-9905952",
40
- "R-HSA-1234567"]
40
+ reactome_pathways = ["R-HSA-3244647", "R-HSA-9905952", "R-HSA-1234567"]
41
41
  descriptions = enrich_obj.enrich_documents_with_rag(reactome_pathways, None)
42
42
  assert descriptions[0].startswith(FIRST_PATHWAY)
43
43
  assert descriptions[1].startswith(SECOND_PATHWAY)
@@ -5,6 +5,7 @@ Test cases for utils/enrichments/uniprot_proteins.py
5
5
  """
6
6
 
7
7
  import pytest
8
+
8
9
  from ..utils.enrichments.uniprot_proteins import EnrichmentWithUniProt
9
10
 
10
11
  # In this test, we will consider 2 examples:
@@ -16,11 +17,13 @@ START_DESCP = "Multifunctional transcription factor"
16
17
  # The expected amino acid sequence of TP53 startswith:
17
18
  START_SEQ = "MEEPQSDPSV"
18
19
 
20
+
19
21
  @pytest.fixture(name="enrich_obj")
20
22
  def fixture_uniprot_config():
21
23
  """Return a dictionary with the configuration for UniProt enrichment."""
22
24
  return EnrichmentWithUniProt()
23
25
 
26
+
24
27
  def test_enrich_documents(enrich_obj):
25
28
  """Test the enrich_documents method."""
26
29
  gene_names = ["TP53", "TP5", "XZ"]
@@ -32,6 +35,7 @@ def test_enrich_documents(enrich_obj):
32
35
  assert descriptions[2] is None
33
36
  assert sequences[2] is None
34
37
 
38
+
35
39
  def test_enrich_documents_with_rag(enrich_obj):
36
40
  """Test the enrich_documents_with_rag method."""
37
41
  gene_names = ["TP53", "TP5", "XZ"]
@@ -5,45 +5,58 @@ Test cases for tools/utils/extractions/milvus_multimodal_pcst.py
5
5
  import importlib
6
6
  import sys
7
7
  import unittest
8
- from unittest.mock import patch, MagicMock, mock_open
8
+ from unittest.mock import MagicMock, mock_open, patch
9
+
9
10
  import numpy as np
10
11
  import pandas as pd
11
- from ..utils.extractions.milvus_multimodal_pcst import MultimodalPCSTPruning
12
+
13
+ from ..utils.extractions.milvus_multimodal_pcst import (
14
+ DynamicLibraryLoader,
15
+ MultimodalPCSTPruning,
16
+ SystemDetector,
17
+ )
18
+
12
19
 
13
20
  class TestMultimodalPCSTPruning(unittest.TestCase):
14
21
  """
15
22
  Test cases for MultimodalPCSTPruning class (Milvus-based PCST pruning).
16
23
  """
24
+
17
25
  def setUp(self):
18
26
  # Patch cupy and cudf to simulate GPU environment
19
- patcher_cupy = patch.dict('sys.modules', {'cupy': MagicMock(), 'cudf': MagicMock()})
27
+ patcher_cupy = patch.dict("sys.modules", {"cupy": MagicMock(), "cudf": MagicMock()})
20
28
  patcher_cupy.start()
21
29
  self.addCleanup(patcher_cupy.stop)
22
30
 
23
31
  # Patch pcst_fast
24
- self.pcst_fast_patcher = patch("aiagents4pharma.talk2knowledgegraphs.utils."
25
- "extractions.milvus_multimodal_pcst.pcst_fast")
26
- self.mock_pcst_fast = self.pcst_fast_patcher.start()
27
- self.addCleanup(self.pcst_fast_patcher.stop)
28
- self.mock_pcst_fast.pcst_fast.return_value = ([0, 1], [0])
32
+ pcst_fast_patcher = patch(
33
+ "aiagents4pharma.talk2knowledgegraphs.utils."
34
+ "extractions.milvus_multimodal_pcst.pcst_fast"
35
+ )
36
+ mock_pcst_fast = pcst_fast_patcher.start()
37
+ self.addCleanup(pcst_fast_patcher.stop)
38
+ mock_pcst_fast.pcst_fast.return_value = ([0, 1], [0])
29
39
 
30
40
  # Patch Collection
31
- self.collection_patcher = patch("aiagents4pharma.talk2knowledgegraphs.utils."
32
- "extractions.milvus_multimodal_pcst.Collection")
33
- self.mock_collection = self.collection_patcher.start()
34
- self.addCleanup(self.collection_patcher.stop)
41
+ collection_patcher = patch(
42
+ "aiagents4pharma.talk2knowledgegraphs.utils."
43
+ "extractions.milvus_multimodal_pcst.Collection"
44
+ )
45
+ self.mock_collection = collection_patcher.start()
46
+ self.addCleanup(collection_patcher.stop)
35
47
 
36
48
  # Patch open for cache_edge_index_path
37
- self.open_patcher = patch('builtins.open', mock_open(read_data='[[0,1],[1,2]]'))
38
- self.mock_open = self.open_patcher.start()
39
- self.addCleanup(self.open_patcher.stop)
49
+ open_patcher = patch("builtins.open", mock_open(read_data="[[0,1],[1,2]]"))
50
+ open_patcher.start()
51
+ self.addCleanup(open_patcher.stop)
40
52
 
41
53
  # Patch pickle.load to return a numpy array for edge_index
42
- self.pickle_patcher = patch("aiagents4pharma.talk2knowledgegraphs.utils."
43
- "extractions.milvus_multimodal_pcst.pickle")
44
- self.mock_pickle = self.pickle_patcher.start()
45
- self.addCleanup(self.pickle_patcher.stop)
46
- self.mock_pickle.load.return_value = np.array([[0, 1], [1, 2]])
54
+ pickle_patcher = patch(
55
+ "aiagents4pharma.talk2knowledgegraphs.utils.extractions.milvus_multimodal_pcst.pickle"
56
+ )
57
+ mock_pickle = pickle_patcher.start()
58
+ self.addCleanup(pickle_patcher.stop)
59
+ mock_pickle.load.return_value = np.array([[0, 1], [1, 2]])
47
60
 
48
61
  # Setup config mock
49
62
  self.cfg = MagicMock()
@@ -57,7 +70,15 @@ class TestMultimodalPCSTPruning(unittest.TestCase):
57
70
  edge_coll = MagicMock()
58
71
  edge_coll.num_entities = 2
59
72
  edge_coll.search.return_value = [[MagicMock(id=0, score=1.0), MagicMock(id=1, score=0.5)]]
60
- self.mock_collection.side_effect = lambda name: node_coll if "nodes" in name else edge_coll
73
+ self.mock_collection.side_effect = lambda name: (
74
+ node_coll if "nodes" in name else edge_coll
75
+ )
76
+
77
+ # Setup mock loader
78
+ self.mock_loader = MagicMock()
79
+ self.mock_loader.py = np # Use numpy for array operations
80
+ self.mock_loader.df = pd # Use pandas for dataframes
81
+ self.mock_loader.to_list = lambda x: x.tolist() if hasattr(x, "tolist") else list(x)
61
82
 
62
83
  def test_extract_subgraph_use_description_true(self):
63
84
  """
@@ -65,8 +86,17 @@ class TestMultimodalPCSTPruning(unittest.TestCase):
65
86
  """
66
87
  # Create instance
67
88
  pcst = MultimodalPCSTPruning(
68
- topk=3, topk_e=3, cost_e=0.5, c_const=0.01, root=-1,
69
- num_clusters=1, pruning="gw", verbosity_level=0, use_description=True, metric_type="IP"
89
+ topk=3,
90
+ topk_e=3,
91
+ cost_e=0.5,
92
+ c_const=0.01,
93
+ root=-1,
94
+ num_clusters=1,
95
+ pruning="gw",
96
+ verbosity_level=0,
97
+ use_description=True,
98
+ metric_type="IP",
99
+ loader=self.mock_loader,
70
100
  )
71
101
  # Dummy embeddings
72
102
  text_emb = [0.1, 0.2, 0.3]
@@ -88,8 +118,17 @@ class TestMultimodalPCSTPruning(unittest.TestCase):
88
118
  """
89
119
  # Create instance
90
120
  pcst = MultimodalPCSTPruning(
91
- topk=3, topk_e=3, cost_e=0.5, c_const=0.01, root=-1,
92
- num_clusters=1, pruning="gw", verbosity_level=0, use_description=False, metric_type="IP"
121
+ topk=3,
122
+ topk_e=3,
123
+ cost_e=0.5,
124
+ c_const=0.01,
125
+ root=-1,
126
+ num_clusters=1,
127
+ pruning="gw",
128
+ verbosity_level=0,
129
+ use_description=False,
130
+ metric_type="IP",
131
+ loader=self.mock_loader,
93
132
  )
94
133
  # Dummy embeddings
95
134
  text_emb = [0.1, 0.2, 0.3]
@@ -110,8 +149,17 @@ class TestMultimodalPCSTPruning(unittest.TestCase):
110
149
  Test get_subgraph_nodes_edges with virtual vertices present (len(virtual_vertices) > 0).
111
150
  """
112
151
  pcst = MultimodalPCSTPruning(
113
- topk=3, topk_e=3, cost_e=0.5, c_const=0.01, root=-1,
114
- num_clusters=1, pruning="gw", verbosity_level=0, use_description=True, metric_type="IP"
152
+ topk=3,
153
+ topk_e=3,
154
+ cost_e=0.5,
155
+ c_const=0.01,
156
+ root=-1,
157
+ num_clusters=1,
158
+ pruning="gw",
159
+ verbosity_level=0,
160
+ use_description=True,
161
+ metric_type="IP",
162
+ loader=self.mock_loader,
115
163
  )
116
164
  # Simulate num_nodes = 2, vertices contains [0, 1, 2, 3] (2 and 3 are virtual)
117
165
  num_nodes = 2
@@ -121,13 +169,10 @@ class TestMultimodalPCSTPruning(unittest.TestCase):
121
169
  edges_dict = {
122
170
  "edges": np.array([0, 1, 2]),
123
171
  "num_prior_edges": 2,
124
- "edge_index": np.array([[0, 1, 2, 3], [1, 2, 3, 4]])
172
+ "edge_index": np.array([[0, 1, 2, 3], [1, 2, 3, 4]]),
125
173
  }
126
174
  # mapping simulates mapping for edges and nodes
127
- mapping = {
128
- "edges": {0: 0, 1: 1},
129
- "nodes": {2: 2, 3: 3}
130
- }
175
+ mapping = {"edges": {0: 0, 1: 1}, "nodes": {2: 2, 3: 3}}
131
176
 
132
177
  # Call extract_subgraph
133
178
  result = pcst.get_subgraph_nodes_edges(num_nodes, vertices, edges_dict, mapping)
@@ -145,20 +190,36 @@ class TestMultimodalPCSTPruning(unittest.TestCase):
145
190
  Test coverage for GPU import branch by patching sys.modules to mock cupy and
146
191
  cudf as numpy and pandas.
147
192
  """
148
- module_name = "aiagents4pharma.talk2knowledgegraphs.utils" + \
149
- ".extractions.milvus_multimodal_pcst"
193
+ module_name = (
194
+ "aiagents4pharma.talk2knowledgegraphs.utils" + ".extractions.milvus_multimodal_pcst"
195
+ )
150
196
  with patch.dict("sys.modules", {"cupy": np, "cudf": pd}):
151
197
  # Reload the module to trigger the GPU branch
152
198
  mod = importlib.reload(sys.modules[module_name])
153
- # Patch Collection, pcst_fast, and pickle after reload
154
- with patch(f"{module_name}.Collection", self.mock_collection), \
155
- patch(f"{module_name}.pcst_fast", self.mock_pcst_fast), \
156
- patch(f"{module_name}.pickle", self.mock_pickle):
157
- pcst_pruning_cls = getattr(mod, "MultimodalPCSTPruning")
199
+ # Create local mocks for this test
200
+ mock_pcst_fast = MagicMock()
201
+ mock_pcst_fast.pcst_fast.return_value = ([0, 1], [0])
202
+ mock_pickle = MagicMock()
203
+ mock_pickle.load.return_value = np.array([[0, 1], [1, 2]])
204
+ # Patch Collection, pcst_fast, and pickle after reload
205
+ with (
206
+ patch(f"{module_name}.Collection", self.mock_collection),
207
+ patch(f"{module_name}.pcst_fast", mock_pcst_fast),
208
+ patch(f"{module_name}.pickle", mock_pickle),
209
+ ):
210
+ pcst_pruning_cls = mod.MultimodalPCSTPruning
158
211
  pcst = pcst_pruning_cls(
159
- topk=3, topk_e=3, cost_e=0.5, c_const=0.01, root=-1,
160
- num_clusters=1, pruning="gw", verbosity_level=0, use_description=True,
161
- metric_type="IP"
212
+ topk=3,
213
+ topk_e=3,
214
+ cost_e=0.5,
215
+ c_const=0.01,
216
+ root=-1,
217
+ num_clusters=1,
218
+ pruning="gw",
219
+ verbosity_level=0,
220
+ use_description=True,
221
+ metric_type="IP",
222
+ loader=self.mock_loader,
162
223
  )
163
224
  # Dummy embeddings
164
225
  text_emb = [0.1, 0.2, 0.3]
@@ -173,3 +234,342 @@ class TestMultimodalPCSTPruning(unittest.TestCase):
173
234
  self.assertIn("edges", result)
174
235
  self.assertGreaterEqual(len(result["nodes"]), 0)
175
236
  self.assertGreaterEqual(len(result["edges"]), 0)
237
+
238
+
239
+ class TestSystemDetector(unittest.TestCase):
240
+ """Test cases for SystemDetector class."""
241
+
242
+ @patch("aiagents4pharma.talk2knowledgegraphs.utils.extractions.milvus_multimodal_pcst.platform")
243
+ @patch(
244
+ "aiagents4pharma.talk2knowledgegraphs.utils.extractions.milvus_multimodal_pcst.subprocess"
245
+ )
246
+ def test_system_detector_gpu_detected(self, mock_subprocess, mock_platform):
247
+ """Test SystemDetector when GPU is detected."""
248
+ # Mock platform calls
249
+ mock_platform.system.return_value = "Linux"
250
+ mock_platform.machine.return_value = "x86_64"
251
+
252
+ # Mock successful nvidia-smi call
253
+ mock_result = MagicMock()
254
+ mock_result.returncode = 0
255
+ mock_subprocess.run.return_value = mock_result
256
+
257
+ detector = SystemDetector()
258
+
259
+ # Assertions
260
+ self.assertEqual(detector.os_type, "linux")
261
+ self.assertEqual(detector.architecture, "x86_64")
262
+ self.assertTrue(detector.has_nvidia_gpu)
263
+ self.assertTrue(detector.use_gpu)
264
+
265
+ @patch("aiagents4pharma.talk2knowledgegraphs.utils.extractions.milvus_multimodal_pcst.platform")
266
+ @patch(
267
+ "aiagents4pharma.talk2knowledgegraphs.utils.extractions.milvus_multimodal_pcst.subprocess"
268
+ )
269
+ def test_system_detector_no_gpu(self, mock_subprocess, mock_platform):
270
+ """Test SystemDetector when no GPU is detected."""
271
+ # Mock platform calls
272
+ mock_platform.system.return_value = "Linux"
273
+ mock_platform.machine.return_value = "x86_64"
274
+
275
+ # Mock failed nvidia-smi call
276
+ mock_result = MagicMock()
277
+ mock_result.returncode = 1
278
+ mock_subprocess.run.return_value = mock_result
279
+
280
+ detector = SystemDetector()
281
+
282
+ # Assertions
283
+ self.assertEqual(detector.os_type, "linux")
284
+ self.assertEqual(detector.architecture, "x86_64")
285
+ self.assertFalse(detector.has_nvidia_gpu)
286
+ self.assertFalse(detector.use_gpu)
287
+
288
+ @patch("aiagents4pharma.talk2knowledgegraphs.utils.extractions.milvus_multimodal_pcst.platform")
289
+ @patch(
290
+ "aiagents4pharma.talk2knowledgegraphs.utils.extractions.milvus_multimodal_pcst.subprocess"
291
+ )
292
+ def test_system_detector_macos_no_gpu(self, mock_subprocess, mock_platform):
293
+ """Test SystemDetector on macOS (no GPU support)."""
294
+ # Mock platform calls
295
+ mock_platform.system.return_value = "Darwin"
296
+ mock_platform.machine.return_value = "arm64"
297
+
298
+ # Mock successful nvidia-smi call (but macOS should still disable GPU)
299
+ mock_result = MagicMock()
300
+ mock_result.returncode = 0
301
+ mock_subprocess.run.return_value = mock_result
302
+
303
+ detector = SystemDetector()
304
+
305
+ # Assertions
306
+ self.assertEqual(detector.os_type, "darwin")
307
+ self.assertEqual(detector.architecture, "arm64")
308
+ self.assertTrue(detector.has_nvidia_gpu) # GPU detected
309
+ self.assertFalse(detector.use_gpu) # But not used on macOS
310
+
311
+ @patch("aiagents4pharma.talk2knowledgegraphs.utils.extractions.milvus_multimodal_pcst.platform")
312
+ @patch(
313
+ "aiagents4pharma.talk2knowledgegraphs.utils.extractions.milvus_multimodal_pcst.subprocess"
314
+ )
315
+ def test_system_detector_subprocess_exception(self, mock_subprocess, mock_platform):
316
+ """Test SystemDetector when subprocess raises exception."""
317
+ # Mock platform calls
318
+ mock_platform.system.return_value = "Linux"
319
+ mock_platform.machine.return_value = "x86_64"
320
+
321
+ # Mock subprocess to raise FileNotFoundError
322
+ mock_subprocess.run.side_effect = FileNotFoundError("nvidia-smi not found")
323
+ mock_subprocess.TimeoutExpired = Exception
324
+ mock_subprocess.SubprocessError = Exception
325
+
326
+ detector = SystemDetector()
327
+
328
+ # Assertions
329
+ self.assertEqual(detector.os_type, "linux")
330
+ self.assertEqual(detector.architecture, "x86_64")
331
+ self.assertFalse(detector.has_nvidia_gpu)
332
+ self.assertFalse(detector.use_gpu)
333
+
334
+ @patch("aiagents4pharma.talk2knowledgegraphs.utils.extractions.milvus_multimodal_pcst.platform")
335
+ @patch(
336
+ "aiagents4pharma.talk2knowledgegraphs.utils.extractions.milvus_multimodal_pcst.subprocess"
337
+ )
338
+ def test_system_detector_timeout(self, mock_subprocess, mock_platform):
339
+ """Test SystemDetector when subprocess times out."""
340
+ # Mock platform calls
341
+ mock_platform.system.return_value = "Linux"
342
+ mock_platform.machine.return_value = "x86_64"
343
+
344
+ # Mock subprocess to raise TimeoutExpired
345
+ mock_subprocess.TimeoutExpired = Exception
346
+ mock_subprocess.SubprocessError = Exception
347
+ mock_subprocess.run.side_effect = mock_subprocess.TimeoutExpired("nvidia-smi", 10)
348
+
349
+ detector = SystemDetector()
350
+
351
+ # Assertions
352
+ self.assertEqual(detector.os_type, "linux")
353
+ self.assertEqual(detector.architecture, "x86_64")
354
+ self.assertFalse(detector.has_nvidia_gpu)
355
+ self.assertFalse(detector.use_gpu)
356
+
357
+ def test_get_system_info(self):
358
+ """Test get_system_info method."""
359
+ with (
360
+ patch(
361
+ "aiagents4pharma.talk2knowledgegraphs.utils.extractions."
362
+ "milvus_multimodal_pcst.platform"
363
+ ) as mock_platform,
364
+ patch(
365
+ "aiagents4pharma.talk2knowledgegraphs.utils.extractions."
366
+ "milvus_multimodal_pcst.subprocess"
367
+ ) as mock_subprocess,
368
+ ):
369
+ mock_platform.system.return_value = "Linux"
370
+ mock_platform.machine.return_value = "x86_64"
371
+
372
+ mock_result = MagicMock()
373
+ mock_result.returncode = 0
374
+ mock_subprocess.run.return_value = mock_result
375
+
376
+ detector = SystemDetector()
377
+ info = detector.get_system_info()
378
+
379
+ expected_info = {
380
+ "os_type": "linux",
381
+ "architecture": "x86_64",
382
+ "has_nvidia_gpu": True,
383
+ "use_gpu": True,
384
+ }
385
+ self.assertEqual(info, expected_info)
386
+
387
+ def test_is_gpu_compatible(self):
388
+ """Test is_gpu_compatible method."""
389
+ with (
390
+ patch(
391
+ "aiagents4pharma.talk2knowledgegraphs.utils.extractions."
392
+ "milvus_multimodal_pcst.platform"
393
+ ) as mock_platform,
394
+ patch(
395
+ "aiagents4pharma.talk2knowledgegraphs.utils.extractions."
396
+ "milvus_multimodal_pcst.subprocess"
397
+ ) as mock_subprocess,
398
+ ):
399
+ mock_platform.system.return_value = "Linux"
400
+ mock_platform.machine.return_value = "x86_64"
401
+
402
+ mock_result = MagicMock()
403
+ mock_result.returncode = 0
404
+ mock_subprocess.run.return_value = mock_result
405
+
406
+ detector = SystemDetector()
407
+
408
+ # Should be compatible (has GPU + not macOS)
409
+ self.assertTrue(detector.is_gpu_compatible())
410
+
411
+
412
+ class TestDynamicLibraryLoader(unittest.TestCase):
413
+ """Test cases for DynamicLibraryLoader class."""
414
+
415
+ def setUp(self):
416
+ """Set up test fixtures."""
417
+ self.mock_detector = MagicMock()
418
+
419
+ def test_dynamic_library_loader_cpu_mode(self):
420
+ """Test DynamicLibraryLoader in CPU mode."""
421
+ self.mock_detector.use_gpu = False
422
+
423
+ loader = DynamicLibraryLoader(self.mock_detector)
424
+
425
+ # Assertions
426
+ self.assertFalse(loader.use_gpu)
427
+ self.assertEqual(loader.py, np)
428
+ self.assertEqual(loader.df, pd)
429
+ self.assertFalse(loader.normalize_vectors)
430
+ self.assertEqual(loader.metric_type, "COSINE")
431
+
432
+ @patch.dict("sys.modules", {"cupy": MagicMock(), "cudf": MagicMock()})
433
+ def test_dynamic_library_loader_gpu_mode_success(self):
434
+ """Test DynamicLibraryLoader in GPU mode with successful imports."""
435
+ self.mock_detector.use_gpu = True
436
+
437
+ # Mock the CUDF_AVAILABLE flag
438
+ with patch(
439
+ "aiagents4pharma.talk2knowledgegraphs.utils.extractions."
440
+ "milvus_multimodal_pcst.CUDF_AVAILABLE",
441
+ True,
442
+ ):
443
+ loader = DynamicLibraryLoader(self.mock_detector)
444
+
445
+ # Assertions
446
+ self.assertTrue(loader.use_gpu)
447
+ self.assertTrue(loader.normalize_vectors)
448
+ self.assertEqual(loader.metric_type, "IP")
449
+
450
+ def test_dynamic_library_loader_gpu_mode_import_failure(self):
451
+ """Test DynamicLibraryLoader when GPU libraries are not available."""
452
+ self.mock_detector.use_gpu = True
453
+
454
+ # Mock CUDF_AVAILABLE as False to simulate import failure
455
+ with patch(
456
+ "aiagents4pharma.talk2knowledgegraphs.utils.extractions."
457
+ "milvus_multimodal_pcst.CUDF_AVAILABLE",
458
+ False,
459
+ ):
460
+ loader = DynamicLibraryLoader(self.mock_detector)
461
+
462
+ # Should fallback to CPU mode
463
+ self.assertFalse(loader.use_gpu)
464
+ self.assertEqual(loader.py, np)
465
+ self.assertEqual(loader.df, pd)
466
+ self.assertFalse(loader.normalize_vectors)
467
+ self.assertEqual(loader.metric_type, "COSINE")
468
+
469
+ def test_normalize_matrix_cpu_mode(self):
470
+ """Test normalize_matrix in CPU mode."""
471
+ self.mock_detector.use_gpu = False
472
+ loader = DynamicLibraryLoader(self.mock_detector)
473
+
474
+ matrix = np.array([[1, 2], [3, 4]])
475
+ result = loader.normalize_matrix(matrix)
476
+
477
+ # In CPU mode, should return matrix unchanged
478
+ np.testing.assert_array_equal(result, matrix)
479
+
480
+ def test_normalize_matrix_cpu_mode_normalize_false(self):
481
+ """Test normalize_matrix in CPU mode with normalize_vectors=False explicitly."""
482
+ self.mock_detector.use_gpu = False
483
+ loader = DynamicLibraryLoader(self.mock_detector)
484
+
485
+ # Explicitly set normalize_vectors to False to test the return path
486
+ loader.normalize_vectors = False
487
+
488
+ matrix = np.array([[1, 2], [3, 4]])
489
+ result = loader.normalize_matrix(matrix)
490
+
491
+ # Should return matrix unchanged when normalize_vectors is False
492
+ np.testing.assert_array_equal(result, matrix)
493
+
494
+ def test_normalize_matrix_cpu_mode_normalize_true(self):
495
+ """Test normalize_matrix in CPU mode with normalize_vectors=True (edge case)."""
496
+ self.mock_detector.use_gpu = False
497
+ loader = DynamicLibraryLoader(self.mock_detector)
498
+
499
+ # Force normalize_vectors to True to test the else branch at line 144
500
+ loader.normalize_vectors = True
501
+ loader.use_gpu = False # Ensure GPU is disabled
502
+
503
+ matrix = np.array([[1, 2], [3, 4]])
504
+ result = loader.normalize_matrix(matrix)
505
+
506
+ # Should return matrix unchanged in CPU mode even when normalize_vectors is True
507
+ np.testing.assert_array_equal(result, matrix)
508
+
509
+ @patch.dict("sys.modules", {"cupy": MagicMock(), "cudf": MagicMock()})
510
+ def test_normalize_matrix_gpu_mode(self):
511
+ """Test normalize_matrix in GPU mode."""
512
+ self.mock_detector.use_gpu = True
513
+
514
+ with patch(
515
+ "aiagents4pharma.talk2knowledgegraphs.utils.extractions."
516
+ "milvus_multimodal_pcst.CUDF_AVAILABLE",
517
+ True,
518
+ ):
519
+ loader = DynamicLibraryLoader(self.mock_detector)
520
+
521
+ # Mock cupy operations
522
+ mock_cp = MagicMock()
523
+ mock_array = MagicMock()
524
+ mock_norms = MagicMock()
525
+
526
+ mock_cp.asarray.return_value = mock_array
527
+ mock_cp.linalg.norm.return_value = mock_norms
528
+ mock_cp.float32 = np.float32
529
+
530
+ loader.cp = mock_cp
531
+ loader.py = mock_cp
532
+
533
+ matrix = [[1, 2], [3, 4]]
534
+ loader.normalize_matrix(matrix)
535
+
536
+ # Verify cupy operations were called
537
+ mock_cp.asarray.assert_called_once()
538
+ mock_cp.linalg.norm.assert_called_once()
539
+
540
+ def test_to_list_with_tolist(self):
541
+ """Test to_list with data that has tolist method."""
542
+ self.mock_detector.use_gpu = False
543
+ loader = DynamicLibraryLoader(self.mock_detector)
544
+
545
+ data = np.array([1, 2, 3])
546
+ result = loader.to_list(data)
547
+
548
+ self.assertEqual(result, [1, 2, 3])
549
+
550
+ def test_to_list_with_to_arrow(self):
551
+ """Test to_list with data that has to_arrow method."""
552
+ self.mock_detector.use_gpu = False
553
+ loader = DynamicLibraryLoader(self.mock_detector)
554
+
555
+ # Mock data with to_arrow method but no tolist method
556
+ mock_data = MagicMock()
557
+ mock_arrow = MagicMock()
558
+ mock_arrow.to_pylist.return_value = [1, 2, 3]
559
+ mock_data.to_arrow.return_value = mock_arrow
560
+ # Remove tolist method to test the to_arrow path
561
+ del mock_data.tolist
562
+
563
+ result = loader.to_list(mock_data)
564
+
565
+ self.assertEqual(result, [1, 2, 3])
566
+
567
+ def test_to_list_fallback(self):
568
+ """Test to_list fallback to list()."""
569
+ self.mock_detector.use_gpu = False
570
+ loader = DynamicLibraryLoader(self.mock_detector)
571
+
572
+ data = (1, 2, 3) # tuple without tolist or to_arrow
573
+ result = loader.to_list(data)
574
+
575
+ self.assertEqual(result, [1, 2, 3])
@@ -2,9 +2,10 @@
2
2
  Test cases for utils/kg_utils.py
3
3
  """
4
4
 
5
- import pytest
6
5
  import networkx as nx
7
6
  import pandas as pd
7
+ import pytest
8
+
8
9
  from ..utils import kg_utils
9
10
 
10
11
 
@@ -62,9 +63,7 @@ def test_df_pandas_to_kg():
62
63
  }
63
64
  df_edges = pd.DataFrame(edges_data)
64
65
 
65
- kg = kg_utils.df_pandas_to_kg(
66
- df_edges, df_nodes_attrs, "node_source", "node_target"
67
- )
66
+ kg = kg_utils.df_pandas_to_kg(df_edges, df_nodes_attrs, "node_source", "node_target")
68
67
 
69
68
  assert len(kg.nodes) == 2
70
69
  assert len(kg.edges) == 1