Skip to content

Commit 6428dc1

Browse files
Merge pull request #28 from ucudal/copilot/sub-pr-26
Fix duplicate conditional edge causing workflow routing failure
2 parents 27cc2cf + ec8e2cf commit 6428dc1

File tree

4 files changed

+50
-23
lines changed

4 files changed

+50
-23
lines changed

RAGManager/app/agents/graph.py

Lines changed: 24 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -6,27 +6,27 @@
66
agent_host,
77
context_builder,
88
fallback,
9-
guard,
9+
guard_inicial,
10+
guard_final,
1011
parafraseo,
1112
retriever,
1213
)
1314
from app.agents.state import AgentState
14-
from app.agents.routing import route_after_guard
15+
from app.agents.routing import route_after_guard, route_after_guard_final
1516

1617
def create_agent_graph() -> StateGraph:
1718
"""
1819
Create and configure the LangGraph agent graph.
1920
2021
The graph implements the following flow:
2122
1. START -> agent_host (Nodo 1)
22-
2. agent_host -> guard (Nodo 2)
23-
3. guard -> [conditional] -> fallback (Nodo 3) or END
24-
4. fallback -> parafraseo (Nodo 4)
25-
5. parafraseo -> retriever (Nodo 5)
26-
6. retriever -> context_builder (Nodo 6)
27-
7. context_builder -> generator (Nodo 7)
28-
8. generator -> fallback (Nodo 8)
29-
9. fallback -> [conditional] -> END (with final_response) or END (with error)
23+
2. agent_host -> guard_inicial (Nodo 2)
24+
3. guard_inicial -> [conditional] -> fallback (if malicious) or parafraseo (if valid)
25+
4. parafraseo -> retriever (Nodo 5)
26+
5. retriever -> context_builder (Nodo 6)
27+
6. context_builder -> guard_final (Nodo 7)
28+
7. guard_final -> [conditional] -> fallback (if risky/PII detected) or END (if valid)
29+
8. fallback -> END
3030
3131
Returns:
3232
Configured StateGraph instance ready for execution
@@ -36,7 +36,8 @@ def create_agent_graph() -> StateGraph:
3636

3737
# Add nodes
3838
workflow.add_node("agent_host", agent_host)
39-
workflow.add_node("guard", guard)
39+
workflow.add_node("guard_inicial", guard_inicial)
40+
workflow.add_node("guard_final", guard_final)
4041
workflow.add_node("fallback", fallback)
4142
workflow.add_node("parafraseo", parafraseo)
4243
workflow.add_node("retriever", retriever)
@@ -46,12 +47,12 @@ def create_agent_graph() -> StateGraph:
4647
# Start -> agent_host
4748
workflow.add_edge(START, "agent_host")
4849

49-
# agent_host -> guard
50-
workflow.add_edge("agent_host", "guard")
50+
# agent_host -> guard_inicial
51+
workflow.add_edge("agent_host", "guard_inicial")
5152

52-
# guard -> conditional routing
53+
# guard_inicial -> conditional routing (first guard check)
5354
workflow.add_conditional_edges(
54-
"guard",
55+
"guard_inicial",
5556
route_after_guard,
5657
{
5758
"malicious": "fallback", # go to fallback if malicious
@@ -65,18 +66,20 @@ def create_agent_graph() -> StateGraph:
6566
# retriever -> context_builder
6667
workflow.add_edge("retriever", "context_builder")
6768

68-
# context_builder -> guard
69-
workflow.add_edge("context_builder", "guard")
69+
# context_builder -> guard_final
70+
workflow.add_edge("context_builder", "guard_final")
7071

71-
# guard -> conditional routing
72+
# guard_final -> conditional routing (second guard check for PII)
7273
workflow.add_conditional_edges(
73-
"guard",
74-
route_after_guard,
74+
"guard_final",
75+
route_after_guard_final,
7576
{
76-
"malicious": "fallback", # go to fallback if malicious
77+
"risky": "fallback", # go to fallback if risky (PII detected)
7778
"continue": END, # if there's no error ends
7879
},
7980
)
81+
82+
# fallback -> END
8083
workflow.add_edge("fallback", END)
8184
# Compile the graph
8285
return workflow.compile()

RAGManager/app/agents/nodes/__init__.py

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,13 +3,15 @@
33
from app.agents.nodes.agent_host import agent_host
44
from app.agents.nodes.context_builder import context_builder
55
from app.agents.nodes.fallback import fallback
6-
from app.agents.nodes.guard import guard
6+
from app.agents.nodes.guard_inicial import guard_inicial
7+
from app.agents.nodes.guard_final import guard_final
78
from app.agents.nodes.parafraseo import parafraseo
89
from app.agents.nodes.retriever import retriever
910

1011
__all__ = [
1112
"agent_host",
12-
"guard",
13+
"guard_inicial",
14+
"guard_final",
1315
"fallback",
1416
"parafraseo",
1517
"retriever",
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
"""Guard node - alias to guard_inicial for backward compatibility."""
2+
3+
from app.agents.nodes.guard_inicial import guard_inicial as guard
4+
5+
__all__ = ["guard"]

RAGManager/app/agents/routing.py

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,3 +18,20 @@ def route_after_guard(state: AgentState) -> str:
1818
if state.get("is_malicious", False):
1919
return "malicious"
2020
return "continue"
21+
22+
23+
def route_after_guard_final(state: AgentState) -> str:
24+
"""
25+
Route after Guard Final node validation (PII detection in generated response).
26+
27+
Determines the next step based on whether the generated response was flagged as risky (PII detected).
28+
29+
Args:
30+
state: Current agent state
31+
32+
Returns:
33+
"risky" if the response contains PII, "continue" otherwise
34+
"""
35+
if state.get("is_risky", False):
36+
return "risky"
37+
return "continue"

0 commit comments

Comments
 (0)