aiagents4pharma 1.16.0__py3-none-any.whl → 1.17.1__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- aiagents4pharma/__init__.py +0 -1
- aiagents4pharma/talk2biomodels/__init__.py +1 -0
- aiagents4pharma/talk2biomodels/agents/t2b_agent.py +3 -3
- aiagents4pharma/{configs/talk2biomodels → talk2biomodels/configs}/agents/t2b_agent/default.yaml +1 -1
- aiagents4pharma/{configs/talk2biomodels → talk2biomodels/configs}/tools/ask_question/default.yaml +1 -1
- aiagents4pharma/{configs/talk2biomodels → talk2biomodels/configs}/tools/get_annotation/default.yaml +1 -1
- aiagents4pharma/talk2biomodels/tools/ask_question.py +5 -4
- aiagents4pharma/talk2biomodels/tools/get_annotation.py +3 -3
- aiagents4pharma/talk2biomodels/tools/search_models.py +1 -1
- aiagents4pharma/talk2scholars/__init__.py +1 -1
- aiagents4pharma/talk2scholars/agents/main_agent.py +36 -15
- aiagents4pharma/talk2scholars/agents/s2_agent.py +38 -29
- aiagents4pharma/talk2scholars/{config → configs}/__init__.py +3 -1
- aiagents4pharma/{configs → talk2scholars/configs/agents}/__init__.py +3 -3
- aiagents4pharma/talk2scholars/configs/agents/talk2scholars/__init__.py +6 -0
- aiagents4pharma/talk2scholars/configs/agents/talk2scholars/main_agent/__init__.py +3 -0
- aiagents4pharma/talk2scholars/configs/agents/talk2scholars/main_agent/default.yaml +39 -0
- aiagents4pharma/talk2scholars/configs/agents/talk2scholars/s2_agent/__init__.py +3 -0
- aiagents4pharma/talk2scholars/configs/agents/talk2scholars/s2_agent/default.yaml +68 -0
- aiagents4pharma/talk2scholars/configs/app/__init__.py +5 -0
- aiagents4pharma/talk2scholars/configs/app/frontend/__init__.py +3 -0
- aiagents4pharma/talk2scholars/configs/app/frontend/default.yaml +33 -0
- aiagents4pharma/talk2scholars/configs/config.yaml +8 -0
- aiagents4pharma/talk2scholars/configs/tools/__init__.py +7 -0
- aiagents4pharma/talk2scholars/configs/tools/multi_paper_recommendation/__init__.py +3 -0
- aiagents4pharma/talk2scholars/configs/tools/multi_paper_recommendation/default.yaml +19 -0
- aiagents4pharma/talk2scholars/configs/tools/search/__init__.py +3 -0
- aiagents4pharma/talk2scholars/configs/tools/search/default.yaml +19 -0
- aiagents4pharma/talk2scholars/configs/tools/single_paper_recommendation/__init__.py +3 -0
- aiagents4pharma/talk2scholars/configs/tools/single_paper_recommendation/default.yaml +20 -0
- aiagents4pharma/talk2scholars/tests/test_langgraph.py +71 -54
- aiagents4pharma/talk2scholars/tools/s2/multi_paper_rec.py +13 -5
- aiagents4pharma/talk2scholars/tools/s2/search.py +9 -3
- aiagents4pharma/talk2scholars/tools/s2/single_paper_rec.py +13 -7
- aiagents4pharma-1.17.1.dist-info/METADATA +150 -0
- {aiagents4pharma-1.16.0.dist-info → aiagents4pharma-1.17.1.dist-info}/RECORD +45 -31
- aiagents4pharma/configs/config.yaml +0 -5
- aiagents4pharma/talk2scholars/config/config.py +0 -110
- aiagents4pharma-1.16.0.dist-info/METADATA +0 -212
- /aiagents4pharma/{configs/talk2biomodels → talk2biomodels/configs}/__init__.py +0 -0
- /aiagents4pharma/{configs/talk2biomodels → talk2biomodels/configs}/agents/__init__.py +0 -0
- /aiagents4pharma/{configs/talk2biomodels → talk2biomodels/configs}/agents/t2b_agent/__init__.py +0 -0
- /aiagents4pharma/{configs/talk2biomodels → talk2biomodels/configs}/tools/__init__.py +0 -0
- /aiagents4pharma/{configs/talk2biomodels → talk2biomodels/configs}/tools/ask_question/__init__.py +0 -0
- /aiagents4pharma/{configs/talk2biomodels → talk2biomodels/configs}/tools/get_annotation/__init__.py +0 -0
- {aiagents4pharma-1.16.0.dist-info → aiagents4pharma-1.17.1.dist-info}/LICENSE +0 -0
- {aiagents4pharma-1.16.0.dist-info → aiagents4pharma-1.17.1.dist-info}/WHEEL +0 -0
- {aiagents4pharma-1.16.0.dist-info → aiagents4pharma-1.17.1.dist-info}/top_level.txt +0 -0
@@ -5,12 +5,14 @@ Tests are deterministic and independent of each other.
|
|
5
5
|
"""
|
6
6
|
|
7
7
|
from unittest.mock import Mock, patch
|
8
|
-
|
9
8
|
import pytest
|
10
9
|
from langchain_core.messages import AIMessage, HumanMessage
|
10
|
+
import hydra
|
11
|
+
from hydra.core.global_hydra import GlobalHydra
|
12
|
+
from omegaconf import DictConfig, OmegaConf
|
11
13
|
|
12
14
|
from ..agents.main_agent import get_app, make_supervisor_node
|
13
|
-
from ..state.state_talk2scholars import replace_dict
|
15
|
+
from ..state.state_talk2scholars import replace_dict, Talk2Scholars
|
14
16
|
from ..tools.s2.display_results import display_results
|
15
17
|
from ..tools.s2.multi_paper_rec import get_multi_paper_recommendations
|
16
18
|
from ..tools.s2.search import search_tool
|
@@ -18,6 +20,42 @@ from ..tools.s2.single_paper_rec import get_single_paper_recommendations
|
|
18
20
|
|
19
21
|
# pylint: disable=redefined-outer-name
|
20
22
|
|
23
|
+
|
24
|
+
@pytest.fixture(autouse=True)
|
25
|
+
def hydra_setup():
|
26
|
+
"""Setup and cleanup Hydra for tests."""
|
27
|
+
GlobalHydra.instance().clear()
|
28
|
+
with hydra.initialize(version_base=None, config_path="../configs"):
|
29
|
+
yield
|
30
|
+
|
31
|
+
|
32
|
+
@pytest.fixture
|
33
|
+
def mock_cfg() -> DictConfig:
|
34
|
+
"""Create a mock configuration for testing."""
|
35
|
+
config = {
|
36
|
+
"agents": {
|
37
|
+
"talk2scholars": {
|
38
|
+
"main_agent": {
|
39
|
+
"state_modifier": "Test prompt for main agent",
|
40
|
+
"temperature": 0,
|
41
|
+
},
|
42
|
+
"s2_agent": {
|
43
|
+
"temperature": 0,
|
44
|
+
"s2_agent": "Test prompt for s2 agent",
|
45
|
+
},
|
46
|
+
}
|
47
|
+
},
|
48
|
+
"tools": {
|
49
|
+
"search": {
|
50
|
+
"api_endpoint": "https://api.semanticscholar.org/graph/v1/paper/search",
|
51
|
+
"default_limit": 2,
|
52
|
+
"api_fields": ["paperId", "title", "abstract", "year", "authors"],
|
53
|
+
}
|
54
|
+
},
|
55
|
+
}
|
56
|
+
return OmegaConf.create(config)
|
57
|
+
|
58
|
+
|
21
59
|
# Fixed test data for deterministic results
|
22
60
|
MOCK_SEARCH_RESPONSE = {
|
23
61
|
"data": [
|
@@ -45,27 +83,33 @@ MOCK_STATE_PAPER = {
|
|
45
83
|
|
46
84
|
|
47
85
|
@pytest.fixture
|
48
|
-
def initial_state():
|
86
|
+
def initial_state() -> Talk2Scholars:
|
49
87
|
"""Create a base state for tests"""
|
50
|
-
return
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
88
|
+
return Talk2Scholars(
|
89
|
+
messages=[],
|
90
|
+
papers={},
|
91
|
+
is_last_step=False,
|
92
|
+
current_agent=None,
|
93
|
+
llm_model="gpt-4o-mini",
|
94
|
+
next="",
|
95
|
+
)
|
57
96
|
|
58
97
|
|
59
98
|
class TestMainAgent:
|
60
99
|
"""Unit tests for main agent functionality"""
|
61
100
|
|
62
|
-
def test_supervisor_routes_search_to_s2(
|
101
|
+
def test_supervisor_routes_search_to_s2(
|
102
|
+
self, initial_state: Talk2Scholars, mock_cfg
|
103
|
+
):
|
63
104
|
"""Verifies that search-related queries are routed to S2 agent"""
|
64
105
|
llm_mock = Mock()
|
65
106
|
llm_mock.invoke.return_value = AIMessage(content="Search initiated")
|
66
107
|
|
67
|
-
|
68
|
-
|
108
|
+
# Extract the main_agent config
|
109
|
+
supervisor = make_supervisor_node(
|
110
|
+
llm_mock, mock_cfg.agents.talk2scholars.main_agent
|
111
|
+
)
|
112
|
+
state = initial_state
|
69
113
|
state["messages"] = [HumanMessage(content="search for papers")]
|
70
114
|
|
71
115
|
result = supervisor(state)
|
@@ -73,13 +117,18 @@ class TestMainAgent:
|
|
73
117
|
assert not result.update["is_last_step"]
|
74
118
|
assert result.update["current_agent"] == "s2_agent"
|
75
119
|
|
76
|
-
def test_supervisor_routes_general_to_end(
|
120
|
+
def test_supervisor_routes_general_to_end(
|
121
|
+
self, initial_state: Talk2Scholars, mock_cfg
|
122
|
+
):
|
77
123
|
"""Verifies that non-search queries end the conversation"""
|
78
124
|
llm_mock = Mock()
|
79
125
|
llm_mock.invoke.return_value = AIMessage(content="General response")
|
80
126
|
|
81
|
-
|
82
|
-
|
127
|
+
# Extract the main_agent config
|
128
|
+
supervisor = make_supervisor_node(
|
129
|
+
llm_mock, mock_cfg.agents.talk2scholars.main_agent
|
130
|
+
)
|
131
|
+
state = initial_state
|
83
132
|
state["messages"] = [HumanMessage(content="What is ML?")]
|
84
133
|
|
85
134
|
result = supervisor(state)
|
@@ -90,9 +139,9 @@ class TestMainAgent:
|
|
90
139
|
class TestS2Tools:
|
91
140
|
"""Unit tests for individual S2 tools"""
|
92
141
|
|
93
|
-
def test_display_results_shows_papers(self, initial_state):
|
142
|
+
def test_display_results_shows_papers(self, initial_state: Talk2Scholars):
|
94
143
|
"""Verifies display_results tool correctly returns papers from state"""
|
95
|
-
state = initial_state
|
144
|
+
state = initial_state
|
96
145
|
state["papers"] = MOCK_STATE_PAPER
|
97
146
|
result = display_results.invoke(input={"state": state})
|
98
147
|
assert result == MOCK_STATE_PAPER
|
@@ -199,40 +248,6 @@ class TestS2Tools:
|
|
199
248
|
assert "papers" in result.update
|
200
249
|
assert len(result.update["messages"]) == 1
|
201
250
|
|
202
|
-
@patch("requests.get")
|
203
|
-
def test_single_paper_rec_empty_response(self, mock_get):
|
204
|
-
"""Tests single paper recommendations with empty response"""
|
205
|
-
mock_get.return_value.json.return_value = {"recommendedPapers": []}
|
206
|
-
mock_get.return_value.status_code = 200
|
207
|
-
|
208
|
-
result = get_single_paper_recommendations.invoke(
|
209
|
-
input={
|
210
|
-
"paper_id": "123",
|
211
|
-
"limit": 1,
|
212
|
-
"tool_call_id": "test123",
|
213
|
-
"id": "test123",
|
214
|
-
}
|
215
|
-
)
|
216
|
-
assert "papers" in result.update
|
217
|
-
assert len(result.update["papers"]) == 0
|
218
|
-
|
219
|
-
@patch("requests.post")
|
220
|
-
def test_multi_paper_rec_empty_response(self, mock_post):
|
221
|
-
"""Tests multi-paper recommendations with empty response"""
|
222
|
-
mock_post.return_value.json.return_value = {"recommendedPapers": []}
|
223
|
-
mock_post.return_value.status_code = 200
|
224
|
-
|
225
|
-
result = get_multi_paper_recommendations.invoke(
|
226
|
-
input={
|
227
|
-
"paper_ids": ["123", "456"],
|
228
|
-
"limit": 1,
|
229
|
-
"tool_call_id": "test123",
|
230
|
-
"id": "test123",
|
231
|
-
}
|
232
|
-
)
|
233
|
-
assert "papers" in result.update
|
234
|
-
assert len(result.update["papers"]) == 0
|
235
|
-
|
236
251
|
|
237
252
|
def test_state_replace_dict():
|
238
253
|
"""Verifies state dictionary replacement works correctly"""
|
@@ -244,11 +259,13 @@ def test_state_replace_dict():
|
|
244
259
|
|
245
260
|
|
246
261
|
@pytest.mark.integration
|
247
|
-
def test_end_to_end_search_workflow(initial_state):
|
262
|
+
def test_end_to_end_search_workflow(initial_state: Talk2Scholars, mock_cfg):
|
248
263
|
"""Integration test: Complete search workflow"""
|
249
264
|
with (
|
250
265
|
patch("requests.get") as mock_get,
|
251
266
|
patch("langchain_openai.ChatOpenAI") as mock_llm,
|
267
|
+
patch("hydra.compose", return_value=mock_cfg),
|
268
|
+
patch("hydra.initialize"),
|
252
269
|
):
|
253
270
|
mock_get.return_value.json.return_value = MOCK_SEARCH_RESPONSE
|
254
271
|
mock_get.return_value.status_code = 200
|
@@ -258,7 +275,7 @@ def test_end_to_end_search_workflow(initial_state):
|
|
258
275
|
mock_llm.return_value = llm_instance
|
259
276
|
|
260
277
|
app = get_app("test_integration")
|
261
|
-
test_state = initial_state
|
278
|
+
test_state = initial_state
|
262
279
|
test_state["messages"] = [HumanMessage(content="search for ML papers")]
|
263
280
|
|
264
281
|
config = {
|
@@ -8,7 +8,7 @@ multi_paper_rec: Tool for getting recommendations
|
|
8
8
|
import json
|
9
9
|
import logging
|
10
10
|
from typing import Annotated, Any, Dict, List, Optional
|
11
|
-
|
11
|
+
import hydra
|
12
12
|
import pandas as pd
|
13
13
|
import requests
|
14
14
|
from langchain_core.messages import ToolMessage
|
@@ -40,6 +40,14 @@ class MultiPaperRecInput(BaseModel):
|
|
40
40
|
model_config = {"arbitrary_types_allowed": True}
|
41
41
|
|
42
42
|
|
43
|
+
# Load hydra configuration
|
44
|
+
with hydra.initialize(version_base=None, config_path="../../configs"):
|
45
|
+
cfg = hydra.compose(
|
46
|
+
config_name="config", overrides=["tools/multi_paper_recommendation=default"]
|
47
|
+
)
|
48
|
+
cfg = cfg.tools.multi_paper_recommendation
|
49
|
+
|
50
|
+
|
43
51
|
@tool(args_schema=MultiPaperRecInput)
|
44
52
|
def get_multi_paper_recommendations(
|
45
53
|
paper_ids: List[str],
|
@@ -62,12 +70,12 @@ def get_multi_paper_recommendations(
|
|
62
70
|
"""
|
63
71
|
logging.info("Starting multi-paper recommendations search.")
|
64
72
|
|
65
|
-
endpoint =
|
66
|
-
headers =
|
73
|
+
endpoint = cfg.api_endpoint
|
74
|
+
headers = cfg.headers
|
67
75
|
payload = {"positivePaperIds": paper_ids, "negativePaperIds": []}
|
68
76
|
params = {
|
69
77
|
"limit": min(limit, 500),
|
70
|
-
"fields": "
|
78
|
+
"fields": ",".join(cfg.api_fields),
|
71
79
|
}
|
72
80
|
|
73
81
|
# Add year parameter if provided
|
@@ -80,7 +88,7 @@ def get_multi_paper_recommendations(
|
|
80
88
|
headers=headers,
|
81
89
|
params=params,
|
82
90
|
data=json.dumps(payload),
|
83
|
-
timeout=
|
91
|
+
timeout=cfg.request_timeout,
|
84
92
|
)
|
85
93
|
logging.info(
|
86
94
|
"API Response Status for multi-paper recommendations: %s", response.status_code
|
@@ -6,7 +6,7 @@ This tool is used to search for academic papers on Semantic Scholar.
|
|
6
6
|
|
7
7
|
import logging
|
8
8
|
from typing import Annotated, Any, Dict, Optional
|
9
|
-
|
9
|
+
import hydra
|
10
10
|
import pandas as pd
|
11
11
|
import requests
|
12
12
|
from langchain_core.messages import ToolMessage
|
@@ -34,6 +34,12 @@ class SearchInput(BaseModel):
|
|
34
34
|
tool_call_id: Annotated[str, InjectedToolCallId]
|
35
35
|
|
36
36
|
|
37
|
+
# Load hydra configuration
|
38
|
+
with hydra.initialize(version_base=None, config_path="../../configs"):
|
39
|
+
cfg = hydra.compose(config_name="config", overrides=["tools/search=default"])
|
40
|
+
cfg = cfg.tools.search
|
41
|
+
|
42
|
+
|
37
43
|
@tool(args_schema=SearchInput)
|
38
44
|
def search_tool(
|
39
45
|
query: str,
|
@@ -55,13 +61,13 @@ def search_tool(
|
|
55
61
|
Dict[str, Any]: The search results and related information.
|
56
62
|
"""
|
57
63
|
print("Starting paper search...")
|
58
|
-
endpoint =
|
64
|
+
endpoint = cfg.api_endpoint
|
59
65
|
params = {
|
60
66
|
"query": query,
|
61
67
|
"limit": min(limit, 100),
|
62
68
|
# "fields": "paperId,title,abstract,year,authors,
|
63
69
|
# citationCount,url,publicationTypes,openAccessPdf",
|
64
|
-
"fields": "
|
70
|
+
"fields": ",".join(cfg.api_fields),
|
65
71
|
}
|
66
72
|
|
67
73
|
# Add year parameter if provided
|
@@ -6,7 +6,7 @@ This tool is used to return recommendations for a single paper.
|
|
6
6
|
|
7
7
|
import logging
|
8
8
|
from typing import Annotated, Any, Dict, Optional
|
9
|
-
|
9
|
+
import hydra
|
10
10
|
import pandas as pd
|
11
11
|
import requests
|
12
12
|
from langchain_core.messages import ToolMessage
|
@@ -41,6 +41,14 @@ class SinglePaperRecInput(BaseModel):
|
|
41
41
|
model_config = {"arbitrary_types_allowed": True}
|
42
42
|
|
43
43
|
|
44
|
+
# Load hydra configuration
|
45
|
+
with hydra.initialize(version_base=None, config_path="../../configs"):
|
46
|
+
cfg = hydra.compose(
|
47
|
+
config_name="config", overrides=["tools/single_paper_recommendation=default"]
|
48
|
+
)
|
49
|
+
cfg = cfg.tools.single_paper_recommendation
|
50
|
+
|
51
|
+
|
44
52
|
@tool(args_schema=SinglePaperRecInput)
|
45
53
|
def get_single_paper_recommendations(
|
46
54
|
paper_id: str,
|
@@ -63,20 +71,18 @@ def get_single_paper_recommendations(
|
|
63
71
|
"""
|
64
72
|
logger.info("Starting single paper recommendations search.")
|
65
73
|
|
66
|
-
endpoint =
|
67
|
-
f"https://api.semanticscholar.org/recommendations/v1/papers/forpaper/{paper_id}"
|
68
|
-
)
|
74
|
+
endpoint = f"{cfg.api_endpoint}/{paper_id}"
|
69
75
|
params = {
|
70
76
|
"limit": min(limit, 500), # Max 500 per API docs
|
71
|
-
"fields": "
|
72
|
-
"from":
|
77
|
+
"fields": ",".join(cfg.api_fields),
|
78
|
+
"from": cfg.recommendation_params.from_pool,
|
73
79
|
}
|
74
80
|
|
75
81
|
# Add year parameter if provided
|
76
82
|
if year:
|
77
83
|
params["year"] = year
|
78
84
|
|
79
|
-
response = requests.get(endpoint, params=params, timeout=
|
85
|
+
response = requests.get(endpoint, params=params, timeout=cfg.request_timeout)
|
80
86
|
data = response.json()
|
81
87
|
papers = data.get("data", [])
|
82
88
|
response = requests.get(endpoint, params=params, timeout=10)
|
@@ -0,0 +1,150 @@
|
|
1
|
+
Metadata-Version: 2.2
|
2
|
+
Name: aiagents4pharma
|
3
|
+
Version: 1.17.1
|
4
|
+
Summary: AI Agents for drug discovery, drug development, and other pharmaceutical R&D
|
5
|
+
Classifier: Programming Language :: Python :: 3
|
6
|
+
Classifier: License :: OSI Approved :: MIT License
|
7
|
+
Classifier: Operating System :: OS Independent
|
8
|
+
Requires-Python: >=3.12
|
9
|
+
Description-Content-Type: text/markdown
|
10
|
+
License-File: LICENSE
|
11
|
+
Requires-Dist: copasi_basico==0.78
|
12
|
+
Requires-Dist: coverage==7.6.4
|
13
|
+
Requires-Dist: einops==0.8.0
|
14
|
+
Requires-Dist: gdown==5.2.0
|
15
|
+
Requires-Dist: huggingface_hub==0.26.5
|
16
|
+
Requires-Dist: hydra-core==1.3.2
|
17
|
+
Requires-Dist: joblib==1.4.2
|
18
|
+
Requires-Dist: langchain==0.3.7
|
19
|
+
Requires-Dist: langchain-community==0.3.5
|
20
|
+
Requires-Dist: langchain-core==0.3.31
|
21
|
+
Requires-Dist: langchain-experimental==0.3.3
|
22
|
+
Requires-Dist: langchain-openai==0.2.5
|
23
|
+
Requires-Dist: langchain_ollama==0.2.2
|
24
|
+
Requires-Dist: langgraph==0.2.66
|
25
|
+
Requires-Dist: matplotlib==3.9.2
|
26
|
+
Requires-Dist: openai==1.59.4
|
27
|
+
Requires-Dist: ollama==0.4.6
|
28
|
+
Requires-Dist: pandas==2.2.3
|
29
|
+
Requires-Dist: plotly==5.24.1
|
30
|
+
Requires-Dist: pydantic==2.9.2
|
31
|
+
Requires-Dist: pylint==3.3.1
|
32
|
+
Requires-Dist: pypdf==5.2.0
|
33
|
+
Requires-Dist: pytest==8.3.3
|
34
|
+
Requires-Dist: pytest-asyncio==0.25.2
|
35
|
+
Requires-Dist: streamlit==1.39.0
|
36
|
+
Requires-Dist: sentence_transformers==3.3.1
|
37
|
+
Requires-Dist: tabulate==0.9.0
|
38
|
+
Requires-Dist: torch==2.2.2
|
39
|
+
Requires-Dist: torch_geometric==2.6.1
|
40
|
+
Requires-Dist: tqdm==4.66.6
|
41
|
+
Requires-Dist: transformers==4.48.0
|
42
|
+
Requires-Dist: mkdocs==1.6.1
|
43
|
+
Requires-Dist: mkdocs-jupyter==0.25.1
|
44
|
+
Requires-Dist: mkdocs-material==9.5.47
|
45
|
+
Requires-Dist: mkdocstrings-python==1.12.2
|
46
|
+
Requires-Dist: mkdocs-include-markdown-plugin==7.1.2
|
47
|
+
Requires-Dist: mkdocstrings==0.27.0
|
48
|
+
Requires-Dist: streamlit-feedback
|
49
|
+
|
50
|
+
[](https://github.com/VirtualPatientEngine/AIAgents4Pharma/actions/workflows/tests_talk2biomodels.yml)
|
51
|
+
[](https://github.com/VirtualPatientEngine/AIAgents4Pharma/actions/workflows/tests_talk2cells.yml)
|
52
|
+
[](https://github.com/VirtualPatientEngine/AIAgents4Pharma/actions/workflows/tests_talk2knowledgegraphs.yml)
|
53
|
+
[](https://github.com/VirtualPatientEngine/AIAgents4Pharma/actions/workflows/tests_talk2scholars.yml)
|
54
|
+

|
55
|
+

|
56
|
+
|
57
|
+
|
58
|
+
## Introduction
|
59
|
+
|
60
|
+
Welcome to **AIAgents4Pharma** – an open-source project by [Team VPE](https://github.com/VirtualPatientEngine) that brings together AI-driven tools to help researchers and pharma interact seamlessly with complex biological data.
|
61
|
+
|
62
|
+
Our toolkit currently consists of the following agents:
|
63
|
+
|
64
|
+
- **Talk2BioModels** _(v1 released; v2 in progress)_: Engage directly with mathematical models in systems biology.
|
65
|
+
- **Talk2KnowledgeGraphs** _(v1 in progress)_: Access and explore complex biological knowledge graphs for insightful data connections.
|
66
|
+
- **Talk2Scholars** _(v1 in progress)_: Get recommendations for articles related to your choice. Download, query, and write/retrieve them to your reference manager (currently supporting Zotero).
|
67
|
+
- **Talk2Cells** _(v1 in progress)_: Query and analyze sequencing data with ease.
|
68
|
+
|
69
|
+

|
70
|
+
|
71
|
+
## Getting Started
|
72
|
+
|
73
|
+

|
74
|
+
|
75
|
+
### Installation
|
76
|
+
|
77
|
+
#### Option 1: PyPI
|
78
|
+
|
79
|
+
```bash
|
80
|
+
pip install aiagents4pharma
|
81
|
+
```
|
82
|
+
|
83
|
+
Check out the tutorials on each agent for detailed instrcutions.
|
84
|
+
|
85
|
+
#### Option 2: git
|
86
|
+
|
87
|
+
1. **Clone the repository:**
|
88
|
+
```bash
|
89
|
+
git clone https://github.com/VirtualPatientEngine/AIAgents4Pharma
|
90
|
+
cd AIAgents4Pharma
|
91
|
+
```
|
92
|
+
2. **Install dependencies:**
|
93
|
+
```bash
|
94
|
+
pip install .
|
95
|
+
```
|
96
|
+
3. **Initialize OPENAI_API_KEY**
|
97
|
+
```bash
|
98
|
+
export OPENAI_API_KEY=....
|
99
|
+
```
|
100
|
+
4. **[Optional] Initialize LANGSMITH_API_KEY**
|
101
|
+
```bash
|
102
|
+
export LANGCHAIN_TRACING_V2=true
|
103
|
+
export LANGCHAIN_API_KEY=<your-api-key>
|
104
|
+
```
|
105
|
+
_Please note that this will create a new tracing project in your Langsmith
|
106
|
+
account with the name `T2X-xxxx`, where `X` can be `B` (Biomodels), `S` (Scholars),
|
107
|
+
`KG` (KnowledgeGraphs), or `C` (Cells). If you skip the previous step, it will
|
108
|
+
default to the name `default`. `xxxx` will be the 4-digit ID created for the
|
109
|
+
session._
|
110
|
+
|
111
|
+
5. **Launch the app:**
|
112
|
+
```bash
|
113
|
+
streamlit run app/frontend/streamlit_app_<agent>.py
|
114
|
+
```
|
115
|
+
_Replace <agent> with the agent name you are interested to launch._
|
116
|
+
|
117
|
+
For detailed instructions on each agent, please refer to their respective modules.
|
118
|
+
|
119
|
+
---
|
120
|
+
|
121
|
+
## Contributing
|
122
|
+
|
123
|
+
We welcome contributions to AIAgents4Pharma! Here’s how you can help:
|
124
|
+
|
125
|
+
1. **Fork the repository**
|
126
|
+
2. **Create a new branch** for your feature (`git checkout -b feat/feature-name`)
|
127
|
+
3. **Commit your changes** (`git commit -m 'feat: Add new feature'`)
|
128
|
+
4. **Push to the branch** (`git push origin feat/feature-name`)
|
129
|
+
5. **Open a pull request** and reach out to any one of us below via Discussions:
|
130
|
+
|
131
|
+
_Note: We welcome all contributions, not just programming-related ones. Feel free to open bug reports, suggest new features, or participate as a beta tester. Your support is greatly appreciated!_
|
132
|
+
|
133
|
+
- **Talk2Biomodels/Talk2Cells**: [@gurdeep330](https://github.com/gurdeep330) [@lilijap](https://github.com/lilijap) [@dmccloskey](https://github.com/dmccloskey)
|
134
|
+
- **Talk2KnowledgeGraphs**: [@awmulyadi](https://github.com/awmulyadi) [@dmccloskey](https://github.com/dmccloskey)
|
135
|
+
- **Talk2Scholars**: [@ansh-info](https://github.com/ansh-info) [@gurdeep330](https://github.com/gurdeep330) [@dmccloskey](https://github.com/dmccloskey)
|
136
|
+
|
137
|
+
### Current Needs
|
138
|
+
|
139
|
+
- **Beta testers** for Talk2BioModels and Talk2Scholars.
|
140
|
+
- **Developers** with experience in Python and Bioinformatics and/or knowledge graphs for contributions to AIAgents4Pharma.
|
141
|
+
|
142
|
+
Feel free to reach out to us via Discussions.
|
143
|
+
|
144
|
+
Check out our [CONTRIBUTING.md](CONTRIBUTING.md) for more information.
|
145
|
+
|
146
|
+
---
|
147
|
+
|
148
|
+
## Feedback
|
149
|
+
|
150
|
+
Questions/Bug reports/Feature requests/Comments/Suggestions? We welcome all. Please use `Isssues` or `Discussions` 😀
|
@@ -1,22 +1,20 @@
|
|
1
|
-
aiagents4pharma/__init__.py,sha256=
|
2
|
-
aiagents4pharma/
|
3
|
-
aiagents4pharma/configs/config.yaml,sha256=e0w2GOBVWcoPDtX-z4S6yKbv2rja5PfGRBhmTPVIXNU,161
|
4
|
-
aiagents4pharma/configs/talk2biomodels/__init__.py,sha256=safyFKhkd5Wlirl9dMZIHWDLTpY2oLw9wjIM7ZtLIHk,88
|
5
|
-
aiagents4pharma/configs/talk2biomodels/agents/__init__.py,sha256=_ZoG8snICK2bidWtc2KOGs738LWg9_r66V9mOMnEb-E,71
|
6
|
-
aiagents4pharma/configs/talk2biomodels/agents/t2b_agent/__init__.py,sha256=-fAORvyFmG2iSvFOFDixmt9OTQRR58y89uhhu2EgbA8,46
|
7
|
-
aiagents4pharma/configs/talk2biomodels/agents/t2b_agent/default.yaml,sha256=eLrJIezoPJ6_DvrSYsi3eALl03o0hJhntej3ESoeKKg,551
|
8
|
-
aiagents4pharma/configs/talk2biomodels/tools/__init__.py,sha256=B08KWjj7bpizuTETGnnngrEVK4nzdWGREdoCCSw1Sm4,102
|
9
|
-
aiagents4pharma/configs/talk2biomodels/tools/ask_question/__init__.py,sha256=-fAORvyFmG2iSvFOFDixmt9OTQRR58y89uhhu2EgbA8,46
|
10
|
-
aiagents4pharma/configs/talk2biomodels/tools/ask_question/default.yaml,sha256=yy-Sq1u4dBlTFi_UeoWYoHkWRDWueJWVNK_rcUCC5bw,1747
|
11
|
-
aiagents4pharma/configs/talk2biomodels/tools/get_annotation/__init__.py,sha256=-fAORvyFmG2iSvFOFDixmt9OTQRR58y89uhhu2EgbA8,46
|
12
|
-
aiagents4pharma/configs/talk2biomodels/tools/get_annotation/default.yaml,sha256=8vUlzU5Y3BPggId5bVMo9B23VG4mp2ziTglb4LmLCsc,319
|
13
|
-
aiagents4pharma/talk2biomodels/__init__.py,sha256=2ICwVh1u07SZv31Jd2DKHobauOxWNWY29_Gqq3kOnNQ,159
|
1
|
+
aiagents4pharma/__init__.py,sha256=Ua9fqYW5gV1SZ0nOyOMd4T3wTlBui1-mrlJzFUQLFgY,161
|
2
|
+
aiagents4pharma/talk2biomodels/__init__.py,sha256=1cq1HX2xoi_a0nDPuXYoSTrnL26OHQBW3zXNwwwjFO0,181
|
14
3
|
aiagents4pharma/talk2biomodels/agents/__init__.py,sha256=sn5-fREjMdEvb-OUan3iOqrgYGjplNx3J8hYOaW0Po8,128
|
15
|
-
aiagents4pharma/talk2biomodels/agents/t2b_agent.py,sha256=
|
4
|
+
aiagents4pharma/talk2biomodels/agents/t2b_agent.py,sha256=CXlqDRqG_cxb1TUEL6960s2ActFiXblYPraagDDGQpo,3416
|
16
5
|
aiagents4pharma/talk2biomodels/api/__init__.py,sha256=_GmDQqDLYpsUPUeE1nBNlT5AI9oTXIcqgOfNfvmonqA,123
|
17
6
|
aiagents4pharma/talk2biomodels/api/kegg.py,sha256=QzYDAfJ16E7tbHGxP8ZNWRizMkMRS_HJuucueXEC1Gg,2943
|
18
7
|
aiagents4pharma/talk2biomodels/api/ols.py,sha256=qq0Qy-gJDxanQW-HfCChDsTQsY1M41ua8hMlTnfuzrA,2202
|
19
8
|
aiagents4pharma/talk2biomodels/api/uniprot.py,sha256=aPUAVBR7UYXDuuhDpKezAK2aTMzo-NxFYFq6C0W5u6U,1175
|
9
|
+
aiagents4pharma/talk2biomodels/configs/__init__.py,sha256=safyFKhkd5Wlirl9dMZIHWDLTpY2oLw9wjIM7ZtLIHk,88
|
10
|
+
aiagents4pharma/talk2biomodels/configs/agents/__init__.py,sha256=_ZoG8snICK2bidWtc2KOGs738LWg9_r66V9mOMnEb-E,71
|
11
|
+
aiagents4pharma/talk2biomodels/configs/agents/t2b_agent/__init__.py,sha256=-fAORvyFmG2iSvFOFDixmt9OTQRR58y89uhhu2EgbA8,46
|
12
|
+
aiagents4pharma/talk2biomodels/configs/agents/t2b_agent/default.yaml,sha256=pSViMKwKyMQDm8LzbfIaGdxph73iHYaXMiv5YOuxM7k,536
|
13
|
+
aiagents4pharma/talk2biomodels/configs/tools/__init__.py,sha256=B08KWjj7bpizuTETGnnngrEVK4nzdWGREdoCCSw1Sm4,102
|
14
|
+
aiagents4pharma/talk2biomodels/configs/tools/ask_question/__init__.py,sha256=-fAORvyFmG2iSvFOFDixmt9OTQRR58y89uhhu2EgbA8,46
|
15
|
+
aiagents4pharma/talk2biomodels/configs/tools/ask_question/default.yaml,sha256=pMjs-peecRl8xtIucbEM1Z8Mm_8KGZj0JBrKKD3cMxU,1732
|
16
|
+
aiagents4pharma/talk2biomodels/configs/tools/get_annotation/__init__.py,sha256=-fAORvyFmG2iSvFOFDixmt9OTQRR58y89uhhu2EgbA8,46
|
17
|
+
aiagents4pharma/talk2biomodels/configs/tools/get_annotation/default.yaml,sha256=o5kqLJ5QGJsLMUhAqotudIMhxxNfPUVcDVH1tdRIutU,304
|
20
18
|
aiagents4pharma/talk2biomodels/models/__init__.py,sha256=5fTHHm3PVloYPNKXbgNlcPgv3-u28ZquxGydFYDfhJA,122
|
21
19
|
aiagents4pharma/talk2biomodels/models/basico_model.py,sha256=PH25FTOuUjsmw_UUxoRb-4kptOYpicEn4GqS0phS3nk,4807
|
22
20
|
aiagents4pharma/talk2biomodels/models/sys_bio_model.py,sha256=JeoiGQAvQABHnG0wKR2XBmmxqQdtgO6kxaLDUTUmr1s,2001
|
@@ -36,15 +34,15 @@ aiagents4pharma/talk2biomodels/tests/test_simulate_model.py,sha256=GjLE1DZpcKUAF
|
|
36
34
|
aiagents4pharma/talk2biomodels/tests/test_steady_state.py,sha256=zt15KQoQku6jyzvpJXwINGTyhEnQl8wX81ueHlxnUCA,3467
|
37
35
|
aiagents4pharma/talk2biomodels/tests/test_sys_bio_model.py,sha256=HSmBBViMi0jYf4gWX21IbppAfDzG0nr_S3KtKS9fZVQ,2165
|
38
36
|
aiagents4pharma/talk2biomodels/tools/__init__.py,sha256=6H2HWv5Q4NZYEmw-Ti5KZnJlEqhaC2HXSDZa6kiSl-U,350
|
39
|
-
aiagents4pharma/talk2biomodels/tools/ask_question.py,sha256=
|
37
|
+
aiagents4pharma/talk2biomodels/tools/ask_question.py,sha256=ASkqT6VHUWcMdkVAlqqfbwq7_EBVAXdtmlkMFy7-XxI,4698
|
40
38
|
aiagents4pharma/talk2biomodels/tools/custom_plotter.py,sha256=HWwKTX3o4dk0GcRVTO2hPrFSu98mtJ4TKC_hbHXOe1c,4018
|
41
|
-
aiagents4pharma/talk2biomodels/tools/get_annotation.py,sha256=
|
39
|
+
aiagents4pharma/talk2biomodels/tools/get_annotation.py,sha256=Cea0vid_KX1xjI6ZqDygREAcM7sC7wZXNLTkAN8Nk3Y,13387
|
42
40
|
aiagents4pharma/talk2biomodels/tools/get_modelinfo.py,sha256=57dkXrBeRpyiaW3dYkoWIfr6zSsFHcWRhvUVNyLcvUs,6363
|
43
41
|
aiagents4pharma/talk2biomodels/tools/load_arguments.py,sha256=bffNIlBDTCSFYiZprA73yi8Jbb8z3Oh2decVNh1UnZc,4162
|
44
42
|
aiagents4pharma/talk2biomodels/tools/load_biomodel.py,sha256=pyVzLQoMnuJYEwsjeOlqcUrbU1F1Z-pNlgkhFaoKpy0,689
|
45
43
|
aiagents4pharma/talk2biomodels/tools/parameter_scan.py,sha256=aNh94LgBgVXBIczuNkbSsOZ9j54YVEdZWmZbZr7Nk8k,12465
|
46
44
|
aiagents4pharma/talk2biomodels/tools/query_article.py,sha256=1tpYiE69MYcqiNcRaBgNiYzkkNmuTnlxLuBL_FnRuBU,2058
|
47
|
-
aiagents4pharma/talk2biomodels/tools/search_models.py,sha256=
|
45
|
+
aiagents4pharma/talk2biomodels/tools/search_models.py,sha256=b2OK-Z4ilddbEaJPSQlnZ6sHX3UAWXr_Hq-knoSbbAE,2654
|
48
46
|
aiagents4pharma/talk2biomodels/tools/simulate_model.py,sha256=qXs9lg9XgA7EaRiX3wBS8w_ug8tI-G3pzhcRg6dTRio,5060
|
49
47
|
aiagents4pharma/talk2biomodels/tools/steady_state.py,sha256=j3ckuNlUtv7lT922MbN0JhT9H0JpWAdx2mLPwao6uu8,7123
|
50
48
|
aiagents4pharma/talk2cells/__init__.py,sha256=zmOP5RAhabgKIQP-W4P4qKME2tG3fhAXM3MeO5_H8kE,120
|
@@ -82,24 +80,40 @@ aiagents4pharma/talk2knowledgegraphs/utils/embeddings/sentence_transformer.py,sh
|
|
82
80
|
aiagents4pharma/talk2knowledgegraphs/utils/enrichments/__init__.py,sha256=tW426knki2DBIHcWyF_K04iMMdbpIn_e_TpPmTgz2dI,113
|
83
81
|
aiagents4pharma/talk2knowledgegraphs/utils/enrichments/enrichments.py,sha256=Bx8x6zzk5614ApWB90N_iv4_Y_Uq0-KwUeBwYSdQMU4,924
|
84
82
|
aiagents4pharma/talk2knowledgegraphs/utils/enrichments/ollama.py,sha256=8eoxR-VHo0G7ReQIwje7xEhE-SJlHdef7_wJRpnvFIc,4116
|
85
|
-
aiagents4pharma/talk2scholars/__init__.py,sha256=
|
83
|
+
aiagents4pharma/talk2scholars/__init__.py,sha256=gphERyVKZHvOnMQsml7TIHlaIshHJ75R1J3FKExkfuY,120
|
86
84
|
aiagents4pharma/talk2scholars/agents/__init__.py,sha256=ykszlVGxz3egLHZAttlNoTPxIrnQJZYva_ssR8fwIFk,117
|
87
|
-
aiagents4pharma/talk2scholars/agents/main_agent.py,sha256=
|
88
|
-
aiagents4pharma/talk2scholars/agents/s2_agent.py,sha256=
|
89
|
-
aiagents4pharma/talk2scholars/
|
90
|
-
aiagents4pharma/talk2scholars/
|
85
|
+
aiagents4pharma/talk2scholars/agents/main_agent.py,sha256=etPQUCjHtD-in-kD7Wg_UD6jRtCHj-mj41y03PYbAQM,4616
|
86
|
+
aiagents4pharma/talk2scholars/agents/s2_agent.py,sha256=0OlxNb8IEhd7JJNL8rRlr_U67iPgtGjbbAiJo9HFPdY,2737
|
87
|
+
aiagents4pharma/talk2scholars/configs/__init__.py,sha256=tf2gz8n7M4ko6xLdX_C925ELVIxoP6SgkPcbeh59ad4,151
|
88
|
+
aiagents4pharma/talk2scholars/configs/config.yaml,sha256=a3_jCFAmsVL6gZuvzoRe4jL94mQaSbp0CUXZDUtqhZA,254
|
89
|
+
aiagents4pharma/talk2scholars/configs/agents/__init__.py,sha256=yyh7PB2oY_JulnpSQCWS4wwCH_uzIdt47O2Ay48x_oU,75
|
90
|
+
aiagents4pharma/talk2scholars/configs/agents/talk2scholars/__init__.py,sha256=Tj4urOkjpu2cTlpJl0Fmr_18RZCR88vns-Gt-XquDzs,95
|
91
|
+
aiagents4pharma/talk2scholars/configs/agents/talk2scholars/main_agent/__init__.py,sha256=fqQQ-GlRcbzru2KmEk3oMma0R6_SzGM8dOXzYeU4oVA,46
|
92
|
+
aiagents4pharma/talk2scholars/configs/agents/talk2scholars/main_agent/default.yaml,sha256=77DLch0YDiGslm3HerBaEDqKj1jLqI_jusHFbCchJDU,1617
|
93
|
+
aiagents4pharma/talk2scholars/configs/agents/talk2scholars/s2_agent/__init__.py,sha256=fqQQ-GlRcbzru2KmEk3oMma0R6_SzGM8dOXzYeU4oVA,46
|
94
|
+
aiagents4pharma/talk2scholars/configs/agents/talk2scholars/s2_agent/default.yaml,sha256=6mgBvjifpHJ20kLwuwWr56UoZqmyf1luZnNWlYR6gnc,3135
|
95
|
+
aiagents4pharma/talk2scholars/configs/app/__init__.py,sha256=JoSZV6N669kGMv5zLDszwf0ZjcRHx9TJfIqGhIIdPXE,70
|
96
|
+
aiagents4pharma/talk2scholars/configs/app/frontend/__init__.py,sha256=fqQQ-GlRcbzru2KmEk3oMma0R6_SzGM8dOXzYeU4oVA,46
|
97
|
+
aiagents4pharma/talk2scholars/configs/app/frontend/default.yaml,sha256=BX-J1zQyb0QJ7hcOFOnkJ8aWoWbjK4WE2VG7OZTOyKU,821
|
98
|
+
aiagents4pharma/talk2scholars/configs/tools/__init__.py,sha256=w0BJK0MR6Et8Pw1htP8JV0Lr9F_N68CqvbpV14KBy_8,151
|
99
|
+
aiagents4pharma/talk2scholars/configs/tools/multi_paper_recommendation/__init__.py,sha256=fqQQ-GlRcbzru2KmEk3oMma0R6_SzGM8dOXzYeU4oVA,46
|
100
|
+
aiagents4pharma/talk2scholars/configs/tools/multi_paper_recommendation/default.yaml,sha256=70HSJ8WbS2Qbhur5FpuOPBjrea9g3TioM0gjGn6U1bE,369
|
101
|
+
aiagents4pharma/talk2scholars/configs/tools/search/__init__.py,sha256=fqQQ-GlRcbzru2KmEk3oMma0R6_SzGM8dOXzYeU4oVA,46
|
102
|
+
aiagents4pharma/talk2scholars/configs/tools/search/default.yaml,sha256=NznRVqB6EamMfsFc5hj5s9ygzl6rPuFPiy9ikcpqp68,486
|
103
|
+
aiagents4pharma/talk2scholars/configs/tools/single_paper_recommendation/__init__.py,sha256=fqQQ-GlRcbzru2KmEk3oMma0R6_SzGM8dOXzYeU4oVA,46
|
104
|
+
aiagents4pharma/talk2scholars/configs/tools/single_paper_recommendation/default.yaml,sha256=4_gTvdVc-hf9GNxBKMGQd72s5h53Zy09j9qeZ9Fys04,578
|
91
105
|
aiagents4pharma/talk2scholars/state/__init__.py,sha256=S6SxlszIMZSIMJehjevPF9sKyR-PAwWb5TEdo6xWXE8,103
|
92
106
|
aiagents4pharma/talk2scholars/state/state_talk2scholars.py,sha256=nwNRKdhoTXAtBGMMp6coMyUCaQVOnoGNqyjpKKw_FVM,998
|
93
107
|
aiagents4pharma/talk2scholars/tests/__init__.py,sha256=U3PsTiUZaUBD1IZanFGkDIOdFieDVJtGKQ5-woYUo8c,45
|
94
|
-
aiagents4pharma/talk2scholars/tests/test_langgraph.py,sha256=
|
108
|
+
aiagents4pharma/talk2scholars/tests/test_langgraph.py,sha256=36tWBmdewCZC8Yw1CCIpJxusGLCy21SVHhG1tR5C3TU,9605
|
95
109
|
aiagents4pharma/talk2scholars/tools/__init__.py,sha256=YudBDRwaEzDnAcpxGZvEOfyh5-6xd51CTvTKTkywgXw,68
|
96
110
|
aiagents4pharma/talk2scholars/tools/s2/__init__.py,sha256=9RQH3efTj6qkXk0ICKSc7Mzpkitt4gRGsQ1pGPrrREU,181
|
97
111
|
aiagents4pharma/talk2scholars/tools/s2/display_results.py,sha256=B8JJGohi1Eyx8C3MhO_SiyQP3R6hPyUKJOAzcHmq3FU,584
|
98
|
-
aiagents4pharma/talk2scholars/tools/s2/multi_paper_rec.py,sha256=
|
99
|
-
aiagents4pharma/talk2scholars/tools/s2/search.py,sha256=
|
100
|
-
aiagents4pharma/talk2scholars/tools/s2/single_paper_rec.py,sha256=
|
101
|
-
aiagents4pharma-1.
|
102
|
-
aiagents4pharma-1.
|
103
|
-
aiagents4pharma-1.
|
104
|
-
aiagents4pharma-1.
|
105
|
-
aiagents4pharma-1.
|
112
|
+
aiagents4pharma/talk2scholars/tools/s2/multi_paper_rec.py,sha256=0Y3q8TkF_Phng9L7g1kk9Fhyit9UNitWurp03H0GZv8,4455
|
113
|
+
aiagents4pharma/talk2scholars/tools/s2/search.py,sha256=CcgFN7YuuQ9Vl1DJcldnnvPrswABKjNxeauK1rABps8,4176
|
114
|
+
aiagents4pharma/talk2scholars/tools/s2/single_paper_rec.py,sha256=irS-igdG8BZbVb0Z4VlIjzsyBlUfREd0v0_RlUM-0_U,4994
|
115
|
+
aiagents4pharma-1.17.1.dist-info/LICENSE,sha256=IcIbyB1Hyk5ZDah03VNQvJkbNk2hkBCDqQ8qtnCvB4Q,1077
|
116
|
+
aiagents4pharma-1.17.1.dist-info/METADATA,sha256=6co2HtNzvTLVFczemaajMlZ-7RrM9lmbYwRD3zcfolw,6744
|
117
|
+
aiagents4pharma-1.17.1.dist-info/WHEEL,sha256=In9FTNxeP60KnTkGw7wk6mJPYd_dQSjEZmXdBdMCI-8,91
|
118
|
+
aiagents4pharma-1.17.1.dist-info/top_level.txt,sha256=-AH8rMmrSnJtq7HaAObS78UU-cTCwvX660dSxeM7a0A,16
|
119
|
+
aiagents4pharma-1.17.1.dist-info/RECORD,,
|