aiagents4pharma 1.28.0__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 (41) hide show
  1. aiagents4pharma/talk2scholars/agents/main_agent.py +35 -209
  2. aiagents4pharma/talk2scholars/agents/s2_agent.py +10 -6
  3. aiagents4pharma/talk2scholars/agents/zotero_agent.py +12 -6
  4. aiagents4pharma/talk2scholars/configs/agents/talk2scholars/main_agent/default.yaml +2 -48
  5. aiagents4pharma/talk2scholars/configs/agents/talk2scholars/s2_agent/default.yaml +5 -28
  6. aiagents4pharma/talk2scholars/configs/agents/talk2scholars/zotero_agent/default.yaml +5 -21
  7. aiagents4pharma/talk2scholars/configs/config.yaml +1 -0
  8. aiagents4pharma/talk2scholars/configs/tools/__init__.py +1 -0
  9. aiagents4pharma/talk2scholars/configs/tools/multi_paper_recommendation/default.yaml +1 -1
  10. aiagents4pharma/talk2scholars/configs/tools/search/default.yaml +1 -1
  11. aiagents4pharma/talk2scholars/configs/tools/single_paper_recommendation/default.yaml +1 -1
  12. aiagents4pharma/talk2scholars/configs/tools/zotero_read/default.yaml +42 -1
  13. aiagents4pharma/talk2scholars/configs/tools/zotero_write/__inti__.py +3 -0
  14. aiagents4pharma/talk2scholars/tests/test_main_agent.py +186 -111
  15. aiagents4pharma/talk2scholars/tests/test_s2_display.py +74 -0
  16. aiagents4pharma/talk2scholars/tests/test_s2_multi.py +282 -0
  17. aiagents4pharma/talk2scholars/tests/test_s2_query.py +78 -0
  18. aiagents4pharma/talk2scholars/tests/test_s2_retrieve.py +65 -0
  19. aiagents4pharma/talk2scholars/tests/test_s2_search.py +266 -0
  20. aiagents4pharma/talk2scholars/tests/test_s2_single.py +274 -0
  21. aiagents4pharma/talk2scholars/tests/test_zotero_path.py +57 -0
  22. aiagents4pharma/talk2scholars/tests/test_zotero_read.py +412 -0
  23. aiagents4pharma/talk2scholars/tests/test_zotero_write.py +626 -0
  24. aiagents4pharma/talk2scholars/tools/s2/multi_paper_rec.py +50 -34
  25. aiagents4pharma/talk2scholars/tools/s2/retrieve_semantic_scholar_paper_id.py +8 -8
  26. aiagents4pharma/talk2scholars/tools/s2/search.py +36 -23
  27. aiagents4pharma/talk2scholars/tools/s2/single_paper_rec.py +44 -38
  28. aiagents4pharma/talk2scholars/tools/zotero/__init__.py +2 -0
  29. aiagents4pharma/talk2scholars/tools/zotero/utils/__init__.py +5 -0
  30. aiagents4pharma/talk2scholars/tools/zotero/utils/zotero_path.py +63 -0
  31. aiagents4pharma/talk2scholars/tools/zotero/zotero_read.py +64 -19
  32. aiagents4pharma/talk2scholars/tools/zotero/zotero_write.py +247 -0
  33. {aiagents4pharma-1.28.0.dist-info → aiagents4pharma-1.29.0.dist-info}/METADATA +6 -5
  34. {aiagents4pharma-1.28.0.dist-info → aiagents4pharma-1.29.0.dist-info}/RECORD +37 -28
  35. aiagents4pharma/talk2scholars/tests/test_call_s2.py +0 -100
  36. aiagents4pharma/talk2scholars/tests/test_call_zotero.py +0 -94
  37. aiagents4pharma/talk2scholars/tests/test_s2_tools.py +0 -355
  38. aiagents4pharma/talk2scholars/tests/test_zotero_tool.py +0 -171
  39. {aiagents4pharma-1.28.0.dist-info → aiagents4pharma-1.29.0.dist-info}/LICENSE +0 -0
  40. {aiagents4pharma-1.28.0.dist-info → aiagents4pharma-1.29.0.dist-info}/WHEEL +0 -0
  41. {aiagents4pharma-1.28.0.dist-info → aiagents4pharma-1.29.0.dist-info}/top_level.txt +0 -0
