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:
@@ -129,3 +129,45 @@ model NotaPlan {
|
||||
|
||||
@@index([planId])
|
||||
}
|
||||
|
||||
// ---------- Agente IA interno (RAG) ----------
|
||||
|
||||
// Documento de la base de conocimiento; `hash` (sha256 del contenido) permite
|
||||
// re-indexar solo cuando cambió.
|
||||
model AIDocumento {
|
||||
id String @id @default(uuid())
|
||||
titulo String @unique
|
||||
contenido String
|
||||
hash String
|
||||
createdAt DateTime @default(now())
|
||||
chunks AIChunk[]
|
||||
}
|
||||
|
||||
model AIChunk {
|
||||
id String @id @default(uuid())
|
||||
documentoId String
|
||||
documento AIDocumento @relation(fields: [documentoId], references: [id], onDelete: Cascade)
|
||||
texto String
|
||||
embedding String // JSON array de floats (SQLite no tiene vector nativo)
|
||||
orden Int
|
||||
|
||||
@@index([documentoId])
|
||||
}
|
||||
|
||||
model AIConversacion {
|
||||
id String @id @default(uuid())
|
||||
createdAt DateTime @default(now())
|
||||
mensajes AIMensaje[]
|
||||
}
|
||||
|
||||
model AIMensaje {
|
||||
id String @id @default(uuid())
|
||||
conversacionId String
|
||||
conversacion AIConversacion @relation(fields: [conversacionId], references: [id], onDelete: Cascade)
|
||||
rol String // user | assistant
|
||||
contenido String
|
||||
fuentes String? // JSON [{titulo, score}] solo en mensajes del asistente
|
||||
createdAt DateTime @default(now())
|
||||
|
||||
@@index([conversacionId])
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user