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.
Files changed (53) hide show
  1. aiagents4pharma/talk2scholars/agents/__init__.py +1 -0
  2. aiagents4pharma/talk2scholars/agents/main_agent.py +35 -209
  3. aiagents4pharma/talk2scholars/agents/pdf_agent.py +106 -0
  4. aiagents4pharma/talk2scholars/agents/s2_agent.py +10 -6
  5. aiagents4pharma/talk2scholars/agents/zotero_agent.py +12 -6
  6. aiagents4pharma/talk2scholars/configs/agents/talk2scholars/__init__.py +1 -0
  7. aiagents4pharma/talk2scholars/configs/agents/talk2scholars/main_agent/default.yaml +2 -48
  8. aiagents4pharma/talk2scholars/configs/agents/talk2scholars/pdf_agent/__init__.py +3 -0
  9. aiagents4pharma/talk2scholars/configs/agents/talk2scholars/s2_agent/default.yaml +5 -28
  10. aiagents4pharma/talk2scholars/configs/agents/talk2scholars/zotero_agent/default.yaml +5 -21
  11. aiagents4pharma/talk2scholars/configs/config.yaml +3 -0
  12. aiagents4pharma/talk2scholars/configs/tools/__init__.py +2 -0
  13. aiagents4pharma/talk2scholars/configs/tools/multi_paper_recommendation/default.yaml +1 -1
  14. aiagents4pharma/talk2scholars/configs/tools/question_and_answer/__init__.py +3 -0
  15. aiagents4pharma/talk2scholars/configs/tools/search/default.yaml +1 -1
  16. aiagents4pharma/talk2scholars/configs/tools/single_paper_recommendation/default.yaml +1 -1
  17. aiagents4pharma/talk2scholars/configs/tools/zotero_read/default.yaml +42 -1
  18. aiagents4pharma/talk2scholars/configs/tools/zotero_write/__inti__.py +3 -0
  19. aiagents4pharma/talk2scholars/state/state_talk2scholars.py +1 -0
  20. aiagents4pharma/talk2scholars/tests/test_main_agent.py +186 -111
  21. aiagents4pharma/talk2scholars/tests/test_pdf_agent.py +126 -0
  22. aiagents4pharma/talk2scholars/tests/test_question_and_answer_tool.py +186 -0
  23. aiagents4pharma/talk2scholars/tests/test_s2_display.py +74 -0
  24. aiagents4pharma/talk2scholars/tests/test_s2_multi.py +282 -0
  25. aiagents4pharma/talk2scholars/tests/test_s2_query.py +78 -0
  26. aiagents4pharma/talk2scholars/tests/test_s2_retrieve.py +65 -0
  27. aiagents4pharma/talk2scholars/tests/test_s2_search.py +266 -0
  28. aiagents4pharma/talk2scholars/tests/test_s2_single.py +274 -0
  29. aiagents4pharma/talk2scholars/tests/test_zotero_path.py +57 -0
  30. aiagents4pharma/talk2scholars/tests/test_zotero_read.py +412 -0
  31. aiagents4pharma/talk2scholars/tests/test_zotero_write.py +626 -0
  32. aiagents4pharma/talk2scholars/tools/__init__.py +1 -0
  33. aiagents4pharma/talk2scholars/tools/pdf/__init__.py +5 -0
  34. aiagents4pharma/talk2scholars/tools/pdf/question_and_answer.py +170 -0
  35. aiagents4pharma/talk2scholars/tools/s2/multi_paper_rec.py +50 -34
  36. aiagents4pharma/talk2scholars/tools/s2/query_results.py +1 -1
  37. aiagents4pharma/talk2scholars/tools/s2/retrieve_semantic_scholar_paper_id.py +8 -8
  38. aiagents4pharma/talk2scholars/tools/s2/search.py +36 -23
  39. aiagents4pharma/talk2scholars/tools/s2/single_paper_rec.py +44 -38
  40. aiagents4pharma/talk2scholars/tools/zotero/__init__.py +2 -0
  41. aiagents4pharma/talk2scholars/tools/zotero/utils/__init__.py +5 -0
  42. aiagents4pharma/talk2scholars/tools/zotero/utils/zotero_path.py +63 -0
  43. aiagents4pharma/talk2scholars/tools/zotero/zotero_read.py +64 -19
  44. aiagents4pharma/talk2scholars/tools/zotero/zotero_write.py +247 -0
  45. {aiagents4pharma-1.27.2.dist-info → aiagents4pharma-1.29.0.dist-info}/METADATA +6 -5
  46. {aiagents4pharma-1.27.2.dist-info → aiagents4pharma-1.29.0.dist-info}/RECORD +49 -33
  47. aiagents4pharma/talk2scholars/tests/test_call_s2.py +0 -100
  48. aiagents4pharma/talk2scholars/tests/test_call_zotero.py +0 -94
  49. aiagents4pharma/talk2scholars/tests/test_s2_tools.py +0 -355
  50. aiagents4pharma/talk2scholars/tests/test_zotero_tool.py +0 -171
  51. {aiagents4pharma-1.27.2.dist-info → aiagents4pharma-1.29.0.dist-info}/LICENSE +0 -0
  52. {aiagents4pharma-1.27.2.dist-info → aiagents4pharma-1.29.0.dist-info}/WHEEL +0 -0
  53. {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"