feat(ai): agente IA interno con RAG sobre NAN + app web en /ai
- API: /api/ai/chat, /conversations, /documents con embeddings qwen3-embedding, coseno en SQLite, dedup por hash, historial de conversaciones - Base de conocimiento semilla (6 docs, 36 chunks): catálogo DIAGONAL, propuestas del cotizador, créditos, proceso de venta, FAQ, privacidad - App agente-ia (Vite/React/Tailwind, StudioBlank) servida en /ai/ vía nginx - 21 tests nuevos (91/91 verdes)
This commit is contained in:
33
apps/agente-ia/src/components/Burbuja.tsx
Normal file
33
apps/agente-ia/src/components/Burbuja.tsx
Normal file
@@ -0,0 +1,33 @@
|
||||
import type { Mensaje } from '../types'
|
||||
|
||||
function Burbuja({ mensaje }: { mensaje: Mensaje }) {
|
||||
const esUsuario = mensaje.rol === 'user'
|
||||
return (
|
||||
<div className={`flex ${esUsuario ? 'justify-end' : 'justify-start'}`}>
|
||||
<div className={`max-w-[80%] ${esUsuario ? 'text-right' : 'text-left'}`}>
|
||||
<div
|
||||
className={`inline-block whitespace-pre-wrap px-4 py-3 text-sm leading-relaxed ${
|
||||
esUsuario ? 'bg-accent text-white' : 'bg-neutral-100 text-neutral-900'
|
||||
}`}
|
||||
>
|
||||
{mensaje.contenido}
|
||||
</div>
|
||||
{!esUsuario && mensaje.fuentes.length > 0 && (
|
||||
<div className="mt-2 flex flex-wrap gap-2">
|
||||
{mensaje.fuentes.map((f) => (
|
||||
<span
|
||||
key={f.titulo}
|
||||
title={`Relevancia: ${(f.score * 100).toFixed(0)}%`}
|
||||
className="border border-neutral-300 px-2 py-1 text-xs font-bold uppercase tracking-widest text-neutral-500"
|
||||
>
|
||||
{f.titulo}
|
||||
</span>
|
||||
))}
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
export default Burbuja
|
||||
Reference in New Issue
Block a user