aiagents4pharma 0.0.0__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (336) hide show
  1. aiagents4pharma/__init__.py +11 -0
  2. aiagents4pharma/talk2aiagents4pharma/.dockerignore +13 -0
  3. aiagents4pharma/talk2aiagents4pharma/Dockerfile +133 -0
  4. aiagents4pharma/talk2aiagents4pharma/README.md +1 -0
  5. aiagents4pharma/talk2aiagents4pharma/__init__.py +5 -0
  6. aiagents4pharma/talk2aiagents4pharma/agents/__init__.py +6 -0
  7. aiagents4pharma/talk2aiagents4pharma/agents/main_agent.py +70 -0
  8. aiagents4pharma/talk2aiagents4pharma/configs/__init__.py +5 -0
  9. aiagents4pharma/talk2aiagents4pharma/configs/agents/__init__.py +5 -0
  10. aiagents4pharma/talk2aiagents4pharma/configs/agents/main_agent/default.yaml +29 -0
  11. aiagents4pharma/talk2aiagents4pharma/configs/app/__init__.py +0 -0
  12. aiagents4pharma/talk2aiagents4pharma/configs/app/frontend/__init__.py +0 -0
  13. aiagents4pharma/talk2aiagents4pharma/configs/app/frontend/default.yaml +102 -0
  14. aiagents4pharma/talk2aiagents4pharma/configs/config.yaml +4 -0
  15. aiagents4pharma/talk2aiagents4pharma/docker-compose/cpu/.env.example +23 -0
  16. aiagents4pharma/talk2aiagents4pharma/docker-compose/cpu/docker-compose.yml +93 -0
  17. aiagents4pharma/talk2aiagents4pharma/docker-compose/gpu/.env.example +23 -0
  18. aiagents4pharma/talk2aiagents4pharma/docker-compose/gpu/docker-compose.yml +108 -0
  19. aiagents4pharma/talk2aiagents4pharma/install.md +154 -0
  20. aiagents4pharma/talk2aiagents4pharma/states/__init__.py +5 -0
  21. aiagents4pharma/talk2aiagents4pharma/states/state_talk2aiagents4pharma.py +18 -0
  22. aiagents4pharma/talk2aiagents4pharma/tests/__init__.py +3 -0
  23. aiagents4pharma/talk2aiagents4pharma/tests/test_main_agent.py +312 -0
  24. aiagents4pharma/talk2biomodels/.dockerignore +13 -0
  25. aiagents4pharma/talk2biomodels/Dockerfile +104 -0
  26. aiagents4pharma/talk2biomodels/README.md +1 -0
  27. aiagents4pharma/talk2biomodels/__init__.py +5 -0
  28. aiagents4pharma/talk2biomodels/agents/__init__.py +6 -0
  29. aiagents4pharma/talk2biomodels/agents/t2b_agent.py +104 -0
  30. aiagents4pharma/talk2biomodels/api/__init__.py +5 -0
  31. aiagents4pharma/talk2biomodels/api/ols.py +75 -0
  32. aiagents4pharma/talk2biomodels/api/uniprot.py +36 -0
  33. aiagents4pharma/talk2biomodels/configs/__init__.py +5 -0
  34. aiagents4pharma/talk2biomodels/configs/agents/__init__.py +5 -0
  35. aiagents4pharma/talk2biomodels/configs/agents/t2b_agent/__init__.py +3 -0
  36. aiagents4pharma/talk2biomodels/configs/agents/t2b_agent/default.yaml +14 -0
  37. aiagents4pharma/talk2biomodels/configs/app/__init__.py +0 -0
  38. aiagents4pharma/talk2biomodels/configs/app/frontend/__init__.py +0 -0
  39. aiagents4pharma/talk2biomodels/configs/app/frontend/default.yaml +72 -0
  40. aiagents4pharma/talk2biomodels/configs/config.yaml +7 -0
  41. aiagents4pharma/talk2biomodels/configs/tools/__init__.py +5 -0
  42. aiagents4pharma/talk2biomodels/configs/tools/ask_question/__init__.py +3 -0
  43. aiagents4pharma/talk2biomodels/configs/tools/ask_question/default.yaml +30 -0
  44. aiagents4pharma/talk2biomodels/configs/tools/custom_plotter/__init__.py +3 -0
  45. aiagents4pharma/talk2biomodels/configs/tools/custom_plotter/default.yaml +8 -0
  46. aiagents4pharma/talk2biomodels/configs/tools/get_annotation/__init__.py +3 -0
  47. aiagents4pharma/talk2biomodels/configs/tools/get_annotation/default.yaml +8 -0
  48. aiagents4pharma/talk2biomodels/install.md +63 -0
  49. aiagents4pharma/talk2biomodels/models/__init__.py +5 -0
  50. aiagents4pharma/talk2biomodels/models/basico_model.py +125 -0
  51. aiagents4pharma/talk2biomodels/models/sys_bio_model.py +60 -0
  52. aiagents4pharma/talk2biomodels/states/__init__.py +6 -0
  53. aiagents4pharma/talk2biomodels/states/state_talk2biomodels.py +49 -0
  54. aiagents4pharma/talk2biomodels/tests/BIOMD0000000449_url.xml +1585 -0
  55. aiagents4pharma/talk2biomodels/tests/__init__.py +3 -0
  56. aiagents4pharma/talk2biomodels/tests/article_on_model_537.pdf +0 -0
  57. aiagents4pharma/talk2biomodels/tests/test_api.py +31 -0
  58. aiagents4pharma/talk2biomodels/tests/test_ask_question.py +42 -0
  59. aiagents4pharma/talk2biomodels/tests/test_basico_model.py +67 -0
  60. aiagents4pharma/talk2biomodels/tests/test_get_annotation.py +190 -0
  61. aiagents4pharma/talk2biomodels/tests/test_getmodelinfo.py +92 -0
  62. aiagents4pharma/talk2biomodels/tests/test_integration.py +116 -0
  63. aiagents4pharma/talk2biomodels/tests/test_load_biomodel.py +35 -0
  64. aiagents4pharma/talk2biomodels/tests/test_param_scan.py +71 -0
  65. aiagents4pharma/talk2biomodels/tests/test_query_article.py +184 -0
  66. aiagents4pharma/talk2biomodels/tests/test_save_model.py +47 -0
  67. aiagents4pharma/talk2biomodels/tests/test_search_models.py +35 -0
  68. aiagents4pharma/talk2biomodels/tests/test_simulate_model.py +44 -0
  69. aiagents4pharma/talk2biomodels/tests/test_steady_state.py +86 -0
  70. aiagents4pharma/talk2biomodels/tests/test_sys_bio_model.py +67 -0
  71. aiagents4pharma/talk2biomodels/tools/__init__.py +17 -0
  72. aiagents4pharma/talk2biomodels/tools/ask_question.py +125 -0
  73. aiagents4pharma/talk2biomodels/tools/custom_plotter.py +165 -0
  74. aiagents4pharma/talk2biomodels/tools/get_annotation.py +342 -0
  75. aiagents4pharma/talk2biomodels/tools/get_modelinfo.py +159 -0
  76. aiagents4pharma/talk2biomodels/tools/load_arguments.py +134 -0
  77. aiagents4pharma/talk2biomodels/tools/load_biomodel.py +44 -0
  78. aiagents4pharma/talk2biomodels/tools/parameter_scan.py +310 -0
  79. aiagents4pharma/talk2biomodels/tools/query_article.py +64 -0
  80. aiagents4pharma/talk2biomodels/tools/save_model.py +98 -0
  81. aiagents4pharma/talk2biomodels/tools/search_models.py +96 -0
  82. aiagents4pharma/talk2biomodels/tools/simulate_model.py +137 -0
  83. aiagents4pharma/talk2biomodels/tools/steady_state.py +187 -0
  84. aiagents4pharma/talk2biomodels/tools/utils.py +23 -0
  85. aiagents4pharma/talk2cells/README.md +1 -0
  86. aiagents4pharma/talk2cells/__init__.py +5 -0
  87. aiagents4pharma/talk2cells/agents/__init__.py +6 -0
  88. aiagents4pharma/talk2cells/agents/scp_agent.py +87 -0
  89. aiagents4pharma/talk2cells/states/__init__.py +6 -0
  90. aiagents4pharma/talk2cells/states/state_talk2cells.py +15 -0
  91. aiagents4pharma/talk2cells/tests/scp_agent/test_scp_agent.py +22 -0
  92. aiagents4pharma/talk2cells/tools/__init__.py +6 -0
  93. aiagents4pharma/talk2cells/tools/scp_agent/__init__.py +6 -0
  94. aiagents4pharma/talk2cells/tools/scp_agent/display_studies.py +27 -0
  95. aiagents4pharma/talk2cells/tools/scp_agent/search_studies.py +78 -0
  96. aiagents4pharma/talk2knowledgegraphs/.dockerignore +13 -0
  97. aiagents4pharma/talk2knowledgegraphs/Dockerfile +131 -0
  98. aiagents4pharma/talk2knowledgegraphs/README.md +1 -0
  99. aiagents4pharma/talk2knowledgegraphs/__init__.py +5 -0
  100. aiagents4pharma/talk2knowledgegraphs/agents/__init__.py +5 -0
  101. aiagents4pharma/talk2knowledgegraphs/agents/t2kg_agent.py +99 -0
  102. aiagents4pharma/talk2knowledgegraphs/configs/__init__.py +5 -0
  103. aiagents4pharma/talk2knowledgegraphs/configs/agents/t2kg_agent/__init__.py +3 -0
  104. aiagents4pharma/talk2knowledgegraphs/configs/agents/t2kg_agent/default.yaml +62 -0
  105. aiagents4pharma/talk2knowledgegraphs/configs/app/__init__.py +5 -0
  106. aiagents4pharma/talk2knowledgegraphs/configs/app/frontend/__init__.py +3 -0
  107. aiagents4pharma/talk2knowledgegraphs/configs/app/frontend/default.yaml +79 -0
  108. aiagents4pharma/talk2knowledgegraphs/configs/config.yaml +13 -0
  109. aiagents4pharma/talk2knowledgegraphs/configs/tools/__init__.py +5 -0
  110. aiagents4pharma/talk2knowledgegraphs/configs/tools/graphrag_reasoning/__init__.py +3 -0
  111. aiagents4pharma/talk2knowledgegraphs/configs/tools/graphrag_reasoning/default.yaml +24 -0
  112. aiagents4pharma/talk2knowledgegraphs/configs/tools/multimodal_subgraph_extraction/__init__.py +0 -0
  113. aiagents4pharma/talk2knowledgegraphs/configs/tools/multimodal_subgraph_extraction/default.yaml +33 -0
  114. aiagents4pharma/talk2knowledgegraphs/configs/tools/subgraph_extraction/__init__.py +3 -0
  115. aiagents4pharma/talk2knowledgegraphs/configs/tools/subgraph_extraction/default.yaml +43 -0
  116. aiagents4pharma/talk2knowledgegraphs/configs/tools/subgraph_summarization/__init__.py +3 -0
  117. aiagents4pharma/talk2knowledgegraphs/configs/tools/subgraph_summarization/default.yaml +9 -0
  118. aiagents4pharma/talk2knowledgegraphs/configs/utils/database/milvus/__init__.py +3 -0
  119. aiagents4pharma/talk2knowledgegraphs/configs/utils/database/milvus/default.yaml +61 -0
  120. aiagents4pharma/talk2knowledgegraphs/configs/utils/enrichments/ols_terms/default.yaml +3 -0
  121. aiagents4pharma/talk2knowledgegraphs/configs/utils/enrichments/reactome_pathways/default.yaml +3 -0
  122. aiagents4pharma/talk2knowledgegraphs/configs/utils/enrichments/uniprot_proteins/default.yaml +6 -0
  123. aiagents4pharma/talk2knowledgegraphs/configs/utils/pubchem_utils/default.yaml +5 -0
  124. aiagents4pharma/talk2knowledgegraphs/datasets/__init__.py +5 -0
  125. aiagents4pharma/talk2knowledgegraphs/datasets/biobridge_primekg.py +607 -0
  126. aiagents4pharma/talk2knowledgegraphs/datasets/dataset.py +25 -0
  127. aiagents4pharma/talk2knowledgegraphs/datasets/primekg.py +212 -0
  128. aiagents4pharma/talk2knowledgegraphs/datasets/starkqa_primekg.py +210 -0
  129. aiagents4pharma/talk2knowledgegraphs/docker-compose/cpu/.env.example +23 -0
  130. aiagents4pharma/talk2knowledgegraphs/docker-compose/cpu/docker-compose.yml +93 -0
  131. aiagents4pharma/talk2knowledgegraphs/docker-compose/gpu/.env.example +23 -0
  132. aiagents4pharma/talk2knowledgegraphs/docker-compose/gpu/docker-compose.yml +108 -0
  133. aiagents4pharma/talk2knowledgegraphs/entrypoint.sh +180 -0
  134. aiagents4pharma/talk2knowledgegraphs/install.md +165 -0
  135. aiagents4pharma/talk2knowledgegraphs/milvus_data_dump.py +886 -0
  136. aiagents4pharma/talk2knowledgegraphs/states/__init__.py +5 -0
  137. aiagents4pharma/talk2knowledgegraphs/states/state_talk2knowledgegraphs.py +40 -0
  138. aiagents4pharma/talk2knowledgegraphs/tests/__init__.py +0 -0
  139. aiagents4pharma/talk2knowledgegraphs/tests/test_agents_t2kg_agent.py +318 -0
  140. aiagents4pharma/talk2knowledgegraphs/tests/test_datasets_biobridge_primekg.py +248 -0
  141. aiagents4pharma/talk2knowledgegraphs/tests/test_datasets_dataset.py +33 -0
  142. aiagents4pharma/talk2knowledgegraphs/tests/test_datasets_primekg.py +86 -0
  143. aiagents4pharma/talk2knowledgegraphs/tests/test_datasets_starkqa_primekg.py +125 -0
  144. aiagents4pharma/talk2knowledgegraphs/tests/test_tools_graphrag_reasoning.py +257 -0
  145. aiagents4pharma/talk2knowledgegraphs/tests/test_tools_milvus_multimodal_subgraph_extraction.py +1444 -0
  146. aiagents4pharma/talk2knowledgegraphs/tests/test_tools_multimodal_subgraph_extraction.py +159 -0
  147. aiagents4pharma/talk2knowledgegraphs/tests/test_tools_subgraph_extraction.py +152 -0
  148. aiagents4pharma/talk2knowledgegraphs/tests/test_tools_subgraph_summarization.py +201 -0
  149. aiagents4pharma/talk2knowledgegraphs/tests/test_utils_database_milvus_connection_manager.py +812 -0
  150. aiagents4pharma/talk2knowledgegraphs/tests/test_utils_embeddings_embeddings.py +51 -0
  151. aiagents4pharma/talk2knowledgegraphs/tests/test_utils_embeddings_huggingface.py +49 -0
  152. aiagents4pharma/talk2knowledgegraphs/tests/test_utils_embeddings_nim_molmim.py +59 -0
  153. aiagents4pharma/talk2knowledgegraphs/tests/test_utils_embeddings_ollama.py +63 -0
  154. aiagents4pharma/talk2knowledgegraphs/tests/test_utils_embeddings_sentencetransformer.py +47 -0
  155. aiagents4pharma/talk2knowledgegraphs/tests/test_utils_enrichments_enrichments.py +40 -0
  156. aiagents4pharma/talk2knowledgegraphs/tests/test_utils_enrichments_ollama.py +94 -0
  157. aiagents4pharma/talk2knowledgegraphs/tests/test_utils_enrichments_ols.py +70 -0
  158. aiagents4pharma/talk2knowledgegraphs/tests/test_utils_enrichments_pubchem.py +45 -0
  159. aiagents4pharma/talk2knowledgegraphs/tests/test_utils_enrichments_reactome.py +44 -0
  160. aiagents4pharma/talk2knowledgegraphs/tests/test_utils_enrichments_uniprot.py +48 -0
  161. aiagents4pharma/talk2knowledgegraphs/tests/test_utils_extractions_milvus_multimodal_pcst.py +759 -0
  162. aiagents4pharma/talk2knowledgegraphs/tests/test_utils_kg_utils.py +78 -0
  163. aiagents4pharma/talk2knowledgegraphs/tests/test_utils_pubchem_utils.py +123 -0
  164. aiagents4pharma/talk2knowledgegraphs/tools/__init__.py +11 -0
  165. aiagents4pharma/talk2knowledgegraphs/tools/graphrag_reasoning.py +138 -0
  166. aiagents4pharma/talk2knowledgegraphs/tools/load_arguments.py +22 -0
  167. aiagents4pharma/talk2knowledgegraphs/tools/milvus_multimodal_subgraph_extraction.py +965 -0
  168. aiagents4pharma/talk2knowledgegraphs/tools/multimodal_subgraph_extraction.py +374 -0
  169. aiagents4pharma/talk2knowledgegraphs/tools/subgraph_extraction.py +291 -0
  170. aiagents4pharma/talk2knowledgegraphs/tools/subgraph_summarization.py +123 -0
  171. aiagents4pharma/talk2knowledgegraphs/utils/__init__.py +5 -0
  172. aiagents4pharma/talk2knowledgegraphs/utils/database/__init__.py +5 -0
  173. aiagents4pharma/talk2knowledgegraphs/utils/database/milvus_connection_manager.py +586 -0
  174. aiagents4pharma/talk2knowledgegraphs/utils/embeddings/__init__.py +5 -0
  175. aiagents4pharma/talk2knowledgegraphs/utils/embeddings/embeddings.py +81 -0
  176. aiagents4pharma/talk2knowledgegraphs/utils/embeddings/huggingface.py +111 -0
  177. aiagents4pharma/talk2knowledgegraphs/utils/embeddings/nim_molmim.py +54 -0
  178. aiagents4pharma/talk2knowledgegraphs/utils/embeddings/ollama.py +87 -0
  179. aiagents4pharma/talk2knowledgegraphs/utils/embeddings/sentence_transformer.py +73 -0
  180. aiagents4pharma/talk2knowledgegraphs/utils/enrichments/__init__.py +12 -0
  181. aiagents4pharma/talk2knowledgegraphs/utils/enrichments/enrichments.py +37 -0
  182. aiagents4pharma/talk2knowledgegraphs/utils/enrichments/ollama.py +129 -0
  183. aiagents4pharma/talk2knowledgegraphs/utils/enrichments/ols_terms.py +89 -0
  184. aiagents4pharma/talk2knowledgegraphs/utils/enrichments/pubchem_strings.py +78 -0
  185. aiagents4pharma/talk2knowledgegraphs/utils/enrichments/reactome_pathways.py +71 -0
  186. aiagents4pharma/talk2knowledgegraphs/utils/enrichments/uniprot_proteins.py +98 -0
  187. aiagents4pharma/talk2knowledgegraphs/utils/extractions/__init__.py +5 -0
  188. aiagents4pharma/talk2knowledgegraphs/utils/extractions/milvus_multimodal_pcst.py +762 -0
  189. aiagents4pharma/talk2knowledgegraphs/utils/extractions/multimodal_pcst.py +298 -0
  190. aiagents4pharma/talk2knowledgegraphs/utils/extractions/pcst.py +229 -0
  191. aiagents4pharma/talk2knowledgegraphs/utils/kg_utils.py +67 -0
  192. aiagents4pharma/talk2knowledgegraphs/utils/pubchem_utils.py +104 -0
  193. aiagents4pharma/talk2scholars/.dockerignore +13 -0
  194. aiagents4pharma/talk2scholars/Dockerfile +104 -0
  195. aiagents4pharma/talk2scholars/README.md +1 -0
  196. aiagents4pharma/talk2scholars/__init__.py +7 -0
  197. aiagents4pharma/talk2scholars/agents/__init__.py +13 -0
  198. aiagents4pharma/talk2scholars/agents/main_agent.py +89 -0
  199. aiagents4pharma/talk2scholars/agents/paper_download_agent.py +96 -0
  200. aiagents4pharma/talk2scholars/agents/pdf_agent.py +101 -0
  201. aiagents4pharma/talk2scholars/agents/s2_agent.py +135 -0
  202. aiagents4pharma/talk2scholars/agents/zotero_agent.py +127 -0
  203. aiagents4pharma/talk2scholars/configs/__init__.py +7 -0
  204. aiagents4pharma/talk2scholars/configs/agents/__init__.py +7 -0
  205. aiagents4pharma/talk2scholars/configs/agents/talk2scholars/__init__.py +7 -0
  206. aiagents4pharma/talk2scholars/configs/agents/talk2scholars/main_agent/__init__.py +3 -0
  207. aiagents4pharma/talk2scholars/configs/agents/talk2scholars/main_agent/default.yaml +52 -0
  208. aiagents4pharma/talk2scholars/configs/agents/talk2scholars/paper_download_agent/__init__.py +3 -0
  209. aiagents4pharma/talk2scholars/configs/agents/talk2scholars/paper_download_agent/default.yaml +19 -0
  210. aiagents4pharma/talk2scholars/configs/agents/talk2scholars/pdf_agent/__init__.py +3 -0
  211. aiagents4pharma/talk2scholars/configs/agents/talk2scholars/pdf_agent/default.yaml +19 -0
  212. aiagents4pharma/talk2scholars/configs/agents/talk2scholars/s2_agent/__init__.py +3 -0
  213. aiagents4pharma/talk2scholars/configs/agents/talk2scholars/s2_agent/default.yaml +44 -0
  214. aiagents4pharma/talk2scholars/configs/agents/talk2scholars/zotero_agent/__init__.py +3 -0
  215. aiagents4pharma/talk2scholars/configs/agents/talk2scholars/zotero_agent/default.yaml +19 -0
  216. aiagents4pharma/talk2scholars/configs/app/__init__.py +7 -0
  217. aiagents4pharma/talk2scholars/configs/app/frontend/__init__.py +3 -0
  218. aiagents4pharma/talk2scholars/configs/app/frontend/default.yaml +72 -0
  219. aiagents4pharma/talk2scholars/configs/config.yaml +16 -0
  220. aiagents4pharma/talk2scholars/configs/tools/__init__.py +21 -0
  221. aiagents4pharma/talk2scholars/configs/tools/multi_paper_recommendation/__init__.py +3 -0
  222. aiagents4pharma/talk2scholars/configs/tools/multi_paper_recommendation/default.yaml +26 -0
  223. aiagents4pharma/talk2scholars/configs/tools/paper_download/__init__.py +3 -0
  224. aiagents4pharma/talk2scholars/configs/tools/paper_download/default.yaml +124 -0
  225. aiagents4pharma/talk2scholars/configs/tools/question_and_answer/__init__.py +3 -0
  226. aiagents4pharma/talk2scholars/configs/tools/question_and_answer/default.yaml +62 -0
  227. aiagents4pharma/talk2scholars/configs/tools/retrieve_semantic_scholar_paper_id/__init__.py +3 -0
  228. aiagents4pharma/talk2scholars/configs/tools/retrieve_semantic_scholar_paper_id/default.yaml +12 -0
  229. aiagents4pharma/talk2scholars/configs/tools/search/__init__.py +3 -0
  230. aiagents4pharma/talk2scholars/configs/tools/search/default.yaml +26 -0
  231. aiagents4pharma/talk2scholars/configs/tools/single_paper_recommendation/__init__.py +3 -0
  232. aiagents4pharma/talk2scholars/configs/tools/single_paper_recommendation/default.yaml +26 -0
  233. aiagents4pharma/talk2scholars/configs/tools/zotero_read/__init__.py +3 -0
  234. aiagents4pharma/talk2scholars/configs/tools/zotero_read/default.yaml +57 -0
  235. aiagents4pharma/talk2scholars/configs/tools/zotero_write/__inti__.py +3 -0
  236. aiagents4pharma/talk2scholars/configs/tools/zotero_write/default.yaml +55 -0
  237. aiagents4pharma/talk2scholars/docker-compose/cpu/.env.example +21 -0
  238. aiagents4pharma/talk2scholars/docker-compose/cpu/docker-compose.yml +90 -0
  239. aiagents4pharma/talk2scholars/docker-compose/gpu/.env.example +21 -0
  240. aiagents4pharma/talk2scholars/docker-compose/gpu/docker-compose.yml +105 -0
  241. aiagents4pharma/talk2scholars/install.md +122 -0
  242. aiagents4pharma/talk2scholars/state/__init__.py +7 -0
  243. aiagents4pharma/talk2scholars/state/state_talk2scholars.py +98 -0
  244. aiagents4pharma/talk2scholars/tests/__init__.py +3 -0
  245. aiagents4pharma/talk2scholars/tests/test_agents_main_agent.py +256 -0
  246. aiagents4pharma/talk2scholars/tests/test_agents_paper_agents_download_agent.py +139 -0
  247. aiagents4pharma/talk2scholars/tests/test_agents_pdf_agent.py +114 -0
  248. aiagents4pharma/talk2scholars/tests/test_agents_s2_agent.py +198 -0
  249. aiagents4pharma/talk2scholars/tests/test_agents_zotero_agent.py +160 -0
  250. aiagents4pharma/talk2scholars/tests/test_s2_tools_display_dataframe.py +91 -0
  251. aiagents4pharma/talk2scholars/tests/test_s2_tools_query_dataframe.py +191 -0
  252. aiagents4pharma/talk2scholars/tests/test_states_state.py +38 -0
  253. aiagents4pharma/talk2scholars/tests/test_tools_paper_downloader.py +507 -0
  254. aiagents4pharma/talk2scholars/tests/test_tools_question_and_answer_tool.py +105 -0
  255. aiagents4pharma/talk2scholars/tests/test_tools_s2_multi.py +307 -0
  256. aiagents4pharma/talk2scholars/tests/test_tools_s2_retrieve.py +67 -0
  257. aiagents4pharma/talk2scholars/tests/test_tools_s2_search.py +286 -0
  258. aiagents4pharma/talk2scholars/tests/test_tools_s2_single.py +298 -0
  259. aiagents4pharma/talk2scholars/tests/test_utils_arxiv_downloader.py +469 -0
  260. aiagents4pharma/talk2scholars/tests/test_utils_base_paper_downloader.py +598 -0
  261. aiagents4pharma/talk2scholars/tests/test_utils_biorxiv_downloader.py +669 -0
  262. aiagents4pharma/talk2scholars/tests/test_utils_medrxiv_downloader.py +500 -0
  263. aiagents4pharma/talk2scholars/tests/test_utils_nvidia_nim_reranker.py +117 -0
  264. aiagents4pharma/talk2scholars/tests/test_utils_pdf_answer_formatter.py +67 -0
  265. aiagents4pharma/talk2scholars/tests/test_utils_pdf_batch_processor.py +92 -0
  266. aiagents4pharma/talk2scholars/tests/test_utils_pdf_collection_manager.py +173 -0
  267. aiagents4pharma/talk2scholars/tests/test_utils_pdf_document_processor.py +68 -0
  268. aiagents4pharma/talk2scholars/tests/test_utils_pdf_generate_answer.py +72 -0
  269. aiagents4pharma/talk2scholars/tests/test_utils_pdf_gpu_detection.py +129 -0
  270. aiagents4pharma/talk2scholars/tests/test_utils_pdf_paper_loader.py +116 -0
  271. aiagents4pharma/talk2scholars/tests/test_utils_pdf_rag_pipeline.py +88 -0
  272. aiagents4pharma/talk2scholars/tests/test_utils_pdf_retrieve_chunks.py +190 -0
  273. aiagents4pharma/talk2scholars/tests/test_utils_pdf_singleton_manager.py +159 -0
  274. aiagents4pharma/talk2scholars/tests/test_utils_pdf_vector_normalization.py +121 -0
  275. aiagents4pharma/talk2scholars/tests/test_utils_pdf_vector_store.py +406 -0
  276. aiagents4pharma/talk2scholars/tests/test_utils_pubmed_downloader.py +1007 -0
  277. aiagents4pharma/talk2scholars/tests/test_utils_read_helper_utils.py +106 -0
  278. aiagents4pharma/talk2scholars/tests/test_utils_s2_utils_ext_ids.py +403 -0
  279. aiagents4pharma/talk2scholars/tests/test_utils_tool_helper_utils.py +85 -0
  280. aiagents4pharma/talk2scholars/tests/test_utils_zotero_human_in_the_loop.py +266 -0
  281. aiagents4pharma/talk2scholars/tests/test_utils_zotero_path.py +496 -0
  282. aiagents4pharma/talk2scholars/tests/test_utils_zotero_pdf_downloader_utils.py +46 -0
  283. aiagents4pharma/talk2scholars/tests/test_utils_zotero_read.py +743 -0
  284. aiagents4pharma/talk2scholars/tests/test_utils_zotero_write.py +151 -0
  285. aiagents4pharma/talk2scholars/tools/__init__.py +9 -0
  286. aiagents4pharma/talk2scholars/tools/paper_download/__init__.py +12 -0
  287. aiagents4pharma/talk2scholars/tools/paper_download/paper_downloader.py +442 -0
  288. aiagents4pharma/talk2scholars/tools/paper_download/utils/__init__.py +22 -0
  289. aiagents4pharma/talk2scholars/tools/paper_download/utils/arxiv_downloader.py +207 -0
  290. aiagents4pharma/talk2scholars/tools/paper_download/utils/base_paper_downloader.py +336 -0
  291. aiagents4pharma/talk2scholars/tools/paper_download/utils/biorxiv_downloader.py +313 -0
  292. aiagents4pharma/talk2scholars/tools/paper_download/utils/medrxiv_downloader.py +196 -0
  293. aiagents4pharma/talk2scholars/tools/paper_download/utils/pubmed_downloader.py +323 -0
  294. aiagents4pharma/talk2scholars/tools/pdf/__init__.py +7 -0
  295. aiagents4pharma/talk2scholars/tools/pdf/question_and_answer.py +170 -0
  296. aiagents4pharma/talk2scholars/tools/pdf/utils/__init__.py +37 -0
  297. aiagents4pharma/talk2scholars/tools/pdf/utils/answer_formatter.py +62 -0
  298. aiagents4pharma/talk2scholars/tools/pdf/utils/batch_processor.py +198 -0
  299. aiagents4pharma/talk2scholars/tools/pdf/utils/collection_manager.py +172 -0
  300. aiagents4pharma/talk2scholars/tools/pdf/utils/document_processor.py +76 -0
  301. aiagents4pharma/talk2scholars/tools/pdf/utils/generate_answer.py +97 -0
  302. aiagents4pharma/talk2scholars/tools/pdf/utils/get_vectorstore.py +59 -0
  303. aiagents4pharma/talk2scholars/tools/pdf/utils/gpu_detection.py +150 -0
  304. aiagents4pharma/talk2scholars/tools/pdf/utils/nvidia_nim_reranker.py +97 -0
  305. aiagents4pharma/talk2scholars/tools/pdf/utils/paper_loader.py +123 -0
  306. aiagents4pharma/talk2scholars/tools/pdf/utils/rag_pipeline.py +113 -0
  307. aiagents4pharma/talk2scholars/tools/pdf/utils/retrieve_chunks.py +197 -0
  308. aiagents4pharma/talk2scholars/tools/pdf/utils/singleton_manager.py +140 -0
  309. aiagents4pharma/talk2scholars/tools/pdf/utils/tool_helper.py +86 -0
  310. aiagents4pharma/talk2scholars/tools/pdf/utils/vector_normalization.py +150 -0
  311. aiagents4pharma/talk2scholars/tools/pdf/utils/vector_store.py +327 -0
  312. aiagents4pharma/talk2scholars/tools/s2/__init__.py +21 -0
  313. aiagents4pharma/talk2scholars/tools/s2/display_dataframe.py +110 -0
  314. aiagents4pharma/talk2scholars/tools/s2/multi_paper_rec.py +111 -0
  315. aiagents4pharma/talk2scholars/tools/s2/query_dataframe.py +233 -0
  316. aiagents4pharma/talk2scholars/tools/s2/retrieve_semantic_scholar_paper_id.py +128 -0
  317. aiagents4pharma/talk2scholars/tools/s2/search.py +101 -0
  318. aiagents4pharma/talk2scholars/tools/s2/single_paper_rec.py +102 -0
  319. aiagents4pharma/talk2scholars/tools/s2/utils/__init__.py +5 -0
  320. aiagents4pharma/talk2scholars/tools/s2/utils/multi_helper.py +223 -0
  321. aiagents4pharma/talk2scholars/tools/s2/utils/search_helper.py +205 -0
  322. aiagents4pharma/talk2scholars/tools/s2/utils/single_helper.py +216 -0
  323. aiagents4pharma/talk2scholars/tools/zotero/__init__.py +7 -0
  324. aiagents4pharma/talk2scholars/tools/zotero/utils/__init__.py +7 -0
  325. aiagents4pharma/talk2scholars/tools/zotero/utils/read_helper.py +270 -0
  326. aiagents4pharma/talk2scholars/tools/zotero/utils/review_helper.py +74 -0
  327. aiagents4pharma/talk2scholars/tools/zotero/utils/write_helper.py +194 -0
  328. aiagents4pharma/talk2scholars/tools/zotero/utils/zotero_path.py +180 -0
  329. aiagents4pharma/talk2scholars/tools/zotero/utils/zotero_pdf_downloader.py +133 -0
  330. aiagents4pharma/talk2scholars/tools/zotero/zotero_read.py +105 -0
  331. aiagents4pharma/talk2scholars/tools/zotero/zotero_review.py +162 -0
  332. aiagents4pharma/talk2scholars/tools/zotero/zotero_write.py +91 -0
  333. aiagents4pharma-0.0.0.dist-info/METADATA +335 -0
  334. aiagents4pharma-0.0.0.dist-info/RECORD +336 -0
  335. aiagents4pharma-0.0.0.dist-info/WHEEL +4 -0
  336. aiagents4pharma-0.0.0.dist-info/licenses/LICENSE +21 -0
