Cliente · Chat y recomendaciones¶
Esta área cubre el camarero virtual: el cliente que escanea el QR de la mesa abre una conversación y dialoga con la IA para consultar la carta, preguntar por alérgenos, pedir recomendaciones y construir su comanda. Todos los endpoints viven bajo el prefijo /api/v1/chat/conversations/... y son públicos (no requieren JWT): la identidad efectiva es el session_token de la TableSession ligada a la conversación, no un usuario autenticado. La multitenancy se ancla en el restaurant_id que se fija al crear la conversación; nunca se confía en un restaurant_id enviado en cada mensaje.
El corazón del dominio es el endpoint de envío de mensajes, que no devuelve JSON sino un flujo Server-Sent Events (Content-Type: text/event-stream) con la respuesta del asistente token a token. El backend ejecuta una arquitectura de chat híbrida: un seam lee restaurants.chat_mode y enruta cada turno al motor legacy (100% LLM) o al motor hybrid (árbol de decisión determinista alimentado por la BD, con el LLM solo redactando), con fail-open a legacy si el stack nuevo falla. Ambos motores emiten el mismo contrato SSE (content, comentario : thinking, done), más el frame aditivo recommendation exclusivo del híbrido. Para el detalle de motores, árbol, clasificador de intents y señales de "control de sala", ver Chat híbrido; para cómo el motor decide los platos y el LLM solo introduce, ver Recomendación; para la forma exacta de cada frame, ver Eventos SSE.
Patrones transversales a tener en cuenta al consumir esta API:
- Tiempo real (SSE): la respuesta del asistente se transmite con cabeceras canónicas (
Cache-Control: no-cache,Connection: keep-alive,X-Accel-Buffering: no). Hay un guard de stream concurrente por conversación: un segundo envío mientras la IA aún responde recibe429. El framedonecierra el turno con metadatos (latency_ms,model,phase,cart_actions,course_actions, etc.). - Sincronización multidispositivo: el mensaje del usuario y el indicador de escritura se publican además por el bus de eventos, de modo que otros dispositivos en la misma sesión los reciben por su propio canal SSE.
- Paginación por cursor: el listado de mensajes es retrocompatible (sin parámetros devuelve todo el historial como array JSON ascendente); con
limit(y opcionalmentecursor) devuelve una página keyset y expone el siguiente cursor en la cabeceraX-Next-Cursor.
Datos en tiempo real, sin razonamiento expuesto
La IA responde con datos vivos de la BD (carta con precios y alérgenos, promociones, políticas del restaurante y preferencias del cliente si las hay). El contenido de thinking/razonamiento nunca viaja en el stream: se persiste internamente pero no se expone al cliente.
Visión general de la API y convenciones comunes: Referencia de la API.
Generado automáticamente
Las tablas y fichas de endpoints de esta página se generan desde el contrato OpenAPI. No las edites a mano; edita la intro en documentation/reference/api/_intros/cliente-chat.md y regenera con python scripts/gen_openapi_reference.py.
Resumen de endpoints¶
| Método | Ruta | Resumen | Auth |
|---|---|---|---|
POST |
/api/v1/chat/conversations |
Create Conversation | Pública |
GET |
/api/v1/chat/conversations/by-session/{session_token} |
Get Conversation By Session | Pública |
GET |
/api/v1/chat/conversations/{conversation_id} |
Get Conversation | Pública |
GET |
/api/v1/chat/conversations/{conversation_id}/messages |
Get Messages | Pública |
POST |
/api/v1/chat/conversations/{conversation_id}/messages |
Send Message | Pública |
GET |
/api/v1/recommendations |
Get Recommendations | Pública |
GET |
/api/v1/recommendations/conversation/{conversation_id} |
Get Conversation Recommendations | Pública |
POST |
/api/v1/recommendations/{recommendation_id}/action |
Recommendation Action | Pública |
Detalle¶
POST /api/v1/chat/conversations¶
Create Conversation
Create a new chat conversation.
- Auth: Pública
- Parámetros: —
- Body:
ConversationCreate - Respuestas:
201ConversationCreateResponse,422HTTPValidationError
GET /api/v1/chat/conversations/by-session/{session_token}¶
Get Conversation By Session
Get conversation by session token.
- Auth: Pública
- Parámetros:
session_token(path, requerido) - Respuestas:
200ConversationResponse,422HTTPValidationError
GET /api/v1/chat/conversations/{conversation_id}¶
Get Conversation
Get a conversation with all messages (without thinking content).
- Auth: Pública
- Parámetros:
conversation_id(path, requerido) - Respuestas:
200ConversationResponse,422HTTPValidationError
GET /api/v1/chat/conversations/{conversation_id}/messages¶
Get Messages
Get messages from a conversation (without thinking content).
- Auth: Pública
- Parámetros:
conversation_id(path, requerido),cursor(query, opcional),limit(query, opcional) - Respuestas:
200ChatMessageResponse[],422HTTPValidationError
POST /api/v1/chat/conversations/{conversation_id}/messages¶
Send Message
Send a message and receive streaming response via SSE.
- Auth: Pública
- Parámetros:
conversation_id(path, requerido) - Body:
ChatMessageRequest - Respuestas:
200,422HTTPValidationError
GET /api/v1/recommendations¶
Get Recommendations
Get AI-powered restaurant recommendations.
- Auth: Pública
- Parámetros:
authorization(header, opcional),hour(query, requerido),max_recommendations(query, opcional),num_guests(query, opcional),restaurant_id(query, requerido) - Respuestas:
200RecommendationsResponse,422HTTPValidationError
GET /api/v1/recommendations/conversation/{conversation_id}¶
Get Conversation Recommendations
Get recommendations for a conversation.
- Auth: Pública
- Parámetros:
conversation_id(path, requerido),lang(query, opcional),page(query, opcional),per_page(query, opcional) - Respuestas:
200RecommendationListResponse,422HTTPValidationError
POST /api/v1/recommendations/{recommendation_id}/action¶
Recommendation Action
Accept or dismiss a recommendation.
- Auth: Pública
- Parámetros:
recommendation_id(path, requerido),lang(query, opcional) - Body:
RecommendationAction - Respuestas:
200RecommendationResponse,422HTTPValidationError