aiagents4pharma 1.27.2__py3-none-any.whl → 1.29.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/talk2scholars/agents/__init__.py +1 -0
- aiagents4pharma/talk2scholars/agents/main_agent.py +35 -209
- aiagents4pharma/talk2scholars/agents/pdf_agent.py +106 -0
- aiagents4pharma/talk2scholars/agents/s2_agent.py +10 -6
- aiagents4pharma/talk2scholars/agents/zotero_agent.py +12 -6
- aiagents4pharma/talk2scholars/configs/agents/talk2scholars/__init__.py +1 -0
- aiagents4pharma/talk2scholars/configs/agents/talk2scholars/main_agent/default.yaml +2 -48
- aiagents4pharma/talk2scholars/configs/agents/talk2scholars/pdf_agent/__init__.py +3 -0
- aiagents4pharma/talk2scholars/configs/agents/talk2scholars/s2_agent/default.yaml +5 -28
- aiagents4pharma/talk2scholars/configs/agents/talk2scholars/zotero_agent/default.yaml +5 -21
- aiagents4pharma/talk2scholars/configs/config.yaml +3 -0
- aiagents4pharma/talk2scholars/configs/tools/__init__.py +2 -0
- aiagents4pharma/talk2scholars/configs/tools/multi_paper_recommendation/default.yaml +1 -1
- aiagents4pharma/talk2scholars/configs/tools/question_and_answer/__init__.py +3 -0
- aiagents4pharma/talk2scholars/configs/tools/search/default.yaml +1 -1
- aiagents4pharma/talk2scholars/configs/tools/single_paper_recommendation/default.yaml +1 -1
- aiagents4pharma/talk2scholars/configs/tools/zotero_read/default.yaml +42 -1
- aiagents4pharma/talk2scholars/configs/tools/zotero_write/__inti__.py +3 -0
- aiagents4pharma/talk2scholars/state/state_talk2scholars.py +1 -0
- aiagents4pharma/talk2scholars/tests/test_main_agent.py +186 -111
- aiagents4pharma/talk2scholars/tests/test_pdf_agent.py +126 -0
- aiagents4pharma/talk2scholars/tests/test_question_and_answer_tool.py +186 -0
- aiagents4pharma/talk2scholars/tests/test_s2_display.py +74 -0
- aiagents4pharma/talk2scholars/tests/test_s2_multi.py +282 -0
- aiagents4pharma/talk2scholars/tests/test_s2_query.py +78 -0
- aiagents4pharma/talk2scholars/tests/test_s2_retrieve.py +65 -0
- aiagents4pharma/talk2scholars/tests/test_s2_search.py +266 -0
- aiagents4pharma/talk2scholars/tests/test_s2_single.py +274 -0
- aiagents4pharma/talk2scholars/tests/test_zotero_path.py +57 -0
- aiagents4pharma/talk2scholars/tests/test_zotero_read.py +412 -0
- aiagents4pharma/talk2scholars/tests/test_zotero_write.py +626 -0
- aiagents4pharma/talk2scholars/tools/__init__.py +1 -0
- aiagents4pharma/talk2scholars/tools/pdf/__init__.py +5 -0
- aiagents4pharma/talk2scholars/tools/pdf/question_and_answer.py +170 -0
- aiagents4pharma/talk2scholars/tools/s2/multi_paper_rec.py +50 -34
- aiagents4pharma/talk2scholars/tools/s2/query_results.py +1 -1
- aiagents4pharma/talk2scholars/tools/s2/retrieve_semantic_scholar_paper_id.py +8 -8
- aiagents4pharma/talk2scholars/tools/s2/search.py +36 -23
- aiagents4pharma/talk2scholars/tools/s2/single_paper_rec.py +44 -38
- aiagents4pharma/talk2scholars/tools/zotero/__init__.py +2 -0
- aiagents4pharma/talk2scholars/tools/zotero/utils/__init__.py +5 -0
- aiagents4pharma/talk2scholars/tools/zotero/utils/zotero_path.py +63 -0
- aiagents4pharma/talk2scholars/tools/zotero/zotero_read.py +64 -19
- aiagents4pharma/talk2scholars/tools/zotero/zotero_write.py +247 -0
- {aiagents4pharma-1.27.2.dist-info → aiagents4pharma-1.29.0.dist-info}/METADATA +6 -5
- {aiagents4pharma-1.27.2.dist-info → aiagents4pharma-1.29.0.dist-info}/RECORD +49 -33
- aiagents4pharma/talk2scholars/tests/test_call_s2.py +0 -100
- aiagents4pharma/talk2scholars/tests/test_call_zotero.py +0 -94
- aiagents4pharma/talk2scholars/tests/test_s2_tools.py +0 -355
- aiagents4pharma/talk2scholars/tests/test_zotero_tool.py +0 -171
- {aiagents4pharma-1.27.2.dist-info → aiagents4pharma-1.29.0.dist-info}/LICENSE +0 -0
- {aiagents4pharma-1.27.2.dist-info → aiagents4pharma-1.29.0.dist-info}/WHEEL +0 -0
- {aiagents4pharma-1.27.2.dist-info → aiagents4pharma-1.29.0.dist-info}/top_level.txt +0 -0
@@ -1,171 +0,0 @@
|
|
1
|
-
"""
|
2
|
-
Unit tests for Zotero search tool in zotero_read.py.
|
3
|
-
"""
|
4
|
-
|
5
|
-
from unittest.mock import patch
|
6
|
-
from langgraph.types import Command
|
7
|
-
from ..tools.zotero.zotero_read import zotero_search_tool
|
8
|
-
|
9
|
-
|
10
|
-
# Mock data for Zotero API response
|
11
|
-
MOCK_ZOTERO_RESPONSE = [
|
12
|
-
{
|
13
|
-
"data": {
|
14
|
-
"key": "ABC123",
|
15
|
-
"title": "Deep Learning in Medicine",
|
16
|
-
"abstractNote": "An overview of deep learning applications in medicine.",
|
17
|
-
"date": "2022",
|
18
|
-
"url": "https://example.com/paper1",
|
19
|
-
"itemType": "journalArticle",
|
20
|
-
}
|
21
|
-
},
|
22
|
-
{
|
23
|
-
"data": {
|
24
|
-
"key": "XYZ789",
|
25
|
-
"title": "Advances in AI",
|
26
|
-
"abstractNote": "Recent advancements in AI research.",
|
27
|
-
"date": "2023",
|
28
|
-
"url": "https://example.com/paper2",
|
29
|
-
"itemType": "conferencePaper",
|
30
|
-
}
|
31
|
-
},
|
32
|
-
]
|
33
|
-
|
34
|
-
|
35
|
-
class TestZoteroRead:
|
36
|
-
"""Unit tests for Zotero search tool"""
|
37
|
-
|
38
|
-
@patch("pyzotero.zotero.Zotero.items")
|
39
|
-
def test_zotero_success(self, mock_zotero):
|
40
|
-
"""Verifies successful retrieval of papers from Zotero"""
|
41
|
-
mock_zotero.return_value = MOCK_ZOTERO_RESPONSE
|
42
|
-
|
43
|
-
result = zotero_search_tool.invoke(
|
44
|
-
input={
|
45
|
-
"query": "deep learning",
|
46
|
-
"only_articles": True,
|
47
|
-
"limit": 2,
|
48
|
-
"tool_call_id": "test123",
|
49
|
-
}
|
50
|
-
)
|
51
|
-
|
52
|
-
assert isinstance(result, Command)
|
53
|
-
assert "zotero_read" in result.update
|
54
|
-
assert "messages" in result.update
|
55
|
-
papers = result.update["zotero_read"]
|
56
|
-
assert len(papers) == 2 # Should return 2 papers
|
57
|
-
assert papers["ABC123"]["Title"] == "Deep Learning in Medicine"
|
58
|
-
assert papers["XYZ789"]["Title"] == "Advances in AI"
|
59
|
-
|
60
|
-
@patch("pyzotero.zotero.Zotero.items")
|
61
|
-
def test_zotero_no_papers_found(self, mock_zotero):
|
62
|
-
"""Verifies Zotero tool behavior when no papers are found"""
|
63
|
-
mock_zotero.return_value = [] # Simulating empty response
|
64
|
-
|
65
|
-
result = zotero_search_tool.invoke(
|
66
|
-
input={
|
67
|
-
"query": "nonexistent topic",
|
68
|
-
"only_articles": True,
|
69
|
-
"limit": 2,
|
70
|
-
"tool_call_id": "test123",
|
71
|
-
}
|
72
|
-
)
|
73
|
-
|
74
|
-
assert isinstance(result, Command)
|
75
|
-
assert "zotero_read" in result.update
|
76
|
-
assert len(result.update["zotero_read"]) == 0 # No papers found
|
77
|
-
assert "messages" in result.update
|
78
|
-
assert "Number of papers found: 0" in result.update["messages"][0].content
|
79
|
-
|
80
|
-
@patch("pyzotero.zotero.Zotero.items")
|
81
|
-
def test_zotero_only_articles_filtering(self, mock_zotero):
|
82
|
-
"""Ensures only journal articles and conference papers are returned"""
|
83
|
-
mock_response = [
|
84
|
-
{
|
85
|
-
"data": {
|
86
|
-
"key": "DEF456",
|
87
|
-
"title": "A Book on AI",
|
88
|
-
"abstractNote": "Book about AI advancements.",
|
89
|
-
"date": "2021",
|
90
|
-
"url": "https://example.com/book",
|
91
|
-
"itemType": "book",
|
92
|
-
}
|
93
|
-
},
|
94
|
-
MOCK_ZOTERO_RESPONSE[0], # Valid journal article
|
95
|
-
]
|
96
|
-
mock_zotero.return_value = mock_response
|
97
|
-
|
98
|
-
result = zotero_search_tool.invoke(
|
99
|
-
input={
|
100
|
-
"query": "AI",
|
101
|
-
"only_articles": True,
|
102
|
-
"limit": 2,
|
103
|
-
"tool_call_id": "test123",
|
104
|
-
}
|
105
|
-
)
|
106
|
-
|
107
|
-
assert isinstance(result, Command)
|
108
|
-
assert "zotero_read" in result.update
|
109
|
-
papers = result.update["zotero_read"]
|
110
|
-
assert len(papers) == 1 # The book should be filtered out
|
111
|
-
assert "ABC123" in papers # Journal article should be included
|
112
|
-
|
113
|
-
@patch("pyzotero.zotero.Zotero.items")
|
114
|
-
def test_zotero_invalid_response(self, mock_zotero):
|
115
|
-
"""Tests handling of malformed API response"""
|
116
|
-
mock_zotero.return_value = [
|
117
|
-
{"data": None}, # Invalid response format
|
118
|
-
{}, # Empty object
|
119
|
-
{"data": {"title": "Missing Key", "itemType": "journalArticle"}}, # No key
|
120
|
-
]
|
121
|
-
|
122
|
-
result = zotero_search_tool.invoke(
|
123
|
-
input={
|
124
|
-
"query": "AI ethics",
|
125
|
-
"only_articles": True,
|
126
|
-
"limit": 2,
|
127
|
-
"tool_call_id": "test123",
|
128
|
-
}
|
129
|
-
)
|
130
|
-
|
131
|
-
assert isinstance(result, Command)
|
132
|
-
assert "zotero_read" in result.update
|
133
|
-
assert (
|
134
|
-
len(result.update["zotero_read"]) == 0
|
135
|
-
) # Should filter out invalid entries
|
136
|
-
assert "messages" in result.update
|
137
|
-
assert "Number of papers found: 0" in result.update["messages"][0].content
|
138
|
-
|
139
|
-
@patch("pyzotero.zotero.Zotero.items")
|
140
|
-
def test_zotero_handles_non_dict_items(self, mock_zotero):
|
141
|
-
"""Ensures that Zotero tool correctly skips non-dictionary items (covers line 86)"""
|
142
|
-
|
143
|
-
# Simulate Zotero returning an invalid item (e.g., `None` and a string)
|
144
|
-
mock_zotero.return_value = [
|
145
|
-
None,
|
146
|
-
"invalid_string",
|
147
|
-
{
|
148
|
-
"data": {
|
149
|
-
"key": "123",
|
150
|
-
"title": "Valid Paper",
|
151
|
-
"itemType": "journalArticle",
|
152
|
-
}
|
153
|
-
},
|
154
|
-
]
|
155
|
-
|
156
|
-
result = zotero_search_tool.invoke(
|
157
|
-
input={
|
158
|
-
"query": "AI ethics",
|
159
|
-
"only_articles": True,
|
160
|
-
"limit": 2,
|
161
|
-
"tool_call_id": "test123",
|
162
|
-
}
|
163
|
-
)
|
164
|
-
|
165
|
-
assert isinstance(result, Command)
|
166
|
-
assert "zotero_read" in result.update
|
167
|
-
|
168
|
-
# Expect only valid items to be processed
|
169
|
-
assert (
|
170
|
-
len(result.update["zotero_read"]) == 1
|
171
|
-
), "Only valid dictionary items should be processed"
|
File without changes
|
File without changes
|
File without changes
|