@@ -0,0 +1,3 @@
1
+ """
2
+ This module contains the test cases.
3
+ """
@@ -0,0 +1,31 @@
1
+ """
2
+ Test cases for Talk2Biomodels.
3
+ """
4
+
5
+ from ..api.ols import fetch_from_ols
6
+ from ..api.uniprot import search_uniprot_labels
7
+
8
+
9
+ def test_search_uniprot_labels():
10
+ """
11
+ Test the search_uniprot_labels function.
12
+ """
13
+ # "P61764" = Positive result, "P0000Q" = negative result
14
+ identifiers = ["P61764", "P0000Q"]
15
+ results = search_uniprot_labels(identifiers)
16
+ assert results["P61764"] == "Syntaxin-binding protein 1"
17
+ assert results["P0000Q"].startswith("Error: 400")
18
+
19
+
20
+ def test_fetch_from_ols():
21
+ """
22
+ Test the fetch_from_ols function.
23
+ """
24
+ term_1 = "GO:0005886" # Positive result
25
+ term_2 = "GO:ABC123" # Negative result
26
+ label_1 = fetch_from_ols(term_1)
27
+ label_2 = fetch_from_ols(term_2)
28
+ assert isinstance(label_1, str), f"Expected string, got {type(label_1)}"
29
+ assert isinstance(label_2, str), f"Expected string, got {type(label_2)}"
30
+ assert label_1 == "plasma membrane"
31
+ assert label_2.startswith("Error: 404")
@@ -0,0 +1,42 @@
1
+ """
2
+ Test cases for Talk2Biomodels.
3
+ """
4
+
5
+ from langchain_core.messages import HumanMessage, ToolMessage
6
+ from langchain_openai import ChatOpenAI
7
+
8
+ from ..agents.t2b_agent import get_app
9
+
10
+
11
+ def test_ask_question_tool():
12
+ """
13
+ Test the ask_question tool without the simulation results.
14
+ """
15
+ unique_id = 12345
16
+ app = get_app(unique_id, llm_model=ChatOpenAI(model="gpt-4o-mini", temperature=0))
17
+ config = {"configurable": {"thread_id": unique_id}}
18
+
19
+ ##########################################
20
+ # Test ask_question tool when simulation
21
+ # results are not available i.e. the
22
+ # simulation has not been run. In this
23
+ # case, the tool should return an error
24
+ ##########################################
25
+ # Define the prompt
26
+ prompt = "Call the ask_question tool to answer the "
27
+ prompt += "question: What is the concentration of CRP "
28
+ prompt += "in serum at 1000 hours? The simulation name "
29
+ prompt += "is `simulation_name`."
30
+ # Invoke the tool
31
+ app.invoke({"messages": [HumanMessage(content=prompt)]}, config=config)
32
+ # Get the messages from the current state
33
+ # and reverse the order
34
+ current_state = app.get_state(config)
35
+ reversed_messages = current_state.values["messages"][::-1]
36
+ # Loop through the reversed messages until a
37
+ # ToolMessage is found.
38
+ for msg in reversed_messages:
39
+ # Assert that the message is a ToolMessage
40
+ # and its status is "error"
41
+ if isinstance(msg, ToolMessage):
42
+ assert msg.status == "error"
@@ -0,0 +1,67 @@
1
+ """
2
+ A test BasicoModel class for pytest unit testing.
3
+ """
4
+
5
+ import basico
6
+ import pandas as pd
7
+ import pytest
8
+
9
+ from ..models.basico_model import BasicoModel
10
+
11
+
12
+ @pytest.fixture(name="model")
13
+ def model_fixture():
14
+ """
15
+ A fixture for the BasicoModel class.
16
+ """
17
+ return BasicoModel(biomodel_id=64, species={"Pyruvate": 100}, duration=2, interval=2)
18
+
19
+
20
+ def test_with_biomodel_id(model):
21
+ """
22
+ Test initialization of BasicoModel with biomodel_id.
23
+ """
24
+ assert model.biomodel_id == 64
25
+ model.update_parameters(parameters={"Pyruvate": 0.5, "KmPFKF6P": 1.5})
26
+ df_species = basico.model_info.get_species(model=model.copasi_model)
27
+ assert df_species.loc["Pyruvate", "initial_concentration"] == 0.5
28
+ df_parameters = basico.model_info.get_parameters(model=model.copasi_model)
29
+ assert df_parameters.loc["KmPFKF6P", "initial_value"] == 1.5
30
+ # check if the simulation results are a pandas DataFrame object
31
+ assert isinstance(model.simulate(duration=2, interval=2), pd.DataFrame)
32
+ # Pass a None value to the update_parameters method
33
+ # and it should not raise an error
34
+ model.update_parameters(parameters={None: None})
35
+ # check if the model description is updated
36
+ assert model.description == basico.biomodels.get_model_info(model.biomodel_id)["description"]
37
+ # check if an error is raised if an invalid species/parameter (`Pyruv`)
38
+ # is passed and it should raise a ValueError
39
+ with pytest.raises(ValueError):
40
+ model.update_parameters(parameters={"Pyruv": 0.5})
41
+
42
+
43
+ def test_with_sbml_file():
44
+ """
45
+ Test initialization of BasicoModel with sbml_file_path.
46
+ """
47
+ model_object = BasicoModel(sbml_file_path="./BIOMD0000000064_url.xml")
48
+ assert model_object.sbml_file_path == "./BIOMD0000000064_url.xml"
49
+ assert isinstance(model_object.simulate(duration=2, interval=2), pd.DataFrame)
50
+
51
+
52
+ def test_check_biomodel_id_or_sbml_file_path():
53
+ """
54
+ Test the check_biomodel_id_or_sbml_file_path method of the BioModel class.
55
+ """
56
+ with pytest.raises(ValueError):
57
+ BasicoModel(species={"Pyruvate": 100}, duration=2, interval=2)
58
+
59
+
60
+ def test_get_model_metadata():
61
+ """
62
+ Test the get_model_metadata method of the BasicoModel class.
63
+ """
64
+ model = BasicoModel(biomodel_id=64)
65
+ metadata = model.get_model_metadata()
66
+ assert metadata["Model Type"] == "SBML Model (COPASI)"
67
+ assert metadata["Parameter Count"] == len(basico.get_parameters())
@@ -0,0 +1,190 @@
1
+ """
2
+ Test cases for Talk2Biomodels get_annotation tool.
3
+ """
4
+
5
+ import random
6
+
7
+ import pytest
8
+ from langchain_core.messages import HumanMessage, ToolMessage
9
+ from langchain_openai import ChatOpenAI
10
+
11
+ from ..agents.t2b_agent import get_app
12
+ from ..tools.get_annotation import prepare_content_msg
13
+
14
+ LLM_MODEL = ChatOpenAI(model="gpt-4o-mini", temperature=0)
15
+
16
+
17
+ @pytest.fixture(name="make_graph")
18
+ def make_graph_fixture():
19
+ """
20
+ Create an instance of the talk2biomodels agent.
21
+ """
22
+ unique_id = random.randint(1000, 9999)
23
+ graph = get_app(unique_id, llm_model=LLM_MODEL)
24
+ config = {"configurable": {"thread_id": unique_id}}
25
+ graph.update_state(config, {"llm_model": LLM_MODEL})
26
+ return graph, config
27
+
28
+
29
+ def test_no_model_provided(make_graph):
30
+ """
31
+ Test the tool by not specifying any model.
32
+ We are testing a condition where the user
33
+ asks for annotations of all species without
34
+ specifying a model.
35
+ """
36
+ app, config = make_graph
37
+ prompt = "Extract annotations of all species. Call the tool get_annotation."
38
+ app.invoke({"messages": [HumanMessage(content=prompt)]}, config=config)
39
+ current_state = app.get_state(config)
40
+ # Assert that the state key model_id is empty.
41
+ assert current_state.values["model_id"] == []
42
+
43
+
44
+ def test_valid_species_provided(make_graph):
45
+ """
46
+ Test the tool by providing a specific species name.
47
+ We are testing a condition where the user asks for annotations
48
+ of a specific species in a specific model.
49
+ """
50
+ # Test with a valid species name
51
+ app, config = make_graph
52
+ prompt = "Extract annotations of species IL6 in model 537."
53
+ app.invoke({"messages": [HumanMessage(content=prompt)]}, config=config)
54
+ current_state = app.get_state(config)
55
+ # print (current_state.values["dic_annotations_data"])
56
+ dic_annotations_data = current_state.values["dic_annotations_data"]
57
+
58
+ # The assert statement checks if IL6 is present in the returned annotations.
59
+ assert dic_annotations_data[0]["data"]["Species Name"][0] == "IL6"
60
+
61
+
62
+ def test_invalid_species_provided(make_graph):
63
+ """
64
+ Test the tool by providing an invalid species name.
65
+ We are testing a condition where the user asks for annotations
66
+ of an invalid species in a specific model.
67
+ """
68
+ # Test with an invalid species name
69
+ app, config = make_graph
70
+ prompt = "Extract annotations of only species NADH in model 537."
71
+ app.invoke({"messages": [HumanMessage(content=prompt)]}, config=config)
72
+ current_state = app.get_state(config)
73
+ reversed_messages = current_state.values["messages"][::-1]
74
+ # Loop through the reversed messages until a
75
+ # ToolMessage is found.
76
+
77
+ test_condition = False
78
+ for msg in reversed_messages:
79
+ # Assert that the one of the messages is a ToolMessage
80
+ # and its artifact is None.
81
+ if isinstance(msg, ToolMessage) and msg.name == "get_annotation":
82
+ # If a ToolMessage exists and artifact is None (meaning no valid annotation was found)
83
+ # and the rejected species (NADH) is mentioned, the test passes.
84
+ if msg.artifact is None and msg.status == "error":
85
+ # If artifact is None, it means no annotation was found
86
+ # (likely due to an invalid species).
87
+ test_condition = True
88
+ break
89
+ assert test_condition
90
+
91
+
92
+ def test_invalid_and_valid_species_provided(make_graph):
93
+ """
94
+ Test the tool by providing an invalid species name and a valid species name.
95
+ We are testing a condition where the user asks for annotations
96
+ of an invalid species and a valid species in a specific model.
97
+ """
98
+ # Test with an invalid species name and a valid species name
99
+ app, config = make_graph
100
+ prompt = "Extract annotations of species NADH, NAD, and IL7 in model 64."
101
+ app.invoke({"messages": [HumanMessage(content=prompt)]}, config=config)
102
+ current_state = app.get_state(config)
103
+ dic_annotations_data = current_state.values["dic_annotations_data"]
104
+ # List of species that are expected to be found in the annotations
105
+ extracted_species = []
106
+ for idx in dic_annotations_data[0]["data"]["Species Name"]:
107
+ extracted_species.append(dic_annotations_data[0]["data"]["Species Name"][idx])
108
+ reversed_messages = current_state.values["messages"][::-1]
109
+ # Loop through the reversed messages until a
110
+ # ToolMessage is found.
111
+ tool_status_success = False
112
+ for msg in reversed_messages:
113
+ # Assert that the one of the messages is a ToolMessage
114
+ # and its artifact is None.
115
+ if isinstance(msg, ToolMessage) and msg.name == "get_annotation":
116
+ if msg.artifact is True and msg.status == "success":
117
+ tool_status_success = True
118
+ break
119
+ assert tool_status_success
120
+ assert set(extracted_species) == {"NADH", "NAD"}
121
+
122
+
123
+ def test_all_species_annotations(make_graph):
124
+ """
125
+ Test the tool by asking for annotations of all species is specific models.
126
+ Here, we test the tool with three models since they have different use cases:
127
+ - model 12 contains a species with no URL provided.
128
+ - model 20 contains a species without description.
129
+ - model 56 contains a species with database outside of UniProt, and OLS.
130
+
131
+ We are testing a condition where the user asks for annotations
132
+ of all species in a specific model.
133
+ """
134
+ # Loop through the models and test the tool
135
+ # for each model's unique use case.
136
+ for model_id in [12, 20, 56]:
137
+ app, config = make_graph
138
+ prompt = f"Extract annotations of all species model {model_id}."
139
+ # Test the tool get_modelinfo
140
+ app.invoke({"messages": [HumanMessage(content=prompt)]}, config=config)
141
+ current_state = app.get_state(config)
142
+
143
+ reversed_messages = current_state.values["messages"][::-1]
144
+ # Coveres all of the use cases for the expecetd sting on all the species
145
+ test_condition = False
146
+ for msg in reversed_messages:
147
+ # Skip messages that are not ToolMessages and those that are not
148
+ # from the get_annotation tool.
149
+ if not isinstance(msg, ToolMessage) or msg.name != "get_annotation":
150
+ continue
151
+ if model_id == 12:
152
+ # Extact the first and second description of the LacI protein
153
+ # We already know that the first or second description is missing ('-')
154
+ dic_annotations_data = current_state.values["dic_annotations_data"][0]
155
+ first_descp_laci_protein = dic_annotations_data["data"]["Description"][0]
156
+ second_descp_laci_protein = dic_annotations_data["data"]["Description"][1]
157
+
158
+ # Expect a successful extraction (artifact is True) and that the content
159
+ # matches what is returned by prepare_content_msg for species.
160
+ # And that the first or second description of the LacI protein is missing.
161
+ if (
162
+ msg.artifact is True
163
+ and msg.content == prepare_content_msg([])
164
+ and msg.status == "success"
165
+ and (first_descp_laci_protein == "-" or second_descp_laci_protein == "-")
166
+ ):
167
+ test_condition = True
168
+ break
169
+
170
+ if model_id == 20:
171
+ # Expect an error message containing a note
172
+ # that species extraction failed.
173
+ if (
174
+ "Unable to extract species from the model" in msg.content
175
+ and msg.status == "error"
176
+ ):
177
+ test_condition = True
178
+ break
179
+
180
+ if model_id == 56:
181
+ # Expect a successful extraction (artifact is True) and that the content
182
+ # matches for for missing description ['ORI'].
183
+ if (
184
+ msg.artifact is True
185
+ and msg.content == prepare_content_msg(["ORI"])
186
+ and msg.status == "success"
187
+ ):
188
+ test_condition = True
189
+ break
190
+ assert test_condition # Expected output is validated
@@ -0,0 +1,92 @@
1
+ """
2
+ Test cases for Talk2Biomodels get_modelinfo tool.
3
+ """
4
+
5
+ from langchain_core.messages import HumanMessage, ToolMessage
6
+ from langchain_openai import ChatOpenAI
7
+
8
+ from ..agents.t2b_agent import get_app
9
+
10
+ LLM_MODEL = ChatOpenAI(model="gpt-4o-mini", temperature=0)
11
+
12
+
13
+ def test_get_modelinfo_tool():
14
+ """
15
+ Test the get_modelinfo tool.
16
+ """
17
+ unique_id = 12345
18
+ app = get_app(unique_id, LLM_MODEL)
19
+ config = {"configurable": {"thread_id": unique_id}}
20
+ # Update state
21
+ app.update_state(
22
+ config,
23
+ {"sbml_file_path": ["aiagents4pharma/talk2biomodels/tests/BIOMD0000000449_url.xml"]},
24
+ )
25
+ prompt = "Extract all relevant information from the uploaded model."
26
+ # Test the tool get_modelinfo
27
+ response = app.invoke({"messages": [HumanMessage(content=prompt)]}, config=config)
28
+ assistant_msg = response["messages"][-1].content
29
+ # Check if the assistant message is a string
30
+ assert isinstance(assistant_msg, str)
31
+
32
+
33
+ def test_model_with_no_species():
34
+ """
35
+ Test the get_modelinfo tool with a model that does not
36
+ return any species.
37
+
38
+ This should raise a tool error.
39
+ """
40
+ unique_id = 12345
41
+ app = get_app(unique_id, LLM_MODEL)
42
+ config = {"configurable": {"thread_id": unique_id}}
43
+ prompt = "Extract all species from model 20"
44
+ # Test the tool get_modelinfo
45
+ app.invoke({"messages": [HumanMessage(content=prompt)]}, config=config)
46
+ current_state = app.get_state(config)
47
+ reversed_messages = current_state.values["messages"][::-1]
48
+ # Loop through the reversed messages until a
49
+ # ToolMessage is found.
50
+ test_condition = False
51
+ for msg in reversed_messages:
52
+ # Check if the message is a ToolMessage from the get_modelinfo tool
53
+ if isinstance(msg, ToolMessage) and msg.name == "get_modelinfo":
54
+ # Check if the message is an error message
55
+ if (
56
+ msg.status == "error"
57
+ and "ValueError('Unable to extract species from the model.')" in msg.content
58
+ ):
59
+ test_condition = True
60
+ break
61
+ assert test_condition
62
+
63
+
64
+ def test_model_with_no_parameters():
65
+ """
66
+ Test the get_modelinfo tool with a model that does not
67
+ return any parameters.
68
+
69
+ This should raise a tool error.
70
+ """
71
+ unique_id = 12345
72
+ app = get_app(unique_id, LLM_MODEL)
73
+ config = {"configurable": {"thread_id": unique_id}}
74
+ prompt = "Extract all parameters from model 10"
75
+ # Test the tool get_modelinfo
76
+ app.invoke({"messages": [HumanMessage(content=prompt)]}, config=config)
77
+ current_state = app.get_state(config)
78
+ reversed_messages = current_state.values["messages"][::-1]
79
+ # Loop through the reversed messages until a
80
+ # ToolMessage is found.
81
+ test_condition = False
82
+ for msg in reversed_messages:
83
+ # Check if the message is a ToolMessage from the get_modelinfo tool
84
+ if isinstance(msg, ToolMessage) and msg.name == "get_modelinfo":
85
+ # Check if the message is an error message
86
+ if (
87
+ msg.status == "error"
88
+ and "ValueError('Unable to extract parameters from the model.')" in msg.content
89
+ ):
90
+ test_condition = True
91
+ break
92
+ assert test_condition
@@ -0,0 +1,116 @@
1
+ """
2
+ Test cases for Talk2Biomodels.
3
+ """
4
+
5
+ import pandas as pd
6
+ from langchain_core.messages import HumanMessage, ToolMessage
7
+ from langchain_openai import ChatOpenAI
8
+
9
+ from ..agents.t2b_agent import get_app
10
+
11
+ LLM_MODEL = ChatOpenAI(model="gpt-4o-mini", temperature=0)
12
+
13
+
14
+ def test_integration():
15
+ """
16
+ Test the integration of the tools.
17
+ """
18
+ unique_id = 1234567
19
+ app = get_app(unique_id, llm_model=LLM_MODEL)
20
+ config = {"configurable": {"thread_id": unique_id}}
21
+ # ##########################################
22
+ # ## Test simulate_model tool
23
+ # ##########################################
24
+ prompt = """Simulate the model BIOMD0000000537 for 100 hours and time intervals
25
+ 100 with an initial concentration of `DoseQ2W` set to 300 and `Dose`
26
+ set to 0. Reset the concentration of `Ab{serum}` to 100 every 25 hours."""
27
+ # Test the tool get_modelinfo
28
+ response = app.invoke({"messages": [HumanMessage(content=prompt)]}, config=config)
29
+ assistant_msg = response["messages"][-1].content
30
+ print(assistant_msg)
31
+ # Check if the assistant message is a string
32
+ assert isinstance(assistant_msg, str)
33
+ ##########################################
34
+ # Test ask_question tool when simulation
35
+ # results are available
36
+ ##########################################
37
+ # Update state
38
+ app.update_state(config, {"llm_model": LLM_MODEL})
39
+ prompt = """What is the concentration of CRP in serum after 100 hours?
40
+ Round off the value to 2 decimal places."""
41
+ # Test the tool get_modelinfo
42
+ response = app.invoke({"messages": [HumanMessage(content=prompt)]}, config=config)
43
+ assistant_msg = response["messages"][-1].content
44
+ # print (assistant_msg)
45
+ # Check if the assistant message is a string
46
+ assert "211" in assistant_msg
47
+
48
+ ##########################################
49
+ # Test the custom_plotter tool when the
50
+ # simulation results are available but
51
+ # the species is not available
52
+ ##########################################
53
+ prompt = """Call the custom_plotter tool to make a plot
54
+ showing only species 'Infected cases'. Let me
55
+ know if these species were not found. Do not
56
+ invoke any other tool."""
57
+ # Update state
58
+ app.update_state(config, {"llm_model": LLM_MODEL})
59
+ # Test the tool get_modelinfo
60
+ response = app.invoke({"messages": [HumanMessage(content=prompt)]}, config=config)
61
+ assistant_msg = response["messages"][-1].content
62
+ current_state = app.get_state(config)
63
+ # Get the messages from the current state
64
+ # and reverse the order
65
+ reversed_messages = current_state.values["messages"][::-1]
66
+ # Loop through the reversed messages until a
67
+ # ToolMessage is found.
68
+ predicted_artifact = []
69
+ for msg in reversed_messages:
70
+ if isinstance(msg, ToolMessage):
71
+ # Work on the message if it is a ToolMessage
72
+ # These may contain additional visuals that
73
+ # need to be displayed to the user.
74
+ if msg.name == "custom_plotter":
75
+ predicted_artifact = msg.artifact
76
+ break
77
+ # Check if the the predicted artifact is `None`
78
+ assert predicted_artifact is None
79
+
80
+ ##########################################
81
+ # Test custom_plotter tool when the
82
+ # simulation results are available
83
+ ##########################################
84
+ prompt = "Plot only CRP related species."
85
+
86
+ # Update state
87
+ app.update_state(config, {"llm_model": LLM_MODEL})
88
+ # Test the tool get_modelinfo
89
+ response = app.invoke({"messages": [HumanMessage(content=prompt)]}, config=config)
90
+ assistant_msg = response["messages"][-1].content
91
+ current_state = app.get_state(config)
92
+ # Get the messages from the current state
93
+ # and reverse the order
94
+ reversed_messages = current_state.values["messages"][::-1]
95
+ # Loop through the reversed messages
96
+ # until a ToolMessage is found.
97
+ expected_header = ["Time", "CRP{serum}", "CRPExtracellular"]
98
+ expected_header += ["CRP Suppression (%)", "CRP (% of baseline)"]
99
+ expected_header += ["CRP{liver}"]
100
+ predicted_artifact = []
101
+ for msg in reversed_messages:
102
+ if isinstance(msg, ToolMessage):
103
+ # Work on the message if it is a ToolMessage
104
+ # These may contain additional visuals that
105
+ # need to be displayed to the user.
106
+ if msg.name == "custom_plotter":
107
+ predicted_artifact = msg.artifact["dic_data"]
108
+ break
109
+ # Convert the artifact into a pandas dataframe
110
+ # for easy comparison
111
+ df = pd.DataFrame(predicted_artifact)
112
+ # Extract the headers from the dataframe
113
+ predicted_header = df.columns.tolist()
114
+ # Check if the header is in the expected_header
115
+ # assert expected_header in predicted_artifact
116
+ assert set(expected_header).issubset(set(predicted_header))
@@ -0,0 +1,35 @@
1
+ """
2
+ Test cases for Talk2Biomodels.
3
+ """
4
+
5
+ import pytest
6
+
7
+ from ..tools.load_biomodel import ModelData
8
+
9
+
10
+ def test_model_data_valid_biomodel_id():
11
+ """
12
+ Test the ModelData class with valid
13
+ biomodel
14
+ """
15
+ # Test with string biomodel_id starting with 'BIOMD'
16
+ model_data = ModelData(biomodel_id="BIOMD0000000537")
17
+ assert model_data.biomodel_id == "BIOMD0000000537"
18
+
19
+ # Test with string biomodel_id starting with 'MODEL'
20
+ model_data = ModelData(biomodel_id="MODEL0000000537")
21
+ assert model_data.biomodel_id == "MODEL0000000537"
22
+
23
+
24
+ def test_model_data_invalid_biomodel_id():
25
+ """
26
+ Test the ModelData class with invalid
27
+ biomodel
28
+ """
29
+ # Test with invalid string biomodel_id
30
+ with pytest.raises(ValueError):
31
+ ModelData(biomodel_id="12345")
32
+
33
+ # Test with float biomodel_id
34
+ with pytest.raises(ValueError):
35
+ ModelData(biomodel_id=123.45)
@@ -0,0 +1,71 @@
1
+ """
2
+ Test cases for Talk2Biomodels parameter scan tool.
3
+ """
4
+
5
+ import pandas as pd
6
+ from langchain_core.messages import HumanMessage, ToolMessage
7
+ from langchain_openai import ChatOpenAI
8
+
9
+ from ..agents.t2b_agent import get_app
10
+
11
+ LLM_MODEL = ChatOpenAI(model="gpt-4o-mini", temperature=0)
12
+
13
+
14
+ def test_param_scan_tool():
15
+ """
16
+ In this test, we will test the parameter_scan tool.
17
+ We will prompt it to scan the parameter `kIL6RBind`
18
+ from 1 to 100 in steps of 10, record the changes
19
+ in the concentration of the species `Ab{serum}` in
20
+ model 537.
21
+
22
+ We will pass the inaccuarate parameter (`KIL6Rbind`)
23
+ and species names (just `Ab`) to the tool to test
24
+ if it can deal with it.
25
+
26
+ We expect the agent to first invoke the parameter_scan
27
+ tool and raise an error. It will then invoke another
28
+ tool get_modelinfo to get the correct parameter
29
+ and species names. Finally, the agent will reinvoke
30
+ the parameter_scan tool with the correct parameter
31
+ and species names.
32
+
33
+ """
34
+ unique_id = 1234
35
+ app = get_app(unique_id, llm_model=LLM_MODEL)
36
+ config = {"configurable": {"thread_id": unique_id}}
37
+ prompt = """How will the value of Ab in serum in model 537 change
38
+ if the param kIL6Rbind is varied from 1 to 100 in steps of 10?
39
+ Set the initial `DoseQ2W` concentration to 300. Assume
40
+ that the model is simulated for 2016 hours with an interval of 50."""
41
+ # Invoke the agent
42
+ app.invoke({"messages": [HumanMessage(content=prompt)]}, config=config)
43
+ current_state = app.get_state(config)
44
+ reversed_messages = current_state.values["messages"][::-1]
45
+ # Loop through the reversed messages until a
46
+ # ToolMessage is found.
47
+ df = pd.DataFrame(columns=["name", "status", "content"])
48
+ names = []
49
+ statuses = []
50
+ contents = []
51
+ for msg in reversed_messages:
52
+ # Assert that the message is a ToolMessage
53
+ # and its status is "error"
54
+ if not isinstance(msg, ToolMessage):
55
+ continue
56
+ names.append(msg.name)
57
+ statuses.append(msg.status)
58
+ contents.append(msg.content)
59
+ df = pd.DataFrame({"name": names, "status": statuses, "content": contents})
60
+ # print (df)
61
+ assert any(
62
+ (df["status"] == "error")
63
+ & (df["name"] == "parameter_scan")
64
+ & (df["content"].str.startswith("Error: ValueError('Invalid species or parameter name:"))
65
+ )
66
+ assert any(
67
+ (df["status"] == "success")
68
+ & (df["name"] == "parameter_scan")
69
+ & (df["content"].str.startswith("Parameter scan results of"))
70
+ )
71
+ assert any((df["status"] == "success") & (df["name"] == "get_modelinfo"))