aiagents4pharma 1.14.1__py3-none-any.whl → 1.15.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.
@@ -5,4 +5,10 @@ state_modifier: >
5
5
  then pass the use_uploaded_model argument
6
6
  as True. If the user asks for simulation
7
7
  or param_scan or steady state, suggest a
8
- value for the `experiment_name` argument.
8
+ value for the `experiment_name` argument.
9
+
10
+ If the user asks question related to the
11
+ uploaded document/pdf/article/document,
12
+ use the tool `query_article` to answer the
13
+ question. Please note that the `experiment_name`
14
+ argument may be unrelated to the question asked.
@@ -0,0 +1,39 @@
1
+ _target_: talk2biomodels.tools.ask_question.AskQuestionTool
2
+ steady_state_prompt: >
3
+ Following are header columns of the data:
4
+ `species_name`: Name of the species,
5
+ `compartment`: Compartment of the species,
6
+ `initial_concentration`: Concentration of the species at the start of steady state,
7
+ `steady_state_concentration`: Concentration of the species at steady state,
8
+ `steady_state_transition_time`: Time taken to reach steady state,
9
+ `display_name`: An alias for the species name.
10
+
11
+ Here are some instructions to help you answer questions:
12
+
13
+ 1. Before you answer any question, follow the plan and solve
14
+ technique. Start by understanding the question, then plan your
15
+ approach to solve the question, and finally solve the question
16
+ by following the plan. Always give a brief explanation of your
17
+ answer to the user.
18
+
19
+ 2. If the user wants to know the time taken by the model to reach
20
+ steady state, you should look at the steady_state_transition_time
21
+ column of the data for the model species. The highest value in
22
+ this column is the time taken by the model to reach steady state.
23
+
24
+ 3. To get accurate results, trim the data to the relevant columns
25
+ before performing any calculations. This will help you avoid
26
+ errors in your calculations, and ignore irrelevant data.
27
+
28
+ 4. Please use the units provided below to answer the questions.
29
+ simulation_prompt: >
30
+ Following is the information about the data frame:
31
+ 1. First column is the time column, and the rest of the columns
32
+ are the species names.
33
+
34
+ 2. While the time column records the simulation time points, the
35
+ rest of the columns record the concentration of the species at
36
+ each time point.
37
+
38
+ 3. Please use the units provided below to answer the questions.
39
+
@@ -19,6 +19,7 @@ from ..tools.get_annotation import GetAnnotationTool
19
19
  from ..tools.ask_question import AskQuestionTool
20
20
  from ..tools.parameter_scan import ParameterScanTool
21
21
  from ..tools.steady_state import SteadyStateTool
22
+ from ..tools.query_article import QueryArticle
22
23
  from ..states.state_talk2biomodels import Talk2Biomodels
23
24
 
24
25
  # Initialize logger
@@ -46,7 +47,8 @@ def get_app(uniq_id, llm_model='gpt-4o-mini'):
46
47
  GetModelInfoTool(),
47
48
  SteadyStateTool(),
48
49
  ParameterScanTool(),
49
- GetAnnotationTool()
50
+ GetAnnotationTool(),
51
+ QueryArticle()
50
52
  ])
51
53
 
52
54
  # Define the model
@@ -27,6 +27,7 @@ class Talk2Biomodels(AgentState):
27
27
  The state for the Talk2BioModels agent.
