Skip to content

Commit

Permalink
Merge pull request #35 from Arquisoft/develop
Browse files Browse the repository at this point in the history
Develop
  • Loading branch information
Jorge-Bs authored Mar 4, 2025
2 parents b00f3d7 + 5a52e01 commit 3bde88b
Show file tree
Hide file tree
Showing 25 changed files with 5,156 additions and 116 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -5,5 +5,6 @@ docs/build

webapp/.env.DS_Store
webapp/.env
llmservice/.env

/.idea
2 changes: 0 additions & 2 deletions docs/src/02_architecture_constraints.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -11,12 +11,10 @@ o mayor medida la arquitectura o forma final que tendrá el proyecto.
=== Restricciones técnicas y estructurales
|===
|*Restricción* | *Descripción*
| Tecnologías a utilizar | La aplicación debe ser desarrollada utilizando las tecnologías React y Node.js.
| Documentación | La documentación del proyecto debe realizarse utilizando la plantilla Arc42.
| Control de versiones | El control de versiones se realizará mediante Git y se alojará en GitHub.
| Host | La aplicación será desplegada en un host de Docker.
| API | Se utilizará una API de WikiData para obtener información a la hora de generar preguntas (distintas fotografías) y respuestas.
| Base de datos | Se utilizará una base de datos MongoDB para almacenar la información de los usuarios.
|===


Expand Down
20 changes: 8 additions & 12 deletions docs/src/09_architecture_decisions.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -9,25 +9,21 @@ una forma en la que se pueda comprender el porqué de cada una de ellas desde el
[cols="1,2"]
|===
|*Decisión*|*Justificación*
|_Git_ | Escogemos Git como sistema de control de versiones por ser la principal opción en el mercado y por ser un sistema
|_Git para el control de versiones_ | Escogemos Git como sistema de control de versiones por ser la principal opción en el mercado y por ser un sistema
de control de versiones distribuido, lo que nos permite trabajar de forma más eficiente y simple.
|_GitHub_ | Se trata del servicio Git basado en la nube más popular y con más funcionalidades, lo que nos permite tener un control total
|_GitHub para gestión de código compartido en la nube_ | Se trata del servicio Git basado en la nube más popular y con más funcionalidades, lo que nos permite tener un control total
sobre los cambios de nuestra aplicación, además de tener la seguridad de que no vamos a perder ni una línea de código, aunque esta se sobreescriba en algún momento.
|_JavaScript_ | La mayor parte de integrantes del grupo tiene experiencia previa en este lenguaje, por lo que se conoce la versatilidad
|_Utilización de JavaScript_ | La mayor parte de integrantes del grupo tiene experiencia previa en este lenguaje, por lo que se conoce la versatilidad
y utilidad de este lenguaje para el desarrollo de aplicaciones web.
|_Docker_ | Principal opción para tener una implementación y despliegue rápidos de la aplicación. Permite desplegar aplicaciones y moverlas
con mucha facilidad, y cuenta con múltiples ejemplos para comprender su funcionamiento.
|_MongoDB_ | Es una de las principales soluciones del mercado, y ha sido elegida por su facilidad de uso y por la previa experiencia
|_BD con MongoDB_ | Es una de las principales soluciones del mercado, y ha sido elegida por su facilidad de uso y por la previa experiencia
de alguno de los componentes con esta base de datos.
|_Node.js_ | Se ha escogido por ser un entorno de ejecución para JavaScript en el servidor, con alto rendimiento y velocidad, ideal para aplicaciones web en tiempo real
|_Despliegue con Node.js_ | Se ha escogido por ser un entorno de ejecución para JavaScript en el servidor, con alto rendimiento y velocidad, ideal para aplicaciones web en tiempo real
como la que nos concierne.
|_React_ | Se ha escogido por ser una de las opciones más populares a la hora de desarrollar JavaScript con interfaces de usuario.
|_Wikidata_ | Esta era una opción clara por ser una base de datos libre, colaborativa y multilingüe, con la que conseguir la información para
|_Desarrollo con React_ | Se ha escogido por ser una de las opciones más populares a la hora de desarrollar JavaScript con interfaces de usuario.
|_Wikidata para la obtención de información_ | Esta era una opción clara por ser una base de datos libre, colaborativa y multilingüe, con la que conseguir la información para
las diferentes preguntas será muy sencillo.
|_Large Language Model (LLM)_ | Se utilizará para poder generar respuestas en tiempo real con el chatbot de inteligencia artificial que
|_Uso de la LLM de Empathy_ | Se utilizará la LLM de Empathy para poder generar respuestas en tiempo real con el chatbot de inteligencia artificial que
se implementará en la aplicación.
|_Plantilla Arc42_ | Se ha escogido esta plantilla por ser una de las más completas y por tener una estructura clara y sencilla de seguir,
permitiendo al lector entender de un vistazo qué es lo que está viendo, y encontrar con facilidad los diferentes apartados de la estructura.
|===


