aiagents4pharma 1.11.0__py3-none-any.whl → 1.12.0__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- aiagents4pharma/talk2knowledgegraphs/__init__.py +2 -1
- aiagents4pharma/talk2knowledgegraphs/tests/test_utils_enrichments_enrichments.py +39 -0
- aiagents4pharma/talk2knowledgegraphs/tests/test_utils_enrichments_ollama.py +117 -0
- aiagents4pharma/talk2knowledgegraphs/utils/__init__.py +5 -0
- aiagents4pharma/talk2knowledgegraphs/utils/enrichments/__init__.py +5 -0
- aiagents4pharma/talk2knowledgegraphs/utils/enrichments/enrichments.py +36 -0
- aiagents4pharma/talk2knowledgegraphs/utils/enrichments/ollama.py +123 -0
- {aiagents4pharma-1.11.0.dist-info → aiagents4pharma-1.12.0.dist-info}/METADATA +3 -1
- {aiagents4pharma-1.11.0.dist-info → aiagents4pharma-1.12.0.dist-info}/RECORD +12 -7
- {aiagents4pharma-1.11.0.dist-info → aiagents4pharma-1.12.0.dist-info}/LICENSE +0 -0
- {aiagents4pharma-1.11.0.dist-info → aiagents4pharma-1.12.0.dist-info}/WHEEL +0 -0
- {aiagents4pharma-1.11.0.dist-info → aiagents4pharma-1.12.0.dist-info}/top_level.txt +0 -0
@@ -0,0 +1,39 @@
|
|
1
|
+
"""
|
2
|
+
Test cases for utils/enrichments/enrichments.py
|
3
|
+
"""
|
4
|
+
|
5
|
+
from ..utils.enrichments.enrichments import Enrichments
|
6
|
+
|
7
|
+
class TestEnrichments(Enrichments):
|
8
|
+
"""Test implementation of the Enrichments interface for testing purposes."""
|
9
|
+
|
10
|
+
def enrich_documents(self, texts: list[str]) -> list[list[float]]:
|
11
|
+
return [
|
12
|
+
f"Additional text description of {text} as the input." for text in texts
|
13
|
+
]
|
14
|
+
|
15
|
+
def enrich_documents_with_rag(self, texts, docs):
|
16
|
+
# Currently we don't have a RAG model to test this method.
|
17
|
+
# Thus, we will just call the enrich_documents method instead.
|
18
|
+
return self.enrich_documents(texts)
|
19
|
+
|
20
|
+
def test_enrich_documents():
|
21
|
+
"""Test enriching documents using the Enrichments interface."""
|
22
|
+
enrichments = TestEnrichments()
|
23
|
+
texts = ["text1", "text2"]
|
24
|
+
result = enrichments.enrich_documents(texts)
|
25
|
+
assert result == [
|
26
|
+
"Additional text description of text1 as the input.",
|
27
|
+
"Additional text description of text2 as the input.",
|
28
|
+
]
|
29
|
+
|
30
|
+
def test_enrich_documents_with_rag():
|
31
|
+
"""Test enriching documents with RAG using the Enrichments interface."""
|
32
|
+
enrichments = TestEnrichments()
|
33
|
+
texts = ["text1", "text2"]
|
34
|
+
docs = ["doc1", "doc2"]
|
35
|
+
result = enrichments.enrich_documents_with_rag(texts, docs)
|
36
|
+
assert result == [
|
37
|
+
"Additional text description of text1 as the input.",
|
38
|
+
"Additional text description of text2 as the input.",
|
39
|
+
]
|
@@ -0,0 +1,117 @@
|
|
1
|
+
"""
|
2
|
+
Test cases for utils/enrichments/ollama.py
|
3
|
+
"""
|
4
|
+
|
5
|
+
import pytest
|
6
|
+
import ollama
|
7
|
+
from ..utils.enrichments.ollama import EnrichmentWithOllama
|
8
|
+
|
9
|
+
@pytest.fixture(name="ollama_config")
|
10
|
+
def fixture_ollama_config():
|
11
|
+
"""Return a dictionary with Ollama configuration."""
|
12
|
+
return {
|
13
|
+
"model_name": "smollm2:360m",
|
14
|
+
"prompt_enrichment": """
|
15
|
+
Given the input as a list of strings, please return the list of addditional information of
|
16
|
+
each input terms using your prior knowledge.
|
17
|
+
|
18
|
+
Example:
|
19
|
+
Input: ['acetaminophen', 'aspirin']
|
20
|
+
Ouput: ['acetaminophen is a medication used to treat pain and fever',
|
21
|
+
'aspirin is a medication used to treat pain, fever, and inflammation']
|
22
|
+
|
23
|
+
Do not include any pretext as the output, only the list of strings enriched.
|
24
|
+
|
25
|
+
Input: {input}
|
26
|
+
""",
|
27
|
+
"temperature": 0.0,
|
28
|
+
"streaming": False,
|
29
|
+
}
|
30
|
+
|
31
|
+
def test_no_model_ollama(ollama_config):
|
32
|
+
"""Test the case when the Ollama model is not available."""
|
33
|
+
cfg = ollama_config
|
34
|
+
cfg_model = "smollm2:135m" # Choose a small model
|
35
|
+
|
36
|
+
# Delete the Ollama model
|
37
|
+
try:
|
38
|
+
ollama.delete(cfg_model)
|
39
|
+
except ollama.ResponseError:
|
40
|
+
pass
|
41
|
+
|
42
|
+
# Check if the model is available
|
43
|
+
with pytest.raises(
|
44
|
+
ValueError, match=f"Error: Pulled {cfg_model} model and restarted Ollama server."
|
45
|
+
):
|
46
|
+
EnrichmentWithOllama(
|
47
|
+
model_name=cfg_model,
|
48
|
+
prompt_enrichment=cfg["prompt_enrichment"],
|
49
|
+
temperature=cfg["temperature"],
|
50
|
+
streaming=cfg["streaming"],
|
51
|
+
)
|
52
|
+
ollama.delete(cfg_model)
|
53
|
+
|
54
|
+
def test_enrich_nodes_ollama(ollama_config):
|
55
|
+
"""Test the Ollama textual enrichment class for node enrichment."""
|
56
|
+
# Prepare enrichment model
|
57
|
+
cfg = ollama_config
|
58
|
+
enr_model = EnrichmentWithOllama(
|
59
|
+
model_name=cfg["model_name"],
|
60
|
+
prompt_enrichment=cfg["prompt_enrichment"],
|
61
|
+
temperature=cfg["temperature"],
|
62
|
+
streaming=cfg["streaming"],
|
63
|
+
)
|
64
|
+
|
65
|
+
# Perform enrichment for nodes
|
66
|
+
nodes = ["Adalimumab", "Infliximab"]
|
67
|
+
enriched_nodes = enr_model.enrich_documents(nodes)
|
68
|
+
# Check the enriched nodes
|
69
|
+
assert len(enriched_nodes) == 2
|
70
|
+
assert all(
|
71
|
+
enriched_nodes[i] != nodes[i] for i in range(len(nodes))
|
72
|
+
)
|
73
|
+
|
74
|
+
|
75
|
+
def test_enrich_relations_ollama(ollama_config):
|
76
|
+
"""Test the Ollama textual enrichment class for relation enrichment."""
|
77
|
+
# Prepare enrichment model
|
78
|
+
cfg = ollama_config
|
79
|
+
enr_model = EnrichmentWithOllama(
|
80
|
+
model_name=cfg["model_name"],
|
81
|
+
prompt_enrichment=cfg["prompt_enrichment"],
|
82
|
+
temperature=cfg["temperature"],
|
83
|
+
streaming=cfg["streaming"],
|
84
|
+
)
|
85
|
+
# Perform enrichment for relations
|
86
|
+
relations = [
|
87
|
+
"IL23R-gene causation disease-inflammatory bowel diseases",
|
88
|
+
"NOD2-gene causation disease-inflammatory bowel diseases",
|
89
|
+
]
|
90
|
+
enriched_relations = enr_model.enrich_documents(relations)
|
91
|
+
# Check the enriched relations
|
92
|
+
assert len(enriched_relations) == 2
|
93
|
+
assert all(
|
94
|
+
enriched_relations[i] != relations[i]
|
95
|
+
for i in range(len(relations))
|
96
|
+
)
|
97
|
+
|
98
|
+
|
99
|
+
def test_enrich_ollama_rag(ollama_config):
|
100
|
+
"""Test the Ollama textual enrichment class for enrichment with RAG (not implemented)."""
|
101
|
+
# Prepare enrichment model
|
102
|
+
cfg = ollama_config
|
103
|
+
enr_model = EnrichmentWithOllama(
|
104
|
+
model_name=cfg["model_name"],
|
105
|
+
prompt_enrichment=cfg["prompt_enrichment"],
|
106
|
+
temperature=cfg["temperature"],
|
107
|
+
streaming=cfg["streaming"],
|
108
|
+
)
|
109
|
+
# Perform enrichment for nodes
|
110
|
+
nodes = ["Adalimumab", "Infliximab"]
|
111
|
+
docs = [r"\path\to\doc1", r"\path\to\doc2"]
|
112
|
+
enriched_nodes = enr_model.enrich_documents_with_rag(nodes, docs)
|
113
|
+
# Check the enriched nodes
|
114
|
+
assert len(enriched_nodes) == 2
|
115
|
+
assert all(
|
116
|
+
enriched_nodes[i] != nodes[i] for i in range(len(nodes))
|
117
|
+
)
|
@@ -0,0 +1,36 @@
|
|
1
|
+
"""
|
2
|
+
Enrichments interface
|
3
|
+
"""
|
4
|
+
|
5
|
+
from abc import ABC, abstractmethod
|
6
|
+
|
7
|
+
class Enrichments(ABC):
|
8
|
+
"""Interface for enrichment models.
|
9
|
+
|
10
|
+
This is an interface meant for implementing text enrichment models.
|
11
|
+
|
12
|
+
Enrichment models are used to enrich node or relation features in a given knowledge graph.
|
13
|
+
"""
|
14
|
+
|
15
|
+
@abstractmethod
|
16
|
+
def enrich_documents(self, texts: list[str]) -> list[list[str]]:
|
17
|
+
"""Enrich documents.
|
18
|
+
|
19
|
+
Args:
|
20
|
+
texts: List of documents to enrich.
|
21
|
+
|
22
|
+
Returns:
|
23
|
+
List of enriched documents.
|
24
|
+
"""
|
25
|
+
|
26
|
+
@abstractmethod
|
27
|
+
def enrich_documents_with_rag(self, texts: list[str], docs: list[str]) -> list[str]:
|
28
|
+
"""Enrich documents with RAG.
|
29
|
+
|
30
|
+
Args:
|
31
|
+
texts: List of documents to enrich.
|
32
|
+
docs: List of reference documents to enrich the input texts.
|
33
|
+
|
34
|
+
Returns:
|
35
|
+
List of enriched documents with RAG.
|
36
|
+
"""
|
@@ -0,0 +1,123 @@
|
|
1
|
+
#!/usr/bin/env python3
|
2
|
+
|
3
|
+
"""
|
4
|
+
Enrichment class using Ollama model based on LangChain Enrichment class.
|
5
|
+
"""
|
6
|
+
|
7
|
+
import time
|
8
|
+
from typing import List
|
9
|
+
import subprocess
|
10
|
+
import ast
|
11
|
+
import ollama
|
12
|
+
from langchain_ollama import ChatOllama
|
13
|
+
from langchain_core.prompts import ChatPromptTemplate
|
14
|
+
from langchain_core.output_parsers import StrOutputParser
|
15
|
+
from .enrichments import Enrichments
|
16
|
+
|
17
|
+
class EnrichmentWithOllama(Enrichments):
|
18
|
+
"""
|
19
|
+
Enrichment class using Ollama model based on the Enrichment abstract class.
|
20
|
+
"""
|
21
|
+
def __init__(
|
22
|
+
self,
|
23
|
+
model_name: str,
|
24
|
+
prompt_enrichment: str,
|
25
|
+
temperature: float,
|
26
|
+
streaming: bool,
|
27
|
+
):
|
28
|
+
"""
|
29
|
+
Initialize the EnrichmentWithOllama class.
|
30
|
+
|
31
|
+
Args:
|
32
|
+
model_name: The name of the Ollama model to be used.
|
33
|
+
prompt_enrichment: The prompt enrichment template.
|
34
|
+
temperature: The temperature for the Ollama model.
|
35
|
+
streaming: The streaming flag for the Ollama model.
|
36
|
+
"""
|
37
|
+
# Setup the Ollama server
|
38
|
+
self.__setup(model_name)
|
39
|
+
|
40
|
+
# Set parameters
|
41
|
+
self.model_name = model_name
|
42
|
+
self.prompt_enrichment = prompt_enrichment
|
43
|
+
self.temperature = temperature
|
44
|
+
self.streaming = streaming
|
45
|
+
|
46
|
+
# Prepare prompt template
|
47
|
+
self.prompt_template = ChatPromptTemplate.from_messages(
|
48
|
+
[
|
49
|
+
("system", self.prompt_enrichment),
|
50
|
+
("human", "{input}"),
|
51
|
+
]
|
52
|
+
)
|
53
|
+
|
54
|
+
# Prepare model
|
55
|
+
self.model = ChatOllama(
|
56
|
+
model=self.model_name,
|
57
|
+
temperature=self.temperature,
|
58
|
+
streaming=self.streaming,
|
59
|
+
)
|
60
|
+
|
61
|
+
def __setup(self, model_name: str) -> None:
|
62
|
+
"""
|
63
|
+
Check if the Ollama model is available and run the Ollama server if needed.
|
64
|
+
|
65
|
+
Args:
|
66
|
+
model_name: The name of the Ollama model to be used.
|
67
|
+
"""
|
68
|
+
try:
|
69
|
+
models_list = ollama.list()["models"]
|
70
|
+
if model_name not in [m['model'].replace(":latest", "") for m in models_list]:
|
71
|
+
ollama.pull(model_name)
|
72
|
+
time.sleep(30)
|
73
|
+
raise ValueError(f"Pulled {model_name} model")
|
74
|
+
except Exception as e:
|
75
|
+
with subprocess.Popen(
|
76
|
+
"ollama serve", shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE
|
77
|
+
):
|
78
|
+
time.sleep(10)
|
79
|
+
raise ValueError(f"Error: {e} and restarted Ollama server.") from e
|
80
|
+
|
81
|
+
def enrich_documents(self, texts: List[str]) -> List[str]:
|
82
|
+
"""
|
83
|
+
Enrich a list of input texts with additional textual features using OLLAMA model.
|
84
|
+
Important: Make sure the input is a list of texts based on the defined prompt template
|
85
|
+
with 'input' as the variable name.
|
86
|
+
|
87
|
+
Args:
|
88
|
+
texts: The list of texts to be enriched.
|
89
|
+
|
90
|
+
Returns:
|
91
|
+
The list of enriched texts.
|
92
|
+
"""
|
93
|
+
|
94
|
+
# Perform enrichment
|
95
|
+
chain = self.prompt_template | self.model | StrOutputParser()
|
96
|
+
|
97
|
+
# Generate the enriched node
|
98
|
+
# Important: Make sure the input is a list of texts based on the defined prompt template
|
99
|
+
# with 'input' as the variable name
|
100
|
+
enriched_texts = chain.invoke({"input": "[" + ", ".join(texts) + "]"})
|
101
|
+
|
102
|
+
# Convert the enriched nodes to a list of dictionary
|
103
|
+
enriched_texts = ast.literal_eval(enriched_texts.replace("```", ""))
|
104
|
+
|
105
|
+
# Final check for the enriched texts
|
106
|
+
assert len(enriched_texts) == len(texts)
|
107
|
+
|
108
|
+
return enriched_texts
|
109
|
+
|
110
|
+
def enrich_documents_with_rag(self, texts, docs):
|
111
|
+
"""
|
112
|
+
Enrich a list of input texts with additional textual features using OLLAMA model with RAG.
|
113
|
+
As of now, we don't have a RAG model to test this method yet.
|
114
|
+
Thus, we will just call the enrich_documents method instead.
|
115
|
+
|
116
|
+
Args:
|
117
|
+
texts: The list of texts to be enriched.
|
118
|
+
docs: The list of reference documents to enrich the input texts.
|
119
|
+
|
120
|
+
Returns:
|
121
|
+
The list of enriched texts
|
122
|
+
"""
|
123
|
+
return self.enrich_documents(texts)
|
@@ -1,6 +1,6 @@
|
|
1
1
|
Metadata-Version: 2.2
|
2
2
|
Name: aiagents4pharma
|
3
|
-
Version: 1.
|
3
|
+
Version: 1.12.0
|
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
|
@@ -20,9 +20,11 @@ Requires-Dist: langchain-community==0.3.5
|
|
20
20
|
Requires-Dist: langchain-core==0.3.31
|
21
21
|
Requires-Dist: langchain-experimental==0.3.3
|
22
22
|
Requires-Dist: langchain-openai==0.2.5
|
23
|
+
Requires-Dist: langchain_ollama==0.2.2
|
23
24
|
Requires-Dist: langgraph==0.2.66
|
24
25
|
Requires-Dist: matplotlib==3.9.2
|
25
26
|
Requires-Dist: openai==1.59.4
|
27
|
+
Requires-Dist: ollama==0.4.6
|
26
28
|
Requires-Dist: pandas==2.2.3
|
27
29
|
Requires-Dist: plotly==5.24.1
|
28
30
|
Requires-Dist: pydantic==2.9.2
|
@@ -51,7 +51,7 @@ aiagents4pharma/talk2competitors/tools/s2/display_results.py,sha256=B8JJGohi1Eyx
|
|
51
51
|
aiagents4pharma/talk2competitors/tools/s2/multi_paper_rec.py,sha256=FYLt47DAk6WOKfEk1Gj9zVvJGNyxA283PCp8IKW9U5M,4262
|
52
52
|
aiagents4pharma/talk2competitors/tools/s2/search.py,sha256=pppjrQv5-8ep4fnqgTSBNgnbSnQsVIcNrRrH0p2TP1o,4025
|
53
53
|
aiagents4pharma/talk2competitors/tools/s2/single_paper_rec.py,sha256=dAfUQxI7T5eu0eDxK8VAl7-JH0Wnw24CVkOQqwj-hXc,4810
|
54
|
-
aiagents4pharma/talk2knowledgegraphs/__init__.py,sha256=
|
54
|
+
aiagents4pharma/talk2knowledgegraphs/__init__.py,sha256=4smVQoSMM6rflVnNkABqlDAAlSn4bYsq7rMVWjRGvis,103
|
55
55
|
aiagents4pharma/talk2knowledgegraphs/datasets/__init__.py,sha256=L3gPuHskSegmtXskVrLIYr7FXe_ibKgJ2GGr1_Wok6k,173
|
56
56
|
aiagents4pharma/talk2knowledgegraphs/datasets/biobridge_primekg.py,sha256=QlzDXmXREoa9MA6-GwzqRjdzndQeGBAF11Td6NFk_9Y,23426
|
57
57
|
aiagents4pharma/talk2knowledgegraphs/datasets/dataset.py,sha256=-LaPLse8BkALqwFetNK7wch2dt9Dz6QKGKZKBKM6bIk,409
|
@@ -65,14 +65,19 @@ aiagents4pharma/talk2knowledgegraphs/tests/test_datasets_starkqa_primekg.py,sha2
|
|
65
65
|
aiagents4pharma/talk2knowledgegraphs/tests/test_utils_embeddings_embeddings.py,sha256=uYFoE_6zeU10_1mLLAHUr5c4S2XZMSc0Q_860o-KWEw,1517
|
66
66
|
aiagents4pharma/talk2knowledgegraphs/tests/test_utils_embeddings_huggingface.py,sha256=EINWyXg_3AMHF3WzFLhIUiFDuaEhTVHBvVAJr8VtMDg,1624
|
67
67
|
aiagents4pharma/talk2knowledgegraphs/tests/test_utils_embeddings_sentencetransformer.py,sha256=Qxo6WeIDRy8aLh1tNKw0kSlzmUj3MtTak63oW2YwB24,1327
|
68
|
-
aiagents4pharma/talk2knowledgegraphs/
|
68
|
+
aiagents4pharma/talk2knowledgegraphs/tests/test_utils_enrichments_enrichments.py,sha256=N6HRr4lWHXY7bTHe2uXJe4D_EG9WqZPibZne6qLl9_k,1447
|
69
|
+
aiagents4pharma/talk2knowledgegraphs/tests/test_utils_enrichments_ollama.py,sha256=kMuB_vci6hKr2qJgXBmcje7yxeJ2nY2ImXw-NSJpts0,3912
|
70
|
+
aiagents4pharma/talk2knowledgegraphs/utils/__init__.py,sha256=X8kSpmDTMkeE0fA5D0CWMsQ52YKoM5rRSXrjnali3IM,97
|
69
71
|
aiagents4pharma/talk2knowledgegraphs/utils/kg_utils.py,sha256=6vQnPkeOWae_8jePjhma3sJuMTngy0I0tqzdFt6OqKg,2507
|
70
72
|
aiagents4pharma/talk2knowledgegraphs/utils/embeddings/__init__.py,sha256=xRb0x7SoAb0nSVZYgjrqxWvENOMDuqIdL43NMjoOaCs,153
|
71
73
|
aiagents4pharma/talk2knowledgegraphs/utils/embeddings/embeddings.py,sha256=1nGznrAj-xT0xuSMBGz2dOujJ7M_IwSR84njxtxsy9A,2523
|
72
74
|
aiagents4pharma/talk2knowledgegraphs/utils/embeddings/huggingface.py,sha256=2vi_elf6EgzfagFAO5QnL3a_aXZyN7B1EBziu44MTfM,3806
|
73
75
|
aiagents4pharma/talk2knowledgegraphs/utils/embeddings/sentence_transformer.py,sha256=36iKlisOpMtGR5xfTAlSHXWvPqVC_Jbezod8kbBBMVg,2136
|
74
|
-
aiagents4pharma
|
75
|
-
aiagents4pharma
|
76
|
-
aiagents4pharma
|
77
|
-
aiagents4pharma-1.
|
78
|
-
aiagents4pharma-1.
|
76
|
+
aiagents4pharma/talk2knowledgegraphs/utils/enrichments/__init__.py,sha256=tW426knki2DBIHcWyF_K04iMMdbpIn_e_TpPmTgz2dI,113
|
77
|
+
aiagents4pharma/talk2knowledgegraphs/utils/enrichments/enrichments.py,sha256=Bx8x6zzk5614ApWB90N_iv4_Y_Uq0-KwUeBwYSdQMU4,924
|
78
|
+
aiagents4pharma/talk2knowledgegraphs/utils/enrichments/ollama.py,sha256=8eoxR-VHo0G7ReQIwje7xEhE-SJlHdef7_wJRpnvFIc,4116
|
79
|
+
aiagents4pharma-1.12.0.dist-info/LICENSE,sha256=IcIbyB1Hyk5ZDah03VNQvJkbNk2hkBCDqQ8qtnCvB4Q,1077
|
80
|
+
aiagents4pharma-1.12.0.dist-info/METADATA,sha256=Okx1RPc3qMmJ2a7ca2YvSFr7-gxqAR51LVLkOTh5O2k,8609
|
81
|
+
aiagents4pharma-1.12.0.dist-info/WHEEL,sha256=In9FTNxeP60KnTkGw7wk6mJPYd_dQSjEZmXdBdMCI-8,91
|
82
|
+
aiagents4pharma-1.12.0.dist-info/top_level.txt,sha256=-AH8rMmrSnJtq7HaAObS78UU-cTCwvX660dSxeM7a0A,16
|
83
|
+
aiagents4pharma-1.12.0.dist-info/RECORD,,
|
File without changes
|
File without changes
|
File without changes
|