@@ -9,117 +9,21 @@ for multi-agent systems and implements proper state management.
9
9
  """
10
10
 
11
11
  import logging
12
- from typing import Literal, Callable
13
- from pydantic import BaseModel
14
12
  import hydra
13
+ from langgraph_supervisor import create_supervisor
14
+ from langchain_openai import ChatOpenAI
15
15
  from langchain_core.language_models.chat_models import BaseChatModel
16
- from langchain_core.messages import SystemMessage, HumanMessage, AIMessage
17
16
  from langgraph.checkpoint.memory import MemorySaver
18
- from langgraph.graph import END, START, StateGraph
19
- from langgraph.types import Command
20
- from ..agents import s2_agent
21
- from ..agents import zotero_agent
17
+ from ..agents.s2_agent import get_app as get_app_s2
18
+ from ..agents.zotero_agent import get_app as get_app_zotero
22
19
  from ..state.state_talk2scholars import Talk2Scholars
23
20
 
24
- # Configure logging
21
+ # Initialize logger
25
22
  logging.basicConfig(level=logging.INFO)
26
23
  logger = logging.getLogger(__name__)
27
24
 
28
25
 
29
- def get_hydra_config():
30
- """
31
- Loads the Hydra configuration for the main agent.
32
-
33
- This function initializes the Hydra configuration system and retrieves the settings
34
- for the `Talk2Scholars` agent, ensuring that all required parameters are loaded.
35
-
36
- Returns:
37
- DictConfig: The configuration object containing parameters for the main agent.
38
- """
39
- with hydra.initialize(version_base=None, config_path="../configs"):
40
- cfg = hydra.compose(
41
- config_name="config", overrides=["agents/talk2scholars/main_agent=default"]
42
- )
43
- return cfg.agents.talk2scholars.main_agent
44
-
45
-
46
- def make_supervisor_node(llm_model: BaseChatModel, thread_id: str) -> Callable:
47
- """
48
- Creates the supervisor node responsible for routing user queries to the appropriate sub-agents.
49
-
50
- This function initializes the routing logic by leveraging the system and router prompts defined
51
- in the Hydra configuration. The supervisor determines whether to
52
- call a sub-agent (like `s2_agent`, `zotero_agent`)
53
- or directly generate a response using the language model.
54
-
55
- Args:
56
- llm_model (BaseChatModel): The language model used for decision-making.
57
- thread_id (str): Unique identifier for the current conversation session.
58
-
59
- Returns:
60
- Callable: The supervisor node function that processes user queries and
61
- decides the next step.
62
- """
63
- cfg = get_hydra_config()
64
- logger.info("Hydra configuration for Talk2Scholars main agent loaded: %s", cfg)
65
- members = ["s2_agent", "zotero_agent"]
66
- options = ["FINISH"] + members
67
- # Define system prompt for general interactions
68
- system_prompt = cfg.system_prompt
69
- # Define router prompt for routing to sub-agents
70
- router_prompt = cfg.router_prompt + " " + " ".join(members)
71
-
72
- class Router(BaseModel):
73
- """Worker to route to next. If no workers needed, route to FINISH."""
74
-
75
- next: Literal[*options]
76
-
77
- def supervisor_node(
78
- state: Talk2Scholars,
79
- ) -> Command:
80
- """
81
- Handles the routing logic for the supervisor agent.
82
-
83
- This function determines the next agent to invoke based on the router prompt response.
84
- If no further processing is required, it generates an AI response using the system prompt.
85
-
86
- Args:
87
- state (Talk2Scholars): The current conversation state, including messages
88
- exchanged so far.
89
-
90
- Returns:
91
- Command: A command dictating whether to invoke a sub-agent or generate a final response.
92
- """
93
- messages = [SystemMessage(content=router_prompt)] + list(state["messages"])
94
- structured_llm = llm_model.with_structured_output(Router)
95
- response = structured_llm.invoke(messages)
96
- goto = response.next
97
- logger.info("Routing to: %s, Thread ID: %s", goto, thread_id)
98
- if goto == "FINISH":
99
- goto = END # Using END from langgraph.graph
100
- # If no agents were called, and the last message was
101
- # from the user, call the LLM to respond to the user
102
- # with a slightly different system prompt.
103
- if isinstance(messages[-1], HumanMessage):
104
- response = llm_model.invoke(
105
- [
106
- SystemMessage(content=system_prompt),
107
- ]
108
- + messages[1:]
109
- )
110
- return Command(
111
- goto=goto, update={"messages": AIMessage(content=response.content)}
112
- )
113
- # Go to the requested agent
114
- return Command(goto=goto)
115
-
116
- return supervisor_node
117
-
118
-
119
- def get_app(
120
- thread_id: str,
121
- llm_model: BaseChatModel
122
- ):
26
+ def get_app(uniq_id, llm_model: BaseChatModel):
123
27
  """
