aiagents4pharma 1.20.0__py3-none-any.whl → 1.21.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/talk2biomodels/configs/config.yaml +5 -0
- aiagents4pharma/talk2scholars/agents/main_agent.py +90 -91
- aiagents4pharma/talk2scholars/agents/s2_agent.py +61 -17
- aiagents4pharma/talk2scholars/configs/agents/talk2scholars/main_agent/default.yaml +31 -10
- aiagents4pharma/talk2scholars/configs/agents/talk2scholars/s2_agent/default.yaml +8 -16
- aiagents4pharma/talk2scholars/configs/app/frontend/default.yaml +11 -9
- aiagents4pharma/talk2scholars/configs/config.yaml +1 -0
- aiagents4pharma/talk2scholars/configs/tools/multi_paper_recommendation/default.yaml +2 -0
- aiagents4pharma/talk2scholars/configs/tools/retrieve_semantic_scholar_paper_id/__init__.py +3 -0
- aiagents4pharma/talk2scholars/configs/tools/search/default.yaml +1 -0
- aiagents4pharma/talk2scholars/configs/tools/single_paper_recommendation/default.yaml +1 -0
- aiagents4pharma/talk2scholars/state/state_talk2scholars.py +36 -7
- aiagents4pharma/talk2scholars/tests/test_llm_main_integration.py +58 -0
- aiagents4pharma/talk2scholars/tests/test_main_agent.py +98 -122
- aiagents4pharma/talk2scholars/tests/test_s2_agent.py +95 -29
- aiagents4pharma/talk2scholars/tests/test_s2_tools.py +158 -22
- aiagents4pharma/talk2scholars/tools/s2/__init__.py +4 -2
- aiagents4pharma/talk2scholars/tools/s2/display_results.py +60 -21
- aiagents4pharma/talk2scholars/tools/s2/multi_paper_rec.py +35 -8
- aiagents4pharma/talk2scholars/tools/s2/query_results.py +61 -0
- aiagents4pharma/talk2scholars/tools/s2/retrieve_semantic_scholar_paper_id.py +79 -0
- aiagents4pharma/talk2scholars/tools/s2/search.py +34 -10
- aiagents4pharma/talk2scholars/tools/s2/single_paper_rec.py +39 -9
- {aiagents4pharma-1.20.0.dist-info → aiagents4pharma-1.21.0.dist-info}/METADATA +2 -2
- {aiagents4pharma-1.20.0.dist-info → aiagents4pharma-1.21.0.dist-info}/RECORD +28 -24
- aiagents4pharma/talk2scholars/tests/test_integration.py +0 -237
- {aiagents4pharma-1.20.0.dist-info → aiagents4pharma-1.21.0.dist-info}/LICENSE +0 -0
- {aiagents4pharma-1.20.0.dist-info → aiagents4pharma-1.21.0.dist-info}/WHEEL +0 -0
- {aiagents4pharma-1.20.0.dist-info → aiagents4pharma-1.21.0.dist-info}/top_level.txt +0 -0
@@ -6,28 +6,17 @@ Main agent for the talk2scholars app using ReAct pattern.
|
|
6
6
|
This module implements a hierarchical agent system where a supervisor agent
|
7
7
|
routes queries to specialized sub-agents. It follows the LangGraph patterns
|
8
8
|
for multi-agent systems and implements proper state management.
|
9
|
-
|
10
|
-
The main components are:
|
11
|
-
1. Supervisor node with ReAct pattern for intelligent routing.
|
12
|
-
2. S2 agent node for handling academic paper queries.
|
13
|
-
3. Shared state management via Talk2Scholars.
|
14
|
-
4. Hydra-based configuration system.
|
15
|
-
|
16
|
-
Example:
|
17
|
-
app = get_app("thread_123", "gpt-4o-mini")
|
18
|
-
result = app.invoke({
|
19
|
-
"messages": [("human", "Find papers about AI agents")]
|
20
|
-
})
|
21
9
|
"""
|
22
10
|
|
23
11
|
import logging
|
24
12
|
from typing import Literal, Callable
|
13
|
+
from pydantic import BaseModel
|
25
14
|
import hydra
|
26
15
|
from langchain_core.language_models.chat_models import BaseChatModel
|
16
|
+
from langchain_core.messages import SystemMessage, HumanMessage, AIMessage
|
27
17
|
from langchain_openai import ChatOpenAI
|
28
18
|
from langgraph.checkpoint.memory import MemorySaver
|
29
19
|
from langgraph.graph import END, START, StateGraph
|
30
|
-
from langgraph.prebuilt import create_react_agent
|
31
20
|
from langgraph.types import Command
|
32
21
|
from ..agents import s2_agent
|
33
22
|
from ..state.state_talk2scholars import Talk2Scholars
|
@@ -39,13 +28,13 @@ logger = logging.getLogger(__name__)
|
|
39
28
|
|
40
29
|
def get_hydra_config():
|
41
30
|
"""
|
42
|
-
Loads
|
31
|
+
Loads the Hydra configuration for the main agent.
|
43
32
|
|
44
|
-
This function
|
45
|
-
agent, ensuring that all required parameters are
|
33
|
+
This function initializes the Hydra configuration system and retrieves the settings
|
34
|
+
for the `Talk2Scholars` agent, ensuring that all required parameters are loaded.
|
46
35
|
|
47
36
|
Returns:
|
48
|
-
|
37
|
+
DictConfig: The configuration object containing parameters for the main agent.
|
49
38
|
"""
|
50
39
|
with hydra.initialize(version_base=None, config_path="../configs"):
|
51
40
|
cfg = hydra.compose(
|
@@ -54,116 +43,127 @@ def get_hydra_config():
|
|
54
43
|
return cfg.agents.talk2scholars.main_agent
|
55
44
|
|
56
45
|
|
57
|
-
def make_supervisor_node(
|
46
|
+
def make_supervisor_node(llm_model: BaseChatModel, thread_id: str) -> Callable:
|
58
47
|
"""
|
59
|
-
Creates
|
48
|
+
Creates the supervisor node responsible for routing user queries to the appropriate sub-agents.
|
60
49
|
|
61
|
-
This function initializes
|
62
|
-
|
63
|
-
|
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`)
|
53
|
+
or directly generate a response using the language model.
|
64
54
|
|
65
55
|
Args:
|
66
|
-
|
67
|
-
thread_id (str): Unique identifier for the conversation session.
|
56
|
+
llm_model (BaseChatModel): The language model used for decision-making.
|
57
|
+
thread_id (str): Unique identifier for the current conversation session.
|
68
58
|
|
69
59
|
Returns:
|
70
|
-
Callable:
|
71
|
-
|
72
|
-
Example:
|
73
|
-
supervisor = make_supervisor_node(llm, "thread_123")
|
74
|
-
workflow.add_node("supervisor", supervisor)
|
60
|
+
Callable: The supervisor node function that processes user queries and
|
61
|
+
decides the next step.
|
75
62
|
"""
|
76
|
-
logger.info("Loading Hydra configuration for Talk2Scholars main agent.")
|
77
63
|
cfg = get_hydra_config()
|
78
|
-
logger.info("Hydra configuration
|
64
|
+
logger.info("Hydra configuration for Talk2Scholars main agent loaded: %s", cfg)
|
65
|
+
members = ["s2_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
|
71
|
+
|
72
|
+
class Router(BaseModel):
|
73
|
+
"""Worker to route to next. If no workers needed, route to FINISH."""
|
79
74
|
|
80
|
-
|
81
|
-
supervisor_agent = create_react_agent(
|
82
|
-
llm,
|
83
|
-
tools=[], # Will add sub-agents later
|
84
|
-
state_modifier=cfg.main_agent,
|
85
|
-
state_schema=Talk2Scholars,
|
86
|
-
checkpointer=MemorySaver(),
|
87
|
-
)
|
75
|
+
next: Literal[*options]
|
88
76
|
|
89
77
|
def supervisor_node(
|
90
78
|
state: Talk2Scholars,
|
91
|
-
) -> Command
|
79
|
+
) -> Command:
|
92
80
|
"""
|
93
|
-
|
81
|
+
Handles the routing logic for the supervisor agent.
|
94
82
|
|
95
|
-
This function
|
96
|
-
|
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.
|
97
85
|
|
98
86
|
Args:
|
99
|
-
state (Talk2Scholars): The current state
|
100
|
-
|
87
|
+
state (Talk2Scholars): The current conversation state, including messages
|
88
|
+
exchanged so far.
|
101
89
|
|
102
90
|
Returns:
|
103
|
-
Command:
|
104
|
-
|
105
|
-
Example:
|
106
|
-
result = supervisor_node(current_state)
|
107
|
-
next_step = result.goto
|
91
|
+
Command: A command dictating whether to invoke a sub-agent or generate a final response.
|
108
92
|
"""
|
109
|
-
|
110
|
-
|
111
|
-
|
112
|
-
|
113
|
-
|
114
|
-
|
115
|
-
|
116
|
-
|
117
|
-
|
118
|
-
|
119
|
-
|
120
|
-
|
93
|
+
messages = [SystemMessage(content=router_prompt)] + 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
|
121
114
|
return Command(goto=goto)
|
122
115
|
|
123
116
|
return supervisor_node
|
124
117
|
|
125
118
|
|
126
|
-
def get_app(
|
119
|
+
def get_app(
|
120
|
+
thread_id: str,
|
121
|
+
llm_model: BaseChatModel = ChatOpenAI(model="gpt-4o-mini", temperature=0),
|
122
|
+
):
|
127
123
|
"""
|
128
|
-
Initializes and returns the LangGraph
|
124
|
+
Initializes and returns the LangGraph-based hierarchical agent system.
|
129
125
|
|
130
|
-
This function
|
131
|
-
and sub-agents
|
126
|
+
This function constructs the agent workflow by defining nodes for the supervisor
|
127
|
+
and sub-agents. It compiles the graph using `StateGraph` to enable structured
|
128
|
+
conversational workflows.
|
132
129
|
|
133
130
|
Args:
|
134
|
-
thread_id (str):
|
135
|
-
llm_model (
|
131
|
+
thread_id (str): A unique session identifier for tracking conversation state.
|
132
|
+
llm_model (BaseChatModel, optional): The language model used for query processing.
|
133
|
+
Defaults to `ChatOpenAI(model="gpt-4o-mini", temperature=0)`.
|
136
134
|
|
137
135
|
Returns:
|
138
|
-
StateGraph: A compiled LangGraph application
|
136
|
+
StateGraph: A compiled LangGraph application that can process user queries.
|
139
137
|
|
140
138
|
Example:
|
141
|
-
app = get_app("thread_123")
|
142
|
-
result = app.invoke(initial_state)
|
139
|
+
>>> app = get_app("thread_123")
|
140
|
+
>>> result = app.invoke(initial_state)
|
143
141
|
"""
|
144
142
|
cfg = get_hydra_config()
|
145
143
|
|
146
144
|
def call_s2_agent(
|
147
145
|
state: Talk2Scholars,
|
148
|
-
) -> Command[Literal["supervisor"
|
146
|
+
) -> Command[Literal["supervisor"]]:
|
149
147
|
"""
|
150
|
-
|
148
|
+
Invokes the Semantic Scholar (S2) agent to retrieve relevant research papers.
|
151
149
|
|
152
|
-
This function
|
153
|
-
|
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.
|
154
153
|
|
155
154
|
Args:
|
156
|
-
state (Talk2Scholars): The current conversation
|
157
|
-
and any
|
155
|
+
state (Talk2Scholars): The current state of the conversation, containing messages
|
156
|
+
and any previous search results.
|
158
157
|
|
159
158
|
Returns:
|
160
|
-
Command:
|
159
|
+
Command: A command to update the conversation state with the retrieved papers
|
160
|
+
and return control to the supervisor node.
|
161
161
|
|
162
162
|
Example:
|
163
|
-
result = call_s2_agent(current_state)
|
164
|
-
next_step = result.goto
|
163
|
+
>>> result = call_s2_agent(current_state)
|
164
|
+
>>> next_step = result.goto
|
165
165
|
"""
|
166
|
-
logger.info("Calling S2 agent
|
166
|
+
logger.info("Calling S2 agent")
|
167
167
|
app = s2_agent.get_app(thread_id, llm_model)
|
168
168
|
|
169
169
|
# Invoke the S2 agent, passing state,
|
@@ -177,31 +177,30 @@ def get_app(thread_id: str, llm_model: str = "gpt-4o-mini") -> StateGraph:
|
|
177
177
|
}
|
178
178
|
},
|
179
179
|
)
|
180
|
-
logger.info("S2 agent completed with response
|
181
|
-
|
180
|
+
logger.info("S2 agent completed with response")
|
182
181
|
return Command(
|
183
|
-
goto=END,
|
184
182
|
update={
|
185
183
|
"messages": response["messages"],
|
186
184
|
"papers": response.get("papers", {}),
|
187
185
|
"multi_papers": response.get("multi_papers", {}),
|
186
|
+
"last_displayed_papers": response.get("last_displayed_papers", {}),
|
188
187
|
},
|
188
|
+
# Always return to supervisor
|
189
|
+
goto="supervisor",
|
189
190
|
)
|
190
191
|
|
191
192
|
# Initialize LLM
|
192
|
-
logger.info("Using
|
193
|
-
llm = ChatOpenAI(model=llm_model, temperature=cfg.temperature)
|
193
|
+
logger.info("Using model %s with temperature %s", llm_model, cfg.temperature)
|
194
194
|
|
195
195
|
# Build the graph
|
196
196
|
workflow = StateGraph(Talk2Scholars)
|
197
|
-
supervisor = make_supervisor_node(
|
198
|
-
|
197
|
+
supervisor = make_supervisor_node(llm_model, thread_id)
|
198
|
+
# Add nodes
|
199
199
|
workflow.add_node("supervisor", supervisor)
|
200
200
|
workflow.add_node("s2_agent", call_s2_agent)
|
201
|
+
# Add edges
|
201
202
|
workflow.add_edge(START, "supervisor")
|
202
|
-
workflow
|
203
|
-
|
204
|
-
# Compile the graph without initial state
|
203
|
+
# Compile the workflow
|
205
204
|
app = workflow.compile(checkpointer=MemorySaver())
|
206
205
|
logger.info("Main agent workflow compiled")
|
207
206
|
return app
|
@@ -5,37 +5,80 @@ Agent for interacting with Semantic Scholar
|
|
5
5
|
"""
|
6
6
|
|
7
7
|
import logging
|
8
|
+
from typing import Any, Dict
|
8
9
|
import hydra
|
9
10
|
from langchain_openai import ChatOpenAI
|
11
|
+
from langchain_core.language_models.chat_models import BaseChatModel
|
10
12
|
from langgraph.graph import START, StateGraph
|
11
13
|
from langgraph.prebuilt import create_react_agent, ToolNode
|
12
14
|
from langgraph.checkpoint.memory import MemorySaver
|
13
15
|
from ..state.state_talk2scholars import Talk2Scholars
|
14
16
|
from ..tools.s2.search import search_tool as s2_search
|
15
17
|
from ..tools.s2.display_results import display_results as s2_display
|
18
|
+
from ..tools.s2.query_results import query_results as s2_query_results
|
19
|
+
from ..tools.s2.retrieve_semantic_scholar_paper_id import (
|
20
|
+
retrieve_semantic_scholar_paper_id as s2_retrieve_id,
|
21
|
+
)
|
16
22
|
from ..tools.s2.single_paper_rec import (
|
17
23
|
get_single_paper_recommendations as s2_single_rec,
|
18
24
|
)
|
19
25
|
from ..tools.s2.multi_paper_rec import get_multi_paper_recommendations as s2_multi_rec
|
20
26
|
|
21
|
-
|
22
27
|
# Initialize logger
|
23
28
|
logging.basicConfig(level=logging.INFO)
|
24
29
|
logger = logging.getLogger(__name__)
|
25
30
|
|
26
31
|
|
27
|
-
def get_app(
|
32
|
+
def get_app(
|
33
|
+
uniq_id, llm_model: BaseChatModel = ChatOpenAI(model="gpt-4o-mini", temperature=0)
|
34
|
+
):
|
28
35
|
"""
|
29
|
-
|
36
|
+
Initializes and returns the LangGraph application for the Semantic Scholar (S2) agent.
|
37
|
+
|
38
|
+
This function sets up the S2 agent, which integrates various tools to search, retrieve,
|
39
|
+
and display research papers from Semantic Scholar. The agent follows the ReAct pattern
|
40
|
+
for structured interaction.
|
41
|
+
|
42
|
+
Args:
|
43
|
+
uniq_id (str): Unique identifier for the current conversation session.
|
44
|
+
llm_model (BaseChatModel, optional): The language model to be used by the agent.
|
45
|
+
Defaults to `ChatOpenAI(model="gpt-4o-mini", temperature=0)`.
|
46
|
+
|
47
|
+
Returns:
|
48
|
+
StateGraph: A compiled LangGraph application that enables the S2 agent to process
|
49
|
+
user queries and retrieve research papers.
|
50
|
+
|
51
|
+
Example:
|
52
|
+
>>> app = get_app("thread_123")
|
53
|
+
>>> result = app.invoke(initial_state)
|
30
54
|
"""
|
31
55
|
|
32
|
-
def agent_s2_node(state: Talk2Scholars):
|
56
|
+
# def agent_s2_node(state: Talk2Scholars) -> Command[Literal["supervisor"]]:
|
57
|
+
def agent_s2_node(state: Talk2Scholars) -> Dict[str, Any]:
|
33
58
|
"""
|
34
|
-
|
59
|
+
Processes the user query and retrieves relevant research papers.
|
60
|
+
|
61
|
+
This function calls the language model using the configured `ReAct` agent to analyze
|
62
|
+
the state and generate an appropriate response. The function then returns control
|
63
|
+
to the main supervisor.
|
64
|
+
|
65
|
+
Args:
|
66
|
+
state (Talk2Scholars): The current conversation state, including messages exchanged
|
67
|
+
and any previously retrieved research papers.
|
68
|
+
|
69
|
+
Returns:
|
70
|
+
Dict[str, Any]: A dictionary containing the updated conversation state.
|
71
|
+
|
72
|
+
Example:
|
73
|
+
>>> result = agent_s2_node(current_state)
|
74
|
+
>>> papers = result.get("papers", [])
|
35
75
|
"""
|
36
76
|
logger.log(logging.INFO, "Creating Agent_S2 node with thread_id %s", uniq_id)
|
37
|
-
|
38
|
-
|
77
|
+
result = model.invoke(state, {"configurable": {"thread_id": uniq_id}})
|
78
|
+
|
79
|
+
return result
|
80
|
+
|
81
|
+
logger.log(logging.INFO, "thread_id, llm_model: %s, %s", uniq_id, llm_model)
|
39
82
|
|
40
83
|
# Load hydra configuration
|
41
84
|
logger.log(logging.INFO, "Load Hydra configuration for Talk2Scholars S2 agent.")
|
@@ -46,30 +89,31 @@ def get_app(uniq_id, llm_model="gpt-4o-mini"):
|
|
46
89
|
cfg = cfg.agents.talk2scholars.s2_agent
|
47
90
|
|
48
91
|
# Define the tools
|
49
|
-
tools = ToolNode(
|
92
|
+
tools = ToolNode(
|
93
|
+
[
|
94
|
+
s2_search,
|
95
|
+
s2_display,
|
96
|
+
s2_query_results,
|
97
|
+
s2_retrieve_id,
|
98
|
+
s2_single_rec,
|
99
|
+
s2_multi_rec,
|
100
|
+
]
|
101
|
+
)
|
50
102
|
|
51
103
|
# Define the model
|
52
104
|
logger.log(logging.INFO, "Using OpenAI model %s", llm_model)
|
53
|
-
llm = ChatOpenAI(model=llm_model, temperature=cfg.temperature)
|
54
105
|
|
55
106
|
# Create the agent
|
56
107
|
model = create_react_agent(
|
57
|
-
|
108
|
+
llm_model,
|
58
109
|
tools=tools,
|
59
110
|
state_schema=Talk2Scholars,
|
60
|
-
# prompt=cfg.s2_agent,
|
61
111
|
state_modifier=cfg.s2_agent,
|
62
112
|
checkpointer=MemorySaver(),
|
63
113
|
)
|
64
114
|
|
65
|
-
# Define a new graph
|
66
115
|
workflow = StateGraph(Talk2Scholars)
|
67
|
-
|
68
|
-
# Define the two nodes we will cycle between
|
69
116
|
workflow.add_node("agent_s2", agent_s2_node)
|
70
|
-
|
71
|
-
# Set the entrypoint as `agent`
|
72
|
-
# This means that this node is the first one called
|
73
117
|
workflow.add_edge(START, "agent_s2")
|
74
118
|
|
75
119
|
# Initialize memory to persist state between graph runs
|
@@ -5,14 +5,35 @@ openai_llms:
|
|
5
5
|
- "gpt-4-turbo"
|
6
6
|
- "gpt-3.5-turbo"
|
7
7
|
temperature: 0
|
8
|
-
|
9
|
-
You are
|
8
|
+
system_prompt: >
|
9
|
+
You are the Talk2Scholars agent coordinating academic paper discovery and analysis.
|
10
10
|
|
11
|
-
|
12
|
-
1.
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
11
|
+
You have access to the following agents:
|
12
|
+
1. S2_agent: This agent can be used to search and recommend papers
|
13
|
+
from Semantic Scholar. Use this agent when the user asks for
|
14
|
+
general paper searches and recommendations. This agent can also
|
15
|
+
retrieve the Semantic Scholar ID of a paper.
|
16
|
+
router_prompt: >
|
17
|
+
You are a supervisor tasked with managing a conversation between the
|
18
|
+
following workers: {members}. Given the user request, respond with the
|
19
|
+
worker to act next. Each worker will perform a task and respond with
|
20
|
+
their results and status. When finished, respond with FINISH.
|
21
|
+
|
22
|
+
Here is a description of the workers:
|
23
|
+
1. S2_agent: This agent can be used to search and recommend papers
|
24
|
+
from Semantic Scholar. Use this agent when the user asks for
|
25
|
+
general paper searches and recommendations. This agent can also
|
26
|
+
retrieve the Semantic Scholar ID of a paper. It can also be used to
|
27
|
+
provide more information about a paper.
|
28
|
+
|
29
|
+
Here are some instructions for the workers:
|
30
|
+
1. Call the S2 agent for general paper searches and recommendations.
|
31
|
+
2. The S2 agent has access to tools for querying and displaying papers.
|
32
|
+
3. If the user wants suggestions for papers and you don’t have
|
33
|
+
a Semantic Scholar ID for it but do have the title from
|
34
|
+
the last displayed results, use the S2 agent to retrieve the
|
35
|
+
Semantic Scholar ID of the paper. Then, use the S2 agent again to display
|
36
|
+
recommendations for the paper.
|
37
|
+
4. You can call the S2 agent to get more information about a paper based
|
38
|
+
on the context of the conversation.
|
39
|
+
5. Respond with FINISH when all tasks are completed.
|
@@ -6,19 +6,11 @@ openai_llms:
|
|
6
6
|
- "gpt-3.5-turbo"
|
7
7
|
temperature: 0
|
8
8
|
s2_agent: >
|
9
|
-
You are
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
- Shows the current research papers.
|
18
|
-
- If no papers are found, it will instruct you to perform a search.
|
19
|
-
|
20
|
-
3. get_single_paper_recommendations:
|
21
|
-
- Provides recommendations based on a single selected paper.
|
22
|
-
|
23
|
-
4. get_multi_paper_recommendations:
|
24
|
-
- Provides recommendations based on multiple selected papers.
|
9
|
+
You are an academic research assistant with access to the
|
10
|
+
Semantic Scholar API for paper discovery and analysis.
|
11
|
+
You also have tools to gain more insights on the papers and
|
12
|
+
display them.
|
13
|
+
You must strictly rely on retrieved information and avoid
|
14
|
+
generating unsupported content. Do not generate hallucinations
|
15
|
+
or fabricate details of any article. Stay focused on accurate,
|
16
|
+
sourced academic insights.
|
@@ -1,14 +1,13 @@
|
|
1
|
-
#
|
2
|
-
|
3
|
-
|
4
|
-
|
5
|
-
|
1
|
+
# Page configuration
|
2
|
+
page:
|
3
|
+
title: "Talk2Scholars"
|
4
|
+
icon: "🤖"
|
5
|
+
layout: "wide"
|
6
6
|
|
7
7
|
# Available LLM models
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
- "gpt-3.5-turbo"
|
8
|
+
llms:
|
9
|
+
available_models:
|
10
|
+
- "OpenAI/gpt-4o-mini"
|
12
11
|
# # Chat UI configuration
|
13
12
|
# chat:
|
14
13
|
# assistant_avatar: "🤖"
|
@@ -16,6 +15,9 @@ llm_models:
|
|
16
15
|
# input_placeholder: "Say something ..."
|
17
16
|
# spinner_text: "Fetching response ..."
|
18
17
|
|
18
|
+
api_keys:
|
19
|
+
openai_key: "OPENAI_API_KEY"
|
20
|
+
nvidia_key: "NVIDIA_API_KEY"
|
19
21
|
# # Feedback configuration
|
20
22
|
# feedback:
|
21
23
|
# type: "thumbs"
|
@@ -1,9 +1,14 @@
|
|
1
1
|
"""
|
2
|
-
|
2
|
+
State management for the Talk2Scholars agent.
|
3
|
+
|
4
|
+
This module defines the state class `Talk2Scholars`, which maintains the conversation
|
5
|
+
context, retrieved papers, and other relevant metadata. The state ensures consistency
|
6
|
+
across agent interactions.
|
3
7
|
"""
|
4
8
|
|
5
9
|
import logging
|
6
10
|
from typing import Annotated, Any, Dict
|
11
|
+
from langchain_core.language_models import BaseChatModel
|
7
12
|
from langgraph.prebuilt.chat_agent_executor import AgentState
|
8
13
|
|
9
14
|
# Configure logging
|
@@ -12,22 +17,46 @@ logger = logging.getLogger(__name__)
|
|
12
17
|
|
13
18
|
|
14
19
|
def replace_dict(existing: Dict[str, Any], new: Dict[str, Any]) -> Dict[str, Any]:
|
15
|
-
"""
|
20
|
+
"""
|
21
|
+
Replaces the existing dictionary with a new dictionary.
|
22
|
+
|
23
|
+
This function logs the state update and ensures that the old state is replaced
|
24
|
+
with the new one.
|
25
|
+
|
26
|
+
Args:
|
27
|
+
existing (Dict[str, Any]): The current dictionary state.
|
28
|
+
new (Dict[str, Any]): The new dictionary state to replace the existing one.
|
29
|
+
|
30
|
+
Returns:
|
31
|
+
Dict[str, Any]: The updated dictionary state.
|
32
|
+
|
33
|
+
Example:
|
34
|
+
>>> old_state = {"papers": {"id1": "Paper 1"}}
|
35
|
+
>>> new_state = {"papers": {"id2": "Paper 2"}}
|
36
|
+
>>> updated_state = replace_dict(old_state, new_state)
|
37
|
+
>>> print(updated_state)
|
38
|
+
{"papers": {"id2": "Paper 2"}}
|
39
|
+
"""
|
16
40
|
logger.info("Updating existing state %s with the state dict: %s", existing, new)
|
17
41
|
return new
|
18
42
|
|
19
43
|
|
20
44
|
class Talk2Scholars(AgentState):
|
21
45
|
"""
|
22
|
-
|
46
|
+
Represents the state of the Talk2Scholars agent.
|
47
|
+
|
48
|
+
This class extends `AgentState` to maintain conversation history, retrieved papers,
|
49
|
+
and interactions with the language model.
|
23
50
|
|
24
51
|
Attributes:
|
25
|
-
|
26
|
-
|
27
|
-
|
52
|
+
last_displayed_papers (Dict[str, Any]): Stores the most recently displayed papers.
|
53
|
+
papers (Dict[str, Any]): Stores the research papers retrieved from the agent's queries.
|
54
|
+
multi_papers (Dict[str, Any]): Stores multiple recommended papers from various sources.
|
55
|
+
llm_model (BaseChatModel): The language model instance used for generating responses.
|
28
56
|
"""
|
29
57
|
|
30
58
|
# Agent state fields
|
59
|
+
last_displayed_papers: Annotated[Dict[str, Any], replace_dict]
|
31
60
|
papers: Annotated[Dict[str, Any], replace_dict]
|
32
61
|
multi_papers: Annotated[Dict[str, Any], replace_dict]
|
33
|
-
llm_model:
|
62
|
+
llm_model: BaseChatModel
|