cryogenic22 commited on
Commit
bf595ba
·
verified ·
1 Parent(s): 78c9869

Update ui/conversation.py

Browse files
Files changed (1) hide show
  1. ui/conversation.py +80 -90
ui/conversation.py CHANGED
@@ -1,95 +1,85 @@
1
- """
2
- Understanding agent for pharmaceutical data management.
3
- This agent extracts user intent from natural language conversations.
4
- """
5
 
6
- import time
7
- from typing import Dict, Any
8
- from langgraph.graph.message import add_messages
9
- from anthropic.types import MessageParam
10
-
11
- def understanding_agent(anthropic_client, state: Dict[str, Any]) -> Dict[str, Any]:
12
- """
13
- Agent that understands user intent and requests clarification if needed.
14
-
15
- Args:
16
- anthropic_client: The Anthropic client for calling Claude API
17
- state: Current state of the agent workflow
18
-
19
- Returns:
20
- Updated state
21
- """
22
- # Ensure messages is properly initialized as a list
23
- messages = state.get("messages", [])
24
- if not isinstance(messages, list):
25
- messages = []
26
-
27
- # Format all messages to ensure they have role and content
28
- formatted_messages = []
29
- for msg in messages:
30
- if isinstance(msg, dict) and "role" in msg and "content" in msg:
31
- formatted_messages.append(msg)
32
-
33
- # Add agent-specific instructions
34
- system_message = """
35
- You are an AI assistant specializing in understanding pharmaceutical data needs.
36
- Your job is to understand what data pipeline the user needs to create.
37
- Extract key information:
38
- 1. Business question/goal
39
- 2. Required data sources/tables
40
- 3. Needed transformations
41
- 4. Output format/visualization
42
- 5. Time frame/frequency
43
-
44
- If information is missing, ask clarifying questions.
45
- If you understand the request fully, summarize the user's intent and tag it as INTENT_COMPLETE.
46
- """
47
-
48
- # Convert messages to the format expected by Anthropic API
49
- anthropic_messages = []
50
- for msg in formatted_messages:
51
- anthropic_messages.append(MessageParam(
52
- role=msg["role"],
53
- content=msg["content"]
54
- ))
55
-
56
- # Call Claude API
57
- response = anthropic_client.messages.create(
58
- model="claude-3-7-sonnet-20250219",
59
- system=system_message,
60
- messages=anthropic_messages,
61
- max_tokens=2000
62
- )
63
-
64
- # Extract the response
65
- agent_response = response.content[0].text
66
-
67
- # Check if intent is complete
68
- intent_complete = "INTENT_COMPLETE" in agent_response
69
 
70
- # Update state based on intent completeness
71
- new_state = state.copy()
72
- if intent_complete:
73
- # Parse the structured intent from the response
74
- # This would be more sophisticated in production
75
- user_intent = {
76
- "understood": True,
77
- "description": agent_response.replace("INTENT_COMPLETE", "").strip(),
78
- "time": time.time()
79
- }
80
- new_state["user_intent"] = user_intent
81
- new_state["current_agent"] = "planning_agent"
82
- else:
83
- # Need more information, stay with understanding agent
84
- new_state["current_agent"] = "understanding_agent"
85
 
86
- # Add agent's response to messages safely
87
- if "messages" not in new_state or not isinstance(new_state["messages"], list):
88
- new_state["messages"] = []
 
 
 
 
89
 
90
- new_state["messages"].append({
91
- "role": "assistant",
92
- "content": agent_response.replace("INTENT_COMPLETE", "").strip()
93
- })
 
94
 
95
- return new_state
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import streamlit as st
 
 
 
2
 
3
+ def render_conversation_tab(session_state, agent_graph, update_state_dict):
4
+ """Render the conversation tab in the UI."""
5
+ st.subheader("Conversation with Data Management Agent")
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
6
 
7
+ # Initialize messages in conversation if not already present
8
+ if "messages" not in session_state.conversation:
9
+ session_state.conversation["messages"] = []
 
 
 
 
 
 
 
 
 
 
 
 
10
 
11
+ # Display conversation history
12
+ for message in session_state.conversation["messages"]:
13
+ if isinstance(message, dict) and "role" in message and "content" in message:
14
+ if message["role"] == "user":
15
+ st.markdown(f"**You:** {message['content']}")
16
+ else:
17
+ st.markdown(f"**Agent:** {message['content']}")
18
 
19
+ # Input for new message
20
+ with st.form(key="user_input_form"):
21
+ user_input = st.text_area("What data pipeline do you need to create?",
22
+ placeholder="e.g., I need a sales performance dashboard showing regional performance by product for the last 2 years")
23
+ submit_button = st.form_submit_button("Submit")
24
 
25
+ if submit_button and user_input:
26
+ # Add user message to conversation
27
+ new_message = {"role": "user", "content": user_input}
28
+ session_state.conversation["messages"].append(new_message)
29
+
30
+ # Update agent state - ensure messages is a list
31
+ agent_state = session_state.agent_state.copy()
32
+ if "messages" not in agent_state or not isinstance(agent_state["messages"], list):
33
+ agent_state["messages"] = []
34
+
35
+ # Add new message to agent state
36
+ agent_state["messages"].append(new_message)
37
+
38
+ # Run the agent graph
39
+ with st.spinner("Agent is processing..."):
40
+ try:
41
+ # Update the state dictionary for tools
42
+ update_state_dict(agent_state)
43
+
44
+ # Execute the agent workflow
45
+ result = agent_graph.invoke(agent_state)
46
+
47
+ # Update session state with result
48
+ session_state.agent_state = result
49
+
50
+ # Update the state dictionary for tools again with the result
51
+ update_state_dict(result)
52
+
53
+ # Ensure messages is a list in the result
54
+ if not isinstance(result.get("messages", []), list):
55
+ result["messages"] = []
56
+
57
+ # Update conversation with agent responses
58
+ for message in result.get("messages", []):
59
+ if isinstance(message, dict) and "role" in message and "content" in message:
60
+ # Check if this message isn't already in the conversation
61
+ message_exists = False
62
+ for existing_msg in session_state.conversation["messages"]:
63
+ if (isinstance(existing_msg, dict) and
64
+ existing_msg.get("role") == message.get("role") and
65
+ existing_msg.get("content") == message.get("content")):
66
+ message_exists = True
67
+ break
68
+
69
+ if not message_exists:
70
+ session_state.conversation["messages"].append(message)
71
+
72
+ # Update other state properties
73
+ session_state.conversation["user_intent"] = result.get("user_intent", {})
74
+ session_state.conversation["pipeline_plan"] = result.get("pipeline_plan", {})
75
+ session_state.conversation["sql_queries"] = result.get("sql_queries", [])
76
+ session_state.conversation["execution_results"] = result.get("execution_results", {})
77
+ session_state.conversation["confidence_scores"] = result.get("confidence_scores", {})
78
+ session_state.conversation["status"] = result.get("status", "planning")
79
+ session_state.conversation["current_agent"] = result.get("current_agent", "understanding_agent")
80
+
81
+ # Force refresh
82
+ st.rerun()
83
+
84
+ except Exception as e:
85
+ st.error(f"Error executing agent workflow: {str(e)}")