cryogenic22 commited on
Commit
b0e5312
Β·
verified Β·
1 Parent(s): 7ab1a2c

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +330 -0
app.py CHANGED
@@ -3,16 +3,346 @@ Main application for Pharmaceutical Data Management Agent.
3
  """
4
 
5
  import os
 
6
  import streamlit as st
7
  from anthropic import Anthropic
8
  from dotenv import load_dotenv
9
 
 
 
 
10
  # Import data module
11
  from data.synthetic_db import SyntheticDatabase
12
 
13
  # Import graph module
14
  from graph.workflow import create_agent_graph
15
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
16
  # Import UI modules
17
  from ui.conversation import render_conversation_tab
18
  from ui.pipeline import render_pipeline_tab
 
3
  """
4
 
5
  import os
6
+ import sys
7
  import streamlit as st
8
  from anthropic import Anthropic
9
  from dotenv import load_dotenv
10
 
11
+ # Add the current directory to the path to enable relative imports
12
+ sys.path.append(os.path.dirname(os.path.abspath(__file__)))
13
+
14
  # Import data module
15
  from data.synthetic_db import SyntheticDatabase
16
 
17
  # Import graph module
18
  from graph.workflow import create_agent_graph
19
 
20
+ # Create ui directory if it doesn't exist
21
+ os.makedirs("ui", exist_ok=True)
22
+
23
+ # Create ui files if they don't exist
24
+ def ensure_ui_files_exist():
25
+ """Create UI module files if they don't exist."""
26
+ # Conversation UI
27
+ conversation_py = "ui/conversation.py"
28
+ if not os.path.exists(conversation_py):
29
+ with open(conversation_py, "w") as f:
30
+ f.write("""
31
+ import streamlit as st
32
+
33
+ def render_conversation_tab(session_state, agent_graph, update_state_dict):
34
+ \"\"\"Render the conversation tab in the UI.\"\"\"
35
+ st.subheader("Conversation with Data Management Agent")
36
+
37
+ # Display conversation history
38
+ for message in session_state.conversation["messages"]:
39
+ if message["role"] == "user":
40
+ st.markdown(f"**You:** {message['content']}")
41
+ else:
42
+ st.markdown(f"**Agent:** {message['content']}")
43
+
44
+ # Input for new message
45
+ with st.form(key="user_input_form"):
46
+ user_input = st.text_area("What data pipeline do you need to create?",
47
+ placeholder="e.g., I need a sales performance dashboard showing regional performance by product for the last 2 years")
48
+ submit_button = st.form_submit_button("Submit")
49
+
50
+ if submit_button and user_input:
51
+ # Add user message to conversation
52
+ new_message = {"role": "user", "content": user_input}
53
+ session_state.conversation["messages"].append(new_message)
54
+
55
+ # Update agent state
56
+ agent_state = session_state.agent_state.copy()
57
+ agent_state["messages"] = agent_state["messages"] + [new_message]
58
+
59
+ # Run the agent graph
60
+ with st.spinner("Agent is processing..."):
61
+ try:
62
+ # Update the state dictionary for tools
63
+ update_state_dict(agent_state)
64
+
65
+ # Execute the agent workflow
66
+ result = agent_graph.invoke(agent_state)
67
+
68
+ # Update session state with result
69
+ session_state.agent_state = result
70
+
71
+ # Update the state dictionary for tools again with the result
72
+ update_state_dict(result)
73
+
74
+ # Update conversation with agent responses
75
+ for message in result["messages"]:
76
+ if message not in session_state.conversation["messages"]:
77
+ session_state.conversation["messages"].append(message)
78
+
79
+ # Update other state properties
80
+ session_state.conversation["user_intent"] = result.get("user_intent", {})
81
+ session_state.conversation["pipeline_plan"] = result.get("pipeline_plan", {})
82
+ session_state.conversation["sql_queries"] = result.get("sql_queries", [])
83
+ session_state.conversation["execution_results"] = result.get("execution_results", {})
84
+ session_state.conversation["confidence_scores"] = result.get("confidence_scores", {})
85
+ session_state.conversation["status"] = result.get("status", "planning")
86
+ session_state.conversation["current_agent"] = result.get("current_agent", "understanding_agent")
87
+
88
+ # Force refresh
89
+ st.rerun()
90
+
91
+ except Exception as e:
92
+ st.error(f"Error executing agent workflow: {str(e)}")
93
+ """)
94
+
95
+ # Pipeline UI
96
+ pipeline_py = "ui/pipeline.py"
97
+ if not os.path.exists(pipeline_py):
98
+ with open(pipeline_py, "w") as f:
99
+ f.write("""
100
+ import streamlit as st
101
+
102
+ def render_pipeline_tab(session_state):
103
+ \"\"\"Render the pipeline details tab in the UI.\"\"\"
104
+ st.subheader("Pipeline Details")
105
+
106
+ # Intent Understanding
107
+ st.markdown("### User Intent")
108
+ if session_state.conversation["user_intent"]:
109
+ st.markdown(session_state.conversation["user_intent"].get("description", "No intent captured yet"))
110
+ if "confidence_scores" in session_state.conversation and "intent_understanding" in session_state.conversation["confidence_scores"]:
111
+ score = session_state.conversation["confidence_scores"]["intent_understanding"] * 100
112
+ st.progress(score / 100, text=f"Intent Understanding Confidence: {score:.1f}%")
113
+ else:
114
+ st.info("No user intent has been captured yet. Start a conversation to extract intent.")
115
+
116
+ # Pipeline Plan
117
+ st.markdown("### Pipeline Plan")
118
+ if session_state.conversation["pipeline_plan"]:
119
+ st.markdown(session_state.conversation["pipeline_plan"].get("description", "No plan created yet"))
120
+ if "confidence_scores" in session_state.conversation and "plan_quality" in session_state.conversation["confidence_scores"]:
121
+ score = session_state.conversation["confidence_scores"]["plan_quality"] * 100
122
+ st.progress(score / 100, text=f"Plan Quality Confidence: {score:.1f}%")
123
+ else:
124
+ st.info("No pipeline plan has been created yet. Continue the conversation to develop a plan.")
125
+
126
+ # SQL Queries
127
+ st.markdown("### SQL Queries")
128
+ if session_state.conversation["sql_queries"]:
129
+ for i, query in enumerate(session_state.conversation["sql_queries"]):
130
+ with st.expander(f"Query {i+1}: {query.get('name', 'Unnamed Query')}"):
131
+ st.code(query.get("sql", ""), language="sql")
132
+ else:
133
+ st.info("No SQL queries have been generated yet. Continue the conversation to generate queries.")
134
+
135
+ # Execution Results
136
+ st.markdown("### Execution Results")
137
+ if session_state.conversation["execution_results"] and "details" in session_state.conversation["execution_results"]:
138
+ st.markdown(session_state.conversation["execution_results"].get("summary", ""))
139
+
140
+ if "success_rate" in session_state.conversation["execution_results"]:
141
+ score = session_state.conversation["execution_results"]["success_rate"] * 100
142
+ st.progress(score / 100, text=f"Execution Success Rate: {score:.1f}%")
143
+
144
+ results = session_state.conversation["execution_results"]["details"]
145
+ for i, result in enumerate(results):
146
+ status = "βœ…" if result["success"] else "❌"
147
+ with st.expander(f"{status} {result.get('query_name', f'Query {i+1}')}"):
148
+ st.markdown(f"**Result:** {result.get('result_summary', 'No summary available')}")
149
+ st.markdown(f"**Rows Processed:** {result.get('row_count', 0)}")
150
+ else:
151
+ st.info("No execution results available yet. Complete the pipeline creation to see results.")
152
+ """)
153
+
154
+ # Agent Workflow UI
155
+ agent_workflow_py = "ui/agent_workflow.py"
156
+ if not os.path.exists(agent_workflow_py):
157
+ with open(agent_workflow_py, "w") as f:
158
+ f.write("""
159
+ import streamlit as st
160
+
161
+ def render_workflow_tab(session_state):
162
+ \"\"\"Render the agent workflow visualization tab in the UI.\"\"\"
163
+ st.subheader("Agent Workflow Visualization")
164
+
165
+ # Display current agent and status
166
+ current_agent = session_state.conversation.get("current_agent", "understanding_agent")
167
+ status = session_state.conversation.get("status", "planning")
168
+
169
+ st.markdown(f"**Current State:** {status.title()}")
170
+ st.markdown(f"**Current Agent:** {current_agent.replace('_', ' ').title()}")
171
+
172
+ # Visualize the workflow
173
+ col1, col2, col3, col4 = st.columns(4)
174
+
175
+ # Determine which agent is active
176
+ understanding_active = current_agent == "understanding_agent"
177
+ planning_active = current_agent == "planning_agent"
178
+ sql_active = current_agent == "sql_generator_agent"
179
+ executor_active = current_agent == "executor_agent"
180
+
181
+ # Show the workflow visualization
182
+ with col1:
183
+ if understanding_active:
184
+ st.markdown("### πŸ” **Understanding**")
185
+ else:
186
+ st.markdown("### πŸ” Understanding")
187
+ st.markdown("Extracts user intent and asks clarification questions")
188
+
189
+ if "user_intent" in session_state.conversation and session_state.conversation["user_intent"]:
190
+ st.success("Completed")
191
+ elif understanding_active:
192
+ st.info("In Progress")
193
+ else:
194
+ st.warning("Not Started")
195
+
196
+ with col2:
197
+ if planning_active:
198
+ st.markdown("### πŸ“‹ **Planning**")
199
+ else:
200
+ st.markdown("### πŸ“‹ Planning")
201
+ st.markdown("Creates data pipeline plan with sources and transformations")
202
+
203
+ if "pipeline_plan" in session_state.conversation and session_state.conversation["pipeline_plan"]:
204
+ st.success("Completed")
205
+ elif planning_active:
206
+ st.info("In Progress")
207
+ elif understanding_active:
208
+ st.warning("Not Started")
209
+ else:
210
+ st.success("Completed")
211
+
212
+ with col3:
213
+ if sql_active:
214
+ st.markdown("### πŸ’» **SQL Generation**")
215
+ else:
216
+ st.markdown("### πŸ’» SQL Generation")
217
+ st.markdown("Converts plan into executable SQL queries")
218
+
219
+ if "sql_queries" in session_state.conversation and session_state.conversation["sql_queries"]:
220
+ st.success("Completed")
221
+ elif sql_active:
222
+ st.info("In Progress")
223
+ elif understanding_active or planning_active:
224
+ st.warning("Not Started")
225
+ else:
226
+ st.success("Completed")
227
+
228
+ with col4:
229
+ if executor_active:
230
+ st.markdown("### βš™οΈ **Execution**")
231
+ else:
232
+ st.markdown("### βš™οΈ Execution")
233
+ st.markdown("Executes queries and reports results")
234
+
235
+ if "execution_results" in session_state.conversation and session_state.conversation["execution_results"]:
236
+ st.success("Completed")
237
+ elif executor_active:
238
+ st.info("In Progress")
239
+ elif understanding_active or planning_active or sql_active:
240
+ st.warning("Not Started")
241
+ else:
242
+ st.success("Completed")
243
+
244
+ # Overall confidence score
245
+ if "confidence_scores" in session_state.conversation and "overall" in session_state.conversation["confidence_scores"]:
246
+ st.markdown("### Overall Pipeline Confidence")
247
+ score = session_state.conversation["confidence_scores"]["overall"] * 100
248
+ st.progress(score / 100, text=f"{score:.1f}%")
249
+
250
+ # Workflow decision points
251
+ if status == "complete":
252
+ if score > 80:
253
+ st.success("βœ… High confidence - Pipeline can be deployed automatically")
254
+ else:
255
+ st.warning("⚠️ Medium confidence - Human review recommended before deployment")
256
+
257
+ # Add human review section for pending approval status
258
+ if status == "pending_approval":
259
+ st.markdown("### πŸ‘€ Human Review Required")
260
+ st.info("This pipeline requires human review before deployment")
261
+
262
+ col1, col2 = st.columns(2)
263
+ with col1:
264
+ if st.button("βœ… Approve Pipeline"):
265
+ # Update state to approved
266
+ session_state.conversation["status"] = "approved"
267
+ # Trigger execution to continue
268
+ st.rerun()
269
+ with col2:
270
+ if st.button("❌ Reject Pipeline"):
271
+ # Update state to rejected
272
+ session_state.conversation["status"] = "rejected"
273
+ st.error("Pipeline rejected. Please provide feedback to refine the pipeline.")
274
+ """)
275
+
276
+ # DB Explorer UI
277
+ db_explorer_py = "ui/db_explorer.py"
278
+ if not os.path.exists(db_explorer_py):
279
+ with open(db_explorer_py, "w") as f:
280
+ f.write("""
281
+ import streamlit as st
282
+ import pandas as pd
283
+
284
+ def render_db_explorer_tab(session_state):
285
+ \"\"\"Render the database explorer tab in the UI.\"\"\"
286
+ st.subheader("Database Explorer")
287
+
288
+ # Get tables by category
289
+ tables = session_state.db.get_tables()
290
+
291
+ # Display tables by category
292
+ col1, col2 = st.columns(2)
293
+
294
+ with col1:
295
+ st.markdown("### Raw Data Tables")
296
+ for table in tables["raw_tables"]:
297
+ with st.expander(table):
298
+ sample = session_state.db.get_table_sample(table, 3)
299
+ st.dataframe(pd.DataFrame(sample))
300
+
301
+ st.markdown("### Staging Tables")
302
+ for table in tables["staging_tables"]:
303
+ with st.expander(table):
304
+ sample = session_state.db.get_table_sample(table, 3)
305
+ st.dataframe(pd.DataFrame(sample))
306
+
307
+ with col2:
308
+ st.markdown("### Analytics Ready Data")
309
+ for table in tables["ard_tables"]:
310
+ with st.expander(table):
311
+ sample = session_state.db.get_table_sample(table, 3)
312
+ st.dataframe(pd.DataFrame(sample))
313
+
314
+ st.markdown("### Data Products")
315
+ for table in tables["data_products"]:
316
+ with st.expander(table):
317
+ sample = session_state.db.get_table_sample(table, 3)
318
+ st.dataframe(pd.DataFrame(sample))
319
+
320
+ # SQL Query Executor
321
+ st.markdown("### Query Explorer")
322
+ with st.form(key="sql_form"):
323
+ sql_query = st.text_area("Enter SQL Query", height=100,
324
+ placeholder="SELECT * FROM ARD_SALES_PERFORMANCE WHERE region = 'North' LIMIT 5")
325
+ run_sql = st.form_submit_button("Run Query")
326
+
327
+ if run_sql and sql_query:
328
+ with st.spinner("Executing query..."):
329
+ result = session_state.db.execute_query(sql_query)
330
+
331
+ if "error" in result:
332
+ st.error(f"Error executing query: {result['error']}")
333
+ elif "data" in result:
334
+ st.dataframe(pd.DataFrame(result["data"]))
335
+ st.success(f"Query returned {len(result['data'])} rows")
336
+ elif "tables" in result:
337
+ st.write(result["tables"])
338
+ elif "schema" in result:
339
+ st.write(f"Schema for {result['table']}:")
340
+ st.dataframe(pd.DataFrame(result["schema"]))
341
+ """)
342
+
343
+ # Now import UI modules after ensuring they exist
344
+ ensure_ui_files_exist()
345
+
346
  # Import UI modules
347
  from ui.conversation import render_conversation_tab
348
  from ui.pipeline import render_pipeline_tab