11import logging
22import os
3- from typing import Literal , Optional
3+ from typing import Literal , Optional , List
44
55from langchain_openai import AzureChatOpenAI
66from langchain_core .output_parsers import PydanticOutputParser
1010from pydantic import BaseModel , Field
1111
1212from uipath_sdk import UiPathSDK
13-
13+ from uipath_sdk . _models import CreateAction
1414logger = logging .getLogger (__name__ )
1515
1616uipath = UiPathSDK ()
1717
1818class GraphInput (BaseModel ):
1919 message : str
2020 ticket_id : str
21+ assignee : Optional [str ]
2122
2223class GraphOutput (BaseModel ):
2324 label : str
@@ -26,9 +27,11 @@ class GraphOutput(BaseModel):
2627class GraphState (BaseModel ):
2728 message : str
2829 ticket_id : str
30+ assignee : Optional [str ] = None
2931 label : Optional [str ] = None
3032 confidence : Optional [float ] = None
31-
33+ rejected_categories : List [str ] = []
34+ human_approval : Optional [bool ] = None
3235
3336class TicketClassification (BaseModel ):
3437 label : Literal ["security" , "error" , "system" , "billing" , "performance" ] = Field (
@@ -78,15 +81,23 @@ def get_azure_openai_api_key() -> str:
7881
7982 return api_key
8083
84+ def decide_next_node (state : GraphState ) -> Literal ["classify" , "notify_team" ]:
85+ if state .human_approval_result is True :
86+ return "notify_team"
87+ return "classify"
8188
8289async def classify (state : GraphState ) -> GraphState :
90+ logger .info ("classify" )
91+
8392 """Classify the support ticket using LLM."""
8493 llm = AzureChatOpenAI (
8594 azure_deployment = "gpt-4o-mini" ,
8695 api_key = get_azure_openai_api_key (),
8796 azure_endpoint = os .getenv ("AZURE_OPENAI_ENDPOINT" ),
8897 api_version = "2024-10-21"
8998 )
99+ if len (state .rejected_categories ) > 0 :
100+ prompt .append (("user" , f"The ticket is 100% not part of the following categories '{ state .rejected_categories } '. Choose another one." ))
90101 _prompt = prompt .partial (
91102 format_instructions = output_parser .get_format_instructions ()
92103 )
@@ -109,17 +120,22 @@ async def classify(state: GraphState) -> GraphState:
109120
110121async def wait_for_human (state : GraphState ) -> GraphState :
111122 logger .info ("Wait for human approval" )
112- feedback = interrupt (f"Label: { state .label } Confidence: { state .confidence } " )
113-
114- if isinstance (feedback , bool ) and feedback is True :
115- return Command (goto = "notify_team" )
116- else :
117- return Command (goto = END )
123+ action_data = interrupt (CreateAction (name = "escalation_agent_app" ,
124+ title = "Action Required: Review classification" ,
125+ data = {
126+ "AgentOutput" : f"This is how I classified the ticket: '{ state .ticket_id } ', with message '{ state .message } ' \n Label: '{ state .label } ' Confidence: '{ state .confidence } '" ,
127+ "AgentName" : "ticket-classification " },
128+ app_version = 1 ,
129+ assignee = state .assignee ,
130+ ))
131+ state .human_approval = isinstance (action_data ["Answer" ], bool ) and action_data ["Answer" ] is True
132+ if not state .human_approval :
133+ state .rejected_categories .append (state .label )
134+ return state
118135
119- async def notify_team (state : GraphState ) -> GraphState :
136+ async def notify_team (state : GraphState ) -> GraphOutput :
120137 logger .info ("Send team email notification" )
121- print (state )
122- return state
138+ return GraphOutput (label = state .label , confidence = state .confidence )
123139
124140"""Process a support ticket through the workflow."""
125141
@@ -131,7 +147,7 @@ async def notify_team(state: GraphState) -> GraphState:
131147
132148builder .add_edge (START , "classify" )
133149builder .add_edge ("classify" , "human_approval" )
134- builder .add_edge ("human_approval" , "notify_team" )
150+ builder .add_conditional_edges ("human_approval" , decide_next_node )
135151builder .add_edge ("notify_team" , END )
136152
137153
@@ -140,3 +156,4 @@ async def notify_team(state: GraphState) -> GraphState:
140156memory = MemorySaver ()
141157
142158graph = builder .compile (checkpointer = memory )
159+
0 commit comments