.
This commit is contained in:
173
src/capa_de_integracion/models/conversation.py
Normal file
173
src/capa_de_integracion/models/conversation.py
Normal file
@@ -0,0 +1,173 @@
|
||||
"""
|
||||
Copyright 2025 Google. This software is provided as-is, without warranty or
|
||||
representation for any use or purpose. Your use of it is subject to your
|
||||
agreement with Google.
|
||||
|
||||
Conversation-related data models.
|
||||
"""
|
||||
|
||||
from datetime import datetime
|
||||
from enum import Enum
|
||||
from typing import Any
|
||||
from pydantic import BaseModel, Field, field_validator
|
||||
|
||||
|
||||
class MessageType(str, Enum):
|
||||
"""Message type enumeration."""
|
||||
|
||||
USER = "USER"
|
||||
AGENT = "AGENT"
|
||||
|
||||
|
||||
class ConversationEntryType(str, Enum):
|
||||
"""Conversation entry type enumeration."""
|
||||
|
||||
INICIO = "INICIO"
|
||||
CONVERSACION = "CONVERSACION"
|
||||
LLM = "LLM"
|
||||
|
||||
|
||||
class UsuarioDTO(BaseModel):
|
||||
"""User information."""
|
||||
|
||||
telefono: str = Field(..., min_length=1)
|
||||
nickname: str | None = None
|
||||
|
||||
|
||||
class TextInputDTO(BaseModel):
|
||||
"""Text input for queries."""
|
||||
|
||||
text: str
|
||||
|
||||
|
||||
class EventInputDTO(BaseModel):
|
||||
"""Event input for queries."""
|
||||
|
||||
event: str
|
||||
|
||||
|
||||
class QueryParamsDTO(BaseModel):
|
||||
"""Query parameters for Dialogflow requests."""
|
||||
|
||||
parameters: dict[str, Any] | None = None
|
||||
|
||||
|
||||
class QueryInputDTO(BaseModel):
|
||||
"""Query input combining text or event."""
|
||||
|
||||
text: TextInputDTO | None = None
|
||||
event: EventInputDTO | None = None
|
||||
language_code: str = "es"
|
||||
|
||||
@field_validator("text", "event")
|
||||
@classmethod
|
||||
def check_at_least_one(cls, v, info):
|
||||
"""Ensure either text or event is provided."""
|
||||
if info.field_name == "event" and v is None:
|
||||
# Check if text was provided
|
||||
if not info.data.get("text"):
|
||||
raise ValueError("Either text or event must be provided")
|
||||
return v
|
||||
|
||||
|
||||
class DetectIntentRequestDTO(BaseModel):
|
||||
"""Dialogflow detect intent request."""
|
||||
|
||||
query_input: QueryInputDTO
|
||||
query_params: QueryParamsDTO | None = None
|
||||
|
||||
|
||||
class QueryResultDTO(BaseModel):
|
||||
"""Query result from Dialogflow."""
|
||||
|
||||
responseText: str | None = Field(None, alias="responseText")
|
||||
parameters: dict[str, Any] | None = Field(None, alias="parameters")
|
||||
|
||||
model_config = {"populate_by_name": True}
|
||||
|
||||
|
||||
class DetectIntentResponseDTO(BaseModel):
|
||||
"""Dialogflow detect intent response."""
|
||||
|
||||
responseId: str | None = Field(None, alias="responseId")
|
||||
queryResult: QueryResultDTO | None = Field(None, alias="queryResult")
|
||||
quick_replies: Any | None = None # QuickReplyDTO from quick_replies module
|
||||
|
||||
model_config = {"populate_by_name": True}
|
||||
|
||||
|
||||
class ExternalConvRequestDTO(BaseModel):
|
||||
"""External conversation request from client."""
|
||||
|
||||
mensaje: str = Field(..., alias="mensaje")
|
||||
usuario: UsuarioDTO = Field(..., alias="usuario")
|
||||
canal: str = Field(..., alias="canal")
|
||||
tipo: ConversationEntryType = Field(..., alias="tipo")
|
||||
pantalla_contexto: str | None = Field(None, alias="pantallaContexto")
|
||||
|
||||
model_config = {"populate_by_name": True}
|
||||
|
||||
|
||||
class ConversationMessageDTO(BaseModel):
|
||||
"""Single conversation message."""
|
||||
|
||||
type: str = Field(..., alias="type") # Maps to MessageType
|
||||
timestamp: datetime = Field(default_factory=datetime.now, alias="timestamp")
|
||||
text: str = Field(..., alias="text")
|
||||
parameters: dict[str, Any] | None = Field(None, alias="parameters")
|
||||
canal: str | None = Field(None, alias="canal")
|
||||
|
||||
model_config = {"populate_by_name": True}
|
||||
|
||||
|
||||
class ConversationEntryDTO(BaseModel):
|
||||
"""Single conversation entry."""
|
||||
|
||||
entity: str = Field(..., alias="entity") # "USUARIO", "AGENTE", "SISTEMA", "LLM"
|
||||
type: str = Field(..., alias="type") # "INICIO", "CONVERSACION", "LLM"
|
||||
timestamp: datetime = Field(default_factory=datetime.now, alias="timestamp")
|
||||
text: str = Field(..., alias="text")
|
||||
parameters: dict[str, Any] | None = Field(None, alias="parameters")
|
||||
canal: str | None = Field(None, alias="canal")
|
||||
|
||||
model_config = {"populate_by_name": True}
|
||||
|
||||
|
||||
class ConversationSessionDTO(BaseModel):
|
||||
"""Conversation session metadata."""
|
||||
|
||||
sessionId: str = Field(..., alias="sessionId")
|
||||
userId: str = Field(..., alias="userId")
|
||||
telefono: str = Field(..., alias="telefono")
|
||||
createdAt: datetime = Field(default_factory=datetime.now, alias="createdAt")
|
||||
lastModified: datetime = Field(default_factory=datetime.now, alias="lastModified")
|
||||
lastMessage: str | None = Field(None, alias="lastMessage")
|
||||
pantallaContexto: str | None = Field(None, alias="pantallaContexto")
|
||||
|
||||
model_config = {"populate_by_name": True}
|
||||
|
||||
@classmethod
|
||||
def create(
|
||||
cls, session_id: str, user_id: str, telefono: str
|
||||
) -> "ConversationSessionDTO":
|
||||
"""Create a new conversation session."""
|
||||
now = datetime.now()
|
||||
return cls(
|
||||
sessionId=session_id,
|
||||
userId=user_id,
|
||||
telefono=telefono,
|
||||
createdAt=now,
|
||||
lastModified=now,
|
||||
)
|
||||
|
||||
def with_last_message(self, last_message: str) -> "ConversationSessionDTO":
|
||||
"""Create copy with updated last message."""
|
||||
return self.model_copy(
|
||||
update={"lastMessage": last_message, "lastModified": datetime.now()}
|
||||
)
|
||||
|
||||
def with_pantalla_contexto(
|
||||
self, pantalla_contexto: str
|
||||
) -> "ConversationSessionDTO":
|
||||
"""Create copy with updated pantalla contexto."""
|
||||
return self.model_copy(update={"pantallaContexto": pantalla_contexto})
|
||||
Reference in New Issue
Block a user