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,233 @@
1
+ #!/usr/bin/env python3
2
+
3
+
4
+ """
5
+ Query the metadata table of the most recently displayed papers.
6
+
7
+ This tool loads `state['last_displayed_papers']` into a pandas DataFrame and uses an
8
+ LLM-driven DataFrame agent to execute metadata-level queries. It supports both
9
+ natural-language prompts (e.g., “list titles by author X”) and direct Python expressions
10
+ over the DataFrame.
11
+
12
+ Capabilities
13
+ - Filter, sort, and aggregate rows using metadata columns (e.g., Title, Authors, Venue, Year).
14
+ - Extract paper identifiers from a designated column (default: 'paper_ids'),
15
+ optionally for a single row.
16
+ - Return the DataFrame agent’s textual result as a ToolMessage.
17
+
18
+ Requirements
19
+ - `state['llm_model']`: model used to instantiate the DataFrame agent.
20
+ - `state['last_displayed_papers']`: dictionary mapping row keys → metadata records.
21
+
22
+ Notes
23
+ - Operates strictly on the metadata table; it does not parse or read PDF content.
24
+ - When `extract_ids=True`, the tool constructs a Python expression for the agent to evaluate
25
+ and return identifiers from `id_column`. If `row_number` is provided (1-based), only that row’s
26
+ first identifier is returned; otherwise a list is returned from all rows that have values.
27
+ """
28
+
29
+ import logging
30
+ from typing import Annotated, Any
31
+
32
+ import pandas as pd
33
+ from langchain_core.messages import ToolMessage
34
+ from langchain_core.tools import tool
35
+ from langchain_core.tools.base import InjectedToolCallId
36
+ from langchain_experimental.agents import create_pandas_dataframe_agent
37
+ from langgraph.prebuilt import InjectedState
38
+ from langgraph.types import Command
39
+ from pydantic import BaseModel, Field
40
+
41
+ # Configure logging
42
+ logging.basicConfig(level=logging.INFO)
43
+ logger = logging.getLogger(__name__)
44
+
45
+
46
+ class NoPapersFoundError(Exception):
47
+ """Exception raised when no papers are found in the state."""
48
+
49
+
50
+ class QueryDataFrameInput(BaseModel):
51
+ """
52
+ Input schema for querying the last displayed papers metadata DataFrame.
53
+
54
+ Fields:
55
+ question (str):
56
+ The query to execute. Accepts natural language (e.g., "List titles from 2024")
57
+ or a Python expression over the DataFrame (e.g., "df['Title'].tolist()").
58
+
59
+ extract_ids (bool, default=False):
60
+ When True, the tool prepares a Python expression for the DataFrame agent to extract
61
+ identifiers from `id_column`. Use to obtain IDs from the metadata table.
62
+
63
+ id_column (str, default="paper_ids"):
64
+ Name of the column that contains per-row lists of identifiers (e.g., ["arxiv:2301.12345"]).
65
+ Used only when `extract_ids=True`.
66
+
67
+ row_number (int | None, default=None):
68
+ 1-based row index. When provided with `extract_ids=True`, returns only that row’s first
69
+ identifier. When omitted, returns a list of first identifiers from each applicable row.
70
+
71
+ tool_call_id (InjectedToolCallId):
72
+ Internal identifier for tracing the tool invocation.
73
+
74
+ state (dict):
75
+ Agent state containing:
76
+ - 'last_displayed_papers': dict with the current results table (rows → metadata)
77
+ - 'llm_model': model object or reference for the DataFrame agent
78
+ """
79
+
80
+ question: str = Field(
81
+ description=(
82
+ "The metadata query to run over the papers DataFrame. Can be natural language "
83
+ "(e.g., 'List all titles by author X') or Python code "
84
+ "(e.g., df['arxiv_id'].dropna().tolist())."
85
+ )
86
+ )
87
+ extract_ids: bool = Field(
88
+ default=False,
89
+ description=(
90
+ "If true, instruct the DataFrame agent to extract values from the"
91
+ "specified ID column via a Python expression."
92
+ ),
93
+ )
94
+ id_column: str = Field(
95
+ default="paper_ids",
96
+ description=(
97
+ "Name of the metadata column containing a list of paper IDs to"
98
+ "extract when extract_ids=True."
99
+ ),
100
+ )
101
+ row_number: int | None = Field(
102
+ default=None,
103
+ description=(
104
+ "1-based index of the ID to extract from the list; if provided, returns only"
105
+ "that single ID."
106
+ ),
107
+ )
108
+ tool_call_id: Annotated[str, InjectedToolCallId]
109
+ state: Annotated[dict, InjectedState]
110
+
111
+
112
+ @tool(
113
+ "query_dataframe",
114
+ args_schema=QueryDataFrameInput,
115
+ parse_docstring=True,
116
+ )
117
+ def query_dataframe(
118
+ question: str,
119
+ state: Annotated[dict, InjectedState],
120
+ tool_call_id: str,
121
+ **kwargs: Any,
122
+ ) -> Command:
123
+ """
124
+ Execute a metadata query against the DataFrame built from `last_displayed_papers`.
125
+
126
+ Behavior
127
+ - Builds a pandas DataFrame from `state['last_displayed_papers']`.
128
+ - Instantiates a pandas DataFrame agent with `state['llm_model']`.
129
+ - Runs either:
130
+ • the provided natural-language prompt, or
131
+ • a constructed Python expression when `extract_ids=True`
132
+ (optionally scoped to `row_number`, 1-based).
133
+ - Returns the DataFrame agent’s output text in a ToolMessage.
134
+
135
+ Parameters
136
+ question (str):
137
+ Natural-language query or Python expression to run on the DataFrame.
138
+ state (dict):
139
+ Must provide 'llm_model' and 'last_displayed_papers'.
140
+ tool_call_id (str):
141
+ Internal identifier for the tool call.
142
+ **kwargs:
143
+ extract_ids (bool): Enable ID extraction from `id_column`.
144
+ id_column (str): Column containing lists of identifiers (default: "paper_ids").
145
+ row_number (int | None): 1-based index for a single-row extraction.
146
+
147
+ Returns
148
+ Command:
149
+ update = {
150
+ "messages": [
151
+ ToolMessage(
152
+ content=<text result from the DataFrame agent>,
153
+ tool_call_id=<tool_call_id>
154
+ )
155
+ ]
156
+ }
157
+
158
+ Errors
159
+ - Raises `ValueError` if 'llm_model' is missing in `state`.
160
+ - Raises `NoPapersFoundError` if `state['last_displayed_papers']` is missing or empty.
161
+ - Raises `ValueError` if a required argument for the chosen mode is invalid
162
+ (e.g., no `id_column` when `extract_ids=True`).
163
+
164
+ Examples
165
+ - Natural language:
166
+ question="List titles where Year >= 2023"
167
+ - Python list of titles:
168
+ question="df.query('Year >= 2023')['Title'].tolist()"
169
+ - Extract first ID from row 1:
170
+ extract_ids=True, row_number=1
171
+ - Extract first IDs from all rows:
172
+ extract_ids=True
173
+ """
174
+ logger.info("Querying last displayed papers with question: %s", question)
175
+ llm_model = state.get("llm_model")
176
+ if llm_model is None:
177
+ raise ValueError("Missing 'llm_model' in state.")
178
+
179
+ context_val = state.get("last_displayed_papers")
180
+ if not context_val:
181
+ logger.info("No papers displayed so far, raising NoPapersFoundError")
182
+ raise NoPapersFoundError("No papers found. A search needs to be performed first.")
183
+
184
+ # Resolve the paper dictionary
185
+ if isinstance(context_val, dict):
186
+ dic_papers = context_val
187
+ else:
188
+ dic_papers = state.get(context_val)
189
+
190
+ if not isinstance(dic_papers, dict):
191
+ raise ValueError(
192
+ "Could not resolve a valid metadata dictionary from 'last_displayed_papers'"
193
+ )
194
+
195
+ df_papers = pd.DataFrame.from_dict(dic_papers, orient="index")
196
+ # Prepare the query: if extracting IDs, let the DataFrame agent handle it via Python code
197
+ extract_ids_flag = kwargs.get("extract_ids", False)
198
+ id_column = kwargs.get("id_column", "paper_ids")
199
+ row_number = kwargs.get("row_number")
200
+ question_to_agent = question
201
+ if extract_ids_flag:
202
+ if not id_column:
203
+ raise ValueError("Must specify 'id_column' when extract_ids=True.")
204
+ if row_number is not None:
205
+ question_to_agent = f"df['{id_column}'].dropna().str[0].tolist()[{row_number - 1}]"
206
+ else:
207
+ question_to_agent = f"df['{id_column}'].dropna().str[0].tolist()"
208
+ logger.info("extract_ids enabled: asking agent to run expression: %s", question_to_agent)
209
+
210
+ df_agent = create_pandas_dataframe_agent(
211
+ llm_model,
212
+ allow_dangerous_code=True,
213
+ agent_type="tool-calling",
214
+ df=df_papers,
215
+ max_iterations=5,
216
+ include_df_in_prompt=True,
217
+ number_of_head_rows=df_papers.shape[0],
218
+ verbose=True,
219
+ )
220
+
221
+ llm_result = df_agent.invoke({"input": question_to_agent}, stream_mode=None)
222
+ response_text = llm_result["output"]
223
+
224
+ return Command(
225
+ update={
226
+ "messages": [
227
+ ToolMessage(
228
+ content=response_text,
229
+ tool_call_id=tool_call_id,
230
+ )
231
+ ],
232
+ }
233
+ )
@@ -0,0 +1,128 @@
1
+ #!/usr/bin/env python3
2
+
3
+ """
4
+ Resolve a paper title to a Semantic Scholar paperId.
5
+
6
+ This module provides a tool that queries the Semantic Scholar API for the best match to a
7
+ given paper title (full or partial) and returns the corresponding `paperId` string.
8
+ Configuration is loaded via Hydra and the top ranked result is returned.
9
+ """
10
+
11
+ import logging
12
+ from typing import Annotated, Any
13
+
14
+ import hydra
15
+ import requests
16
+ from langchain_core.messages import ToolMessage
17
+ from langchain_core.tools import tool
18
+ from langchain_core.tools.base import InjectedToolCallId
19
+ from langgraph.types import Command
20
+ from pydantic import BaseModel, Field
21
+
22
+ # Configure logging
23
+ logging.basicConfig(level=logging.INFO)
24
+ logger = logging.getLogger(__name__)
25
+
26
+
27
+ class RetrieveSemanticScholarPaperIdInput(BaseModel):
28
+ """
29
+ Input schema for title→paperId resolution.
30
+
31
+ Fields
32
+ -------
33
+ paper_title : str
34
+ Paper title to search. Accepts full titles or informative partial titles.
35
+ tool_call_id : InjectedToolCallId
36
+ Runtime-injected identifier for tracing the tool invocation.
37
+ """
38
+
39
+ paper_title: str = Field(..., description="The paper title to search for on Semantic Scholar.")
40
+ tool_call_id: Annotated[str, InjectedToolCallId]
41
+
42
+
43
+ @tool(
44
+ "retrieve_semantic_scholar_paper_id",
45
+ args_schema=RetrieveSemanticScholarPaperIdInput,
46
+ parse_docstring=True,
47
+ )
48
+ def retrieve_semantic_scholar_paper_id(
49
+ paper_title: str,
50
+ tool_call_id: str,
51
+ ) -> Command[Any]:
52
+ """
53
+ Look up a Semantic Scholar paperId from a paper title.
54
+
55
+ Behavior
56
+ --------
57
+ - Loads Hydra config from `tools.retrieve_semantic_scholar_paper_id`.
58
+ - Sends a search request with `query=<paper_title>`, `limit=1`, and requested fields.
59
+ - Parses the top hit and returns its `paperId` as the ToolMessage content (plain string).
60
+
61
+ Parameters
62
+ ----------
63
+ paper_title : str
64
+ Title or informative partial title to resolve.
65
+ tool_call_id : str
66
+ Runtime-injected identifier for the tool call.
67
+
68
+ Returns
69
+ -------
70
+ Command
71
+ update = {
72
+ "messages": [
73
+ ToolMessage(
74
+ content="<paperId>", # Semantic Scholar paperId string
75
+ tool_call_id=<tool_call_id>
76
+ )
77
+ ]
78
+ }
79
+
80
+ Exceptions
81
+ ----------
82
+ ValueError
83
+ Raised when no match is found for the provided title.
84
+ requests.RequestException
85
+ Raised on network/HTTP errors (timeout, connection issues, etc.).
86
+
87
+ Examples
88
+ --------
89
+ >>> retrieve_semantic_scholar_paper_id("Attention Is All You Need", "tc_123")
90
+ """
91
+ # Load hydra configuration
92
+ with hydra.initialize(version_base=None, config_path="../../configs"):
93
+ cfg = hydra.compose(
94
+ config_name="config",
95
+ overrides=["tools/retrieve_semantic_scholar_paper_id=default"],
96
+ )
97
+ cfg = cfg.tools.retrieve_semantic_scholar_paper_id
98
+ logger.info("Loaded configuration for Semantic Scholar paper ID retrieval tool")
99
+ logger.info("Retrieving ID of paper with title: %s", paper_title)
100
+ endpoint = cfg.api_endpoint
101
+ params = {
102
+ "query": paper_title,
103
+ "limit": 1,
104
+ "fields": ",".join(cfg.api_fields),
105
+ }
106
+
107
+ response = requests.get(endpoint, params=params, timeout=10)
108
+ data = response.json()
109
+ papers = data.get("data", [])
110
+ logger.info("Received %d papers", len(papers))
111
+ if not papers:
112
+ logger.error("No papers found for query: %s", paper_title)
113
+ raise ValueError(f"No papers found for query: {paper_title}. Try again.")
114
+ # Extract the paper ID from the top result
115
+ paper_id = papers[0]["paperId"]
116
+ logger.info("Found paper ID: %s", paper_id)
117
+ # Prepare the response content (just the ID)
118
+ response_text = paper_id
119
+ return Command(
120
+ update={
121
+ "messages": [
122
+ ToolMessage(
123
+ content=response_text,
124
+ tool_call_id=tool_call_id,
125
+ )
126
+ ],
127
+ }
128
+ )
@@ -0,0 +1,101 @@
1
+ #!/usr/bin/env python3
2
+
3
+ """
4
+ Search for academic papers on Semantic Scholar by title or keywords.
5
+
6
+ Given a text query, this tool retrieves relevant papers from Semantic Scholar,
7
+ optionally filtered by publication year.
8
+ """
9
+
10
+ import logging
11
+ from typing import Annotated, Any
12
+
13
+ from langchain_core.messages import ToolMessage
14
+ from langchain_core.tools import tool
15
+ from langchain_core.tools.base import InjectedToolCallId
16
+ from langgraph.types import Command
17
+ from pydantic import BaseModel, Field
18
+
19
+ from .utils.search_helper import SearchData
20
+
21
+ # Configure logging
22
+ logging.basicConfig(level=logging.INFO)
23
+ logger = logging.getLogger(__name__)
24
+
25
+
26
+ class SearchInput(BaseModel):
27
+ """Defines the input schema for the paper search tool.
28
+
29
+ Attributes:
30
+ query: Full or partial paper title or keywords to search for.
31
+ limit: Maximum number of search results to return (1-100).
32
+ year: Optional publication year filter; supports 'YYYY',
33
+ 'YYYY-', '-YYYY', 'YYYY:YYYY'.
34
+ tool_call_id: Internal tool call identifier injected by the system.
35
+ """
36
+
37
+ query: str = Field(description="Full or partial paper title or keywords to search for")
38
+ limit: int = Field(
39
+ default=10,
40
+ description="Maximum number of search results to return (1-100)",
41
+ ge=1,
42
+ le=100,
43
+ )
44
+ year: str | None = Field(
45
+ default=None,
46
+ description="Publication year filter; supports formats:"
47
+ "'YYYY', 'YYYY-', '-YYYY', 'YYYY:YYYY'",
48
+ )
49
+ tool_call_id: Annotated[str, InjectedToolCallId]
50
+
51
+
52
+ @tool(
53
+ "search_tool",
54
+ args_schema=SearchInput,
55
+ parse_docstring=True,
56
+ )
57
+ def search_tool(
58
+ query: str,
59
+ tool_call_id: Annotated[str, InjectedToolCallId],
60
+ limit: int = 10,
61
+ year: str | None = None,
62
+ ) -> Command[Any]:
63
+ """
64
+ Return academic papers from Semantic Scholar matching a title or keyword query.
65
+
66
+ This tool searches Semantic Scholar for papers whose titles or keywords
67
+ match the given text, optionally filtered by publication year.
68
+
69
+ Args:
70
+ query (str): Full or partial paper title or keywords to search for.
71
+ tool_call_id (str): Internal tool call identifier injected by the system.
72
+ limit (int, optional): Maximum number of search results to return. Defaults to 5.
73
+ year (str, optional): Publication year filter; supports 'YYYY',
74
+ 'YYYY-', '-YYYY', 'YYYY:YYYY'. Defaults to None.
75
+
76
+ Returns:
77
+ Command: A Command object containing:
78
+ - papers: List of matching papers.
79
+ - last_displayed_papers: Same list for display purposes.
80
+ - messages: List containing a ToolMessage with search results details.
81
+ """
82
+ # Create search data object to organize variables
83
+ search_data = SearchData(query, limit, year, tool_call_id)
84
+
85
+ # Process the search
86
+ results = search_data.process_search()
87
+
88
+ return Command(
89
+ update={
90
+ "papers": results["papers"],
91
+ # Store the latest results mapping directly for display
92
+ "last_displayed_papers": results["papers"],
93
+ "messages": [
94
+ ToolMessage(
95
+ content=results["content"],
96
+ tool_call_id=tool_call_id,
97
+ artifact=results["papers"],
98
+ )
99
+ ],
100
+ }
101
+ )
@@ -0,0 +1,102 @@
1
+ #!/usr/bin/env python3
2
+
3
+ """
4
+ Recommend research papers related to a single input paper using Semantic Scholar.
5
+
6
+ Given a Semantic Scholar paper ID, this tool retrieves related works
7
+ (citations and references) and returns a curated list of recommended papers.
8
+ """
9
+
10
+ import logging
11
+ from typing import Annotated, Any
12
+
13
+ from langchain_core.messages import ToolMessage
14
+ from langchain_core.tools import tool
15
+ from langchain_core.tools.base import InjectedToolCallId
16
+ from langgraph.types import Command
17
+ from pydantic import BaseModel, Field
18
+
19
+ from .utils.single_helper import SinglePaperRecData
20
+
21
+ # Configure logging
22
+ logging.basicConfig(level=logging.INFO)
23
+ logger = logging.getLogger(__name__)
24
+
25
+
26
+ class SinglePaperRecInput(BaseModel):
27
+ """Defines the input schema for the single-paper recommendation tool.
28
+
29
+ Attributes:
30
+ paper_id: 40-character Semantic Scholar Paper ID to base recommendations on.
31
+ limit: Maximum number of recommendations to return (1-500).
32
+ year: Optional publication year filter; supports 'YYYY', 'YYYY-', '-YYYY', 'YYYY:YYYY'.
33
+ tool_call_id: Internal tool call identifier injected by the system.
34
+ """
35
+
36
+ paper_id: str = Field(
37
+ description="40-character Semantic Scholar Paper ID to base recommendations on"
38
+ )
39
+ limit: int = Field(
40
+ default=10,
41
+ description="Maximum number of recommendations to return (1-500)",
42
+ ge=1,
43
+ le=500,
44
+ )
45
+ year: str | None = Field(
46
+ default=None,
47
+ description="Publication year filter; supports formats::"
48
+ "'YYYY', 'YYYY-', '-YYYY', 'YYYY:YYYY'",
49
+ )
50
+ tool_call_id: Annotated[str, InjectedToolCallId]
51
+ model_config = {"arbitrary_types_allowed": True}
52
+
53
+
54
+ @tool(
55
+ args_schema=SinglePaperRecInput,
56
+ parse_docstring=True,
57
+ )
58
+ def get_single_paper_recommendations(
59
+ paper_id: str,
60
+ tool_call_id: Annotated[str, InjectedToolCallId],
61
+ limit: int = 10,
62
+ year: str | None = None,
63
+ ) -> Command[Any]:
64
+ """
65
+ Recommend related research papers using the Semantic Scholar API for a single paper ID.
66
+
67
+ This tool is designed to suggest relevant papers based on one input Semantic Scholar paper ID.
68
+ It fetches citations and references for the given paper and returns a set of recommended works.
69
+
70
+ Args:
71
+ paper_id (str): 40-character Semantic Scholar paper ID.
72
+ tool_call_id (str): Internal tool call identifier injected by the system.
73
+ limit (int, optional): Maximum number of recommendations to return. Defaults to 5.
74
+ year (str, optional): Filter recommendations by publication year.
75
+ Supports formats: 'YYYY', 'YYYY-', '-YYYY', or 'YYYY:YYYY'. Defaults to None.
76
+
77
+ Returns:
78
+ Command: A Command object containing:
79
+ - papers: List of recommended papers.
80
+ - last_displayed_papers: Same list for display purposes.
81
+ - messages: List containing a ToolMessage with recommendation details.
82
+ """
83
+ # Create recommendation data object to organize variables
84
+ rec_data = SinglePaperRecData(paper_id, limit, year, tool_call_id)
85
+
86
+ # Process the recommendations
87
+ results = rec_data.process_recommendations()
88
+
89
+ return Command(
90
+ update={
91
+ "papers": results["papers"],
92
+ # Store the latest single-paper results mapping directly for display
93
+ "last_displayed_papers": results["papers"],
94
+ "messages": [
95
+ ToolMessage(
96
+ content=results["content"],
97
+ tool_call_id=tool_call_id,
98
+ artifact=results["papers"],
99
+ )
100
+ ],
101
+ }
102
+ )
@@ -0,0 +1,5 @@
1
+ """This module contains utility functions for the Semantic Scholar search tool."""
2
+
3
+ from . import multi_helper, search_helper, single_helper
4
+
5
+ __all__ = ["search_helper", "single_helper", "multi_helper"]