28
28
  """
29
29
  llm_model: str
30
+ pdf_file_name: str
30
31
  # A StateGraph may receive a concurrent updates
31
32
  # which is not supported by the StateGraph. Hence,
32
33
  # we need to add a reducer function to handle the
@@ -0,0 +1,76 @@
1
+ '''
2
+ Test cases for Talk2Biomodels query_article tool.
3
+ '''
4
+
5
+ from pydantic import BaseModel, Field
6
+ from langchain_core.messages import HumanMessage, ToolMessage
7
+ from langchain_openai import ChatOpenAI
8
+ from ..agents.t2b_agent import get_app
9
+
10
+ class Article(BaseModel):
11
+ '''
12
+ Article schema.
13
+ '''
14
+ title: str = Field(description="Title of the article.")
15
+
16
+ def test_query_article_with_an_article():
17
+ '''
18
+ Test the query_article tool by providing an article.
19
+ '''
20
+ unique_id = 12345
21
+ app = get_app(unique_id)
22
+ config = {"configurable": {"thread_id": unique_id}}
23
+ # Update state by providing the pdf file name
24
+ app.update_state(config,
25
+ {"pdf_file_name": "aiagents4pharma/talk2biomodels/tests/article_on_model_537.pdf"})
26
+ prompt = "What is the title of the article?"
27
+ # Test the tool query_article
28
+ response = app.invoke(
29
+ {"messages": [HumanMessage(content=prompt)]},
30
+ config=config
31
+ )
32
+ # Get the response from the tool
33
+ assistant_msg = response["messages"][-1].content
34
+ # Prepare a LLM that can be used as a judge
35
+ llm = ChatOpenAI(model='gpt-4o-mini', temperature=0)
36
+ # Make it return a structured output
37
+ structured_llm = llm.with_structured_output(Article)
38
+ # Prepare a prompt for the judge
39
+ prompt = "Given the text below, what is the title of the article?"
40
+ prompt += f"\n\n{assistant_msg}"
41
+ # Get the structured output
42
+ article = structured_llm.invoke(prompt)
43
+ # Check if the article title is correct
44
+ expected_title = "A Multiscale Model of IL-6–Mediated "
45
+ expected_title += "Immune Regulation in Crohn’s Disease"
46
+ # Check if the article title is correct
47
+ assert article.title == expected_title
48
+
49
+ def test_query_article_without_an_article():
50
+ '''
51
+ Test the query_article tool without providing an article.
52
+ The status of the tool should be error.
53
+ '''
54
+ unique_id = 12345
55
+ app = get_app(unique_id)
56
+ config = {"configurable": {"thread_id": unique_id}}
57
+ prompt = "What is the title of the uploaded article?"
58
+ # Test the tool query_article
59
+ app.invoke(
60
+ {"messages": [HumanMessage(content=prompt)]},
61
+ config=config
62
+ )
63
+ current_state = app.get_state(config)
64
+ # Get the messages from the current state
65
+ # and reverse the order
66
+ reversed_messages = current_state.values["messages"][::-1]
67
+ # Loop through the reversed messages
68
+ # until a ToolMessage is found.
69
+ tool_status_is_error = False
70
+ for msg in reversed_messages:
71
+ if isinstance(msg, ToolMessage):
72
+ # Skip until it finds a ToolMessage
73
+ if msg.name == "query_article" and msg.status == "error":
74
+ tool_status_is_error = True
75
+ break
76
+ assert tool_status_is_error
@@ -10,3 +10,4 @@ from . import parameter_scan
10
10
  from . import steady_state
11
11
  from . import load_biomodel
12
12
  from . import get_annotation
13
+ from . import query_article
@@ -0,0 +1,59 @@
1
+ #!/usr/bin/env python3
2
+
3
+ """
4
+ Tool for asking questions to the article.
5
+ """
6
+
7
+ import logging
8
+ from typing import Type, Annotated
9
+ from pydantic import BaseModel, Field
10
+ from langchain_core.tools import BaseTool
11
+ from langchain_core.vectorstores import InMemoryVectorStore
12
+ from langchain_openai.embeddings import OpenAIEmbeddings
13
+ from langchain_community.document_loaders import PyPDFLoader
14
+ from langgraph.prebuilt import InjectedState
15
+
16
+ # Initialize logger
17
+ logging.basicConfig(level=logging.INFO)
18
+ logger = logging.getLogger(__name__)
19
+
20
+ class QueryArticleInput(BaseModel):
21
+ """
22
+ Input schema for the query_articles tool.
23
+ """
24
+ question: Annotated[str, Field(description="User question to search articles.")]
25
+ state: Annotated[dict, InjectedState]
26
+
27
+ # Note: It's important that every field has type hints. BaseTool is a
28
+ # Pydantic class and not having type hints can lead to unexpected behavior.
29
+ class QueryArticle(BaseTool):
30
+ """
31
+ Tool to ask questions to the article.
32
+ """
33
+ name: str = "query_article"
34
+ description: str = "Ask questions to the article."
35
+ args_schema: Type[BaseModel] = QueryArticleInput
36
+
37
+ def _run(self,
38
+ question: str,
39
+ state: Annotated[dict, InjectedState]):
40
+ """
41
+ Run the tool.
42
+
43
+ Args:
44
+ query (str): The search query.
45
+ """
46
+ logger.log(logging.INFO, "loading the article from %s", state['pdf_file_name'])
47
+ logger.log(logging.INFO, "searching the article with the question: %s", question)
48
+ # Load the article
49
+ loader = PyPDFLoader(state['pdf_file_name'])
50
+ # Load the pages of the article
51
+ pages = []
52
+ for page in loader.lazy_load():
53
+ pages.append(page)
54
+ # Create a vector store from the pages
55
+ vector_store = InMemoryVectorStore.from_documents(pages, OpenAIEmbeddings())
56
+ # Search the article with the question
57
+ docs = vector_store.similarity_search(question)
58
+ # Return the content of the pages
59
+ return "\n".join([doc.page_content for doc in docs])
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.2
2
2
  Name: aiagents4pharma
3
- Version: 1.14.1
3
+ Version: 1.15.1
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
@@ -29,6 +29,7 @@ Requires-Dist: pandas==2.2.3
29
29
  Requires-Dist: plotly==5.24.1
30
30
  Requires-Dist: pydantic==2.9.2
31
31
  Requires-Dist: pylint==3.3.1
32
+ Requires-Dist: pypdf==5.2.0
32
33
  Requires-Dist: pytest==8.3.3
33
34
  Requires-Dist: pytest-asyncio==0.25.2
34
35
  Requires-Dist: streamlit==1.39.0
@@ -4,12 +4,13 @@ aiagents4pharma/configs/config.yaml,sha256=4t7obD0gOSfqnDDZZBB53ZC7zsmk7QDcM7T_1
4
4
  aiagents4pharma/configs/talk2biomodels/__init__.py,sha256=safyFKhkd5Wlirl9dMZIHWDLTpY2oLw9wjIM7ZtLIHk,88
5
5
  aiagents4pharma/configs/talk2biomodels/agents/__init__.py,sha256=_ZoG8snICK2bidWtc2KOGs738LWg9_r66V9mOMnEb-E,71
6
6
  aiagents4pharma/configs/talk2biomodels/agents/t2b_agent/__init__.py,sha256=-fAORvyFmG2iSvFOFDixmt9OTQRR58y89uhhu2EgbA8,46
7
- aiagents4pharma/configs/talk2biomodels/agents/t2b_agent/default.yaml,sha256=w0ES09GSuY61x7C9FSx9auwhoGc6xVeG51roe6tT4Bk,317
7
+ aiagents4pharma/configs/talk2biomodels/agents/t2b_agent/default.yaml,sha256=eLrJIezoPJ6_DvrSYsi3eALl03o0hJhntej3ESoeKKg,551
8
8
  aiagents4pharma/configs/talk2biomodels/tools/__init__.py,sha256=WxK7h5n39l-NSMvjLZyxDqzwWlVA6mQ69gzsbJ17vEk,72
9
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
10
11
  aiagents4pharma/talk2biomodels/__init__.py,sha256=2ICwVh1u07SZv31Jd2DKHobauOxWNWY29_Gqq3kOnNQ,159
11
12
  aiagents4pharma/talk2biomodels/agents/__init__.py,sha256=sn5-fREjMdEvb-OUan3iOqrgYGjplNx3J8hYOaW0Po8,128
12
- aiagents4pharma/talk2biomodels/agents/t2b_agent.py,sha256=13aSlBZBWtjXOLq7c99u33c923fi2Ab0VW--eX5gF-o,3366
13
+ aiagents4pharma/talk2biomodels/agents/t2b_agent.py,sha256=5h4n7dF13KuT5f9vzfK7EQTu_b0a0hB7ScLFlTKaNko,3449
13
14
  aiagents4pharma/talk2biomodels/api/__init__.py,sha256=_GmDQqDLYpsUPUeE1nBNlT5AI9oTXIcqgOfNfvmonqA,123
14
15
  aiagents4pharma/talk2biomodels/api/kegg.py,sha256=QzYDAfJ16E7tbHGxP8ZNWRizMkMRS_HJuucueXEC1Gg,2943
15
16
  aiagents4pharma/talk2biomodels/api/ols.py,sha256=qq0Qy-gJDxanQW-HfCChDsTQsY1M41ua8hMlTnfuzrA,2202
@@ -18,7 +19,7 @@ aiagents4pharma/talk2biomodels/models/__init__.py,sha256=5fTHHm3PVloYPNKXbgNlcPg
18
19
  aiagents4pharma/talk2biomodels/models/basico_model.py,sha256=PH25FTOuUjsmw_UUxoRb-4kptOYpicEn4GqS0phS3nk,4807
19
20
  aiagents4pharma/talk2biomodels/models/sys_bio_model.py,sha256=JeoiGQAvQABHnG0wKR2XBmmxqQdtgO6kxaLDUTUmr1s,2001
20
21
  aiagents4pharma/talk2biomodels/states/__init__.py,sha256=YLg1-N0D9qyRRLRqwqfLCLAqZYDtMVZTfI8Y0b_4tbA,139
21
- aiagents4pharma/talk2biomodels/states/state_talk2biomodels.py,sha256=WriIk_MH9XyUD-WAcIFVjHZMegwrh2-zQpXleTzpHEU,1332
22
+ aiagents4pharma/talk2biomodels/states/state_talk2biomodels.py,sha256=d_tDh93ip36hlUpMh-KOkYfBZ2SQwZlaY8p-1ZWKPhY,1355
22
23
  aiagents4pharma/talk2biomodels/tests/__init__.py,sha256=Jbw5tJxSrjGoaK5IX3pJWDCNzhrVQ10lkYq2oQ_KQD8,45
23
24
  aiagents4pharma/talk2biomodels/tests/test_api.py,sha256=7Kz2r5F5tjmn3F0LoM33oP-21W633936YHiyf5toGg0,1716
24
25
  aiagents4pharma/talk2biomodels/tests/test_ask_question.py,sha256=yRkKK9HLB1bGGWm_WwOckwaUmmRfRAD9z2NFFGLIGTY,1560
@@ -27,11 +28,12 @@ aiagents4pharma/talk2biomodels/tests/test_get_annotation.py,sha256=mKOacH28OB6xp
27
28
  aiagents4pharma/talk2biomodels/tests/test_getmodelinfo.py,sha256=6kChSc_MCnzXlDao_R8pKdhIELlg3MZrUa7hg8piJ4E,883
28
29
  aiagents4pharma/talk2biomodels/tests/test_integration.py,sha256=ZsBXWSFLIcdzrO8obLJx8Ib2f9AAW3BI7H9Eqjdc5to,5057
29
30
  aiagents4pharma/talk2biomodels/tests/test_param_scan.py,sha256=vRbnn4uVWFbfZbU4gVCjHi5WDCUrErut8ElzAPE5y84,2648
31
+ aiagents4pharma/talk2biomodels/tests/test_query_article.py,sha256=HhFgU5HzCipecEYlfbpPxN-SCIPKep22gpXCutWXRb8,2820
30
32
  aiagents4pharma/talk2biomodels/tests/test_search_models.py,sha256=8ODFubLxWYD3I3KQWuUnJ2GZRzMjFpXInFBLxKxG_ME,929
31
33
  aiagents4pharma/talk2biomodels/tests/test_simulate_model.py,sha256=GjLE1DZpcKUAFSmoHD86vkfK0b5LJPM8a4WYyraazig,1487
32
34
  aiagents4pharma/talk2biomodels/tests/test_steady_state.py,sha256=zt15KQoQku6jyzvpJXwINGTyhEnQl8wX81ueHlxnUCA,3467
33
35
  aiagents4pharma/talk2biomodels/tests/test_sys_bio_model.py,sha256=HSmBBViMi0jYf4gWX21IbppAfDzG0nr_S3KtKS9fZVQ,2165
34
- aiagents4pharma/talk2biomodels/tools/__init__.py,sha256=ZiOdSFaeHW6y3hdtBfsKf0vSb3MuCLuy9MDyjARggb4,322
36
+ aiagents4pharma/talk2biomodels/tools/__init__.py,sha256=6H2HWv5Q4NZYEmw-Ti5KZnJlEqhaC2HXSDZa6kiSl-U,350
35
37
  aiagents4pharma/talk2biomodels/tools/ask_question.py,sha256=hWXg7o0sTMDWH1ZnxtashTALvXpvNoaomfcniEhw-Bw,4684
36
38
  aiagents4pharma/talk2biomodels/tools/custom_plotter.py,sha256=HWwKTX3o4dk0GcRVTO2hPrFSu98mtJ4TKC_hbHXOe1c,4018
37
39
  aiagents4pharma/talk2biomodels/tools/get_annotation.py,sha256=jCGkidvafuk1YzAH9GFwaVUF35maXTjg6XqBg_zLk44,12475
@@ -39,6 +41,7 @@ aiagents4pharma/talk2biomodels/tools/get_modelinfo.py,sha256=qA-4FOI-O728Nmn7s8J
39
41
  aiagents4pharma/talk2biomodels/tools/load_arguments.py,sha256=bffNIlBDTCSFYiZprA73yi8Jbb8z3Oh2decVNh1UnZc,4162
40
42
  aiagents4pharma/talk2biomodels/tools/load_biomodel.py,sha256=pyVzLQoMnuJYEwsjeOlqcUrbU1F1Z-pNlgkhFaoKpy0,689
41
43
  aiagents4pharma/talk2biomodels/tools/parameter_scan.py,sha256=aNh94LgBgVXBIczuNkbSsOZ9j54YVEdZWmZbZr7Nk8k,12465
44
+ aiagents4pharma/talk2biomodels/tools/query_article.py,sha256=1tpYiE69MYcqiNcRaBgNiYzkkNmuTnlxLuBL_FnRuBU,2058
42
45
  aiagents4pharma/talk2biomodels/tools/search_models.py,sha256=Iq2ddofOOfZYtAurCISq3bAq5rbwB3l_rL1lgEFyFCI,2653
43
46
  aiagents4pharma/talk2biomodels/tools/simulate_model.py,sha256=qXs9lg9XgA7EaRiX3wBS8w_ug8tI-G3pzhcRg6dTRio,5060
44
47
  aiagents4pharma/talk2biomodels/tools/steady_state.py,sha256=j3ckuNlUtv7lT922MbN0JhT9H0JpWAdx2mLPwao6uu8,7123
@@ -93,8 +96,8 @@ aiagents4pharma/talk2knowledgegraphs/utils/embeddings/sentence_transformer.py,sh
93
96
  aiagents4pharma/talk2knowledgegraphs/utils/enrichments/__init__.py,sha256=tW426knki2DBIHcWyF_K04iMMdbpIn_e_TpPmTgz2dI,113
94
97
  aiagents4pharma/talk2knowledgegraphs/utils/enrichments/enrichments.py,sha256=Bx8x6zzk5614ApWB90N_iv4_Y_Uq0-KwUeBwYSdQMU4,924
95
98
  aiagents4pharma/talk2knowledgegraphs/utils/enrichments/ollama.py,sha256=8eoxR-VHo0G7ReQIwje7xEhE-SJlHdef7_wJRpnvFIc,4116
96
- aiagents4pharma-1.14.1.dist-info/LICENSE,sha256=IcIbyB1Hyk5ZDah03VNQvJkbNk2hkBCDqQ8qtnCvB4Q,1077
97
- aiagents4pharma-1.14.1.dist-info/METADATA,sha256=zwewL1DN0qEv3L7l901tNdc6PaX1wrKvRIkZ0dFIqHU,8609
98
- aiagents4pharma-1.14.1.dist-info/WHEEL,sha256=In9FTNxeP60KnTkGw7wk6mJPYd_dQSjEZmXdBdMCI-8,91
99
- aiagents4pharma-1.14.1.dist-info/top_level.txt,sha256=-AH8rMmrSnJtq7HaAObS78UU-cTCwvX660dSxeM7a0A,16
100
- aiagents4pharma-1.14.1.dist-info/RECORD,,
99
+ aiagents4pharma-1.15.1.dist-info/LICENSE,sha256=IcIbyB1Hyk5ZDah03VNQvJkbNk2hkBCDqQ8qtnCvB4Q,1077
100
+ aiagents4pharma-1.15.1.dist-info/METADATA,sha256=J1AkLBxq9Pb1bo2tfkr8isyCozXB1aUi79jOlx6KDp8,8637
101
+ aiagents4pharma-1.15.1.dist-info/WHEEL,sha256=In9FTNxeP60KnTkGw7wk6mJPYd_dQSjEZmXdBdMCI-8,91
102
+ aiagents4pharma-1.15.1.dist-info/top_level.txt,sha256=-AH8rMmrSnJtq7HaAObS78UU-cTCwvX660dSxeM7a0A,16
103
+ aiagents4pharma-1.15.1.dist-info/RECORD,,