Expand Down
8 changes: 4 additions & 4 deletions docs/src/10_quality_requirements.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -17,19 +17,19 @@ image::arbol_de_calidad.png[Árbol de calidad]
| *Prioridad*

| Rendimiento
| Se buscará que los tiempos de espera de la aplicación sean reducidos, para que el usuario pueda disfrutar de una experiencia fluida y con las mínimas interrupciones posibles.
| Los tiempos de espera o respuesta de la aplicación sean reducidos, para que el usuario pueda disfrutar de una experiencia fluida y con las mínimas interrupciones posibles. Se buscará que los tiempos sean no superirores a 1 segundo.
| Medio

| Testeabilidad
| Nuestra aplicación podrá ser testeable, es decir, estará sometida a una serie de pruebas que realizaremos para garantizar el correcto funcionamiento del sistema. También nos ayudará a identificar errores y solucionarlos.
| Nuestra aplicación podrá ser testeable, es decir, estará sometida a una serie de pruebas que realizaremos para garantizar el correcto funcionamiento del sistema. El 80% del código tendrá cobertura con pruebas unitarias exitosas. También nos ayudará a identificar errores y solucionarlos.
| Medio-Alto

| Usabilidad
| La aplicación deberá ser intuitiva y fácil de usar, para que cualquier usuario pueda disfrutar de la experiencia sin necesidad de instrucciones previas. El ojetivo es que el usuario pueda navegar sin dificultades y se sienta cómodo en la aplicación.
| La aplicación deberá ser intuitiva y fácil de usar, para que cualquier usuario pueda disfrutar de la experiencia sin necesidad de instrucciones previas. Se usarán paletas de colores aptas para daltónicos. El ojetivo es que el usuario pueda navegar sin dificultades y se sienta cómodo en la aplicación. Registrase como nuevo usuario será un proceso sencillo y rápido que no requerirá más de 1 minuto.
| Alto

| Mantenibilidad
| Se tratará de cuidar la arquitectura de la aplicación para futuras nuevas implementaciones, modificaciones o correcciones. Se buscará que el código sea limpio y fácil de entender, para que cualquier miembro del equipo pueda trabajar en él. También se revisará periódicamente la documentación para mantenerla actualizada.
| Se tratará de cuidar la arquitectura de la aplicación para futuras nuevas implementaciones, modificaciones o correcciones. Se buscará que el código sea limpio y fácil de entender, para que cualquier miembro del equipo pueda trabajar en él. También se revisará periódicamente la documentación para mantenerla actualizada. Se puede añadir una funcionalidad sin modificar más del 10% del código.
| Medio-Alto

|===
33 changes: 2 additions & 31 deletions docs/src/12_glossary.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -8,39 +8,10 @@ ifndef::imagesdir[:imagesdir: ../images]
|===
|Término | Definición

| Git
| Sistema de control de versiones.

| GitHub
| Servicio basado en la nube que aloja el sistema de control de versiones, Git.

| Wikidata
| Web de dónde se sacará la información para las preguntas.

| JavaScript
| Lenguaje de programación interpretado, dialecto del estándar ECMAScript. Se utiliza para crear páginas web dinámicas.

| React
| Biblioteca de JavaScript para construir interfaces de usuario.

| Node.js
| Entorno de ejecución para JavaScript en el servidor, con alto rendimiento y velocidad, ideal para aplicaciones en tiempo real.

| CSS
| Cascading Style Sheets. Lenguaje de diseño gráfico para definir y crear la presentación de un documento.

| MongoDB
| Sistema de bases de datos no relacional, orientada a documentos.

| Docker
| Herramienta para realizar el despliegue de la aplicación.

| API
| Application Programming Interface. Conjunto de reglas y especificaciones que las aplicaciones pueden usar para comunicarse entre sí.

| Draw.io
| Herramienta para realizar diagramas.
| LLM
| Large Language Model. Es un modelo de IA poderoso que aprende del lenguaje humano y puede usarse en diversas aplicaciones para generar y comprender texto.

| Plantilla Arc42
| Estructura para documentar sistemas de software
|===
66 changes: 32 additions & 34 deletions llmservice/llm-service.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,37 +3,30 @@ const express = require('express');

const app = express();
const port = 8003;
let moderation = "You are a helpful assistant.";

// Middleware to parse JSON in request body
app.use(express.json());
app.use(express.json()); // Middleware para parsear JSON