124
28
  Initializes and returns the LangGraph-based hierarchical agent system.
125
29
 
@@ -139,114 +43,36 @@ def get_app(
139
43
  >>> app = get_app("thread_123")
140
44
  >>> result = app.invoke(initial_state)
141
45
  """
142
- cfg = get_hydra_config()
143
-
144
- def call_s2_agent(
145
- state: Talk2Scholars,
146
- ) -> Command[Literal["supervisor"]]:
147
- """
148
- Invokes the Semantic Scholar (S2) agent to retrieve relevant research papers.
149
-
150
- This function calls the `s2_agent` and updates the conversation state with retrieved
151
- academic papers. The agent uses Semantic Scholar's API to find papers based on
152
- user queries.
153
-
154
- Args:
155
- state (Talk2Scholars): The current state of the conversation, containing messages
156
- and any previous search results.
157
-
158
- Returns:
159
- Command: A command to update the conversation state with the retrieved papers
160
- and return control to the supervisor node.
161
-
162
- Example:
163
- >>> result = call_s2_agent(current_state)
164
- >>> next_step = result.goto
165
- """
166
- logger.info("Calling S2 agent")
167
- app = s2_agent.get_app(thread_id, llm_model)
168
-
169
- # Invoke the S2 agent, passing state,
170
- # Pass both config_id and thread_id
171
- response = app.invoke(
172
- state,
173
- {
174
- "configurable": {
175
- "config_id": thread_id,
176
- "thread_id": thread_id,
177
- }
178
- },
46
+ if llm_model.model_name == "gpt-4o-mini":
47
+ llm_model = ChatOpenAI(
48
+ model="gpt-4o-mini",
49
+ temperature=0,
50
+ model_kwargs={"parallel_tool_calls": False},
179
51
  )
180
- logger.info("S2 agent completed with response")
181
- return Command(
182
- update={
183
- "messages": response["messages"],
184
- "papers": response.get("papers", {}),
185
- "multi_papers": response.get("multi_papers", {}),
186
- "last_displayed_papers": response.get("last_displayed_papers", {}),
187
- },
188
- # Always return to supervisor
189
- goto="supervisor",
190
- )
191
-
192
- def call_zotero_agent(
193
- state: Talk2Scholars,
194
- ) -> Command[Literal["supervisor"]]:
195
- """
196
- Invokes the Zotero agent to retrieve and process papers from the user's Zotero library.
197
-
198
- This function calls the Zotero agent, which interacts with the user's Zotero database
199
- to retrieve relevant papers based on the conversation context. It updates the
200
- conversation state with the retrieved papers and relevant metadata.
201
-
202
- Args:
203
- state (Talk2Scholars): The current conversation state, containing user messages
204
- and any previously retrieved Zotero data.
205
-
206
- Returns:
207
- Command: A command that updates the conversation state with retrieved Zotero
208
- papers and metadata before returning control to the supervisor node.
209
-
210
- Example:
211
- >>> result = call_zotero_agent(current_state)
212
- >>> next_step = result.goto
213
- """
214
- logger.info("Calling Zotero agent")
215
- app = zotero_agent.get_app(thread_id, llm_model)
216
- # Invoke the Zotero agent, passing state
217
- response = app.invoke(
218
- state,
219
- {
220
- "configurable": {
221
- "config_id": thread_id,
222
- "thread_id": thread_id,
223
- }
224
- },
225
- )
226
- logger.info("Zotero agent completed with response")
227
- return Command(
228
- update={
229
- "messages": response["messages"],
230
- "zotero_read": response.get("zotero_read", {}),
231
- "last_displayed_papers": response.get("last_displayed_papers", {}),
232
- },
233
- # Always return to supervisor
234
- goto="supervisor",
52
+ # Load hydra configuration
53
+ logger.log(logging.INFO, "Launching Talk2Scholars with thread_id %s", uniq_id)
54
+ with hydra.initialize(version_base=None, config_path="../configs/"):
55
+ cfg = hydra.compose(
56
+ config_name="config", overrides=["agents/talk2scholars/main_agent=default"]
235
57
  )
58
+ cfg = cfg.agents.talk2scholars.main_agent
59
+ logger.log(logging.INFO, "System_prompt of Talk2Scholars: %s", cfg.system_prompt)
60
+ # Create supervisor workflow
61
+ workflow = create_supervisor(
62
+ [
63
+ get_app_s2(uniq_id, llm_model), # semantic scholar
64
+ get_app_zotero(uniq_id, llm_model), # zotero
65
+ ],
66
+ model=llm_model,
67
+ state_schema=Talk2Scholars,
68
+ # Full history is needed to extract
69
+ # the tool artifacts
70
+ output_mode="full_history",
71
+ add_handoff_back_messages=False,
72
+ prompt=cfg.system_prompt,
73
+ )
74
+
75
+ # Compile and run
76
+ app = workflow.compile(checkpointer=MemorySaver(), name="Talk2Scholars_MainAgent")
236
77
 
237
- # Initialize LLM
238
- logger.info("Using model %s with temperature %s", llm_model, cfg.temperature)
239
-
240
- # Build the graph
241
- workflow = StateGraph(Talk2Scholars)
242
- supervisor = make_supervisor_node(llm_model, thread_id)
243
- # Add nodes
244
- workflow.add_node("supervisor", supervisor)
245
- workflow.add_node("s2_agent", call_s2_agent)
246
- workflow.add_node("zotero_agent", call_zotero_agent)
247
- # Add edges
248
- workflow.add_edge(START, "supervisor")
249
- # Compile the workflow
250
- app = workflow.compile(checkpointer=MemorySaver())
251
- logger.info("Main agent workflow compiled")
252
78
  return app
@@ -28,9 +28,7 @@ logging.basicConfig(level=logging.INFO)
28
28
  logger = logging.getLogger(__name__)
29
29
 
30
30
 
31
- def get_app(
32
- uniq_id, llm_model: BaseChatModel
33
- ):
31
+ def get_app(uniq_id, llm_model: BaseChatModel):
34
32
  """
35
33
  Initializes and returns the LangGraph application for the Semantic Scholar (S2) agent.
36
34
 
@@ -86,6 +84,7 @@ def get_app(
86
84
  config_name="config", overrides=["agents/talk2scholars/s2_agent=default"]
87
85
  )
88
86
  cfg = cfg.agents.talk2scholars.s2_agent
87
+ logger.log(logging.INFO, "Loaded configuration for S2 agent")
89
88
 
90
89
  # Define the tools
91
90
  tools = ToolNode(
@@ -107,7 +106,7 @@ def get_app(
107
106
  llm_model,
108
107
  tools=tools,
109
108
  state_schema=Talk2Scholars,
110
- state_modifier=cfg.s2_agent,
109
+ prompt=cfg.s2_agent,
111
110
  checkpointer=MemorySaver(),
112
111
  )
113
112
 
@@ -122,7 +121,12 @@ def get_app(
122
121
  # This compiles it into a LangChain Runnable,
123
122
  # meaning you can use it as you would any other runnable.
124
123
  # Note that we're (optionally) passing the memory when compiling the graph
125
- app = workflow.compile(checkpointer=checkpointer)
126
- logger.log(logging.INFO, "Compiled the graph")
124
+ app = workflow.compile(checkpointer=checkpointer, name="agent_s2")
125
+ logger.log(
126
+ logging.INFO,
127
+ "Compiled the graph with thread_id %s and llm_model %s",
128
+ uniq_id,
129
+ llm_model,
130
+ )
127
131
 
128
132
  return app
@@ -14,6 +14,7 @@ from langgraph.prebuilt import create_react_agent, ToolNode
14
14
  from langgraph.checkpoint.memory import MemorySaver
15
15
  from ..state.state_talk2scholars import Talk2Scholars
16
16
  from ..tools.zotero.zotero_read import zotero_search_tool
17
+ from ..tools.zotero.zotero_write import zotero_save_tool
17
18
  from ..tools.s2.display_results import display_results as s2_display
18
19
  from ..tools.s2.query_results import query_results as s2_query_results
19
20
  from ..tools.s2.retrieve_semantic_scholar_paper_id import (
@@ -25,9 +26,7 @@ logging.basicConfig(level=logging.INFO)
25
26
  logger = logging.getLogger(__name__)
26
27
 
27
28
 
28
- def get_app(
29
- uniq_id, llm_model: BaseChatModel
30
- ):
29
+ def get_app(uniq_id, llm_model: BaseChatModel):
31
30
  """
32
31
  Initializes and returns the LangGraph application for the Zotero agent.
33
32
 
@@ -83,6 +82,7 @@ def get_app(
83
82
  overrides=["agents/talk2scholars/zotero_agent=default"],
84
83
  )
85
84
  cfg = cfg.agents.talk2scholars.zotero_agent
85
+ logger.log(logging.INFO, "Loaded configuration for Zotero agent")
86
86
 
87
87
  # Define the tools
88
88
  tools = ToolNode(
@@ -91,6 +91,7 @@ def get_app(
91
91
  s2_display,
92
92
  s2_query_results,
93
93
  retrieve_semantic_scholar_paper_id,
94
+ zotero_save_tool,
94
95
  ]
95
96
  )
96
97
 
@@ -102,7 +103,7 @@ def get_app(
102
103
  llm_model,
103
104
  tools=tools,
104
105
  state_schema=Talk2Scholars,
105
- state_modifier=cfg.zotero_agent,
106
+ prompt=cfg.zotero_agent,
106
107
  checkpointer=MemorySaver(),
107
108
  )
108
109
 
@@ -114,7 +115,12 @@ def get_app(
114
115
  checkpointer = MemorySaver()
115
116
 
116
117
  # Compile the graph
117
- app = workflow.compile(checkpointer=checkpointer)
118
- logger.log(logging.INFO, "Compiled the graph")
118
+ app = workflow.compile(checkpointer=checkpointer, name="agent_zotero")
119
+ logger.log(
120
+ logging.INFO,
121
+ "Compiled the graph with thread_id %s and llm_model %s",
122
+ uniq_id,
123
+ llm_model,
124
+ )
119
125
 
120
126
  return app
@@ -1,9 +1,4 @@
1
1
  _target_: agents.main_agent.get_app
2
- openai_api_key: ${oc.env:OPENAI_API_KEY}
3
- openai_llms:
4
- - "gpt-4o-mini"
5
- - "gpt-4-turbo"
6
- - "gpt-3.5-turbo"
7
2
  temperature: 0
8
3
  system_prompt: >
9
4
  You are the Talk2Scholars agent coordinating academic paper discovery and analysis.
@@ -14,46 +9,5 @@ system_prompt: >
14
9
  general paper searches and recommendations.
15
10
  2. Zotero_agent: This agent can be used to retrieve, display, and query
16
11
  papers from the Zotero library. Use this agent only when the user
17
- explicitly asks for papers from Zotero.
18
-
19
- router_prompt: >
20
- You are a supervisor tasked with managing a conversation between the
21
- following workers/members: ["s2_agent", "zotero_agent"] Given the user request, respond with the
22
- worker to act next. Each worker will perform a task and respond with
23
- their results and status. When finished, respond with FINISH.
24
-
25
- Here is a description of the workers:
26
- 1. S2_agent: This agent can be used to search and recommend papers
27
- from Semantic Scholar. Use this agent when the user asks for
28
- general paper searches and recommendations. This agent can also
29
- retrieve the Semantic Scholar ID of a paper. It can also be used to
30
- provide more information about a paper.
31
- 2. Zotero_agent: This agent can be used to retrieve, display, and query
32
- papers from the Zotero library. Use this agent only when the user
33
- explicitly asks for papers from Zotero. This agent can also
34
- retrieve the Semantic Scholar ID of a paper.
35
-
36
- CRITICAL RULES:
37
- 1. Do not generate any content or modify worker outputs
38
- 2. Route to FINISH ONLY when a worker has COMPLETELY finished their task
39
- 3. For the S2_agent and zotero_agent, ensure it has both SEARCHED and DISPLAYED results before FINISH
40
-
41
- Available workers: members
42
-
43
- Worker descriptions:
44
- 1. S2_agent: Routes to this agent ONLY for:
45
- - Initial paper searches
46
- - Getting paper recommendations
47
- - Retrieving paper IDs based on the title of a paper
48
- - Displaying search/recommendation results
49
- - Query over papers
50
- 2. Zotero_agent: Routes to this agent ONLY for:
51
- - Paper/journals searches from Zotero library
52
- - Displaying search results
53
- - Retrieving paper IDs based on the title of a paper
54
- - Query over papers
55
-
56
- Respond with FINISH when and ONLY when:
57
- 1. A worker has COMPLETELY finished their task (including display)
58
- 2. The results have been displayed to the user using display_results
59
- 3. No further action is needed
12
+ explicitly asks for papers from Zotero. This tool can also be used to
13
+ save papers in under collections in the zotero library
@@ -1,42 +1,19 @@
1
1
  _target_: agents.s2_agent.get_app
2
- openai_api_key: ${oc.env:OPENAI_API_KEY}
3
- openai_llms:
4
- - "gpt-4o-mini"
5
- - "gpt-4-turbo"
6
- - "gpt-3.5-turbo"
7
- temperature: 0
8
2
  s2_agent: >
9
3
  You are an academic research assistant with access to the
10
4
  Semantic Scholar API for paper discovery and analysis.
11
5
 
12
6
  AVAILABLE TOOLS:
13
- 1. search_tool - Search for academic papers by query string
7
+ 1. search - Search for academic papers by query string
14
8
  2. display_results - Display the papers retrieved by other tools
15
9
  3. single_paper_rec - Get recommendations based on a SINGLE paper
16
10
  4. multi_paper_rec - Get recommendations based on MULTIPLE papers
17
11
  5. query_results - Ask questions about the current set of papers
18
12
  6. retrieve_semantic_scholar_paper_id - Get Semantic Scholar ID for a paper title
19
13
 
20
- You also have tools to gain more insights on the papers and
21
- display them.
22
- You must strictly rely on retrieved information and avoid
23
- generating unsupported content. Do not generate hallucinations
24
- or fabricate details of any article. Stay focused on accurate,
25
- sourced academic insights.
26
-
27
- CRITICAL INSTRUCTIONS:
28
- 1. You must ONLY use information retrieved directly from the API
29
- 2. NEVER generate or fabricate paper details
30
- 3. NEVER modify or enhance the API responses
31
- 4. If information is missing from the API response, state that it's not available
32
- 5. ALWAYS CALL THE DISPLAY_RESULTS TOOL after completing a search
33
-
34
- WORKFLOW STEPS (ALWAYS FOLLOW THIS EXACT SEQUENCE):
14
+ WORKFLOW STEPS:
35
15
  1. When user requests papers, use search/recommendation tools to find papers
36
- 2. IMMEDIATELY AFTER `search_tool`, `single_paper_rec`, `multi_paper_rec` completes, ALWAYS call display_results tool
16
+ 2. Use `display_results` tool to display the response from the search/recommendation tools
37
17
  3. Use `query_results` tool to query over the selected paper only when the user asks to
38
- 4. NEVER skip the display_results step - it is REQUIRED for showing results to the user
39
- 5. Do not try to analyze or summarize papers yourself
40
-
41
- Remember: The display_results tool is MANDATORY after every search -
42
- without it, users cannot see the search results.
18
+ 4. When the user wants recommendations, you can get the "paper_id" using `query_results` tool in the "last_displayed_results" key, then
19
+ pass the "paper_id" to `search`, `single_paper_rec` or `multi_paper_rec` tools depending on the user's query. Do not use "arxiv_id"
@@ -1,10 +1,4 @@
1
1
  target: agents.zotero_agent.get_app
2
- openai_api_key: ${oc.env:OPENAI_API_KEY}
3
- openai_llms:
4
- - "gpt-4o-mini"
5
- - "gpt-4-turbo"
6
- - "gpt-3.5-turbo"
7
- temperature: 0
8
2
  zotero_agent: >
9
3
  You are a specialized Zotero library agent with access to tools for paper retrieval and management.
10
4
 
@@ -13,23 +7,13 @@ zotero_agent: >
13
7
  2. display_results - Display the papers retrieved by other tools
14
8
  3. query_results - Ask questions about the current set of papers
15
9
  4. retrieve_semantic_scholar_paper_id - Get Semantic Scholar ID for a paper title for the papers from zotero library
10
+ 5. zotero_write - Save paper to users zotero library under specfied collections
16
11
 
17
- You also have tools to gain more insights on the papers and display them.
18
- You must strictly rely on retrieved information and avoid generating unsupported content. Do not generate hallucinations or fabricate details of any article. Stay focused on accurate, sourced academic insights.
19
12
 
20
- CRITICAL INSTRUCTIONS:
21
- 1. You must ONLY use information retrieved directly from the Zotero Library
22
- 2. NEVER generate or fabricate paper details
23
- 3. NEVER modify or enhance the responses
24
- 4. If information is missing from the response, state that it's not available
25
- 5. ALWAYS CALL THE DISPLAY_RESULTS TOOL after completing a search
26
-
27
- WORKFLOW STEPS (ALWAYS FOLLOW THIS EXACT SEQUENCE):
13
+ WORKFLOW STEPS
28
14
  1. When user requests papers, use `zotero_search_tool` to find papers
29
- 2. IMMEDIATELY AFTER `zotero_search_tool` completes, ALWAYS call display_results tool
15
+ 2. Use `display_results` tool to display the response
30
16
  3. Use `query_results` tool to query over the selected paper only when the user asks to
31
17
  4. Use `retrieve_semantic_scholar_paper_id` to get the semantic scholar id of a paper title for the papers from zotero library
32
- 5. NEVER skip the display_results step - it is REQUIRED for showing results to the user
33
- 6. Do not try to analyze or summarize papers yourself
34
-
35
- Remember: The display_results tool is MANDATORY after every search - without it, users cannot see the search results.
18
+ 5. Use `zotero_write` to save the papers to users zotero library under collections and call `display_results` only after you recive
19
+ the save was successfull
@@ -11,3 +11,4 @@ defaults:
11
11
  - tools/retrieve_semantic_scholar_paper_id: default
12
12
  - tools/question_and_answer: default
13
13
  - tools/zotero_read: default
14
+ - tools/zotero_write: default
@@ -7,3 +7,4 @@ from . import single_paper_recommendation
7
7
  from . import multi_paper_recommendation
8
8
  from . import question_and_answer
9
9
  from . import zotero_read
10
+ from . import zotero_write
@@ -9,8 +9,8 @@ api_fields:
9
9
  - "authors"
10
10
  - "citationCount"
11
11
  - "url"
12
+ - "externalIds"
12
13
  # Commented fields that could be added later if needed
13
- # - "externalIds"
14
14
 
15
15
  # Default headers and params
16
16
  headers:
@@ -9,8 +9,8 @@ api_fields:
9
9
  - "authors"
10
10
  - "citationCount"
11
11
  - "url"
12
+ - "externalIds"
12
13
  # Commented fields that could be added later if needed
13
- # - "externalIds"
14
14
  # - "publicationTypes"
15
15
  # - "openAccessPdf"
16
16
 
@@ -9,8 +9,8 @@ api_fields:
9
9
  - "authors"
10
10
  - "citationCount"
11
11
  - "url"
12
+ - "externalIds"
12
13
  # Commented fields that could be added later if needed
13
- # - "externalIds"
14
14
  # - "publicationTypes"
15
15
  # - "openAccessPdf"
16
16
 
@@ -12,4 +12,45 @@ search_params:
12
12
  # Item Types and Limit
13
13
  zotero:
14
14
  max_limit: 100
15
- filter_item_types: ["journalArticle", "conferencePaper", "preprint"]
15
+ filter_item_types:
16
+ [
17
+ "Artwork",
18
+ "Audio Recording",
19
+ "Bill",
20
+ "Blog Post",
21
+ "Book",
22
+ "Book Section",
23
+ "Case",
24
+ "Conference Paper",
25
+ "Dataset",
26
+ "Dictionary Entry",
27
+ "Document",
28
+ "E-mail",
29
+ "Encyclopedia Article",
30
+ "Film",
31
+ "Forum Post",
32
+ "Hearing",
33
+ "Instant Message",
34
+ "Interview",
35
+ "Journal Article",
36
+ "Letter",
37
+ "Magazine Article",
38
+ "Manuscript",
39
+ "Map",
40
+ "Newspaper Article",
41
+ "Patent",
42
+ "Podcast",
43
+ "Preprint",
44
+ "Presentation",
45
+ "Radio Broadcast",
46
+ "Report",
47
+ "Software",
48
+ "Standard",
49
+ "Statute",
50
+ "Thesis",
51
+ "TV Broadcast",
52
+ "Video Recording",
53
+ "Web Page",
54
+ ]
55
+
56
+ filter_excluded_types: ["attachment", "note", "annotation"]
@@ -0,0 +1,3 @@
1
+ """
2
+ Import all the modules in the package
3
+ """