aiagents4pharma 1.30.1__tar.gz → 1.30.3__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {aiagents4pharma-1.30.1 → aiagents4pharma-1.30.3}/PKG-INFO +3 -2
- {aiagents4pharma-1.30.1 → aiagents4pharma-1.30.3}/aiagents4pharma/talk2scholars/__init__.py +2 -0
- {aiagents4pharma-1.30.1 → aiagents4pharma-1.30.3}/aiagents4pharma/talk2scholars/agents/__init__.py +8 -0
- {aiagents4pharma-1.30.1 → aiagents4pharma-1.30.3}/aiagents4pharma/talk2scholars/agents/zotero_agent.py +9 -7
- {aiagents4pharma-1.30.1 → aiagents4pharma-1.30.3}/aiagents4pharma/talk2scholars/configs/__init__.py +2 -0
- {aiagents4pharma-1.30.1 → aiagents4pharma-1.30.3}/aiagents4pharma/talk2scholars/configs/agents/__init__.py +2 -0
- {aiagents4pharma-1.30.1 → aiagents4pharma-1.30.3}/aiagents4pharma/talk2scholars/configs/agents/talk2scholars/__init__.py +2 -0
- aiagents4pharma-1.30.3/aiagents4pharma/talk2scholars/configs/agents/talk2scholars/zotero_agent/default.yaml +13 -0
- {aiagents4pharma-1.30.1 → aiagents4pharma-1.30.3}/aiagents4pharma/talk2scholars/configs/app/__init__.py +2 -0
- {aiagents4pharma-1.30.1 → aiagents4pharma-1.30.3}/aiagents4pharma/talk2scholars/configs/tools/__init__.py +9 -0
- aiagents4pharma-1.30.3/aiagents4pharma/talk2scholars/configs/tools/zotero_write/default.yaml +55 -0
- {aiagents4pharma-1.30.1 → aiagents4pharma-1.30.3}/aiagents4pharma/talk2scholars/state/__init__.py +4 -2
- {aiagents4pharma-1.30.1 → aiagents4pharma-1.30.3}/aiagents4pharma/talk2scholars/state/state_talk2scholars.py +3 -0
- {aiagents4pharma-1.30.1 → aiagents4pharma-1.30.3}/aiagents4pharma/talk2scholars/tests/test_routing_logic.py +1 -2
- {aiagents4pharma-1.30.1 → aiagents4pharma-1.30.3}/aiagents4pharma/talk2scholars/tests/test_s2_multi.py +10 -8
- {aiagents4pharma-1.30.1 → aiagents4pharma-1.30.3}/aiagents4pharma/talk2scholars/tests/test_s2_search.py +9 -5
- {aiagents4pharma-1.30.1 → aiagents4pharma-1.30.3}/aiagents4pharma/talk2scholars/tests/test_s2_single.py +7 -7
- {aiagents4pharma-1.30.1 → aiagents4pharma-1.30.3}/aiagents4pharma/talk2scholars/tests/test_zotero_agent.py +3 -2
- aiagents4pharma-1.30.3/aiagents4pharma/talk2scholars/tests/test_zotero_human_in_the_loop.py +273 -0
- aiagents4pharma-1.30.3/aiagents4pharma/talk2scholars/tests/test_zotero_path.py +489 -0
- {aiagents4pharma-1.30.1 → aiagents4pharma-1.30.3}/aiagents4pharma/talk2scholars/tests/test_zotero_read.py +57 -43
- aiagents4pharma-1.30.3/aiagents4pharma/talk2scholars/tests/test_zotero_write.py +161 -0
- {aiagents4pharma-1.30.1 → aiagents4pharma-1.30.3}/aiagents4pharma/talk2scholars/tools/__init__.py +3 -0
- {aiagents4pharma-1.30.1 → aiagents4pharma-1.30.3}/aiagents4pharma/talk2scholars/tools/pdf/__init__.py +4 -2
- {aiagents4pharma-1.30.1 → aiagents4pharma-1.30.3}/aiagents4pharma/talk2scholars/tools/s2/__init__.py +9 -0
- aiagents4pharma-1.30.3/aiagents4pharma/talk2scholars/tools/s2/multi_paper_rec.py +83 -0
- aiagents4pharma-1.30.3/aiagents4pharma/talk2scholars/tools/s2/search.py +77 -0
- aiagents4pharma-1.30.3/aiagents4pharma/talk2scholars/tools/s2/single_paper_rec.py +81 -0
- aiagents4pharma-1.30.3/aiagents4pharma/talk2scholars/tools/s2/utils/__init__.py +7 -0
- aiagents4pharma-1.30.3/aiagents4pharma/talk2scholars/tools/s2/utils/multi_helper.py +194 -0
- aiagents4pharma-1.30.3/aiagents4pharma/talk2scholars/tools/s2/utils/search_helper.py +175 -0
- aiagents4pharma-1.30.3/aiagents4pharma/talk2scholars/tools/s2/utils/single_helper.py +186 -0
- {aiagents4pharma-1.30.1 → aiagents4pharma-1.30.3}/aiagents4pharma/talk2scholars/tools/zotero/__init__.py +3 -0
- aiagents4pharma-1.30.3/aiagents4pharma/talk2scholars/tools/zotero/utils/__init__.py +10 -0
- aiagents4pharma-1.30.3/aiagents4pharma/talk2scholars/tools/zotero/utils/read_helper.py +167 -0
- aiagents4pharma-1.30.3/aiagents4pharma/talk2scholars/tools/zotero/utils/review_helper.py +78 -0
- aiagents4pharma-1.30.3/aiagents4pharma/talk2scholars/tools/zotero/utils/write_helper.py +197 -0
- aiagents4pharma-1.30.3/aiagents4pharma/talk2scholars/tools/zotero/utils/zotero_path.py +188 -0
- aiagents4pharma-1.30.3/aiagents4pharma/talk2scholars/tools/zotero/zotero_read.py +75 -0
- aiagents4pharma-1.30.3/aiagents4pharma/talk2scholars/tools/zotero/zotero_review.py +164 -0
- aiagents4pharma-1.30.3/aiagents4pharma/talk2scholars/tools/zotero/zotero_write.py +90 -0
- {aiagents4pharma-1.30.1 → aiagents4pharma-1.30.3}/aiagents4pharma.egg-info/PKG-INFO +3 -2
- {aiagents4pharma-1.30.1 → aiagents4pharma-1.30.3}/aiagents4pharma.egg-info/SOURCES.txt +10 -0
- {aiagents4pharma-1.30.1 → aiagents4pharma-1.30.3}/pyproject.toml +1 -0
- aiagents4pharma-1.30.3/release_version.txt +1 -0
- aiagents4pharma-1.30.1/aiagents4pharma/talk2scholars/configs/agents/talk2scholars/zotero_agent/default.yaml +0 -19
- aiagents4pharma-1.30.1/aiagents4pharma/talk2scholars/tests/test_zotero_path.py +0 -57
- aiagents4pharma-1.30.1/aiagents4pharma/talk2scholars/tests/test_zotero_write.py +0 -626
- aiagents4pharma-1.30.1/aiagents4pharma/talk2scholars/tools/s2/multi_paper_rec.py +0 -209
- aiagents4pharma-1.30.1/aiagents4pharma/talk2scholars/tools/s2/search.py +0 -183
- aiagents4pharma-1.30.1/aiagents4pharma/talk2scholars/tools/s2/single_paper_rec.py +0 -199
- aiagents4pharma-1.30.1/aiagents4pharma/talk2scholars/tools/zotero/utils/__init__.py +0 -5
- aiagents4pharma-1.30.1/aiagents4pharma/talk2scholars/tools/zotero/utils/zotero_path.py +0 -63
- aiagents4pharma-1.30.1/aiagents4pharma/talk2scholars/tools/zotero/zotero_read.py +0 -204
- aiagents4pharma-1.30.1/aiagents4pharma/talk2scholars/tools/zotero/zotero_write.py +0 -279
- aiagents4pharma-1.30.1/release_version.txt +0 -1
- {aiagents4pharma-1.30.1 → aiagents4pharma-1.30.3}/LICENSE +0 -0
- {aiagents4pharma-1.30.1 → aiagents4pharma-1.30.3}/README.md +0 -0
- {aiagents4pharma-1.30.1 → aiagents4pharma-1.30.3}/aiagents4pharma/__init__.py +0 -0
- {aiagents4pharma-1.30.1 → aiagents4pharma-1.30.3}/aiagents4pharma/talk2aiagents4pharma/__init__.py +0 -0
- {aiagents4pharma-1.30.1 → aiagents4pharma-1.30.3}/aiagents4pharma/talk2aiagents4pharma/agents/__init__.py +0 -0
- {aiagents4pharma-1.30.1 → aiagents4pharma-1.30.3}/aiagents4pharma/talk2aiagents4pharma/agents/main_agent.py +0 -0
- {aiagents4pharma-1.30.1 → aiagents4pharma-1.30.3}/aiagents4pharma/talk2aiagents4pharma/configs/__init__.py +0 -0
- {aiagents4pharma-1.30.1 → aiagents4pharma-1.30.3}/aiagents4pharma/talk2aiagents4pharma/configs/agents/__init__.py +0 -0
- {aiagents4pharma-1.30.1 → aiagents4pharma-1.30.3}/aiagents4pharma/talk2aiagents4pharma/configs/agents/main_agent/default.yaml +0 -0
- {aiagents4pharma-1.30.1 → aiagents4pharma-1.30.3}/aiagents4pharma/talk2aiagents4pharma/configs/config.yaml +0 -0
- {aiagents4pharma-1.30.1 → aiagents4pharma-1.30.3}/aiagents4pharma/talk2aiagents4pharma/states/__init__.py +0 -0
- {aiagents4pharma-1.30.1 → aiagents4pharma-1.30.3}/aiagents4pharma/talk2aiagents4pharma/states/state_talk2aiagents4pharma.py +0 -0
- {aiagents4pharma-1.30.1 → aiagents4pharma-1.30.3}/aiagents4pharma/talk2aiagents4pharma/tests/__init__.py +0 -0
- {aiagents4pharma-1.30.1 → aiagents4pharma-1.30.3}/aiagents4pharma/talk2aiagents4pharma/tests/test_main_agent.py +0 -0
- {aiagents4pharma-1.30.1 → aiagents4pharma-1.30.3}/aiagents4pharma/talk2biomodels/__init__.py +0 -0
- {aiagents4pharma-1.30.1 → aiagents4pharma-1.30.3}/aiagents4pharma/talk2biomodels/agents/__init__.py +0 -0
- {aiagents4pharma-1.30.1 → aiagents4pharma-1.30.3}/aiagents4pharma/talk2biomodels/agents/t2b_agent.py +0 -0
- {aiagents4pharma-1.30.1 → aiagents4pharma-1.30.3}/aiagents4pharma/talk2biomodels/api/__init__.py +0 -0
- {aiagents4pharma-1.30.1 → aiagents4pharma-1.30.3}/aiagents4pharma/talk2biomodels/api/kegg.py +0 -0
- {aiagents4pharma-1.30.1 → aiagents4pharma-1.30.3}/aiagents4pharma/talk2biomodels/api/ols.py +0 -0
- {aiagents4pharma-1.30.1 → aiagents4pharma-1.30.3}/aiagents4pharma/talk2biomodels/api/uniprot.py +0 -0
- {aiagents4pharma-1.30.1 → aiagents4pharma-1.30.3}/aiagents4pharma/talk2biomodels/configs/__init__.py +0 -0
- {aiagents4pharma-1.30.1 → aiagents4pharma-1.30.3}/aiagents4pharma/talk2biomodels/configs/agents/__init__.py +0 -0
- {aiagents4pharma-1.30.1 → aiagents4pharma-1.30.3}/aiagents4pharma/talk2biomodels/configs/agents/t2b_agent/__init__.py +0 -0
- {aiagents4pharma-1.30.1 → aiagents4pharma-1.30.3}/aiagents4pharma/talk2biomodels/configs/agents/t2b_agent/default.yaml +0 -0
- {aiagents4pharma-1.30.1 → aiagents4pharma-1.30.3}/aiagents4pharma/talk2biomodels/configs/config.yaml +0 -0
- {aiagents4pharma-1.30.1 → aiagents4pharma-1.30.3}/aiagents4pharma/talk2biomodels/configs/tools/__init__.py +0 -0
- {aiagents4pharma-1.30.1 → aiagents4pharma-1.30.3}/aiagents4pharma/talk2biomodels/configs/tools/ask_question/__init__.py +0 -0
- {aiagents4pharma-1.30.1 → aiagents4pharma-1.30.3}/aiagents4pharma/talk2biomodels/configs/tools/ask_question/default.yaml +0 -0
- {aiagents4pharma-1.30.1 → aiagents4pharma-1.30.3}/aiagents4pharma/talk2biomodels/configs/tools/custom_plotter/__init__.py +0 -0
- {aiagents4pharma-1.30.1 → aiagents4pharma-1.30.3}/aiagents4pharma/talk2biomodels/configs/tools/custom_plotter/default.yaml +0 -0
- {aiagents4pharma-1.30.1 → aiagents4pharma-1.30.3}/aiagents4pharma/talk2biomodels/configs/tools/get_annotation/__init__.py +0 -0
- {aiagents4pharma-1.30.1 → aiagents4pharma-1.30.3}/aiagents4pharma/talk2biomodels/configs/tools/get_annotation/default.yaml +0 -0
- {aiagents4pharma-1.30.1 → aiagents4pharma-1.30.3}/aiagents4pharma/talk2biomodels/models/__init__.py +0 -0
- {aiagents4pharma-1.30.1 → aiagents4pharma-1.30.3}/aiagents4pharma/talk2biomodels/models/basico_model.py +0 -0
- {aiagents4pharma-1.30.1 → aiagents4pharma-1.30.3}/aiagents4pharma/talk2biomodels/models/sys_bio_model.py +0 -0
- {aiagents4pharma-1.30.1 → aiagents4pharma-1.30.3}/aiagents4pharma/talk2biomodels/states/__init__.py +0 -0
- {aiagents4pharma-1.30.1 → aiagents4pharma-1.30.3}/aiagents4pharma/talk2biomodels/states/state_talk2biomodels.py +0 -0
- {aiagents4pharma-1.30.1 → aiagents4pharma-1.30.3}/aiagents4pharma/talk2biomodels/tests/__init__.py +0 -0
- {aiagents4pharma-1.30.1 → aiagents4pharma-1.30.3}/aiagents4pharma/talk2biomodels/tests/test_api.py +0 -0
- {aiagents4pharma-1.30.1 → aiagents4pharma-1.30.3}/aiagents4pharma/talk2biomodels/tests/test_ask_question.py +0 -0
- {aiagents4pharma-1.30.1 → aiagents4pharma-1.30.3}/aiagents4pharma/talk2biomodels/tests/test_basico_model.py +0 -0
- {aiagents4pharma-1.30.1 → aiagents4pharma-1.30.3}/aiagents4pharma/talk2biomodels/tests/test_get_annotation.py +0 -0
- {aiagents4pharma-1.30.1 → aiagents4pharma-1.30.3}/aiagents4pharma/talk2biomodels/tests/test_getmodelinfo.py +0 -0
- {aiagents4pharma-1.30.1 → aiagents4pharma-1.30.3}/aiagents4pharma/talk2biomodels/tests/test_integration.py +0 -0
- {aiagents4pharma-1.30.1 → aiagents4pharma-1.30.3}/aiagents4pharma/talk2biomodels/tests/test_load_biomodel.py +0 -0
- {aiagents4pharma-1.30.1 → aiagents4pharma-1.30.3}/aiagents4pharma/talk2biomodels/tests/test_param_scan.py +0 -0
- {aiagents4pharma-1.30.1 → aiagents4pharma-1.30.3}/aiagents4pharma/talk2biomodels/tests/test_query_article.py +0 -0
- {aiagents4pharma-1.30.1 → aiagents4pharma-1.30.3}/aiagents4pharma/talk2biomodels/tests/test_search_models.py +0 -0
- {aiagents4pharma-1.30.1 → aiagents4pharma-1.30.3}/aiagents4pharma/talk2biomodels/tests/test_simulate_model.py +0 -0
- {aiagents4pharma-1.30.1 → aiagents4pharma-1.30.3}/aiagents4pharma/talk2biomodels/tests/test_steady_state.py +0 -0
- {aiagents4pharma-1.30.1 → aiagents4pharma-1.30.3}/aiagents4pharma/talk2biomodels/tests/test_sys_bio_model.py +0 -0
- {aiagents4pharma-1.30.1 → aiagents4pharma-1.30.3}/aiagents4pharma/talk2biomodels/tools/__init__.py +0 -0
- {aiagents4pharma-1.30.1 → aiagents4pharma-1.30.3}/aiagents4pharma/talk2biomodels/tools/ask_question.py +0 -0
- {aiagents4pharma-1.30.1 → aiagents4pharma-1.30.3}/aiagents4pharma/talk2biomodels/tools/custom_plotter.py +0 -0
- {aiagents4pharma-1.30.1 → aiagents4pharma-1.30.3}/aiagents4pharma/talk2biomodels/tools/get_annotation.py +0 -0
- {aiagents4pharma-1.30.1 → aiagents4pharma-1.30.3}/aiagents4pharma/talk2biomodels/tools/get_modelinfo.py +0 -0
- {aiagents4pharma-1.30.1 → aiagents4pharma-1.30.3}/aiagents4pharma/talk2biomodels/tools/load_arguments.py +0 -0
- {aiagents4pharma-1.30.1 → aiagents4pharma-1.30.3}/aiagents4pharma/talk2biomodels/tools/load_biomodel.py +0 -0
- {aiagents4pharma-1.30.1 → aiagents4pharma-1.30.3}/aiagents4pharma/talk2biomodels/tools/parameter_scan.py +0 -0
- {aiagents4pharma-1.30.1 → aiagents4pharma-1.30.3}/aiagents4pharma/talk2biomodels/tools/query_article.py +0 -0
- {aiagents4pharma-1.30.1 → aiagents4pharma-1.30.3}/aiagents4pharma/talk2biomodels/tools/search_models.py +0 -0
- {aiagents4pharma-1.30.1 → aiagents4pharma-1.30.3}/aiagents4pharma/talk2biomodels/tools/simulate_model.py +0 -0
- {aiagents4pharma-1.30.1 → aiagents4pharma-1.30.3}/aiagents4pharma/talk2biomodels/tools/steady_state.py +0 -0
- {aiagents4pharma-1.30.1 → aiagents4pharma-1.30.3}/aiagents4pharma/talk2biomodels/tools/utils.py +0 -0
- {aiagents4pharma-1.30.1 → aiagents4pharma-1.30.3}/aiagents4pharma/talk2cells/__init__.py +0 -0
- {aiagents4pharma-1.30.1 → aiagents4pharma-1.30.3}/aiagents4pharma/talk2cells/agents/__init__.py +0 -0
- {aiagents4pharma-1.30.1 → aiagents4pharma-1.30.3}/aiagents4pharma/talk2cells/agents/scp_agent.py +0 -0
- {aiagents4pharma-1.30.1 → aiagents4pharma-1.30.3}/aiagents4pharma/talk2cells/states/__init__.py +0 -0
- {aiagents4pharma-1.30.1 → aiagents4pharma-1.30.3}/aiagents4pharma/talk2cells/states/state_talk2cells.py +0 -0
- {aiagents4pharma-1.30.1 → aiagents4pharma-1.30.3}/aiagents4pharma/talk2cells/tests/scp_agent/test_scp_agent.py +0 -0
- {aiagents4pharma-1.30.1 → aiagents4pharma-1.30.3}/aiagents4pharma/talk2cells/tools/__init__.py +0 -0
- {aiagents4pharma-1.30.1 → aiagents4pharma-1.30.3}/aiagents4pharma/talk2cells/tools/scp_agent/__init__.py +0 -0
- {aiagents4pharma-1.30.1 → aiagents4pharma-1.30.3}/aiagents4pharma/talk2cells/tools/scp_agent/display_studies.py +0 -0
- {aiagents4pharma-1.30.1 → aiagents4pharma-1.30.3}/aiagents4pharma/talk2cells/tools/scp_agent/search_studies.py +0 -0
- {aiagents4pharma-1.30.1 → aiagents4pharma-1.30.3}/aiagents4pharma/talk2knowledgegraphs/__init__.py +0 -0
- {aiagents4pharma-1.30.1 → aiagents4pharma-1.30.3}/aiagents4pharma/talk2knowledgegraphs/agents/__init__.py +0 -0
- {aiagents4pharma-1.30.1 → aiagents4pharma-1.30.3}/aiagents4pharma/talk2knowledgegraphs/agents/t2kg_agent.py +0 -0
- {aiagents4pharma-1.30.1 → aiagents4pharma-1.30.3}/aiagents4pharma/talk2knowledgegraphs/configs/__init__.py +0 -0
- {aiagents4pharma-1.30.1 → aiagents4pharma-1.30.3}/aiagents4pharma/talk2knowledgegraphs/configs/agents/t2kg_agent/__init__.py +0 -0
- {aiagents4pharma-1.30.1 → aiagents4pharma-1.30.3}/aiagents4pharma/talk2knowledgegraphs/configs/agents/t2kg_agent/default.yaml +0 -0
- {aiagents4pharma-1.30.1 → aiagents4pharma-1.30.3}/aiagents4pharma/talk2knowledgegraphs/configs/app/__init__.py +0 -0
- {aiagents4pharma-1.30.1 → aiagents4pharma-1.30.3}/aiagents4pharma/talk2knowledgegraphs/configs/app/frontend/__init__.py +0 -0
- {aiagents4pharma-1.30.1 → aiagents4pharma-1.30.3}/aiagents4pharma/talk2knowledgegraphs/configs/app/frontend/default.yaml +0 -0
- {aiagents4pharma-1.30.1 → aiagents4pharma-1.30.3}/aiagents4pharma/talk2knowledgegraphs/configs/config.yaml +0 -0
- {aiagents4pharma-1.30.1 → aiagents4pharma-1.30.3}/aiagents4pharma/talk2knowledgegraphs/configs/tools/__init__.py +0 -0
- {aiagents4pharma-1.30.1 → aiagents4pharma-1.30.3}/aiagents4pharma/talk2knowledgegraphs/configs/tools/graphrag_reasoning/__init__.py +0 -0
- {aiagents4pharma-1.30.1 → aiagents4pharma-1.30.3}/aiagents4pharma/talk2knowledgegraphs/configs/tools/graphrag_reasoning/default.yaml +0 -0
- {aiagents4pharma-1.30.1 → aiagents4pharma-1.30.3}/aiagents4pharma/talk2knowledgegraphs/configs/tools/subgraph_extraction/__init__.py +0 -0
- {aiagents4pharma-1.30.1 → aiagents4pharma-1.30.3}/aiagents4pharma/talk2knowledgegraphs/configs/tools/subgraph_extraction/default.yaml +0 -0
- {aiagents4pharma-1.30.1 → aiagents4pharma-1.30.3}/aiagents4pharma/talk2knowledgegraphs/configs/tools/subgraph_summarization/__init__.py +0 -0
- {aiagents4pharma-1.30.1 → aiagents4pharma-1.30.3}/aiagents4pharma/talk2knowledgegraphs/configs/tools/subgraph_summarization/default.yaml +0 -0
- {aiagents4pharma-1.30.1 → aiagents4pharma-1.30.3}/aiagents4pharma/talk2knowledgegraphs/datasets/__init__.py +0 -0
- {aiagents4pharma-1.30.1 → aiagents4pharma-1.30.3}/aiagents4pharma/talk2knowledgegraphs/datasets/biobridge_primekg.py +0 -0
- {aiagents4pharma-1.30.1 → aiagents4pharma-1.30.3}/aiagents4pharma/talk2knowledgegraphs/datasets/dataset.py +0 -0
- {aiagents4pharma-1.30.1 → aiagents4pharma-1.30.3}/aiagents4pharma/talk2knowledgegraphs/datasets/primekg.py +0 -0
- {aiagents4pharma-1.30.1 → aiagents4pharma-1.30.3}/aiagents4pharma/talk2knowledgegraphs/datasets/starkqa_primekg.py +0 -0
- {aiagents4pharma-1.30.1 → aiagents4pharma-1.30.3}/aiagents4pharma/talk2knowledgegraphs/states/__init__.py +0 -0
- {aiagents4pharma-1.30.1 → aiagents4pharma-1.30.3}/aiagents4pharma/talk2knowledgegraphs/states/state_talk2knowledgegraphs.py +0 -0
- {aiagents4pharma-1.30.1 → aiagents4pharma-1.30.3}/aiagents4pharma/talk2knowledgegraphs/tests/__init__.py +0 -0
- {aiagents4pharma-1.30.1 → aiagents4pharma-1.30.3}/aiagents4pharma/talk2knowledgegraphs/tests/test_agents_t2kg_agent.py +0 -0
- {aiagents4pharma-1.30.1 → aiagents4pharma-1.30.3}/aiagents4pharma/talk2knowledgegraphs/tests/test_datasets_biobridge_primekg.py +0 -0
- {aiagents4pharma-1.30.1 → aiagents4pharma-1.30.3}/aiagents4pharma/talk2knowledgegraphs/tests/test_datasets_dataset.py +0 -0
- {aiagents4pharma-1.30.1 → aiagents4pharma-1.30.3}/aiagents4pharma/talk2knowledgegraphs/tests/test_datasets_primekg.py +0 -0
- {aiagents4pharma-1.30.1 → aiagents4pharma-1.30.3}/aiagents4pharma/talk2knowledgegraphs/tests/test_datasets_starkqa_primekg.py +0 -0
- {aiagents4pharma-1.30.1 → aiagents4pharma-1.30.3}/aiagents4pharma/talk2knowledgegraphs/tests/test_tools_graphrag_reasoning.py +0 -0
- {aiagents4pharma-1.30.1 → aiagents4pharma-1.30.3}/aiagents4pharma/talk2knowledgegraphs/tests/test_tools_subgraph_extraction.py +0 -0
- {aiagents4pharma-1.30.1 → aiagents4pharma-1.30.3}/aiagents4pharma/talk2knowledgegraphs/tests/test_tools_subgraph_summarization.py +0 -0
- {aiagents4pharma-1.30.1 → aiagents4pharma-1.30.3}/aiagents4pharma/talk2knowledgegraphs/tests/test_utils_embeddings_embeddings.py +0 -0
- {aiagents4pharma-1.30.1 → aiagents4pharma-1.30.3}/aiagents4pharma/talk2knowledgegraphs/tests/test_utils_embeddings_huggingface.py +0 -0
- {aiagents4pharma-1.30.1 → aiagents4pharma-1.30.3}/aiagents4pharma/talk2knowledgegraphs/tests/test_utils_embeddings_nim_molmim.py +0 -0
- {aiagents4pharma-1.30.1 → aiagents4pharma-1.30.3}/aiagents4pharma/talk2knowledgegraphs/tests/test_utils_embeddings_ollama.py +0 -0
- {aiagents4pharma-1.30.1 → aiagents4pharma-1.30.3}/aiagents4pharma/talk2knowledgegraphs/tests/test_utils_embeddings_sentencetransformer.py +0 -0
- {aiagents4pharma-1.30.1 → aiagents4pharma-1.30.3}/aiagents4pharma/talk2knowledgegraphs/tests/test_utils_enrichments_enrichments.py +0 -0
- {aiagents4pharma-1.30.1 → aiagents4pharma-1.30.3}/aiagents4pharma/talk2knowledgegraphs/tests/test_utils_enrichments_ollama.py +0 -0
- {aiagents4pharma-1.30.1 → aiagents4pharma-1.30.3}/aiagents4pharma/talk2knowledgegraphs/tests/test_utils_enrichments_pubchem.py +0 -0
- {aiagents4pharma-1.30.1 → aiagents4pharma-1.30.3}/aiagents4pharma/talk2knowledgegraphs/tests/test_utils_kg_utils.py +0 -0
- {aiagents4pharma-1.30.1 → aiagents4pharma-1.30.3}/aiagents4pharma/talk2knowledgegraphs/tests/test_utils_pubchem_utils.py +0 -0
- {aiagents4pharma-1.30.1 → aiagents4pharma-1.30.3}/aiagents4pharma/talk2knowledgegraphs/tools/__init__.py +0 -0
- {aiagents4pharma-1.30.1 → aiagents4pharma-1.30.3}/aiagents4pharma/talk2knowledgegraphs/tools/graphrag_reasoning.py +0 -0
- {aiagents4pharma-1.30.1 → aiagents4pharma-1.30.3}/aiagents4pharma/talk2knowledgegraphs/tools/load_arguments.py +0 -0
- {aiagents4pharma-1.30.1 → aiagents4pharma-1.30.3}/aiagents4pharma/talk2knowledgegraphs/tools/subgraph_extraction.py +0 -0
- {aiagents4pharma-1.30.1 → aiagents4pharma-1.30.3}/aiagents4pharma/talk2knowledgegraphs/tools/subgraph_summarization.py +0 -0
- {aiagents4pharma-1.30.1 → aiagents4pharma-1.30.3}/aiagents4pharma/talk2knowledgegraphs/utils/__init__.py +0 -0
- {aiagents4pharma-1.30.1 → aiagents4pharma-1.30.3}/aiagents4pharma/talk2knowledgegraphs/utils/embeddings/__init__.py +0 -0
- {aiagents4pharma-1.30.1 → aiagents4pharma-1.30.3}/aiagents4pharma/talk2knowledgegraphs/utils/embeddings/embeddings.py +0 -0
- {aiagents4pharma-1.30.1 → aiagents4pharma-1.30.3}/aiagents4pharma/talk2knowledgegraphs/utils/embeddings/huggingface.py +0 -0
- {aiagents4pharma-1.30.1 → aiagents4pharma-1.30.3}/aiagents4pharma/talk2knowledgegraphs/utils/embeddings/nim_molmim.py +0 -0
- {aiagents4pharma-1.30.1 → aiagents4pharma-1.30.3}/aiagents4pharma/talk2knowledgegraphs/utils/embeddings/ollama.py +0 -0
- {aiagents4pharma-1.30.1 → aiagents4pharma-1.30.3}/aiagents4pharma/talk2knowledgegraphs/utils/embeddings/sentence_transformer.py +0 -0
- {aiagents4pharma-1.30.1 → aiagents4pharma-1.30.3}/aiagents4pharma/talk2knowledgegraphs/utils/enrichments/__init__.py +0 -0
- {aiagents4pharma-1.30.1 → aiagents4pharma-1.30.3}/aiagents4pharma/talk2knowledgegraphs/utils/enrichments/enrichments.py +0 -0
- {aiagents4pharma-1.30.1 → aiagents4pharma-1.30.3}/aiagents4pharma/talk2knowledgegraphs/utils/enrichments/ollama.py +0 -0
- {aiagents4pharma-1.30.1 → aiagents4pharma-1.30.3}/aiagents4pharma/talk2knowledgegraphs/utils/enrichments/pubchem_strings.py +0 -0
- {aiagents4pharma-1.30.1 → aiagents4pharma-1.30.3}/aiagents4pharma/talk2knowledgegraphs/utils/extractions/__init__.py +0 -0
- {aiagents4pharma-1.30.1 → aiagents4pharma-1.30.3}/aiagents4pharma/talk2knowledgegraphs/utils/extractions/pcst.py +0 -0
- {aiagents4pharma-1.30.1 → aiagents4pharma-1.30.3}/aiagents4pharma/talk2knowledgegraphs/utils/kg_utils.py +0 -0
- {aiagents4pharma-1.30.1 → aiagents4pharma-1.30.3}/aiagents4pharma/talk2knowledgegraphs/utils/pubchem_utils.py +0 -0
- {aiagents4pharma-1.30.1 → aiagents4pharma-1.30.3}/aiagents4pharma/talk2scholars/agents/main_agent.py +0 -0
- {aiagents4pharma-1.30.1 → aiagents4pharma-1.30.3}/aiagents4pharma/talk2scholars/agents/paper_download_agent.py +0 -0
- {aiagents4pharma-1.30.1 → aiagents4pharma-1.30.3}/aiagents4pharma/talk2scholars/agents/pdf_agent.py +0 -0
- {aiagents4pharma-1.30.1 → aiagents4pharma-1.30.3}/aiagents4pharma/talk2scholars/agents/s2_agent.py +0 -0
- {aiagents4pharma-1.30.1 → aiagents4pharma-1.30.3}/aiagents4pharma/talk2scholars/configs/agents/talk2scholars/main_agent/__init__.py +0 -0
- {aiagents4pharma-1.30.1 → aiagents4pharma-1.30.3}/aiagents4pharma/talk2scholars/configs/agents/talk2scholars/main_agent/default.yaml +0 -0
- {aiagents4pharma-1.30.1 → aiagents4pharma-1.30.3}/aiagents4pharma/talk2scholars/configs/agents/talk2scholars/paper_download_agent/__init__.py +0 -0
- {aiagents4pharma-1.30.1 → aiagents4pharma-1.30.3}/aiagents4pharma/talk2scholars/configs/agents/talk2scholars/pdf_agent/__init__.py +0 -0
- {aiagents4pharma-1.30.1 → aiagents4pharma-1.30.3}/aiagents4pharma/talk2scholars/configs/agents/talk2scholars/s2_agent/__init__.py +0 -0
- {aiagents4pharma-1.30.1 → aiagents4pharma-1.30.3}/aiagents4pharma/talk2scholars/configs/agents/talk2scholars/s2_agent/default.yaml +0 -0
- {aiagents4pharma-1.30.1 → aiagents4pharma-1.30.3}/aiagents4pharma/talk2scholars/configs/agents/talk2scholars/zotero_agent/__init__.py +0 -0
- {aiagents4pharma-1.30.1 → aiagents4pharma-1.30.3}/aiagents4pharma/talk2scholars/configs/app/frontend/__init__.py +0 -0
- {aiagents4pharma-1.30.1 → aiagents4pharma-1.30.3}/aiagents4pharma/talk2scholars/configs/app/frontend/default.yaml +0 -0
- {aiagents4pharma-1.30.1 → aiagents4pharma-1.30.3}/aiagents4pharma/talk2scholars/configs/config.yaml +0 -0
- {aiagents4pharma-1.30.1 → aiagents4pharma-1.30.3}/aiagents4pharma/talk2scholars/configs/tools/download_arxiv_paper/__init__.py +0 -0
- {aiagents4pharma-1.30.1 → aiagents4pharma-1.30.3}/aiagents4pharma/talk2scholars/configs/tools/multi_paper_recommendation/__init__.py +0 -0
- {aiagents4pharma-1.30.1 → aiagents4pharma-1.30.3}/aiagents4pharma/talk2scholars/configs/tools/multi_paper_recommendation/default.yaml +0 -0
- {aiagents4pharma-1.30.1 → aiagents4pharma-1.30.3}/aiagents4pharma/talk2scholars/configs/tools/question_and_answer/__init__.py +0 -0
- {aiagents4pharma-1.30.1 → aiagents4pharma-1.30.3}/aiagents4pharma/talk2scholars/configs/tools/retrieve_semantic_scholar_paper_id/__init__.py +0 -0
- {aiagents4pharma-1.30.1 → aiagents4pharma-1.30.3}/aiagents4pharma/talk2scholars/configs/tools/retrieve_semantic_scholar_paper_id/default.yaml +0 -0
- {aiagents4pharma-1.30.1 → aiagents4pharma-1.30.3}/aiagents4pharma/talk2scholars/configs/tools/search/__init__.py +0 -0
- {aiagents4pharma-1.30.1 → aiagents4pharma-1.30.3}/aiagents4pharma/talk2scholars/configs/tools/search/default.yaml +0 -0
- {aiagents4pharma-1.30.1 → aiagents4pharma-1.30.3}/aiagents4pharma/talk2scholars/configs/tools/single_paper_recommendation/__init__.py +0 -0
- {aiagents4pharma-1.30.1 → aiagents4pharma-1.30.3}/aiagents4pharma/talk2scholars/configs/tools/single_paper_recommendation/default.yaml +0 -0
- {aiagents4pharma-1.30.1 → aiagents4pharma-1.30.3}/aiagents4pharma/talk2scholars/configs/tools/zotero_read/__init__.py +0 -0
- {aiagents4pharma-1.30.1 → aiagents4pharma-1.30.3}/aiagents4pharma/talk2scholars/configs/tools/zotero_read/default.yaml +0 -0
- {aiagents4pharma-1.30.1 → aiagents4pharma-1.30.3}/aiagents4pharma/talk2scholars/configs/tools/zotero_write/__inti__.py +0 -0
- {aiagents4pharma-1.30.1 → aiagents4pharma-1.30.3}/aiagents4pharma/talk2scholars/tests/__init__.py +0 -0
- {aiagents4pharma-1.30.1 → aiagents4pharma-1.30.3}/aiagents4pharma/talk2scholars/tests/test_llm_main_integration.py +0 -0
- {aiagents4pharma-1.30.1 → aiagents4pharma-1.30.3}/aiagents4pharma/talk2scholars/tests/test_main_agent.py +0 -0
- {aiagents4pharma-1.30.1 → aiagents4pharma-1.30.3}/aiagents4pharma/talk2scholars/tests/test_paper_download_agent.py +0 -0
- {aiagents4pharma-1.30.1 → aiagents4pharma-1.30.3}/aiagents4pharma/talk2scholars/tests/test_paper_download_tools.py +0 -0
- {aiagents4pharma-1.30.1 → aiagents4pharma-1.30.3}/aiagents4pharma/talk2scholars/tests/test_pdf_agent.py +0 -0
- {aiagents4pharma-1.30.1 → aiagents4pharma-1.30.3}/aiagents4pharma/talk2scholars/tests/test_question_and_answer_tool.py +0 -0
- {aiagents4pharma-1.30.1 → aiagents4pharma-1.30.3}/aiagents4pharma/talk2scholars/tests/test_s2_agent.py +0 -0
- {aiagents4pharma-1.30.1 → aiagents4pharma-1.30.3}/aiagents4pharma/talk2scholars/tests/test_s2_display.py +0 -0
- {aiagents4pharma-1.30.1 → aiagents4pharma-1.30.3}/aiagents4pharma/talk2scholars/tests/test_s2_query.py +0 -0
- {aiagents4pharma-1.30.1 → aiagents4pharma-1.30.3}/aiagents4pharma/talk2scholars/tests/test_s2_retrieve.py +0 -0
- {aiagents4pharma-1.30.1 → aiagents4pharma-1.30.3}/aiagents4pharma/talk2scholars/tests/test_state.py +0 -0
- {aiagents4pharma-1.30.1 → aiagents4pharma-1.30.3}/aiagents4pharma/talk2scholars/tools/paper_download/__init__.py +0 -0
- {aiagents4pharma-1.30.1 → aiagents4pharma-1.30.3}/aiagents4pharma/talk2scholars/tools/paper_download/abstract_downloader.py +0 -0
- {aiagents4pharma-1.30.1 → aiagents4pharma-1.30.3}/aiagents4pharma/talk2scholars/tools/paper_download/arxiv_downloader.py +0 -0
- {aiagents4pharma-1.30.1 → aiagents4pharma-1.30.3}/aiagents4pharma/talk2scholars/tools/paper_download/download_arxiv_input.py +0 -0
- {aiagents4pharma-1.30.1 → aiagents4pharma-1.30.3}/aiagents4pharma/talk2scholars/tools/pdf/question_and_answer.py +0 -0
- {aiagents4pharma-1.30.1 → aiagents4pharma-1.30.3}/aiagents4pharma/talk2scholars/tools/s2/display_results.py +0 -0
- {aiagents4pharma-1.30.1 → aiagents4pharma-1.30.3}/aiagents4pharma/talk2scholars/tools/s2/query_results.py +0 -0
- {aiagents4pharma-1.30.1 → aiagents4pharma-1.30.3}/aiagents4pharma/talk2scholars/tools/s2/retrieve_semantic_scholar_paper_id.py +0 -0
- {aiagents4pharma-1.30.1 → aiagents4pharma-1.30.3}/aiagents4pharma.egg-info/dependency_links.txt +0 -0
- {aiagents4pharma-1.30.1 → aiagents4pharma-1.30.3}/aiagents4pharma.egg-info/requires.txt +0 -0
- {aiagents4pharma-1.30.1 → aiagents4pharma-1.30.3}/aiagents4pharma.egg-info/top_level.txt +0 -0
- {aiagents4pharma-1.30.1 → aiagents4pharma-1.30.3}/setup.cfg +0 -0
@@ -1,6 +1,6 @@
|
|
1
|
-
Metadata-Version: 2.
|
1
|
+
Metadata-Version: 2.4
|
2
2
|
Name: aiagents4pharma
|
3
|
-
Version: 1.30.
|
3
|
+
Version: 1.30.3
|
4
4
|
Summary: AI Agents for drug discovery, drug development, and other pharmaceutical R&D.
|
5
5
|
Classifier: Programming Language :: Python :: 3
|
6
6
|
Classifier: License :: OSI Approved :: MIT License
|
@@ -62,6 +62,7 @@ Requires-Dist: umap-learn==0.5.7
|
|
62
62
|
Requires-Dist: plotly-express==0.4.1
|
63
63
|
Requires-Dist: seaborn==0.13.2
|
64
64
|
Requires-Dist: scanpy==1.11.0
|
65
|
+
Dynamic: license-file
|
65
66
|
|
66
67
|
[](https://github.com/VirtualPatientEngine/AIAgents4Pharma/actions/workflows/tests_talk2biomodels.yml)
|
67
68
|
[](https://github.com/VirtualPatientEngine/AIAgents4Pharma/actions/workflows/tests_talk2cells.yml)
|
@@ -1,7 +1,7 @@
|
|
1
1
|
#!/usr/bin/env python3
|
2
2
|
|
3
3
|
"""
|
4
|
-
Agent for interacting with Zotero
|
4
|
+
Agent for interacting with Zotero with human-in-the-loop features
|
5
5
|
"""
|
6
6
|
|
7
7
|
import logging
|
@@ -13,8 +13,9 @@ from langgraph.graph import START, StateGraph
|
|
13
13
|
from langgraph.prebuilt import create_react_agent, ToolNode
|
14
14
|
from langgraph.checkpoint.memory import MemorySaver
|
15
15
|
from ..state.state_talk2scholars import Talk2Scholars
|
16
|
-
from ..tools.zotero.zotero_read import
|
17
|
-
from ..tools.zotero.
|
16
|
+
from ..tools.zotero.zotero_read import zotero_read
|
17
|
+
from ..tools.zotero.zotero_review import zotero_review
|
18
|
+
from ..tools.zotero.zotero_write import zotero_write
|
18
19
|
from ..tools.s2.display_results import display_results as s2_display
|
19
20
|
from ..tools.s2.query_results import query_results as s2_query_results
|
20
21
|
from ..tools.s2.retrieve_semantic_scholar_paper_id import (
|
@@ -32,7 +33,7 @@ def get_app(uniq_id, llm_model: BaseChatModel):
|
|
32
33
|
|
33
34
|
This function sets up the Zotero agent, which integrates various tools to search,
|
34
35
|
retrieve, and display research papers from Zotero. The agent follows the ReAct
|
35
|
-
pattern for structured interaction.
|
36
|
+
pattern for structured interaction and includes human-in-the-loop features.
|
36
37
|
|
37
38
|
Args:
|
38
39
|
uniq_id (str): Unique identifier for the current conversation session.
|
@@ -87,11 +88,12 @@ def get_app(uniq_id, llm_model: BaseChatModel):
|
|
87
88
|
# Define the tools
|
88
89
|
tools = ToolNode(
|
89
90
|
[
|
90
|
-
|
91
|
+
zotero_read,
|
91
92
|
s2_display,
|
92
93
|
s2_query_results,
|
93
94
|
retrieve_semantic_scholar_paper_id,
|
94
|
-
|
95
|
+
zotero_review, # First review
|
96
|
+
zotero_write, # Then save with user confirmation
|
95
97
|
]
|
96
98
|
)
|
97
99
|
|
@@ -104,7 +106,7 @@ def get_app(uniq_id, llm_model: BaseChatModel):
|
|
104
106
|
tools=tools,
|
105
107
|
state_schema=Talk2Scholars,
|
106
108
|
prompt=cfg.zotero_agent,
|
107
|
-
checkpointer=MemorySaver(),
|
109
|
+
checkpointer=MemorySaver(), # Required for interrupts to work
|
108
110
|
)
|
109
111
|
|
110
112
|
workflow = StateGraph(Talk2Scholars)
|
@@ -0,0 +1,13 @@
|
|
1
|
+
target: agents.zotero_agent.get_app
|
2
|
+
zotero_agent: >
|
3
|
+
You are a knowledgeable research assistant with expertise in academic literature.
|
4
|
+
Your goal is to help users find, manage, and save relevant research papers and display them.
|
5
|
+
|
6
|
+
When saving papers to Zotero:
|
7
|
+
1. First use zotero_review with the collection path.
|
8
|
+
2. Wait for user confirmation (they must say "Yes" or "Approve").
|
9
|
+
3. Use zotero_write with both the collection_path and user_confirmation and call `s2_display` tool after the papers as saved.
|
10
|
+
|
11
|
+
IMPORTANT: Human approval is required for saving papers to Zotero. Never save papers
|
12
|
+
without explicit approval from the user. Always respect the user's decision if they
|
13
|
+
choose not to save papers.
|
@@ -8,3 +8,12 @@ from . import multi_paper_recommendation
|
|
8
8
|
from . import question_and_answer
|
9
9
|
from . import zotero_read
|
10
10
|
from . import zotero_write
|
11
|
+
|
12
|
+
__all__ = [
|
13
|
+
"search",
|
14
|
+
"single_paper_recommendation",
|
15
|
+
"multi_paper_recommendation",
|
16
|
+
"question_and_answer",
|
17
|
+
"zotero_read",
|
18
|
+
"zotero_write",
|
19
|
+
]
|
@@ -0,0 +1,55 @@
|
|
1
|
+
# Default configuration for Zotero search tool
|
2
|
+
library_type: "user" # Type of library ('user' or 'group')
|
3
|
+
default_limit: 2
|
4
|
+
request_timeout: 10
|
5
|
+
user_id: ${oc.env:ZOTERO_USER_ID} # Load from environment variable
|
6
|
+
api_key: ${oc.env:ZOTERO_API_KEY} # Load from environment variable
|
7
|
+
|
8
|
+
# Default search parameters
|
9
|
+
search_params:
|
10
|
+
limit: ${.default_limit}
|
11
|
+
|
12
|
+
# Item Types and Limit
|
13
|
+
zotero:
|
14
|
+
max_limit: 100
|
15
|
+
filter_item_types:
|
16
|
+
[
|
17
|
+
"Artwork",
|
18
|
+
"Audio Recording",
|
19
|
+
"Bill",
|
20
|
+
"Blog Post",
|
21
|
+
"Book",
|
22
|
+
"Book Section",
|
23
|
+
"Case",
|
24
|
+
"Conference Paper",
|
25
|
+
"Dataset",
|
26
|
+
"Dictionary Entry",
|
27
|
+
"Document",
|
28
|
+
"E-mail",
|
29
|
+
"Encyclopedia Article",
|
30
|
+
"Film",
|
31
|
+
"Forum Post",
|
32
|
+
"Hearing",
|
33
|
+
"Instant Message",
|
34
|
+
"Interview",
|
35
|
+
"Journal Article",
|
36
|
+
"Letter",
|
37
|
+
"Magazine Article",
|
38
|
+
"Manuscript",
|
39
|
+
"Map",
|
40
|
+
"Newspaper Article",
|
41
|
+
"Patent",
|
42
|
+
"Podcast",
|
43
|
+
"Preprint",
|
44
|
+
"Presentation",
|
45
|
+
"Radio Broadcast",
|
46
|
+
"Report",
|
47
|
+
"Software",
|
48
|
+
"Standard",
|
49
|
+
"Statute",
|
50
|
+
"Thesis",
|
51
|
+
"TV Broadcast",
|
52
|
+
"Video Recording",
|
53
|
+
"Web Page",
|
54
|
+
]
|
55
|
+
# filter_excluded_types: ["attachment", "note", "annotation"]
|
@@ -54,6 +54,8 @@ class Talk2Scholars(AgentState):
|
|
54
54
|
papers (Dict[str, Any]): Stores the research papers retrieved from the agent's queries.
|
55
55
|
multi_papers (Dict[str, Any]): Stores multiple recommended papers from various sources.
|
56
56
|
zotero_read (Dict[str, Any]): Stores the papers retrieved from Zotero.
|
57
|
+
zotero_write_approval_status (Dict[str, Any]): Stores the approval status and collection
|
58
|
+
path for Zotero save operations.
|
57
59
|
llm_model (BaseChatModel): The language model instance used for generating responses.
|
58
60
|
text_embedding_model (Embeddings): The text embedding model used for
|
59
61
|
similarity calculations.
|
@@ -65,5 +67,6 @@ class Talk2Scholars(AgentState):
|
|
65
67
|
multi_papers: Annotated[Dict[str, Any], replace_dict]
|
66
68
|
pdf_data: Annotated[Dict[str, Any], replace_dict]
|
67
69
|
zotero_read: Annotated[Dict[str, Any], replace_dict]
|
70
|
+
zotero_write_approval_status: Annotated[Dict[str, Any], replace_dict]
|
68
71
|
llm_model: BaseChatModel
|
69
72
|
text_embedding_model: Embeddings
|
@@ -22,6 +22,7 @@ def mock_router():
|
|
22
22
|
"""Creates a mock supervisor router that routes based on keyword matching."""
|
23
23
|
|
24
24
|
def mock_supervisor_node(state):
|
25
|
+
"""Mock supervisor node that routes based on keyword matching."""
|
25
26
|
query = state["messages"][-1].content.lower()
|
26
27
|
# Define keywords for each sub-agent.
|
27
28
|
s2_keywords = [
|
@@ -70,6 +71,4 @@ def test_routing_logic(mock_state, mock_router, user_query, expected_agent):
|
|
70
71
|
mock_state["messages"].append(HumanMessage(content=user_query))
|
71
72
|
result = mock_router(mock_state)
|
72
73
|
|
73
|
-
print(f"\nDEBUG: Query '{user_query}' routed to: {result.goto}")
|
74
|
-
|
75
74
|
assert result.goto == expected_agent, f"Failed for query: {user_query}"
|
@@ -12,6 +12,7 @@ import hydra
|
|
12
12
|
from aiagents4pharma.talk2scholars.tools.s2.multi_paper_rec import (
|
13
13
|
get_multi_paper_recommendations,
|
14
14
|
)
|
15
|
+
from aiagents4pharma.talk2scholars.tools.s2.utils import multi_helper
|
15
16
|
|
16
17
|
# --- Dummy Hydra Config Setup ---
|
17
18
|
|
@@ -285,20 +286,21 @@ def test_multi_paper_rec_requests_exception(monkeypatch):
|
|
285
286
|
|
286
287
|
def test_multi_paper_rec_no_response(monkeypatch):
|
287
288
|
"""
|
288
|
-
Test that get_multi_paper_recommendations raises a RuntimeError
|
289
|
-
This is simulated by patching 'range'
|
290
|
-
return an empty iterator,
|
291
|
-
so that the for loop
|
289
|
+
Test that get_multi_paper_recommendations raises a RuntimeError
|
290
|
+
when no response is obtained. This is simulated by patching 'range'
|
291
|
+
in the module namespace of multi_helper to return an empty iterator,
|
292
|
+
so that the for loop in _fetch_recommendations never iterates and
|
293
|
+
self.response remains None.
|
292
294
|
"""
|
293
|
-
#
|
294
|
-
monkeypatch.setitem(
|
295
|
-
|
296
|
-
)
|
295
|
+
# Inject a patched 'range' into the multi_helper module's dictionary.
|
296
|
+
monkeypatch.setitem(multi_helper.__dict__, "range", lambda x: iter([]))
|
297
|
+
|
297
298
|
tool_call_id = "test_tool_call_id"
|
298
299
|
input_data = {
|
299
300
|
"paper_ids": ["p1", "p2"],
|
300
301
|
"tool_call_id": tool_call_id,
|
301
302
|
}
|
303
|
+
|
302
304
|
with pytest.raises(
|
303
305
|
RuntimeError, match="Failed to obtain a response from the Semantic Scholar API."
|
304
306
|
):
|
@@ -9,6 +9,7 @@ import requests
|
|
9
9
|
from langgraph.types import Command
|
10
10
|
from langchain_core.messages import ToolMessage
|
11
11
|
from aiagents4pharma.talk2scholars.tools.s2.search import search_tool
|
12
|
+
from aiagents4pharma.talk2scholars.tools.s2.utils import search_helper
|
12
13
|
|
13
14
|
# --- Dummy Hydra Config Setup ---
|
14
15
|
|
@@ -269,12 +270,15 @@ def test_search_tool_requests_exception(monkeypatch):
|
|
269
270
|
|
270
271
|
def test_search_tool_no_response(monkeypatch):
|
271
272
|
"""
|
272
|
-
Test that search_tool raises a RuntimeError when no response
|
273
|
-
This is simulated by patching 'range' in the
|
274
|
-
|
273
|
+
Test that search_tool raises a RuntimeError when no response
|
274
|
+
is obtained. This is simulated by patching 'range' in the
|
275
|
+
module namespace of search_helper to return an empty iterator,
|
276
|
+
so that the for-loop in _fetch_papers never iterates and self.response
|
277
|
+
remains None.
|
275
278
|
"""
|
276
|
-
# Patch 'range' in the
|
277
|
-
monkeypatch.setitem(
|
279
|
+
# Patch 'range' in the module globals of search_helper.
|
280
|
+
monkeypatch.setitem(search_helper.__dict__, "range", lambda x: iter([]))
|
281
|
+
|
278
282
|
tool_call_id = "test_tool_call_id"
|
279
283
|
with pytest.raises(
|
280
284
|
RuntimeError, match="Failed to obtain a response from the Semantic Scholar API."
|
@@ -11,6 +11,7 @@ from langchain_core.messages import ToolMessage
|
|
11
11
|
from aiagents4pharma.talk2scholars.tools.s2.single_paper_rec import (
|
12
12
|
get_single_paper_recommendations,
|
13
13
|
)
|
14
|
+
from aiagents4pharma.talk2scholars.tools.s2.utils import single_helper
|
14
15
|
|
15
16
|
# --- Dummy Hydra Config Setup ---
|
16
17
|
|
@@ -279,14 +280,13 @@ def test_single_paper_rec_no_response(monkeypatch):
|
|
279
280
|
"""
|
280
281
|
Test that get_single_paper_recommendations raises a RuntimeError
|
281
282
|
when no response is obtained from the API.
|
282
|
-
|
283
|
-
|
284
|
-
|
283
|
+
This is simulated by patching 'range' in the module namespace
|
284
|
+
of single_helper to return an empty iterator, so that the for-loop
|
285
|
+
in _fetch_recommendations never iterates and response remains None.
|
285
286
|
"""
|
286
|
-
# Patch 'range' in the
|
287
|
-
monkeypatch.setitem(
|
288
|
-
|
289
|
-
)
|
287
|
+
# Patch 'range' in the module globals of single_helper.
|
288
|
+
monkeypatch.setitem(single_helper.__dict__, "range", lambda x: iter([]))
|
289
|
+
|
290
290
|
tool_call_id = "test_tool_call_id"
|
291
291
|
input_data = {
|
292
292
|
"paper_id": "12345",
|
@@ -10,7 +10,8 @@ from langchain_openai import ChatOpenAI
|
|
10
10
|
from ..agents.zotero_agent import get_app
|
11
11
|
from ..state.state_talk2scholars import Talk2Scholars
|
12
12
|
|
13
|
-
LLM_MODEL = ChatOpenAI(model=
|
13
|
+
LLM_MODEL = ChatOpenAI(model="gpt-4o-mini", temperature=0)
|
14
|
+
|
14
15
|
|
15
16
|
@pytest.fixture(autouse=True)
|
16
17
|
def mock_hydra_fixture():
|
@@ -39,7 +40,7 @@ def mock_tools_fixture():
|
|
39
40
|
"retrieve_semantic_scholar_paper_id"
|
40
41
|
) as mock_s2_retrieve_id,
|
41
42
|
mock.patch(
|
42
|
-
"aiagents4pharma.talk2scholars.tools.zotero.zotero_read.
|
43
|
+
"aiagents4pharma.talk2scholars.tools.zotero.zotero_read.zotero_read"
|
43
44
|
) as mock_zotero_query_results,
|
44
45
|
):
|
45
46
|
mock_s2_display.return_value = {"result": "Mock Display Result"}
|
@@ -0,0 +1,273 @@
|
|
1
|
+
"""
|
2
|
+
Unit tests for Zotero human in the loop in zotero_review.py with structured output.
|
3
|
+
"""
|
4
|
+
|
5
|
+
import unittest
|
6
|
+
from unittest.mock import patch, MagicMock
|
7
|
+
from aiagents4pharma.talk2scholars.tools.zotero.zotero_review import zotero_review
|
8
|
+
|
9
|
+
|
10
|
+
class TestZoteroReviewTool(unittest.TestCase):
|
11
|
+
"""Test class for Zotero review tool with structured LLM output."""
|
12
|
+
|
13
|
+
def setUp(self):
|
14
|
+
self.tool_call_id = "tc"
|
15
|
+
self.collection_path = "/Col"
|
16
|
+
# Create a sample fetched papers dictionary with one paper.
|
17
|
+
self.sample_papers = {"p1": {"Title": "T1", "Authors": ["A1", "A2", "A3"]}}
|
18
|
+
|
19
|
+
@patch(
|
20
|
+
"aiagents4pharma.talk2scholars.tools.zotero.zotero_review.fetch_papers_for_save",
|
21
|
+
return_value=None,
|
22
|
+
)
|
23
|
+
def test_no_fetched_papers(self, mock_fetch):
|
24
|
+
"""Test when no fetched papers are found."""
|
25
|
+
with self.assertRaises(ValueError) as context:
|
26
|
+
zotero_review.run(
|
27
|
+
{
|
28
|
+
"tool_call_id": self.tool_call_id,
|
29
|
+
"collection_path": self.collection_path,
|
30
|
+
"state": {},
|
31
|
+
}
|
32
|
+
)
|
33
|
+
self.assertIn("No fetched papers were found to save", str(context.exception))
|
34
|
+
mock_fetch.assert_called_once()
|
35
|
+
|
36
|
+
@patch(
|
37
|
+
"aiagents4pharma.talk2scholars.tools.zotero.zotero_review.fetch_papers_for_save",
|
38
|
+
return_value={"p1": {"Title": "T1", "Authors": ["A1", "A2"]}},
|
39
|
+
)
|
40
|
+
@patch(
|
41
|
+
"aiagents4pharma.talk2scholars.tools.zotero.zotero_review.interrupt",
|
42
|
+
return_value="dummy_response",
|
43
|
+
)
|
44
|
+
def test_missing_llm_model(self, mock_interrupt, mock_fetch):
|
45
|
+
"""Test when LLM model is not available in state, expecting fallback confirmation."""
|
46
|
+
state = {"last_displayed_papers": self.sample_papers} # llm_model missing
|
47
|
+
result = zotero_review.run(
|
48
|
+
{
|
49
|
+
"tool_call_id": self.tool_call_id,
|
50
|
+
"collection_path": self.collection_path,
|
51
|
+
"state": state,
|
52
|
+
}
|
53
|
+
)
|
54
|
+
upd = result.update
|
55
|
+
# The fallback message should start with "REVIEW REQUIRED:"
|
56
|
+
self.assertTrue(upd["messages"][0].content.startswith("REVIEW REQUIRED:"))
|
57
|
+
# Check that the approval status is set as fallback values.
|
58
|
+
approval = upd["zotero_write_approval_status"]
|
59
|
+
self.assertEqual(approval["collection_path"], self.collection_path)
|
60
|
+
self.assertTrue(approval["papers_reviewed"])
|
61
|
+
self.assertFalse(approval["approved"])
|
62
|
+
self.assertEqual(approval["papers_count"], len(self.sample_papers))
|
63
|
+
mock_fetch.assert_called_once()
|
64
|
+
mock_interrupt.assert_called_once()
|
65
|
+
|
66
|
+
@patch(
|
67
|
+
"aiagents4pharma.talk2scholars.tools.zotero.zotero_review.fetch_papers_for_save",
|
68
|
+
return_value={"p1": {"Title": "T1", "Authors": ["A1", "A2"]}},
|
69
|
+
)
|
70
|
+
@patch(
|
71
|
+
"aiagents4pharma.talk2scholars.tools.zotero.zotero_review.interrupt",
|
72
|
+
return_value="dummy_response",
|
73
|
+
)
|
74
|
+
def test_human_approve(self, mock_interrupt, mock_fetch):
|
75
|
+
"""Test when human approves saving papers using structured output."""
|
76
|
+
# Prepare a fake llm_model with structured output.
|
77
|
+
fake_structured_llm = MagicMock()
|
78
|
+
# Simulate invoke() returns an object with decision "approve"
|
79
|
+
fake_decision = MagicMock()
|
80
|
+
fake_decision.decision = "approve"
|
81
|
+
fake_structured_llm.invoke.return_value = fake_decision
|
82
|
+
|
83
|
+
fake_llm_model = MagicMock()
|
84
|
+
fake_llm_model.with_structured_output.return_value = fake_structured_llm
|
85
|
+
|
86
|
+
state = {
|
87
|
+
"last_displayed_papers": self.sample_papers,
|
88
|
+
"llm_model": fake_llm_model,
|
89
|
+
}
|
90
|
+
|
91
|
+
result = zotero_review.run(
|
92
|
+
{
|
93
|
+
"tool_call_id": self.tool_call_id,
|
94
|
+
"collection_path": self.collection_path,
|
95
|
+
"state": state,
|
96
|
+
}
|
97
|
+
)
|
98
|
+
|
99
|
+
upd = result.update
|
100
|
+
self.assertEqual(
|
101
|
+
upd["zotero_write_approval_status"],
|
102
|
+
{"collection_path": self.collection_path, "approved": True},
|
103
|
+
)
|
104
|
+
self.assertIn(
|
105
|
+
f"Human approved saving 1 papers to Zotero collection '{self.collection_path}'",
|
106
|
+
upd["messages"][0].content,
|
107
|
+
)
|
108
|
+
mock_fetch.assert_called_once()
|
109
|
+
mock_interrupt.assert_called_once()
|
110
|
+
|
111
|
+
@patch(
|
112
|
+
"aiagents4pharma.talk2scholars.tools.zotero.zotero_review.fetch_papers_for_save",
|
113
|
+
return_value={"p1": {"Title": "T1", "Authors": ["A1", "A2"]}},
|
114
|
+
)
|
115
|
+
@patch(
|
116
|
+
"aiagents4pharma.talk2scholars.tools.zotero.zotero_review.interrupt",
|
117
|
+
return_value="dummy_response",
|
118
|
+
)
|
119
|
+
def test_human_approve_custom(self, mock_interrupt, mock_fetch):
|
120
|
+
"""Test when human approves with a custom collection path."""
|
121
|
+
fake_structured_llm = MagicMock()
|
122
|
+
fake_decision = MagicMock()
|
123
|
+
fake_decision.decision = "custom"
|
124
|
+
fake_decision.custom_path = "/Custom"
|
125
|
+
fake_structured_llm.invoke.return_value = fake_decision
|
126
|
+
|
127
|
+
fake_llm_model = MagicMock()
|
128
|
+
fake_llm_model.with_structured_output.return_value = fake_structured_llm
|
129
|
+
|
130
|
+
state = {
|
131
|
+
"last_displayed_papers": self.sample_papers,
|
132
|
+
"llm_model": fake_llm_model,
|
133
|
+
}
|
134
|
+
|
135
|
+
result = zotero_review.run(
|
136
|
+
{
|
137
|
+
"tool_call_id": self.tool_call_id,
|
138
|
+
"collection_path": self.collection_path,
|
139
|
+
"state": state,
|
140
|
+
}
|
141
|
+
)
|
142
|
+
|
143
|
+
upd = result.update
|
144
|
+
self.assertEqual(
|
145
|
+
upd["zotero_write_approval_status"],
|
146
|
+
{"collection_path": "/Custom", "approved": True},
|
147
|
+
)
|
148
|
+
self.assertIn(
|
149
|
+
"Human approved saving papers to custom Zotero collection '/Custom'",
|
150
|
+
upd["messages"][0].content,
|
151
|
+
)
|
152
|
+
mock_fetch.assert_called_once()
|
153
|
+
mock_interrupt.assert_called_once()
|
154
|
+
|
155
|
+
@patch(
|
156
|
+
"aiagents4pharma.talk2scholars.tools.zotero.zotero_review.fetch_papers_for_save",
|
157
|
+
return_value={"p1": {"Title": "T1", "Authors": ["A1", "A2"]}},
|
158
|
+
)
|
159
|
+
@patch(
|
160
|
+
"aiagents4pharma.talk2scholars.tools.zotero.zotero_review.interrupt",
|
161
|
+
return_value="dummy_response",
|
162
|
+
)
|
163
|
+
def test_human_reject(self, mock_interrupt, mock_fetch):
|
164
|
+
"""Test when human rejects saving papers via structured output."""
|
165
|
+
fake_structured_llm = MagicMock()
|
166
|
+
fake_decision = MagicMock()
|
167
|
+
fake_decision.decision = "reject"
|
168
|
+
fake_structured_llm.invoke.return_value = fake_decision
|
169
|
+
|
170
|
+
fake_llm_model = MagicMock()
|
171
|
+
fake_llm_model.with_structured_output.return_value = fake_structured_llm
|
172
|
+
|
173
|
+
state = {
|
174
|
+
"last_displayed_papers": self.sample_papers,
|
175
|
+
"llm_model": fake_llm_model,
|
176
|
+
}
|
177
|
+
|
178
|
+
result = zotero_review.run(
|
179
|
+
{
|
180
|
+
"tool_call_id": self.tool_call_id,
|
181
|
+
"collection_path": self.collection_path,
|
182
|
+
"state": state,
|
183
|
+
}
|
184
|
+
)
|
185
|
+
|
186
|
+
upd = result.update
|
187
|
+
self.assertEqual(upd["zotero_write_approval_status"], {"approved": False})
|
188
|
+
self.assertIn(
|
189
|
+
"Human rejected saving papers to Zotero", upd["messages"][0].content
|
190
|
+
)
|
191
|
+
mock_fetch.assert_called_once()
|
192
|
+
mock_interrupt.assert_called_once()
|
193
|
+
|
194
|
+
@patch(
|
195
|
+
"aiagents4pharma.talk2scholars.tools.zotero.zotero_review.fetch_papers_for_save"
|
196
|
+
)
|
197
|
+
@patch("aiagents4pharma.talk2scholars.tools.zotero.zotero_review.interrupt")
|
198
|
+
def test_structured_processing_failure(self, mock_interrupt, mock_fetch):
|
199
|
+
"""Test fallback when structured review processing fails."""
|
200
|
+
# Simulate valid fetched papers with multiple entries.
|
201
|
+
papers = {
|
202
|
+
f"p{i}": {"Title": f"Title{i}", "Authors": [f"A{i}"]} for i in range(1, 8)
|
203
|
+
}
|
204
|
+
mock_fetch.return_value = papers
|
205
|
+
mock_interrupt.return_value = "dummy_response"
|
206
|
+
# Provide a fake llm_model whose invoke() raises an exception.
|
207
|
+
fake_structured_llm = MagicMock()
|
208
|
+
fake_structured_llm.invoke.side_effect = Exception("structured error")
|
209
|
+
fake_llm_model = MagicMock()
|
210
|
+
fake_llm_model.with_structured_output.return_value = fake_structured_llm
|
211
|
+
|
212
|
+
state = {"last_displayed_papers": papers, "llm_model": fake_llm_model}
|
213
|
+
|
214
|
+
result = zotero_review.run(
|
215
|
+
{
|
216
|
+
"tool_call_id": self.tool_call_id,
|
217
|
+
"collection_path": "/MyCol",
|
218
|
+
"state": state,
|
219
|
+
}
|
220
|
+
)
|
221
|
+
|
222
|
+
upd = result.update
|
223
|
+
content = upd["messages"][0].content
|
224
|
+
# The fallback message should start with "REVIEW REQUIRED:".
|
225
|
+
self.assertTrue(content.startswith("REVIEW REQUIRED:"))
|
226
|
+
self.assertIn("Would you like to save 7 papers", content)
|
227
|
+
self.assertIn("... and 2 more papers", content)
|
228
|
+
|
229
|
+
approved = upd["zotero_write_approval_status"]
|
230
|
+
self.assertEqual(approved["collection_path"], "/MyCol")
|
231
|
+
self.assertTrue(approved["papers_reviewed"])
|
232
|
+
self.assertFalse(approved["approved"])
|
233
|
+
self.assertEqual(approved["papers_count"], 7)
|
234
|
+
|
235
|
+
@patch(
|
236
|
+
"aiagents4pharma.talk2scholars.tools.zotero.zotero_review.fetch_papers_for_save",
|
237
|
+
return_value={
|
238
|
+
"p1": {"Title": "Test Paper", "Authors": ["Alice", "Bob", "Charlie"]}
|
239
|
+
},
|
240
|
+
)
|
241
|
+
@patch(
|
242
|
+
"aiagents4pharma.talk2scholars.tools.zotero.zotero_review.interrupt",
|
243
|
+
return_value="dummy_response",
|
244
|
+
)
|
245
|
+
def test_authors_et_al_in_summary(self, mock_interrupt, mock_fetch):
|
246
|
+
"""
|
247
|
+
Test that the papers summary includes 'et al.' when a paper has more than two authors.
|
248
|
+
This is achieved by forcing a fallback (structured processing failure) so that the fallback
|
249
|
+
message with the papers summary is generated.
|
250
|
+
"""
|
251
|
+
# Create a fake llm_model whose structured output processing fails.
|
252
|
+
fake_structured_llm = MagicMock()
|
253
|
+
fake_structured_llm.invoke.side_effect = Exception("structured error")
|
254
|
+
fake_llm_model = MagicMock()
|
255
|
+
fake_llm_model.with_structured_output.return_value = fake_structured_llm
|
256
|
+
|
257
|
+
state = {
|
258
|
+
"last_displayed_papers": {
|
259
|
+
"p1": {"Title": "Test Paper", "Authors": ["Alice", "Bob", "Charlie"]}
|
260
|
+
},
|
261
|
+
"llm_model": fake_llm_model,
|
262
|
+
}
|
263
|
+
result = zotero_review.run(
|
264
|
+
{
|
265
|
+
"tool_call_id": self.tool_call_id,
|
266
|
+
"collection_path": self.collection_path,
|
267
|
+
"state": state,
|
268
|
+
}
|
269
|
+
)
|
270
|
+
fallback_message = result.update["messages"][0].content
|
271
|
+
self.assertIn("et al.", fallback_message)
|
272
|
+
mock_fetch.assert_called_once()
|
273
|
+
mock_interrupt.assert_called_once()
|