cryogenic22 commited on
Commit
d3afdfe
·
verified ·
1 Parent(s): b9b7220

Update graph/workflow.py

Browse files
Files changed (1) hide show
  1. 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
- # In the updated LangGraph, we don't use ToolNode directly
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 LangChain integration
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
- # Define the edges (transitions between agents)
135
- # First, create 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
- "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 edge from tools back to the calling agent
170
- # This is a simplified approach - in a production system, you would
171
- # need to track which agent called the tool and return to that agent
172
- workflow.add_conditional_edges(
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()