Skip to content

Commit b4af608

Browse files
Merge remote-tracking branch 'origin/devops' into devops
2 parents 0d1c362 + b285743 commit b4af608

File tree

19 files changed

+499
-263
lines changed

19 files changed

+499
-263
lines changed
Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
from fastapi import APIRouter, Depends
2+
from sqlalchemy.orm import Session
3+
4+
from app.core.db_connection import get_sessionmaker
5+
from app.schemas.chatMessage import UserMessageIn, AssistantMessageOut
6+
from app.services.chatMessage import create_user_message
7+
8+
SessionMaker = get_sessionmaker()
9+
10+
11+
def get_db():
12+
db = SessionMaker()
13+
try:
14+
yield db
15+
finally:
16+
db.close()
17+
18+
19+
router = APIRouter(
20+
prefix="/chat",
21+
tags=["Chat"]
22+
)
23+
24+
25+
@router.post(
26+
"/messages",
27+
response_model=AssistantMessageOut
28+
)
29+
def post_user_message(
30+
payload: UserMessageIn,
31+
db: Session = Depends(get_db)
32+
):
33+
assistant_msg, session_id = create_user_message(
34+
db=db,
35+
message=payload.message,
36+
session_id=payload.session_id
37+
)
38+
39+
return {
40+
"session_id": session_id,
41+
"message": assistant_msg.message
42+
}

DocsManager/app/models/chat_message.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,9 +11,9 @@
1111
from sqlalchemy.orm import relationship
1212

1313

14-
from schemas.enums.sender_type import SenderType
14+
from app.schemas.enums.sender_type import SenderType
1515

16-
from DocsManager.app.core.db_connection import Base
16+
from app.core.db_connection import Base
1717

1818

1919
class ChatMessage(Base):

DocsManager/app/models/chat_session.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
)
77
from sqlalchemy.dialects.postgresql import UUID
88
from sqlalchemy.orm import relationship
9-
from DocsManager.app.core.db_connection import Base
9+
from app.core.db_connection import Base
1010

1111

1212
class ChatSession(Base):
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
from pydantic import BaseModel
2+
from uuid import UUID
3+
from typing import Optional
4+
5+
class UserMessageIn(BaseModel):
6+
session_id: Optional[UUID] = None
7+
message: str
8+
9+
10+
class AssistantMessageOut(BaseModel):
11+
message: str
Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
from sqlalchemy.orm import Session
2+
3+
from app.models.chat_message import ChatMessage
4+
from app.schemas.enums.sender_type import SenderType
5+
from app.models.chat_session import ChatSession
6+
7+
def assistant_reply(text: str) -> str:
8+
return f"Respuesta del asistente a: {text}"
9+
10+
11+
def create_user_message(
12+
db: Session,
13+
message: str,
14+
session_id=None
15+
):
16+
# 1. Si no hay session_id → crear sesión nueva
17+
if session_id is None:
18+
session = ChatSession()
19+
db.add(session)
20+
db.flush() # genera el UUID sin commit
21+
session_id = session.id
22+
else:
23+
session = db.get(ChatSession, session_id)
24+
if not session:
25+
raise ValueError("Chat session not found")
26+
27+
# 2. Guardar mensaje del usuario
28+
user_msg = ChatMessage(
29+
session_id=session_id,
30+
sender=SenderType.user,
31+
message=message
32+
)
33+
db.add(user_msg)
34+
35+
# 3. Respuesta del asistente
36+
assistant_text = assistant_reply(message)
37+
38+
assistant_msg = ChatMessage(
39+
session_id=session_id,
40+
sender=SenderType.assistant,
41+
message=assistant_text
42+
)
43+
db.add(assistant_msg)
44+
45+
db.commit()
46+
db.refresh(assistant_msg)
47+
48+
return assistant_msg, session_id

DocsManager/main.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,11 +4,11 @@
44
from fastapi import FastAPI
55

66
from app.api.routes.base import router as base_router
7-
7+
from app.api.routes.chatMessage import router as chat_router
88

99
app = FastAPI()
1010

1111
app.include_router(base_router)
1212

13-
13+
app.include_router(chat_router)
1414

RAGManager/app/agents/graph.py

Lines changed: 46 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -5,11 +5,18 @@
55
from app.agents.nodes import (
66
agent_host,
77
context_builder,
8-
fallback,
9-
guard,
8+
fallback_final,
9+
fallback_inicial,
10+
generator,
11+
guard_final,
12+
guard_inicial,
1013
parafraseo,
1114
retriever,
1215
)
16+
from app.agents.routing import (
17+
route_after_guard_final,
18+
route_after_guard_inicial,
19+
)
1320
from app.agents.state import AgentState
1421
from app.agents.routing import route_after_guard
1522

