Spaces:
Runtime error
Runtime error
Update graph/workflow.py
Browse files- graph/workflow.py +19 -31
graph/workflow.py
CHANGED
|
@@ -2,10 +2,10 @@
|
|
| 2 |
LangGraph workflow for pharmaceutical data management agents.
|
| 3 |
"""
|
| 4 |
|
| 5 |
-
from langgraph.graph import StateGraph, END
|
| 6 |
from langchain.tools import StructuredTool
|
| 7 |
from langchain_core.tools import tool
|
| 8 |
-
from typing import Dict, Any, List
|
| 9 |
|
| 10 |
from agents.state import AgentState
|
| 11 |
from agents.understanding import understanding_agent
|
|
@@ -19,8 +19,8 @@ from agents.tools import (
|
|
| 19 |
tool_execute_query,
|
| 20 |
tool_get_confidence
|
| 21 |
)
|
|
|
|
| 22 |
|
| 23 |
-
# Fix for the workflow.py file
|
| 24 |
def create_agent_graph(anthropic_client, db):
|
| 25 |
"""
|
| 26 |
Create the agent workflow graph.
|
|
@@ -30,7 +30,7 @@ def create_agent_graph(anthropic_client, db):
|
|
| 30 |
db: The database connection
|
| 31 |
|
| 32 |
Returns:
|
| 33 |
-
Compiled LangGraph workflow
|
| 34 |
"""
|
| 35 |
# Wrap the agents with the anthropic client
|
| 36 |
understanding = lambda state: understanding_agent(anthropic_client, state)
|
|
@@ -47,8 +47,8 @@ def create_agent_graph(anthropic_client, db):
|
|
| 47 |
}
|
| 48 |
|
| 49 |
# Create a function to access the current state for the confidence tool
|
| 50 |
-
state_provider = lambda: state_dict
|
| 51 |
state_dict = {} # This will be updated in the Streamlit app
|
|
|
|
| 52 |
|
| 53 |
# Create tools node with database-related tools
|
| 54 |
# Convert our custom tools to LangChain StructuredTool format
|
|
@@ -110,16 +110,14 @@ def create_agent_graph(anthropic_client, db):
|
|
| 110 |
lc_tools.append(get_confidence)
|
| 111 |
|
| 112 |
# Create Tool Agent Node
|
| 113 |
-
#
|
| 114 |
-
# We'll create a tool handler function instead
|
| 115 |
def tool_handler(state: Dict[str, Any]) -> Dict[str, Any]:
|
| 116 |
"""Handle tool calls from the agent workflow."""
|
|
|
|
| 117 |
# This would normally implement logic to determine which tool to call
|
| 118 |
-
# based on the agent's request, but for this demo we'll use a simpler approach
|
| 119 |
# In production, you would parse agent messages to identify tool calls
|
| 120 |
|
| 121 |
-
# Just return the state unmodified - tools are actually called via the
|
| 122 |
-
# in each agent's implementation
|
| 123 |
return state
|
| 124 |
|
| 125 |
nodes["tools"] = tool_handler
|
|
@@ -131,15 +129,16 @@ def create_agent_graph(anthropic_client, db):
|
|
| 131 |
for name, node in nodes.items():
|
| 132 |
workflow.add_node(name, node)
|
| 133 |
|
| 134 |
-
#
|
| 135 |
-
|
|
|
|
|
|
|
| 136 |
workflow.add_conditional_edges(
|
| 137 |
"understanding_agent",
|
| 138 |
lambda x: x["current_agent"],
|
| 139 |
{
|
| 140 |
"understanding_agent": "understanding_agent",
|
| 141 |
-
"planning_agent": "planning_agent"
|
| 142 |
-
"tools": "tools" # Add tools as a possible destination
|
| 143 |
}
|
| 144 |
)
|
| 145 |
|
|
@@ -148,8 +147,7 @@ def create_agent_graph(anthropic_client, db):
|
|
| 148 |
lambda x: x["current_agent"],
|
| 149 |
{
|
| 150 |
"planning_agent": "planning_agent",
|
| 151 |
-
"sql_generator_agent": "sql_generator_agent"
|
| 152 |
-
"tools": "tools" # Add tools as a possible destination
|
| 153 |
}
|
| 154 |
)
|
| 155 |
|
|
@@ -158,27 +156,17 @@ def create_agent_graph(anthropic_client, db):
|
|
| 158 |
lambda x: x["current_agent"],
|
| 159 |
{
|
| 160 |
"sql_generator_agent": "sql_generator_agent",
|
| 161 |
-
"executor_agent": "executor_agent"
|
| 162 |
-
"tools": "tools" # Add tools as a possible destination
|
| 163 |
}
|
| 164 |
)
|
| 165 |
|
| 166 |
# Executor agent finishes the workflow
|
| 167 |
workflow.add_edge("executor_agent", END)
|
| 168 |
|
| 169 |
-
# Add
|
| 170 |
-
|
| 171 |
-
|
| 172 |
-
|
| 173 |
-
"tools",
|
| 174 |
-
lambda x: x["current_agent"],
|
| 175 |
-
{
|
| 176 |
-
"understanding_agent": "understanding_agent",
|
| 177 |
-
"planning_agent": "planning_agent",
|
| 178 |
-
"sql_generator_agent": "sql_generator_agent",
|
| 179 |
-
"executor_agent": "executor_agent"
|
| 180 |
-
}
|
| 181 |
-
)
|
| 182 |
|
| 183 |
# Compile the workflow
|
| 184 |
app = workflow.compile()
|
|
|
|
| 2 |
LangGraph workflow for pharmaceutical data management agents.
|
| 3 |
"""
|
| 4 |
|
| 5 |
+
from langgraph.graph import StateGraph, END, START
|
| 6 |
from langchain.tools import StructuredTool
|
| 7 |
from langchain_core.tools import tool
|
| 8 |
+
from typing import Dict, Any, List, Callable
|
| 9 |
|
| 10 |
from agents.state import AgentState
|
| 11 |
from agents.understanding import understanding_agent
|
|
|
|
| 19 |
tool_execute_query,
|
| 20 |
tool_get_confidence
|
| 21 |
)
|
| 22 |
+
from agents.utils.logging import log_agent_activity
|
| 23 |
|
|
|
|
| 24 |
def create_agent_graph(anthropic_client, db):
|
| 25 |
"""
|
| 26 |
Create the agent workflow graph.
|
|
|
|
| 30 |
db: The database connection
|
| 31 |
|
| 32 |
Returns:
|
| 33 |
+
Compiled LangGraph workflow and state update function
|
| 34 |
"""
|
| 35 |
# Wrap the agents with the anthropic client
|
| 36 |
understanding = lambda state: understanding_agent(anthropic_client, state)
|
|
|
|
| 47 |
}
|
| 48 |
|
| 49 |
# Create a function to access the current state for the confidence tool
|
|
|
|
| 50 |
state_dict = {} # This will be updated in the Streamlit app
|
| 51 |
+
state_provider = lambda: state_dict
|
| 52 |
|
| 53 |
# Create tools node with database-related tools
|
| 54 |
# Convert our custom tools to LangChain StructuredTool format
|
|
|
|
| 110 |
lc_tools.append(get_confidence)
|
| 111 |
|
| 112 |
# Create Tool Agent Node
|
| 113 |
+
# We'll create a tool handler function
|
|
|
|
| 114 |
def tool_handler(state: Dict[str, Any]) -> Dict[str, Any]:
|
| 115 |
"""Handle tool calls from the agent workflow."""
|
| 116 |
+
log_agent_activity("TOOL", state)
|
| 117 |
# This would normally implement logic to determine which tool to call
|
|
|
|
| 118 |
# In production, you would parse agent messages to identify tool calls
|
| 119 |
|
| 120 |
+
# Just return the state unmodified - tools are actually called via the agents
|
|
|
|
| 121 |
return state
|
| 122 |
|
| 123 |
nodes["tools"] = tool_handler
|
|
|
|
| 129 |
for name, node in nodes.items():
|
| 130 |
workflow.add_node(name, node)
|
| 131 |
|
| 132 |
+
# Set the entry point to understanding_agent (FIX APPLIED HERE)
|
| 133 |
+
workflow.add_edge(START, "understanding_agent")
|
| 134 |
+
|
| 135 |
+
# Define conditional routing based on the current_agent field
|
| 136 |
workflow.add_conditional_edges(
|
| 137 |
"understanding_agent",
|
| 138 |
lambda x: x["current_agent"],
|
| 139 |
{
|
| 140 |
"understanding_agent": "understanding_agent",
|
| 141 |
+
"planning_agent": "planning_agent"
|
|
|
|
| 142 |
}
|
| 143 |
)
|
| 144 |
|
|
|
|
| 147 |
lambda x: x["current_agent"],
|
| 148 |
{
|
| 149 |
"planning_agent": "planning_agent",
|
| 150 |
+
"sql_generator_agent": "sql_generator_agent"
|
|
|
|
| 151 |
}
|
| 152 |
)
|
| 153 |
|
|
|
|
| 156 |
lambda x: x["current_agent"],
|
| 157 |
{
|
| 158 |
"sql_generator_agent": "sql_generator_agent",
|
| 159 |
+
"executor_agent": "executor_agent"
|
|
|
|
| 160 |
}
|
| 161 |
)
|
| 162 |
|
| 163 |
# Executor agent finishes the workflow
|
| 164 |
workflow.add_edge("executor_agent", END)
|
| 165 |
|
| 166 |
+
# Add edges for tools - they can be called from any agent and return to that agent
|
| 167 |
+
for agent in ["understanding_agent", "planning_agent", "sql_generator_agent", "executor_agent"]:
|
| 168 |
+
workflow.add_edge(agent, "tools")
|
| 169 |
+
workflow.add_edge("tools", agent)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 170 |
|
| 171 |
# Compile the workflow
|
| 172 |
app = workflow.compile()
|