// Define configurations for different LLM APIs
const llmConfigs = {
gemini: {
url: (apiKey) => `https://generativelanguage.googleapis.com/v1beta/models/gemini-1.5-flash:generateContent?key=${apiKey}`,
transformRequest: (question) => ({
contents: [{ parts: [{ text: question }] }]
}),
transformResponse: (response) => response.data.candidates[0]?.content?.parts[0]?.text
},
empathy: {
url: () => 'https://empathyai.staging.empathy.co/v1/chat/completions',
transformRequest: (question) => ({
url: () => 'https://ai-challenge.empathy.ai/v1/chat/completions',
transformRequest: (question, moderation) => ({
model: "qwen/Qwen2.5-Coder-7B-Instruct",
stream: false, // No soporta stream=true con axios directamente
messages: [
{ role: "system", content: "You are a helpful assistant." },
{ role: "system", content: moderation },
{ role: "user", content: question }
]
}),
transformResponse: (response) => response.data.choices[0]?.message?.content,
transformResponse: (response) => response.data.choices?.[0]?.message?.content || "No response",
headers: (apiKey) => ({
Authorization: `Bearer ${apiKey}`,
'Content-Type': 'application/json'
})
}
};

// Function to validate required fields in the request body
// Validar campos requeridos
function validateRequiredFields(req, requiredFields) {
for (const field of requiredFields) {
if (!(field in req.body)) {
Expand All @@ -42,39 +35,46 @@ function validateRequiredFields(req, requiredFields) {
}
}

// Generic function to send questions to LLM
async function sendQuestionToLLM(question, apiKey, model = 'gemini') {
// Función genérica para enviar preguntas al LLM
async function sendQuestionToLLM(question, apiKey, moderation) {
try {
const config = llmConfigs[model];
const config = llmConfigs["empathy"];
if (!config) {
throw new Error(`Model "${model}" is not supported.`);
throw new Error(`Model is not supported.`);
}

const url = config.url(apiKey);
const requestData = config.transformRequest(question);
const url = config.url();
const requestData = config.transformRequest(question, moderation);

const headers = {
'Content-Type': 'application/json',
...(config.headers ? config.headers(apiKey) : {})
};
const headers = config.headers(apiKey);

const response = await axios.post(url, requestData, { headers });

return config.transformResponse(response);

} catch (error) {
console.error(`Error sending question to ${model}:`, error.message || error);
return null;
console.error(`Error sending question:`, error.message || error);
return "Error processing request.";
}
}

// Ruta para configurar el prompt del asistente
app.post('/configureAssistant', async (req, res) => {
if (!req.body.moderation) {
return res.status(400).json({ error: "Missing moderation prompt" });
}
moderation = req.body.moderation;
res.json({ message: "Moderation prompt updated" });
});

// Ruta para enviar una pregunta
app.post('/ask', async (req, res) => {
try {
// Check if required fields are present in the request body
validateRequiredFields(req, ['question', 'model', 'apiKey']);
validateRequiredFields(req, ['question', 'apiKey']);

const { question, apiKey } = req.body;
const answer = await sendQuestionToLLM(question, apiKey, moderation);

const { question, model, apiKey } = req.body;
const answer = await sendQuestionToLLM(question, apiKey, model);
res.json({ answer });

} catch (error) {
Expand All @@ -86,6 +86,4 @@ const server = app.listen(port, () => {
console.log(`LLM Service listening at http://localhost:${port}`);
});

module.exports = server


module.exports = server;
13 changes: 9 additions & 4 deletions llmservice/llm-service.test.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
const request = require('supertest');
const axios = require('axios');
const app = require('./llm-service');
const app = require('./llm-service');
require('dotenv').config();

afterAll(async () => {
app.close();
Expand All @@ -13,16 +14,20 @@ describe('LLM Service', () => {
axios.post.mockImplementation((url, data) => {
if (url.startsWith('https://generativelanguage')) {
return Promise.resolve({ data: { candidates: [{ content: { parts: [{ text: 'llmanswer' }] } }] } });
} else if (url.endsWith('https://empathyai')) {
return Promise.resolve({ data: { answer: 'llmanswer' } });
} else if (url.startsWith('https://ai-challenge.empathy.ai')) {
return Promise.resolve({
data: {
choices: [{ message: { content: 'llmanswer' } }]
}
});
}
});

// Test /ask endpoint
it('the llm should reply', async () => {
const response = await request(app)
.post('/ask')
.send({ question: 'a question', apiKey: 'apiKey', model: 'gemini' });
.send({ question: 'a question', apiKey: process.env['api-key-password']});

expect(response.statusCode).toBe(200);
expect(response.body.answer).toBe('llmanswer');
Expand Down
Loading

0 comments on commit 3bde88b

Please sign in to comment.