@@ -18,15 +25,18 @@ def create_agent_graph() -> StateGraph:
1825
Create and configure the LangGraph agent graph.
1926
2027
The graph implements the following flow:
21-
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)
28+
1. START -> agent_host (Nodo 1) - Prepares state, no DB operations
29+
2. agent_host -> guard (Nodo 2) - Validates for malicious content
30+
3. guard -> [conditional]:
31+
- malicious -> fallback -> END (stops processing, no DB save)
32+
- continue -> parafraseo (Nodo 4)
33+
4. parafraseo -> Saves message to DB, retrieves chat history, paraphrases
2534
5. parafraseo -> retriever (Nodo 5)
2635
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)
36+
7. context_builder -> guard (validates response)
37+
8. guard -> [conditional]:
38+
- malicious -> fallback -> END
39+
- continue -> END (success)
3040
3141
Returns:
3242
Configured StateGraph instance ready for execution
@@ -36,29 +46,35 @@ def create_agent_graph() -> StateGraph:
3646

3747
# Add nodes
3848
workflow.add_node("agent_host", agent_host)
39-
workflow.add_node("guard", guard)
40-
workflow.add_node("fallback", fallback)
49+
workflow.add_node("guard_inicial", guard_inicial)
50+
workflow.add_node("fallback_inicial", fallback_inicial)
4151
workflow.add_node("parafraseo", parafraseo)
4252
workflow.add_node("retriever", retriever)
4353
workflow.add_node("context_builder", context_builder)
54+
workflow.add_node("generator", generator)
55+
workflow.add_node("guard_final", guard_final)
56+
workflow.add_node("fallback_final", fallback_final)
4457

4558
# Define edges
4659
# Start -> agent_host
4760
workflow.add_edge(START, "agent_host")
4861

49-
# agent_host -> guard
50-
workflow.add_edge("agent_host", "guard")
62+
# agent_host -> guard_inicial
63+
workflow.add_edge("agent_host", "guard_inicial")
5164

52-
# guard -> conditional routing
65+
# guard_inicial -> conditional routing
5366
workflow.add_conditional_edges(
54-
"guard",
55-
route_after_guard,
67+
"guard_inicial",
68+
route_after_guard_inicial,
5669
{
57-
"malicious": "fallback", # go to fallback if malicious
58-
"continue": "parafraseo", # Continue to parafraseo if valid
70+
"malicious": "fallback_inicial", # Exception path: malicious content detected
71+
"continue": "parafraseo", # Normal path: continue processing
5972
},
6073
)
6174

75+
# fallback_inicial -> END (stop flow with error message)
76+
workflow.add_edge("fallback_inicial", END)
77+
6278
# parafraseo -> retriever
6379
workflow.add_edge("parafraseo", "retriever")
6480

@@ -68,15 +84,21 @@ def create_agent_graph() -> StateGraph:
6884
# context_builder -> guard
6985
workflow.add_edge("context_builder", "guard")
7086

71-
# guard -> conditional routing
87+
# generator -> guard_final
88+
workflow.add_edge("generator", "guard_final")
89+
90+
# guard_final -> conditional routing
7291
workflow.add_conditional_edges(
73-
"guard",
74-
route_after_guard,
92+
"guard_final",
93+
route_after_guard_final,
7594
{
76-
"malicious": "fallback", # go to fallback if malicious
77-
"continue": END, # if there's no error ends
95+
"risky": "fallback_final", # Exception path: risky content detected
96+
"continue": END, # Normal path: end successfully
7897
},
7998
)
80-
workflow.add_edge("fallback", END)
99+
100+
# fallback_final -> END (stop flow with error message)
101+
workflow.add_edge("fallback_final", END)
102+
81103
# Compile the graph
82104
return workflow.compile()

RAGManager/app/agents/nodes/__init__.py

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2,15 +2,19 @@
22

33
from app.agents.nodes.agent_host import agent_host
44
from app.agents.nodes.context_builder import context_builder
5-
from app.agents.nodes.fallback import fallback
6-
from app.agents.nodes.guard import guard
5+
from app.agents.nodes.fallback_final import fallback_final
6+
from app.agents.nodes.fallback_inicial import fallback_inicial
7+
from app.agents.nodes.generator import generator
8+
from app.agents.nodes.guard_final import guard_final
9+
from app.agents.nodes.guard_inicial import guard_inicial
710
from app.agents.nodes.parafraseo import parafraseo
811
from app.agents.nodes.retriever import retriever
912

1013
__all__ = [
1114
"agent_host",
12-
"guard",
13-
"fallback",
15+
"guard_inicial",
16+
"guard_final",
17+
"fallback_inicial",
1418
"parafraseo",
1519
"retriever",
1620
"context_builder",

0 commit comments

Comments
 (0)