Refactor project structure and implement new features

- Removed unused security module and updated import paths.
- Enhanced OpenAI client with streaming capabilities for chat completions.
- Added new backend API endpoints for health check (ping).
- Established a new FastAPI application with CORS configuration.
- Created a new Appshell component for the frontend with navigation links.
- Integrated SVG icons and improved styling for the Appshell component.
- Implemented memory management for conversation history using PostgreSQL.
- Developed abstract classes for AI agents and models, with OpenAI integration.
- Added encryption utilities for secure data handling.
This commit is contained in:
2025-05-06 23:33:41 +02:00
parent 234639a34a
commit b4ca0cf600
51 changed files with 2026 additions and 338 deletions
+11
View File
@@ -12,3 +12,14 @@ wheels/
# Volume mounts
data/postgresql/pgdata/*
pruebas_conceptos/postgres_extensions/pgdata/*
# Local configuration files
*.env
config/.env
#Icon files
frontend/src/assets/icons/filled/** */
frontend/src/assets/icons/outlined/** */
+78 -50
View File
@@ -2,7 +2,7 @@
"cells": [
{
"cell_type": "code",
"execution_count": null,
"execution_count": 1,
"id": "26aa8e2b",
"metadata": {},
"outputs": [
@@ -31,7 +31,7 @@
},
{
"cell_type": "code",
"execution_count": null,
"execution_count": 2,
"id": "e5b665a6",
"metadata": {},
"outputs": [],
@@ -60,12 +60,12 @@
},
{
"cell_type": "code",
"execution_count": 3,
"execution_count": null,
"id": "ada431b7",
"metadata": {},
"outputs": [],
"source": [
"from llms.Modelos.Openai_model import ModeloOpenAI\n",
"from src.Llms.Modelos.Openai_model import ModeloOpenAI\n",
"\n",
"modelo = ModeloOpenAI(\n",
" cliente=cliente,\n",
@@ -98,12 +98,12 @@
},
{
"cell_type": "code",
"execution_count": 5,
"execution_count": null,
"id": "ce8628d4",
"metadata": {},
"outputs": [],
"source": [
"from llms.Memory.postgres_MemoryConv import MemoryConvPostgres\n",
"from src.Llms.Memory.postgres_MemoryConv import MemoryConvPostgres\n",
"\n",
"memoria = MemoryConvPostgres(\n",
" credencial=db_credencial,\n",
@@ -114,29 +114,13 @@
},
{
"cell_type": "code",
"execution_count": 6,
"execution_count": null,
"id": "a25bc742",
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"```json\n",
"{\n",
" \"objeto_celeste\": \"Betelgeuse\",\n",
" \"tipo_objeto\": \"Supergigante Roja\",\n",
" \"respuesta_resumida\": \"Betelgeuse es una supergigante roja en la constelación de Orión que se volvió más tenue en 2019 debido a una gran eyección de material estelar y la formación de polvo.\",\n",
" \"respuesta_detallada\": \"Betelgeuse es una estrella supergigante roja localizada a unos 640 años luz en la constelación de Orión. A finales de 2019 y principios de 2020, Betelgeuse experimentó una notable disminución en su brillo que atrajo gran atención. Esta atenuación fue causada principalmente por una eyección masiva de gas desde la estrella, que al enfriarse, se condensó formando polvo estelar cerca de la estrella. Este polvo bloqueó parcialmente la luz de Betelgeuse, haciendo que pareciera más tenue desde la Tierra. Tal comportamiento no es inesperado en supergigantes rojas, que son estrellas en etapas avanzadas de evolución y pueden mostrar variaciones de brillo debido a pulsaciones internas y procesos de pérdida de masa.\",\n",
" \"contexto_observacional\": \"Betelgeuse es visible a simple vista en el cielo nocturno, especialmente durante el invierno en el hemisferio norte. Sus cambios de brillo fueron observados tanto por astrónomos aficionados como por profesionales usando telescopios.\",\n",
" \"referencias_relevantes\": [\"Evolución de las estrellas masivas y supergigantes rojas, Nature Astronomy (2020)\", \"Observaciones del Telescopio Espacial Hubble sobre Betelgeuse\"]\n",
"}\n",
"```\n"
]
}
],
"outputs": [],
"source": [
"from llms.Agente import AgenteAI\n",
"from src.Llms.Agente import AgenteAI\n",
"import asyncio\n",
"\n",
"output_schema = {\n",
" \"objeto_celeste\": \"<nombre del objeto o fenómeno principal al que se refiere la respuesta, e.g., 'Júpiter', 'Vía Láctea', 'Supernova tipo Ia'>\",\n",
@@ -155,15 +139,14 @@
" rol=\"astronomo\",\n",
" memoria=memoria,\n",
" objetivos=[\"Responder preguntas sobre astronomía y astrofísica\", \"Proporcionar explicaciones detalladas y ejemplos numéricos\"],\n",
" output_schema=output_schema\n",
")\n",
"\n",
"respuesta = agente.interactuar(\n",
" prompt=\"¿Qué es Betelgeuse y por qué se volvió más tenue en 2019?\",\n",
")\n",
"# respuesta = await agente.interactuar(\n",
"# prompt=\"¿Qué es Betelgeuse y por qué se volvió más tenue en 2019?\",\n",
"# )\n",
"\n",
"\n",
"print(respuesta)"
"# print(respuesta)"
]
},
{
@@ -181,11 +164,7 @@
"Tu Rol: astronomo\n",
"Tus Objetivos: Responder preguntas sobre astronomía y astrofísica, Proporcionar explicaciones detalladas y ejemplos numéricos\n",
"\n",
"Actúa como un experto en astronomía y astrofísica con experiencia académica y práctica en observación astronómica, física estelar, cosmología, mecánica orbital y análisis de datos astronómicos. Cuando respondas, utiliza lenguaje técnico pero accesible para alguien con conocimientos intermedios en física y matemáticas. Siempre que sea posible, incluye explicaciones detalladas, ejemplos numéricos y referencias a teorías o descubrimientos relevantes (por ejemplo, relatividad general, evolución estelar, espectroscopía, etc.). No simplifiques en exceso. Si la pregunta tiene múltiples dimensiones (como observacional y teórica), aborda todas. ¿Estás listo para empezar?\n",
"SIEMPRE formatea la respuesta final siguiendo estrictamente el siguiente esquema JSON:\n",
"```json\n",
"{'objeto_celeste': \"<nombre del objeto o fenómeno principal al que se refiere la respuesta, e.g., 'Júpiter', 'Vía Láctea', 'Supernova tipo Ia'>\", 'tipo_objeto': '<clasificación general: planeta, estrella, galaxia, agujero negro, fenómeno cosmológico, etc.>', 'respuesta_resumida': '<resumen de máximo 3 líneas de la explicación>', 'respuesta_detallada': '<explicación extensa con base científica, observacional y teórica si aplica>', 'contexto_observacional': '<si es observable desde la Tierra, en qué condiciones o con qué instrumentos>', 'referencias_relevantes': ['<libros, papers, misiones espaciales o catálogos astronómicos relevantes>']}\n",
"```\n"
"Actúa como un experto en astronomía y astrofísica con experiencia académica y práctica en observación astronómica, física estelar, cosmología, mecánica orbital y análisis de datos astronómicos. Cuando respondas, utiliza lenguaje técnico pero accesible para alguien con conocimientos intermedios en física y matemáticas. Siempre que sea posible, incluye explicaciones detalladas, ejemplos numéricos y referencias a teorías o descubrimientos relevantes (por ejemplo, relatividad general, evolución estelar, espectroscopía, etc.). No simplifiques en exceso. Si la pregunta tiene múltiples dimensiones (como observacional y teórica), aborda todas. ¿Estás listo para empezar?\n"
]
}
],
@@ -195,36 +174,85 @@
},
{
"cell_type": "code",
"execution_count": 11,
"execution_count": 8,
"id": "07e3b6de",
"metadata": {},
"outputs": [],
"source": [
"# agente_con_herramientas = AgenteAI(\n",
"# modelo=modelo,\n",
"# nombre=\"Agente con herramientas\",\n",
"# descripcion=\"Un agente que puede usar herramientas\",\n",
"# system_prompt=\"Eres un asistente que puede usar herramientas para responder preguntas.\",\n",
"# rol=\"asistente\",\n",
"# memoria= memoria,\n",
"# objetivos=[\"Asistir al usuario en tareas complejas\", \"usar herramientas para obtener información adicional\"]\n",
"# # tools=\n",
"\n",
"# )\n",
"\n",
"# respuesta = agente_con_herramientas.interactuar(\n",
"# prompt=\"Hola como estas?\",\n",
"# )\n",
"\n",
"# print(respuesta)"
]
},
{
"cell_type": "code",
"execution_count": 10,
"id": "5d9fc77e",
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"¡Hola! Estoy aquí para ayudarte con cualquier pregunta o tarea que tengas. ¿En qué puedo asistirte hoy?\n"
"Desde una perspectiva astronómica y cosmológica, \"de dónde venimos\" y \"a dónde vamos\" son preguntas profundas que tocan conceptos sobre el origen y el destino del Universo y de la humanidad dentro de él.\n",
"\n",
"**De dónde venimos:**\n",
"\n",
"1. **Origen del Universo**: La teoría más aceptada sobre el origen del Universo es el Big Bang, que propone que el Universo nació hace aproximadamente 13.8 mil millones de años a partir de una singularidad extremadamente caliente y densa. Desde entonces, ha estado expandiéndose y enfriándose, permitiendo la formación de partículas, átomos y eventualmente estrellas y galaxias.\n",
"\n",
"2. **Formación de elementos y planetas**: Las primeras generaciones de estrellas sintetizaron elementos pesados en sus núcleos y, al explotar como supernovas, dispersaron estos elementos al espacio, enriqueciendo el medio interestelar. Este material enriquecido permitió la formación de planetas como la Tierra.\n",
"\n",
"3. **Evolución de la Vida**: En la Tierra, los procesos químicos dieron lugar a organismos primitivos, los cuales evolucionaron a lo largo de miles de millones de años para dar lugar a la biodiversidad actual, incluyendo a los seres humanos.\n",
"\n",
"**A dónde vamos:**\n",
"\n",
"1. **Destinos individuales y colectivos**: A nivel personal y colectivo, los destinos humanos dependen de nuestra evolución tecnológica y social. Estamos explorando nuestro sistema solar e incluso considerando la colonización de otros planetas, como Marte.\n",
"\n",
"2. **Futuro del Universo**: El futuro del Universo dependerá de su composición y energía oscura. Dos posibles destinos son:\n",
"\n",
" - *Expansión infinita*: El Universo podría continuar expandiéndose indefinidamente, llevando a un futuro frío y oscuro conocido como muerte térmica, donde las estrellas se agoten y las galaxias se separen.\n",
"\n",
" - *Big Crunch o Big Rip*: Alternativamente, si la densidad del Universo es lo suficientemente alta, podría detenerse y comenzar a contraerse en un Big Crunch, o si la energía oscura desempeña un papel más caótico, experimentar un Big Rip, donde el Universo se desgarra.\n",
"\n",
"Estas fascinantes preguntas inspiran tanto la ciencia como la filosofía y nos estimulan a seguir explorando el cosmos para comprender nuestro lugar y destino en él. <FIN>\n"
]
}
],
"source": [
"agente_con_herramientas = AgenteAI(\n",
"agente2 = AgenteAI(\n",
" modelo=modelo,\n",
" nombre=\"Agente con herramientas\",\n",
" descripcion=\"Un agente que puede usar herramientas\",\n",
" system_prompt=\"Eres un asistente que puede usar herramientas para responder preguntas.\",\n",
" rol=\"asistente\",\n",
" memoria= memoria,\n",
" objetivos=[\"Asistir al usuario en tareas complejas\", \"usar herramientas para obtener información adicional\"]\n",
" # tools=\n",
"\n",
" nombre=\"Experto en Astronomía\",\n",
" descripcion=\"Un experto en astronomía que responde preguntas sobre el universo.\",\n",
" system_prompt=\"Actúa como un experto en astronomía y astrofísica con experiencia académica y práctica en observación astronómica, física estelar, cosmología, mecánica orbital y análisis de datos astronómicos. Cuando respondas, utiliza lenguaje técnico pero accesible para alguien con conocimientos intermedios en física y matemáticas. Siempre que sea posible, incluye explicaciones detalladas, ejemplos numéricos y referencias a teorías o descubrimientos relevantes (por ejemplo, relatividad general, evolución estelar, espectroscopía, etc.). No simplifiques en exceso. Si la pregunta tiene múltiples dimensiones (como observacional y teórica), aborda todas. ¿Estás listo para empezar?\",\n",
" rol=\"astronomo\",\n",
" max_iterations=5,\n",
" memoria=memoria,\n",
" objetivos=[\"Responder preguntas sobre astronomía y astrofísica\", \"Proporcionar explicaciones detalladas y ejemplos numéricos\"],\n",
")\n",
"\n",
"respuesta = agente_con_herramientas.interactuar(\n",
" prompt=\"Hola como estas?\",\n",
"\n",
"\n",
"\n",
"respuesta2 = await agente2.interactuar_en_bucle(\n",
" prompt=\"De donde venimos y donde vamos?\"\n",
")\n",
"\n",
"print(respuesta)"
"for r in respuesta2:\n",
" print(r)"
]
}
],
+9
View File
@@ -0,0 +1,9 @@
# backend/api/endpoints/ping.py
from fastapi import APIRouter
router = APIRouter()
@router.get("/ping")
async def ping():
return {"message": "pong"}
+7
View File
@@ -0,0 +1,7 @@
# backend/api/router.py
from fastapi import APIRouter
from backend.api.v1.endpoints import ping
router = APIRouter()
router.include_router(ping.router, prefix="/api/v1")
View File
+24
View File
@@ -0,0 +1,24 @@
# backend/main.py
from fastapi import FastAPI
from fastapi.middleware.cors import CORSMiddleware
from backend.api.v1.router import router
app = FastAPI(
title="Fitz Backend",
description="API para interacción con el frontend y ejecución de tareas",
version="0.1.0"
)
# Configuración de CORS
app.add_middleware(
CORSMiddleware,
allow_origins=["http://localhost:5173"], # Solo permite tu frontend local
allow_credentials=True,
allow_methods=["*"],
allow_headers=["*"],
)
# Incluye las rutas de tu API
app.include_router(router)
+961
View File
@@ -0,0 +1,961 @@
E:\Fitz_Studio
├── .git
│ ├── COMMIT_EDITMSG
│ ├── FETCH_HEAD
│ ├── HEAD
│ ├── ORIG_HEAD
│ ├── config
│ ├── description
│ ├── hooks
│ │ ├── applypatch-msg.sample
│ │ ├── commit-msg.sample
│ │ ├── fsmonitor-watchman.sample
│ │ ├── post-update.sample
│ │ ├── pre-applypatch.sample
│ │ ├── pre-commit.sample
│ │ ├── pre-merge-commit.sample
│ │ ├── pre-push.sample
│ │ ├── pre-rebase.sample
│ │ ├── pre-receive.sample
│ │ ├── prepare-commit-msg.sample
│ │ ├── push-to-checkout.sample
│ │ ├── sendemail-validate.sample
│ │ └── update.sample
│ ├── index
│ ├── info
│ │ └── exclude
│ ├── logs
│ │ ├── HEAD
│ │ └── refs
│ ├── objects
│ │ ├── 00
│ │ ├── 01
│ │ ├── 04
│ │ ├── 05
│ │ ├── 06
│ │ ├── 0a
│ │ ├── 0b
│ │ ├── 0c
│ │ ├── 0e
│ │ ├── 10
│ │ ├── 11
│ │ ├── 15
│ │ ├── 17
│ │ ├── 18
│ │ ├── 19
│ │ ├── 1a
│ │ ├── 1b
│ │ ├── 1d
│ │ ├── 1f
│ │ ├── 20
│ │ ├── 23
│ │ ├── 26
│ │ ├── 27
│ │ ├── 2c
│ │ ├── 2d
│ │ ├── 31
│ │ ├── 33
│ │ ├── 34
│ │ ├── 39
│ │ ├── 3c
│ │ ├── 3d
│ │ ├── 3f
│ │ ├── 41
│ │ ├── 42
│ │ ├── 43
│ │ ├── 47
│ │ ├── 48
│ │ ├── 4a
│ │ ├── 4b
│ │ ├── 4c
│ │ ├── 4d
│ │ ├── 4e
│ │ ├── 4f
│ │ ├── 51
│ │ ├── 55
│ │ ├── 57
│ │ ├── 5b
│ │ ├── 5c
│ │ ├── 5d
│ │ ├── 5e
│ │ ├── 60
│ │ ├── 61
│ │ ├── 62
│ │ ├── 63
│ │ ├── 65
│ │ ├── 67
│ │ ├── 69
│ │ ├── 6c
│ │ ├── 6d
│ │ ├── 6e
│ │ ├── 70
│ │ ├── 71
│ │ ├── 74
│ │ ├── 75
│ │ ├── 76
│ │ ├── 7b
│ │ ├── 7c
│ │ ├── 7d
│ │ ├── 7f
│ │ ├── 80
│ │ ├── 81
│ │ ├── 83
│ │ ├── 84
│ │ ├── 85
│ │ ├── 87
│ │ ├── 89
│ │ ├── 8a
│ │ ├── 8b
│ │ ├── 94
│ │ ├── 95
│ │ ├── 97
│ │ ├── 99
│ │ ├── 9a
│ │ ├── 9c
│ │ ├── 9d
│ │ ├── a2
│ │ ├── a3
│ │ ├── a4
│ │ ├── a5
│ │ ├── a6
│ │ ├── a8
│ │ ├── a9
│ │ ├── aa
│ │ ├── ab
│ │ ├── ac
│ │ ├── ad
│ │ ├── ae
│ │ ├── b1
│ │ ├── b3
│ │ ├── b4
│ │ ├── b5
│ │ ├── b6
│ │ ├── b8
│ │ ├── b9
│ │ ├── ba
│ │ ├── bb
│ │ ├── bf
│ │ ├── c0
│ │ ├── c4
│ │ ├── c6
│ │ ├── c7
│ │ ├── c9
│ │ ├── cf
│ │ ├── d1
│ │ ├── d5
│ │ ├── d6
│ │ ├── d7
│ │ ├── d9
│ │ ├── da
│ │ ├── db
│ │ ├── dc
│ │ ├── dd
│ │ ├── de
│ │ ├── df
│ │ ├── e3
│ │ ├── e4
│ │ ├── e5
│ │ ├── e6
│ │ ├── e7
│ │ ├── e8
│ │ ├── e9
│ │ ├── ec
│ │ ├── ed
│ │ ├── ee
│ │ ├── ef
│ │ ├── f1
│ │ ├── f2
│ │ ├── f3
│ │ ├── f6
│ │ ├── f7
│ │ ├── f9
│ │ ├── fb
│ │ ├── fc
│ │ ├── fd
│ │ ├── ff
│ │ ├── info
│ │ └── pack
│ └── refs
│ ├── heads
│ ├── remotes
│ └── tags
├── .gitignore
├── .python-version
├── .venv
│ ├── .gitignore
│ ├── .lock
│ ├── CACHEDIR.TAG
│ ├── Lib
│ │ └── site-packages
│ ├── Scripts
│ │ ├── activate
│ │ ├── activate.bat
│ │ ├── activate.csh
│ │ ├── activate.fish
│ │ ├── activate.nu
│ │ ├── activate.ps1
│ │ ├── activate_this.py
│ │ ├── deactivate.bat
│ │ ├── debugpy-adapter.exe
│ │ ├── debugpy.exe
│ │ ├── distro.exe
│ │ ├── dotenv.exe
│ │ ├── f2py.exe
│ │ ├── fastapi.exe
│ │ ├── httpx.exe
│ │ ├── huggingface-cli.exe
│ │ ├── ipython.exe
│ │ ├── ipython3.exe
│ │ ├── isympy.exe
│ │ ├── jlpm.exe
│ │ ├── jsonpointer
│ │ ├── jsonschema.exe
│ │ ├── jupyter-console.exe
│ │ ├── jupyter-dejavu.exe
│ │ ├── jupyter-events.exe
│ │ ├── jupyter-execute.exe
│ │ ├── jupyter-kernel.exe
│ │ ├── jupyter-kernelspec.exe
│ │ ├── jupyter-lab.exe
│ │ ├── jupyter-labextension.exe
│ │ ├── jupyter-labhub.exe
│ │ ├── jupyter-migrate.exe
│ │ ├── jupyter-nbconvert.exe
│ │ ├── jupyter-notebook.exe
│ │ ├── jupyter-run.exe
│ │ ├── jupyter-server.exe
│ │ ├── jupyter-troubleshoot.exe
│ │ ├── jupyter-trust.exe
│ │ ├── jupyter.exe
│ │ ├── markdown-it.exe
│ │ ├── mcp.exe
│ │ ├── normalizer.exe
│ │ ├── numpy-config.exe
│ │ ├── openai.exe
│ │ ├── petname.exe
│ │ ├── pip.exe
│ │ ├── pip3.11.exe
│ │ ├── pip3.exe
│ │ ├── pybabel.exe
│ │ ├── pydoc.bat
│ │ ├── pygmentize.exe
│ │ ├── pyjson5.exe
│ │ ├── python.exe
│ │ ├── pythonw.exe
│ │ ├── pywin32_postinstall.exe
│ │ ├── pywin32_postinstall.py
│ │ ├── pywin32_testall.exe
│ │ ├── pywin32_testall.py
│ │ ├── send2trash.exe
│ │ ├── torchfrtrace.exe
│ │ ├── torchrun.exe
│ │ ├── tqdm.exe
│ │ ├── transformers-cli.exe
│ │ ├── typer.exe
│ │ ├── uvicorn.exe
│ │ └── wsdump.exe
│ ├── etc
│ │ └── jupyter
│ ├── include
│ │ └── site
│ ├── pyvenv.cfg
│ └── share
│ ├── applications
│ ├── icons
│ ├── jupyter
│ └── man
├── Apikeys.ipynb
├── Credenciales.ipynb
├── Encriptacion.ipynb
├── README.md
├── backend
│ ├── __init__.py
│ ├── __pycache__
│ │ ├── __init__.cpython-311.pyc
│ │ └── main.cpython-311.pyc
│ ├── api
│ │ ├── __init__.py
│ │ ├── __pycache__
│ │ └── v1
│ ├── deps
│ │ ├── __init__.py
│ │ └── auth.py
│ └── main.py
├── config
│ └── .env
├── data
│ ├── files
│ │ ├── pdf
│ │ └── txt
│ ├── postgresql
│ │ ├── docker-compose.yml
│ │ └── pgdata
│ └── sqlite
├── entrypoint
│ ├── __init__.py
│ ├── __pycache__
│ │ ├── __init__.cpython-311.pyc
│ │ └── init_db.cpython-311.pyc
│ ├── add_to_pythonpath.ps1
│ └── init_db.py
├── frontend
│ ├── .github
│ │ └── workflows
│ ├── .gitignore
│ ├── .nvmrc
│ ├── .prettierrc.mjs
│ ├── .storybook
│ │ ├── main.ts
│ │ └── preview.tsx
│ ├── .stylelintignore
│ ├── .stylelintrc.json
│ ├── .yarn
│ │ └── releases
│ ├── .yarnrc.yml
│ ├── README.md
│ ├── eslint.config.js
│ ├── index.html
│ ├── node_modules
│ │ ├── .bin
│ │ ├── .package-lock.json
│ │ ├── .vite
│ │ ├── .vite-temp
│ │ ├── @adobe
│ │ ├── @ampproject
│ │ ├── @asamuzakjp
│ │ ├── @babel
│ │ ├── @csstools
│ │ ├── @dimforge
│ │ ├── @dual-bundle
│ │ ├── @esbuild
│ │ ├── @eslint
│ │ ├── @eslint-community
│ │ ├── @floating-ui
│ │ ├── @humanfs
│ │ ├── @humanwhocodes
│ │ ├── @ianvs
│ │ ├── @isaacs
│ │ ├── @joshwooding
│ │ ├── @jridgewell
│ │ ├── @keyv
│ │ ├── @mantine
│ │ ├── @modelcontextprotocol
│ │ ├── @nodelib
│ │ ├── @pkgjs
│ │ ├── @react-three
│ │ ├── @rollup
│ │ ├── @storybook
│ │ ├── @svgr
│ │ ├── @tabler
│ │ ├── @testing-library
│ │ ├── @tweenjs
│ │ ├── @types
│ │ ├── @typescript-eslint
│ │ ├── @vitejs
│ │ ├── @vitest
│ │ ├── @webgpu
│ │ ├── accepts
│ │ ├── acorn
│ │ ├── acorn-jsx
│ │ ├── agent-base
│ │ ├── ajv
│ │ ├── ansi-regex
│ │ ├── ansi-styles
│ │ ├── argparse
│ │ ├── aria-query
│ │ ├── array-buffer-byte-length
│ │ ├── array-includes
│ │ ├── array-union
│ │ ├── array.prototype.findlast
│ │ ├── array.prototype.flat
│ │ ├── array.prototype.flatmap
│ │ ├── array.prototype.tosorted
│ │ ├── arraybuffer.prototype.slice
│ │ ├── assertion-error
│ │ ├── ast-types
│ │ ├── ast-types-flow
│ │ ├── astral-regex
│ │ ├── async-function
│ │ ├── available-typed-arrays
│ │ ├── axe-core
│ │ ├── axobject-query
│ │ ├── balanced-match
│ │ ├── base64-js
│ │ ├── better-opn
│ │ ├── body-parser
│ │ ├── brace-expansion
│ │ ├── braces
│ │ ├── browser-assert
│ │ ├── browserslist
│ │ ├── buffer
│ │ ├── bytes
│ │ ├── cac
│ │ ├── cacheable
│ │ ├── call-bind
│ │ ├── call-bind-apply-helpers
│ │ ├── call-bound
│ │ ├── callsites
│ │ ├── camelcase
│ │ ├── camelcase-css
│ │ ├── caniuse-lite
│ │ ├── chai
│ │ ├── chalk
│ │ ├── check-error
│ │ ├── clsx
│ │ ├── color-convert
│ │ ├── color-name
│ │ ├── colord
│ │ ├── concat-map
│ │ ├── content-disposition
│ │ ├── content-type
│ │ ├── convert-source-map
│ │ ├── cookie
│ │ ├── cookie-signature
│ │ ├── cors
│ │ ├── cosmiconfig
│ │ ├── cross-spawn
│ │ ├── css-functions-list
│ │ ├── css-tree
│ │ ├── css.escape
│ │ ├── cssesc
│ │ ├── cssstyle
│ │ ├── csstype
│ │ ├── damerau-levenshtein
│ │ ├── data-urls
│ │ ├── data-view-buffer
│ │ ├── data-view-byte-length
│ │ ├── data-view-byte-offset
│ │ ├── debug
│ │ ├── decimal.js
│ │ ├── deep-eql
│ │ ├── deep-is
│ │ ├── define-data-property
│ │ ├── define-lazy-prop
│ │ ├── define-properties
│ │ ├── depd
│ │ ├── dequal
│ │ ├── detect-node-es
│ │ ├── dir-glob
│ │ ├── doctrine
│ │ ├── dom-accessibility-api
│ │ ├── dot-case
│ │ ├── dunder-proto
│ │ ├── eastasianwidth
│ │ ├── ee-first
│ │ ├── electron-to-chromium
│ │ ├── emoji-regex
│ │ ├── encodeurl
│ │ ├── entities
│ │ ├── env-paths
│ │ ├── error-ex
│ │ ├── es-abstract
│ │ ├── es-define-property
│ │ ├── es-errors
│ │ ├── es-iterator-helpers
│ │ ├── es-module-lexer
│ │ ├── es-object-atoms
│ │ ├── es-set-tostringtag
│ │ ├── es-shim-unscopables
│ │ ├── es-to-primitive
│ │ ├── esbuild
│ │ ├── esbuild-register
│ │ ├── escalade
│ │ ├── escape-html
│ │ ├── escape-string-regexp
│ │ ├── eslint
│ │ ├── eslint-config-mantine
│ │ ├── eslint-plugin-jsx-a11y
│ │ ├── eslint-plugin-react
│ │ ├── eslint-scope
│ │ ├── eslint-visitor-keys
│ │ ├── espree
│ │ ├── esprima
│ │ ├── esquery
│ │ ├── esrecurse
│ │ ├── estraverse
│ │ ├── estree-walker
│ │ ├── esutils
│ │ ├── etag
│ │ ├── eventsource
│ │ ├── eventsource-parser
│ │ ├── expect-type
│ │ ├── express
│ │ ├── express-rate-limit
│ │ ├── fast-deep-equal
│ │ ├── fast-glob
│ │ ├── fast-json-stable-stringify
│ │ ├── fast-levenshtein
│ │ ├── fast-uri
│ │ ├── fastest-levenshtein
│ │ ├── fastq
│ │ ├── fdir
│ │ ├── fflate
│ │ ├── file-entry-cache
│ │ ├── fill-range
│ │ ├── finalhandler
│ │ ├── find-up
│ │ ├── flat-cache
│ │ ├── flatted
│ │ ├── for-each
│ │ ├── foreground-child
│ │ ├── forwarded
│ │ ├── fresh
│ │ ├── function-bind
│ │ ├── function.prototype.name
│ │ ├── functions-have-names
│ │ ├── gensync
│ │ ├── get-intrinsic
│ │ ├── get-nonce
│ │ ├── get-proto
│ │ ├── get-symbol-description
│ │ ├── glob
│ │ ├── glob-parent
│ │ ├── global-modules
│ │ ├── global-prefix
│ │ ├── globals
│ │ ├── globalthis
│ │ ├── globby
│ │ ├── globjoin
│ │ ├── globrex
│ │ ├── gopd
│ │ ├── graphemer
│ │ ├── harmony-reflect
│ │ ├── has-bigints
│ │ ├── has-flag
│ │ ├── has-property-descriptors
│ │ ├── has-proto
│ │ ├── has-symbols
│ │ ├── has-tostringtag
│ │ ├── hasown
│ │ ├── hookified
│ │ ├── html-encoding-sniffer
│ │ ├── html-tags
│ │ ├── http-errors
│ │ ├── http-proxy-agent
│ │ ├── https-proxy-agent
│ │ ├── iconv-lite
│ │ ├── identity-obj-proxy
│ │ ├── ieee754
│ │ ├── ignore
│ │ ├── import-fresh
│ │ ├── imurmurhash
│ │ ├── indent-string
│ │ ├── inherits
│ │ ├── ini
│ │ ├── internal-slot
│ │ ├── ipaddr.js
│ │ ├── is-arguments
│ │ ├── is-array-buffer
│ │ ├── is-arrayish
│ │ ├── is-async-function
│ │ ├── is-bigint
│ │ ├── is-boolean-object
│ │ ├── is-callable
│ │ ├── is-core-module
│ │ ├── is-data-view
│ │ ├── is-date-object
│ │ ├── is-docker
│ │ ├── is-extglob
│ │ ├── is-finalizationregistry
│ │ ├── is-fullwidth-code-point
│ │ ├── is-generator-function
│ │ ├── is-glob
│ │ ├── is-map
│ │ ├── is-number
│ │ ├── is-number-object
│ │ ├── is-plain-object
│ │ ├── is-potential-custom-element-name
│ │ ├── is-promise
│ │ ├── is-regex
│ │ ├── is-set
│ │ ├── is-shared-array-buffer
│ │ ├── is-string
│ │ ├── is-symbol
│ │ ├── is-typed-array
│ │ ├── is-weakmap
│ │ ├── is-weakref
│ │ ├── is-weakset
│ │ ├── is-wsl
│ │ ├── isarray
│ │ ├── isexe
│ │ ├── iterator.prototype
│ │ ├── its-fine
│ │ ├── jackspeak
│ │ ├── js-tokens
│ │ ├── js-yaml
│ │ ├── jsdoc-type-pratt-parser
│ │ ├── jsdom
│ │ ├── jsesc
│ │ ├── json-buffer
│ │ ├── json-parse-even-better-errors
│ │ ├── json-schema-traverse
│ │ ├── json-stable-stringify-without-jsonify
│ │ ├── json5
│ │ ├── jsx-ast-utils
│ │ ├── keyv
│ │ ├── kind-of
│ │ ├── known-css-properties
│ │ ├── language-subtag-registry
│ │ ├── language-tags
│ │ ├── levn
│ │ ├── lines-and-columns
│ │ ├── locate-path
│ │ ├── lodash
│ │ ├── lodash.merge
│ │ ├── lodash.truncate
│ │ ├── loose-envify
│ │ ├── loupe
│ │ ├── lower-case
│ │ ├── lru-cache
│ │ ├── lz-string
│ │ ├── magic-string
│ │ ├── map-or-similar
│ │ ├── math-intrinsics
│ │ ├── mathml-tag-names
│ │ ├── mdn-data
│ │ ├── media-typer
│ │ ├── memoizerific
│ │ ├── meow
│ │ ├── merge-descriptors
│ │ ├── merge2
│ │ ├── meshoptimizer
│ │ ├── micromatch
│ │ ├── mime-db
│ │ ├── mime-types
│ │ ├── min-indent
│ │ ├── minimatch
│ │ ├── minimist
│ │ ├── minipass
│ │ ├── ms
│ │ ├── nanoid
│ │ ├── natural-compare
│ │ ├── negotiator
│ │ ├── no-case
│ │ ├── node-releases
│ │ ├── normalize-path
│ │ ├── nwsapi
│ │ ├── object-assign
│ │ ├── object-inspect
│ │ ├── object-keys
│ │ ├── object.assign
│ │ ├── object.entries
│ │ ├── object.fromentries
│ │ ├── object.values
│ │ ├── on-finished
│ │ ├── once
│ │ ├── open
│ │ ├── optionator
│ │ ├── own-keys
│ │ ├── p-limit
│ │ ├── p-locate
│ │ ├── package-json-from-dist
│ │ ├── parent-module
│ │ ├── parse-json
│ │ ├── parse5
│ │ ├── parseurl
│ │ ├── path-exists
│ │ ├── path-key
│ │ ├── path-parse
│ │ ├── path-scurry
│ │ ├── path-to-regexp
│ │ ├── path-type
│ │ ├── pathe
│ │ ├── pathval
│ │ ├── picocolors
│ │ ├── picomatch
│ │ ├── pkce-challenge
│ │ ├── possible-typed-array-names
│ │ ├── postcss
│ │ ├── postcss-js
│ │ ├── postcss-media-query-parser
│ │ ├── postcss-mixins
│ │ ├── postcss-nested
│ │ ├── postcss-preset-mantine
│ │ ├── postcss-resolve-nested-selector
│ │ ├── postcss-safe-parser
│ │ ├── postcss-scss
│ │ ├── postcss-selector-parser
│ │ ├── postcss-simple-vars
│ │ ├── postcss-value-parser
│ │ ├── prelude-ls
│ │ ├── prettier
│ │ ├── pretty-format
│ │ ├── process
│ │ ├── prop-types
│ │ ├── proxy-addr
│ │ ├── punycode
│ │ ├── qs
│ │ ├── queue-microtask
│ │ ├── range-parser
│ │ ├── raw-body
│ │ ├── react
│ │ ├── react-docgen
│ │ ├── react-docgen-typescript
│ │ ├── react-dom
│ │ ├── react-is
│ │ ├── react-number-format
│ │ ├── react-reconciler
│ │ ├── react-refresh
│ │ ├── react-remove-scroll
│ │ ├── react-remove-scroll-bar
│ │ ├── react-router
│ │ ├── react-router-dom
│ │ ├── react-style-singleton
│ │ ├── react-textarea-autosize
│ │ ├── react-use-measure
│ │ ├── recast
│ │ ├── redent
│ │ ├── reflect.getprototypeof
│ │ ├── regexp.prototype.flags
│ │ ├── require-from-string
│ │ ├── resolve
│ │ ├── resolve-from
│ │ ├── reusify
│ │ ├── rollup
│ │ ├── router
│ │ ├── rrweb-cssom
│ │ ├── run-parallel
│ │ ├── safe-array-concat
│ │ ├── safe-buffer
│ │ ├── safe-push-apply
│ │ ├── safe-regex-test
│ │ ├── safer-buffer
│ │ ├── saxes
│ │ ├── scheduler
│ │ ├── semver
│ │ ├── send
│ │ ├── serve-static
│ │ ├── set-cookie-parser
│ │ ├── set-function-length
│ │ ├── set-function-name
│ │ ├── set-proto
│ │ ├── setprototypeof
│ │ ├── shebang-command
│ │ ├── shebang-regex
│ │ ├── side-channel
│ │ ├── side-channel-list
│ │ ├── side-channel-map
│ │ ├── side-channel-weakmap
│ │ ├── siginfo
│ │ ├── signal-exit
│ │ ├── slash
│ │ ├── slice-ansi
│ │ ├── snake-case
│ │ ├── source-map
│ │ ├── source-map-js
│ │ ├── stackback
│ │ ├── statuses
│ │ ├── std-env
│ │ ├── storybook
│ │ ├── storybook-dark-mode
│ │ ├── string-width
│ │ ├── string-width-cjs
│ │ ├── string.prototype.includes
│ │ ├── string.prototype.matchall
│ │ ├── string.prototype.repeat
│ │ ├── string.prototype.trim
│ │ ├── string.prototype.trimend
│ │ ├── string.prototype.trimstart
│ │ ├── strip-ansi
│ │ ├── strip-ansi-cjs
│ │ ├── strip-bom
│ │ ├── strip-indent
│ │ ├── strip-json-comments
│ │ ├── stylelint
│ │ ├── stylelint-config-recommended
│ │ ├── stylelint-config-recommended-scss
│ │ ├── stylelint-config-standard
│ │ ├── stylelint-config-standard-scss
│ │ ├── stylelint-scss
│ │ ├── sugarss
│ │ ├── supports-color
│ │ ├── supports-hyperlinks
│ │ ├── supports-preserve-symlinks-flag
│ │ ├── suspend-react
│ │ ├── svg-parser
│ │ ├── svg-tags
│ │ ├── symbol-tree
│ │ ├── tabbable
│ │ ├── table
│ │ ├── three
│ │ ├── tiny-invariant
│ │ ├── tinybench
│ │ ├── tinyexec
│ │ ├── tinyglobby
│ │ ├── tinypool
│ │ ├── tinyrainbow
│ │ ├── tinyspy
│ │ ├── tldts
│ │ ├── tldts-core
│ │ ├── to-regex-range
│ │ ├── toidentifier
│ │ ├── tough-cookie
│ │ ├── tr46
│ │ ├── ts-api-utils
│ │ ├── ts-dedent
│ │ ├── tsconfck
│ │ ├── tsconfig-paths
│ │ ├── tslib
│ │ ├── turbo-stream
│ │ ├── type-check
│ │ ├── type-fest
│ │ ├── type-is
│ │ ├── typed-array-buffer
│ │ ├── typed-array-byte-length
│ │ ├── typed-array-byte-offset
│ │ ├── typed-array-length
│ │ ├── typescript
│ │ ├── typescript-eslint
│ │ ├── unbox-primitive
│ │ ├── undici-types
│ │ ├── unpipe
│ │ ├── unplugin
│ │ ├── update-browserslist-db
│ │ ├── uri-js
│ │ ├── use-callback-ref
│ │ ├── use-composed-ref
│ │ ├── use-isomorphic-layout-effect
│ │ ├── use-latest
│ │ ├── use-sidecar
│ │ ├── use-sync-external-store
│ │ ├── util
│ │ ├── util-deprecate
│ │ ├── vary
│ │ ├── vite
│ │ ├── vite-node
│ │ ├── vite-plugin-svgr
│ │ ├── vite-tsconfig-paths
│ │ ├── vitest
│ │ ├── w3c-xmlserializer
│ │ ├── webidl-conversions
│ │ ├── webpack-virtual-modules
│ │ ├── whatwg-encoding
│ │ ├── whatwg-mimetype
│ │ ├── whatwg-url
│ │ ├── which
│ │ ├── which-boxed-primitive
│ │ ├── which-builtin-type
│ │ ├── which-collection
│ │ ├── which-typed-array
│ │ ├── why-is-node-running
│ │ ├── word-wrap
│ │ ├── wrap-ansi
│ │ ├── wrap-ansi-cjs
│ │ ├── wrappy
│ │ ├── write-file-atomic
│ │ ├── ws
│ │ ├── xml-name-validator
│ │ ├── xmlchars
│ │ ├── yallist
│ │ ├── yocto-queue
│ │ ├── zod
│ │ ├── zod-to-json-schema
│ │ └── zustand
│ ├── package-lock.json
│ ├── package.json
│ ├── postcss.config.cjs
│ ├── src
│ │ ├── App.tsx
│ │ ├── Router.tsx
│ │ ├── assets
│ │ ├── components
│ │ ├── favicon.svg
│ │ ├── main.tsx
│ │ ├── pages
│ │ ├── theme.ts
│ │ └── vite-env.d.ts
│ ├── test-utils
│ │ ├── index.ts
│ │ └── render.tsx
│ ├── tsconfig.json
│ ├── vite.config.mjs
│ ├── vitest.setup.mjs
│ └── yarn.lock
├── llms
│ ├── Agente.py
│ ├── MCPs
│ │ ├── MCPStdioServer.py
│ │ ├── __init__.py
│ │ └── __pycache__
│ ├── Memory
│ │ ├── Base_MemoryConv.py
│ │ ├── __pycache__
│ │ └── postgres_MemoryConv.py
│ ├── Modelos
│ │ ├── Base_model.py
│ │ ├── Openai_model.py
│ │ ├── Openai_model_mmr.py
│ │ ├── __init__.py
│ │ └── __pycache__
│ ├── __init__.py
│ └── __pycache__
│ ├── Agente.cpython-311.pyc
│ └── __init__.cpython-311.pyc
├── main.py
├── notebooks
│ └── hacer_script_nombres.ipynb
├── prueba_loop_agente.py
├── prueba_mcp.py
├── pruebas_conceptos
│ ├── async
│ │ ├── async_con_procesos.py
│ │ ├── cliente.py
│ │ ├── esperar_await.py
│ │ ├── prueba_async.py
│ │ └── server_loop.py
│ ├── añadir_vectores_textos_postgres
│ │ └── pruebas_vectores.ipynb
│ ├── duckdb
│ │ ├── prueba_duckdb.ipynb
│ │ ├── textos_vss.duckdb
│ │ └── textos_vss.duckdb.wal
│ └── postgres_extensions
│ ├── Dockerfile
│ ├── backup_postgres15.sql
│ ├── docker-compose.yml
│ ├── init.sql
│ └── pgdata
├── pyproject.toml
├── scripts
│ ├── __init_.py
│ ├── __pycache__
│ │ └── prueba_carga_postrgesql.cpython-311.pyc
│ └── datos_para_llms
│ └── generar_tree.py
├── security
│ ├── Encriptar.py
│ ├── __init__.py
│ └── __pycache__
│ ├── Encriptar.cpython-311.pyc
│ └── __init__.cpython-311.pyc
├── src
│ ├── ApiKeys
│ │ ├── __init__.py
│ │ ├── __pycache__
│ │ ├── openai_apikey.py
│ │ └── openai_apikey_mmr.py
│ ├── ConexionApis
│ │ ├── OpenAi_conexion.py
│ │ ├── __init__.py
│ │ └── __pycache__
│ ├── ConexionSql
│ │ ├── Base_conexion.py
│ │ ├── Postgres_conexion.py
│ │ ├── __init__.py
│ │ └── __pycache__
│ ├── Credenciales
│ │ ├── __init__.py
│ │ ├── __pycache__
│ │ ├── postgres_credencial.py
│ │ └── postgres_credencial_mmr.py
│ ├── __init__.py
│ ├── __pycache__
│ │ ├── __init__.cpython-311.pyc
│ │ └── base.cpython-311.pyc
│ └── base.py
└── utils
├── Generar_nombres.py
├── __init__.py
└── __pycache__
├── Generar_nombres.cpython-311.pyc
└── __init__.cpython-311.pyc
+1 -1
View File
@@ -6,7 +6,7 @@ from src.Credenciales.postgres_credencial import PostgresCredencial # Asegúrat
from src.Credenciales.postgres_credencial_mmr import PostgresCredencialModel
from src.ApiKeys.openai_apikey_mmr import OpenAICredencialModel
from llms.Modelos.Openai_model_mmr import ModeloOpenAIConfigModel
from src.Llms.Modelos.Openai_model_mmr import ModeloOpenAIConfigModel
from dotenv import load_dotenv
import os
+3
View File
@@ -7,6 +7,9 @@ yarn-error.log*
lerna-debug.log*
.pnpm-debug.log*
src/assets/icons/filled/*
src/assets/icons/outlined/*
# Diagnostic reports (https://nodejs.org/api/report.html)
report.[0-9]*.[0-9]*.[0-9]*.[0-9]*.json
+2 -2
View File
@@ -2,12 +2,12 @@
<html lang="en">
<head>
<meta charset="UTF-8" />
<link rel="icon" type="image/svg+xml" href="/src/favicon.svg" />
<link rel="icon" type="image/svg+xml" href="/public/favicon.svg" />
<meta
name="viewport"
content="minimum-scale=1, initial-scale=1, width=device-width, user-scalable=no"
/>
<title>Vite + Mantine App</title>
<title>FitzStudio</title>
</head>
<body>
<div id="root"></div>
+345
View File
@@ -11,6 +11,7 @@
"@mantine/core": "8.0.0",
"@mantine/hooks": "8.0.0",
"@react-three/fiber": "^9.1.2",
"@tabler/icons": "^3.31.0",
"@tabler/icons-react": "^3.31.0",
"react": "^19.1.0",
"react-dom": "^19.1.0",
@@ -48,6 +49,7 @@
"typescript": "^5.8.2",
"typescript-eslint": "^8.27.0",
"vite": "^6.2.2",
"vite-plugin-svgr": "^4.3.0",
"vite-tsconfig-paths": "^5.1.4",
"vitest": "^3.0.9"
}
@@ -2093,6 +2095,271 @@
"storybook": "^8.2.0 || ^8.3.0-0 || ^8.4.0-0 || ^8.5.0-0 || ^8.6.0-0"
}
},
"node_modules/@svgr/babel-plugin-add-jsx-attribute": {
"version": "8.0.0",
"resolved": "https://registry.npmjs.org/@svgr/babel-plugin-add-jsx-attribute/-/babel-plugin-add-jsx-attribute-8.0.0.tgz",
"integrity": "sha512-b9MIk7yhdS1pMCZM8VeNfUlSKVRhsHZNMl5O9SfaX0l0t5wjdgu4IDzGB8bpnGBBOjGST3rRFVsaaEtI4W6f7g==",
"dev": true,
"license": "MIT",
"engines": {
"node": ">=14"
},
"funding": {
"type": "github",
"url": "https://github.com/sponsors/gregberge"
},
"peerDependencies": {
"@babel/core": "^7.0.0-0"
}
},
"node_modules/@svgr/babel-plugin-remove-jsx-attribute": {
"version": "8.0.0",
"resolved": "https://registry.npmjs.org/@svgr/babel-plugin-remove-jsx-attribute/-/babel-plugin-remove-jsx-attribute-8.0.0.tgz",
"integrity": "sha512-BcCkm/STipKvbCl6b7QFrMh/vx00vIP63k2eM66MfHJzPr6O2U0jYEViXkHJWqXqQYjdeA9cuCl5KWmlwjDvbA==",
"dev": true,
"license": "MIT",
"engines": {
"node": ">=14"
},
"funding": {
"type": "github",
"url": "https://github.com/sponsors/gregberge"
},
"peerDependencies": {
"@babel/core": "^7.0.0-0"
}
},
"node_modules/@svgr/babel-plugin-remove-jsx-empty-expression": {
"version": "8.0.0",
"resolved": "https://registry.npmjs.org/@svgr/babel-plugin-remove-jsx-empty-expression/-/babel-plugin-remove-jsx-empty-expression-8.0.0.tgz",
"integrity": "sha512-5BcGCBfBxB5+XSDSWnhTThfI9jcO5f0Ai2V24gZpG+wXF14BzwxxdDb4g6trdOux0rhibGs385BeFMSmxtS3uA==",
"dev": true,
"license": "MIT",
"engines": {
"node": ">=14"
},
"funding": {
"type": "github",
"url": "https://github.com/sponsors/gregberge"
},
"peerDependencies": {
"@babel/core": "^7.0.0-0"
}
},
"node_modules/@svgr/babel-plugin-replace-jsx-attribute-value": {
"version": "8.0.0",
"resolved": "https://registry.npmjs.org/@svgr/babel-plugin-replace-jsx-attribute-value/-/babel-plugin-replace-jsx-attribute-value-8.0.0.tgz",
"integrity": "sha512-KVQ+PtIjb1BuYT3ht8M5KbzWBhdAjjUPdlMtpuw/VjT8coTrItWX6Qafl9+ji831JaJcu6PJNKCV0bp01lBNzQ==",
"dev": true,
"license": "MIT",
"engines": {
"node": ">=14"
},
"funding": {
"type": "github",
"url": "https://github.com/sponsors/gregberge"
},
"peerDependencies": {
"@babel/core": "^7.0.0-0"
}
},
"node_modules/@svgr/babel-plugin-svg-dynamic-title": {
"version": "8.0.0",
"resolved": "https://registry.npmjs.org/@svgr/babel-plugin-svg-dynamic-title/-/babel-plugin-svg-dynamic-title-8.0.0.tgz",
"integrity": "sha512-omNiKqwjNmOQJ2v6ge4SErBbkooV2aAWwaPFs2vUY7p7GhVkzRkJ00kILXQvRhA6miHnNpXv7MRnnSjdRjK8og==",
"dev": true,
"license": "MIT",
"engines": {
"node": ">=14"
},
"funding": {
"type": "github",
"url": "https://github.com/sponsors/gregberge"
},
"peerDependencies": {
"@babel/core": "^7.0.0-0"
}
},
"node_modules/@svgr/babel-plugin-svg-em-dimensions": {
"version": "8.0.0",
"resolved": "https://registry.npmjs.org/@svgr/babel-plugin-svg-em-dimensions/-/babel-plugin-svg-em-dimensions-8.0.0.tgz",
"integrity": "sha512-mURHYnu6Iw3UBTbhGwE/vsngtCIbHE43xCRK7kCw4t01xyGqb2Pd+WXekRRoFOBIY29ZoOhUCTEweDMdrjfi9g==",
"dev": true,
"license": "MIT",
"engines": {
"node": ">=14"
},
"funding": {
"type": "github",
"url": "https://github.com/sponsors/gregberge"
},
"peerDependencies": {
"@babel/core": "^7.0.0-0"
}
},
"node_modules/@svgr/babel-plugin-transform-react-native-svg": {
"version": "8.1.0",
"resolved": "https://registry.npmjs.org/@svgr/babel-plugin-transform-react-native-svg/-/babel-plugin-transform-react-native-svg-8.1.0.tgz",
"integrity": "sha512-Tx8T58CHo+7nwJ+EhUwx3LfdNSG9R2OKfaIXXs5soiy5HtgoAEkDay9LIimLOcG8dJQH1wPZp/cnAv6S9CrR1Q==",
"dev": true,
"license": "MIT",
"engines": {
"node": ">=14"
},
"funding": {
"type": "github",
"url": "https://github.com/sponsors/gregberge"
},
"peerDependencies": {
"@babel/core": "^7.0.0-0"
}
},
"node_modules/@svgr/babel-plugin-transform-svg-component": {
"version": "8.0.0",
"resolved": "https://registry.npmjs.org/@svgr/babel-plugin-transform-svg-component/-/babel-plugin-transform-svg-component-8.0.0.tgz",
"integrity": "sha512-DFx8xa3cZXTdb/k3kfPeaixecQLgKh5NVBMwD0AQxOzcZawK4oo1Jh9LbrcACUivsCA7TLG8eeWgrDXjTMhRmw==",
"dev": true,
"license": "MIT",
"engines": {
"node": ">=12"
},
"funding": {
"type": "github",
"url": "https://github.com/sponsors/gregberge"
},
"peerDependencies": {
"@babel/core": "^7.0.0-0"
}
},
"node_modules/@svgr/babel-preset": {
"version": "8.1.0",
"resolved": "https://registry.npmjs.org/@svgr/babel-preset/-/babel-preset-8.1.0.tgz",
"integrity": "sha512-7EYDbHE7MxHpv4sxvnVPngw5fuR6pw79SkcrILHJ/iMpuKySNCl5W1qcwPEpU+LgyRXOaAFgH0KhwD18wwg6ug==",
"dev": true,
"license": "MIT",
"dependencies": {
"@svgr/babel-plugin-add-jsx-attribute": "8.0.0",
"@svgr/babel-plugin-remove-jsx-attribute": "8.0.0",
"@svgr/babel-plugin-remove-jsx-empty-expression": "8.0.0",
"@svgr/babel-plugin-replace-jsx-attribute-value": "8.0.0",
"@svgr/babel-plugin-svg-dynamic-title": "8.0.0",
"@svgr/babel-plugin-svg-em-dimensions": "8.0.0",
"@svgr/babel-plugin-transform-react-native-svg": "8.1.0",
"@svgr/babel-plugin-transform-svg-component": "8.0.0"
},
"engines": {
"node": ">=14"
},
"funding": {
"type": "github",
"url": "https://github.com/sponsors/gregberge"
},
"peerDependencies": {
"@babel/core": "^7.0.0-0"
}
},
"node_modules/@svgr/core": {
"version": "8.1.0",
"resolved": "https://registry.npmjs.org/@svgr/core/-/core-8.1.0.tgz",
"integrity": "sha512-8QqtOQT5ACVlmsvKOJNEaWmRPmcojMOzCz4Hs2BGG/toAp/K38LcsMRyLp349glq5AzJbCEeimEoxaX6v/fLrA==",
"dev": true,
"license": "MIT",
"dependencies": {
"@babel/core": "^7.21.3",
"@svgr/babel-preset": "8.1.0",
"camelcase": "^6.2.0",
"cosmiconfig": "^8.1.3",
"snake-case": "^3.0.4"
},
"engines": {
"node": ">=14"
},
"funding": {
"type": "github",
"url": "https://github.com/sponsors/gregberge"
}
},
"node_modules/@svgr/core/node_modules/cosmiconfig": {
"version": "8.3.6",
"resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-8.3.6.tgz",
"integrity": "sha512-kcZ6+W5QzcJ3P1Mt+83OUv/oHFqZHIx8DuxG6eZ5RGMERoLqp4BuGjhHLYGK+Kf5XVkQvqBSmAy/nGWN3qDgEA==",
"dev": true,
"license": "MIT",
"dependencies": {
"import-fresh": "^3.3.0",
"js-yaml": "^4.1.0",
"parse-json": "^5.2.0",
"path-type": "^4.0.0"
},
"engines": {
"node": ">=14"
},
"funding": {
"url": "https://github.com/sponsors/d-fischer"
},
"peerDependencies": {
"typescript": ">=4.9.5"
},
"peerDependenciesMeta": {
"typescript": {
"optional": true
}
}
},
"node_modules/@svgr/hast-util-to-babel-ast": {
"version": "8.0.0",
"resolved": "https://registry.npmjs.org/@svgr/hast-util-to-babel-ast/-/hast-util-to-babel-ast-8.0.0.tgz",
"integrity": "sha512-EbDKwO9GpfWP4jN9sGdYwPBU0kdomaPIL2Eu4YwmgP+sJeXT+L7bMwJUBnhzfH8Q2qMBqZ4fJwpCyYsAN3mt2Q==",
"dev": true,
"license": "MIT",
"dependencies": {
"@babel/types": "^7.21.3",
"entities": "^4.4.0"
},
"engines": {
"node": ">=14"
},
"funding": {
"type": "github",
"url": "https://github.com/sponsors/gregberge"
}
},
"node_modules/@svgr/hast-util-to-babel-ast/node_modules/entities": {
"version": "4.5.0",
"resolved": "https://registry.npmjs.org/entities/-/entities-4.5.0.tgz",
"integrity": "sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw==",
"dev": true,
"license": "BSD-2-Clause",
"engines": {
"node": ">=0.12"
},
"funding": {
"url": "https://github.com/fb55/entities?sponsor=1"
}
},
"node_modules/@svgr/plugin-jsx": {
"version": "8.1.0",
"resolved": "https://registry.npmjs.org/@svgr/plugin-jsx/-/plugin-jsx-8.1.0.tgz",
"integrity": "sha512-0xiIyBsLlr8quN+WyuxooNW9RJ0Dpr8uOnH/xrCVO8GLUcwHISwj1AG0k+LFzteTkAA0GbX0kj9q6Dk70PTiPA==",
"dev": true,
"license": "MIT",
"dependencies": {
"@babel/core": "^7.21.3",
"@svgr/babel-preset": "8.1.0",
"@svgr/hast-util-to-babel-ast": "8.0.0",
"svg-parser": "^2.0.4"
},
"engines": {
"node": ">=14"
},
"funding": {
"type": "github",
"url": "https://github.com/sponsors/gregberge"
},
"peerDependencies": {
"@svgr/core": "*"
}
},
"node_modules/@tabler/icons": {
"version": "3.31.0",
"resolved": "https://registry.npmjs.org/@tabler/icons/-/icons-3.31.0.tgz",
@@ -3321,6 +3588,19 @@
"node": ">=6"
}
},
"node_modules/camelcase": {
"version": "6.3.0",
"resolved": "https://registry.npmjs.org/camelcase/-/camelcase-6.3.0.tgz",
"integrity": "sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA==",
"dev": true,
"license": "MIT",
"engines": {
"node": ">=10"
},
"funding": {
"url": "https://github.com/sponsors/sindresorhus"
}
},
"node_modules/camelcase-css": {
"version": "2.0.1",
"resolved": "https://registry.npmjs.org/camelcase-css/-/camelcase-css-2.0.1.tgz",
@@ -3831,6 +4111,17 @@
"dev": true,
"license": "MIT"
},
"node_modules/dot-case": {
"version": "3.0.4",
"resolved": "https://registry.npmjs.org/dot-case/-/dot-case-3.0.4.tgz",
"integrity": "sha512-Kv5nKlh6yRrdrGvxeJ2e5y2eRUpkUosIW4A2AS38zwSz27zu7ufDwQPi5Jhs3XAlGNetl3bmnGhQsMtkKJnj3w==",
"dev": true,
"license": "MIT",
"dependencies": {
"no-case": "^3.0.4",
"tslib": "^2.0.3"
}
},
"node_modules/dunder-proto": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/dunder-proto/-/dunder-proto-1.0.1.tgz",
@@ -6238,6 +6529,16 @@
"dev": true,
"license": "MIT"
},
"node_modules/lower-case": {
"version": "2.0.2",
"resolved": "https://registry.npmjs.org/lower-case/-/lower-case-2.0.2.tgz",
"integrity": "sha512-7fm3l3NAF9WfN6W3JOmf5drwpVqX78JtoGJ3A6W0a6ZnldM41w2fV5D490psKFTpMds8TJse/eHLFFsNHHjHgg==",
"dev": true,
"license": "MIT",
"dependencies": {
"tslib": "^2.0.3"
}
},
"node_modules/lru-cache": {
"version": "5.1.1",
"resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-5.1.1.tgz",
@@ -6502,6 +6803,17 @@
"node": ">= 0.6"
}
},
"node_modules/no-case": {
"version": "3.0.4",
"resolved": "https://registry.npmjs.org/no-case/-/no-case-3.0.4.tgz",
"integrity": "sha512-fgAN3jGAh+RoxUGZHTSOLJIqUc2wmoBwGR4tbpNAKmmovFoWq0OdRkb0VkldReO2a2iBT/OEulG9XSUc10r3zg==",
"dev": true,
"license": "MIT",
"dependencies": {
"lower-case": "^2.0.2",
"tslib": "^2.0.3"
}
},
"node_modules/node-releases": {
"version": "2.0.19",
"resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.19.tgz",
@@ -8175,6 +8487,17 @@
"url": "https://github.com/chalk/slice-ansi?sponsor=1"
}
},
"node_modules/snake-case": {
"version": "3.0.4",
"resolved": "https://registry.npmjs.org/snake-case/-/snake-case-3.0.4.tgz",
"integrity": "sha512-LAOh4z89bGQvl9pFfNF8V146i7o7/CqFPbqzYgP+yYzDIDeS9HaNFtXABamRW+AQzEVODcvE79ljJ+8a9YSdMg==",
"dev": true,
"license": "MIT",
"dependencies": {
"dot-case": "^3.0.4",
"tslib": "^2.0.3"
}
},
"node_modules/source-map": {
"version": "0.6.1",
"resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz",
@@ -8905,6 +9228,13 @@
"react": ">=17.0"
}
},
"node_modules/svg-parser": {
"version": "2.0.4",
"resolved": "https://registry.npmjs.org/svg-parser/-/svg-parser-2.0.4.tgz",
"integrity": "sha512-e4hG1hRwoOdRb37cIMSgzNsxyzKfayW6VOflrwvR+/bzrkyxY/31WkbgnQpgtrNp1SdpJvpUAGTa/ZoiPNDuRQ==",
"dev": true,
"license": "MIT"
},
"node_modules/svg-tags": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/svg-tags/-/svg-tags-1.0.0.tgz",
@@ -9687,6 +10017,21 @@
"url": "https://opencollective.com/vitest"
}
},
"node_modules/vite-plugin-svgr": {
"version": "4.3.0",
"resolved": "https://registry.npmjs.org/vite-plugin-svgr/-/vite-plugin-svgr-4.3.0.tgz",
"integrity": "sha512-Jy9qLB2/PyWklpYy0xk0UU3TlU0t2UMpJXZvf+hWII1lAmRHrOUKi11Uw8N3rxoNk7atZNYO3pR3vI1f7oi+6w==",
"dev": true,
"license": "MIT",
"dependencies": {
"@rollup/pluginutils": "^5.1.3",
"@svgr/core": "^8.1.0",
"@svgr/plugin-jsx": "^8.1.0"
},
"peerDependencies": {
"vite": ">=2.6.0"
}
},
"node_modules/vite-tsconfig-paths": {
"version": "5.1.4",
"resolved": "https://registry.npmjs.org/vite-tsconfig-paths/-/vite-tsconfig-paths-5.1.4.tgz",
+2
View File
@@ -23,6 +23,7 @@
"@mantine/core": "8.0.0",
"@mantine/hooks": "8.0.0",
"@react-three/fiber": "^9.1.2",
"@tabler/icons": "^3.31.0",
"@tabler/icons-react": "^3.31.0",
"react": "^19.1.0",
"react-dom": "^19.1.0",
@@ -60,6 +61,7 @@
"typescript": "^5.8.2",
"typescript-eslint": "^8.27.0",
"vite": "^6.2.2",
"vite-plugin-svgr": "^4.3.0",
"vite-tsconfig-paths": "^5.1.4",
"vitest": "^3.0.9"
},

Before

Width:  |  Height:  |  Size: 1.2 KiB

After

Width:  |  Height:  |  Size: 1.2 KiB

+18
View File
@@ -0,0 +1,18 @@
// OUTLINED
export { default as IconArrowLeft } from './outlined/arrow-left.svg?react';
export { default as IconHomeOutline } from './outlined/home.svg?react';
export { default as IconUserOutline } from './outlined/user.svg?react';
export { default as IconCalendarStats } from './outlined/calendar-stats.svg?react';
export { default as IconDeviceDesktopAnalytics } from './outlined/device-desktop-analytics.svg?react';
export { default as IconFingerprint } from './outlined/fingerprint.svg?react';
export { default as IconGauge } from './outlined/gauge.svg?react';
export { default as IconHome2 } from './outlined/home-2.svg?react';
export { default as IconSettings } from './outlined/settings.svg?react';
export { default as IconArrowBarLeft } from './outlined/arrow-bar-left.svg?react';
export { default as IconArrowBarRight } from './outlined/arrow-bar-right.svg?react';
export { default as IconCheck } from './outlined/check.svg?react';
// FILLED
export { default as IconHomeFilled } from './filled/home.svg?react';
export { default as IconUserFilled } from './filled/user.svg?react';
@@ -5,10 +5,10 @@ import {
IconGauge,
IconHome2,
IconSettings,
IconUser,
IconUserOutline as IconUser,
IconArrowBarLeft,
IconArrowBarRight,
} from '@tabler/icons-react';
} from '../../assets/icons';
import {
AppShell,
@@ -109,7 +109,7 @@ import {
className={classes.mainLink}
data-active={link.label === active || undefined}
>
<link.icon size={22} stroke={1.5} />
<link.icon />
</UnstyledButton>
</Tooltip>
));
@@ -154,7 +154,7 @@ import {
<Group h="100%" px="md">
<Burger opened={mobileOpened} onClick={toggleMobile} hiddenFrom="sm" size="sm" />
<Burger opened={desktopOpened} onClick={toggleDesktop} visibleFrom="sm" size="sm" />
<img src="/src/favicon.svg" alt="Logo" style={{ width: 30, height: 30 }} />
<img src="/public/favicon.svg" alt="Logo" style={{ width: 30, height: 30 }} />
</Group>
</AppShell.Header>
+2 -2
View File
@@ -1,5 +1,5 @@
import { Select, Group } from '@mantine/core';
import { IconCheck } from '@tabler/icons-react';
import { IconCheck } from '../assets/icons';
interface MetodoSelectProps {
metodo: string;
@@ -37,7 +37,7 @@ export function MetodoSelect({ metodo, setMetodo }: MetodoSelectProps) {
renderOption={({ option, checked }) => (
<Group style={{ color: colorMap[option.value], fontWeight: 600 }}>
{option.label}
{checked && <IconCheck size={14} />}
{checked && <IconCheck/>}
</Group>
)}
styles={{
+26 -20
View File
@@ -1,31 +1,38 @@
import { Box, Title, Text, Button, Group, Stack, Image, Center } from '@mantine/core';
import { IconArrowLeft } from '@tabler/icons-react';
import { IconArrowLeft } from '../assets/icons';
import { Link } from 'react-router-dom';
import { MantineCardWithShader } from '../components/HoloShader'; // Ajusta ruta si es necesario
import { AppShellWithMenu } from '../components/Appshell';
import { AppShellWithMenu } from '../components/Appshell/Appshell';
export function Error_404() {
return (
<AppShellWithMenu>
<Box style={{
flex: 1,
display: 'flex',
justifyContent: 'center',
alignItems: 'flex-start', // alinea arriba
padding: '2rem',
paddingTop: '0.5rem', // agrega espacio desde arriba si deseas
}}>
<Box style={{ flex: 1, display: 'flex', justifyContent: 'center', alignItems: 'center', padding: '2rem' }}>
<Box
style={{
flex: 1,
display: 'flex',
justifyContent: 'center',
alignItems: 'flex-start',
padding: '2rem',
paddingTop: '0.5rem',
}}
>
<Box
style={{
flex: 1,
display: 'flex',
justifyContent: 'center',
alignItems: 'center',
padding: '2rem',
}}
>
<Stack align="center" maw={500} mx="auto">
<MantineCardWithShader />
<Title order={1}>
Página no encontrada
</Title>
<MantineCardWithShader />
<Title order={1}>Página no encontrada</Title>
<Text size="lg">
Parece que la página que estás buscando no existe o fue removida. Pero no te preocupes, puedes volver al inicio fácilmente.
Parece que la página que estás buscando no existe o fue removida. Pero no te preocupes,
puedes volver al inicio fácilmente.
</Text>
<Group mt="md">
@@ -35,7 +42,7 @@ export function Error_404() {
size="md"
variant="gradient"
gradient={{ from: 'blue', to: 'cyan' }}
leftSection={<IconArrowLeft size={18} />}
leftSection={<IconArrowLeft width={18} height={18} />}
>
Volver al inicio
</Button>
@@ -44,6 +51,5 @@ export function Error_404() {
</Box>
</Box>
</AppShellWithMenu>
);
}
+1 -5
View File
@@ -1,8 +1,4 @@
import { ColorSchemeToggle } from '../components/ColorSchemeToggle/ColorSchemeToggle';
import { Welcome } from '../components/Welcome/Welcome';
import MiBoton from '../components/botoncito';
import { Center, Box } from '@mantine/core';
import { AppShellWithMenu } from '../components/Appshell';
import { AppShellWithMenu } from '../components/Appshell/Appshell';
+2 -2
View File
@@ -1,6 +1,6 @@
import { Box } from '@mantine/core';
import { LlamadorAPI } from '../components/LlamadorAPI';
import { AppShellWithMenu } from '../components/Appshell';
import { AppShellWithMenu } from '../components/Appshell/Appshell';
export function Consulta_API() {
+1 -1
View File
@@ -1,4 +1,4 @@
import { AppShellWithMenu } from '../components/Appshell';
import { AppShellWithMenu } from '../components/Appshell/Appshell';
export function HomePage() {
+1 -1
View File
@@ -1,4 +1,4 @@
import { AppShellWithMenu } from '../components/Appshell';
import { AppShellWithMenu } from '../components/Appshell/Appshell';
export function Plantilla() {
+1 -6
View File
@@ -1,9 +1,4 @@
import { ColorSchemeToggle } from '../components/ColorSchemeToggle/ColorSchemeToggle';
import { Welcome } from '../components/Welcome/Welcome';
import MiBoton from '../components/botoncito';
import { Center, Box } from '@mantine/core';
import { MantineCardWithShader } from '../components/HoloShader';
import { AppShellWithMenu } from '../components/Appshell';
import { AppShellWithMenu } from '../components/Appshell/Appshell';
export function Prueba_appshell() {
return (
+7
View File
@@ -0,0 +1,7 @@
declare module '*.svg' {
import * as React from 'react';
export const ReactComponent: React.FunctionComponent<React.SVGProps<SVGSVGElement>>;
const src: string;
export default src;
}
+1
View File
@@ -0,0 +1 @@
/// <reference types="vite-plugin-svgr/client" />
+1 -1
View File
@@ -21,5 +21,5 @@
"@test-utils": ["./test-utils"]
}
},
"include": ["src", "test-utils"]
"include": ["src", "src/types", "test-utils"]
}
@@ -1,12 +1,13 @@
import { defineConfig } from 'vite';
import react from '@vitejs/plugin-react';
import tsconfigPaths from 'vite-tsconfig-paths';
import svgr from 'vite-plugin-svgr';
export default defineConfig({
plugins: [react(), tsconfigPaths()],
plugins: [react(), tsconfigPaths(), svgr()],
test: {
globals: true,
environment: 'jsdom',
setupFiles: './vitest.setup.mjs',
},
});
});
+154 -6
View File
@@ -40,7 +40,7 @@
resolved "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.27.1.tgz"
integrity sha512-Q+E+rd/yBzNQhXkG+zQnF58e4zoZfBedaxwzPmicKsiK3nt8iJYrSrDbjwFFDGC4f+rPafqRaPH6TsDoSvMf7A==
"@babel/core@^7.0.0", "@babel/core@^7.0.0-0", "@babel/core@^7.18.9", "@babel/core@^7.26.10":
"@babel/core@^7.0.0", "@babel/core@^7.0.0-0", "@babel/core@^7.18.9", "@babel/core@^7.21.3", "@babel/core@^7.26.10":
version "7.27.1"
resolved "https://registry.npmjs.org/@babel/core/-/core-7.27.1.tgz"
integrity sha512-IaaGWsQqfsQWVLqMn9OB92MNN7zukfVA4s7KKAI0KfrrDsZ0yhi5uV4baBuLuN7n3vsZpwP8asPPcVwApxvjBQ==
@@ -176,7 +176,7 @@
debug "^4.3.1"
globals "^11.1.0"
"@babel/types@^7.0.0", "@babel/types@^7.18.9", "@babel/types@^7.20.7", "@babel/types@^7.26.0", "@babel/types@^7.27.1":
"@babel/types@^7.0.0", "@babel/types@^7.18.9", "@babel/types@^7.20.7", "@babel/types@^7.21.3", "@babel/types@^7.26.0", "@babel/types@^7.27.1":
version "7.27.1"
resolved "https://registry.npmjs.org/@babel/types/-/types-7.27.1.tgz"
integrity sha512-+EzkxvLNfiUeKMgy/3luqfsCWFRXLb7U6wNQTk60tovuckwB15B191tJWvpp4HjiQWdJkCxO3Wbvc6jlk3Xb2Q==
@@ -515,7 +515,7 @@
use-sync-external-store "^1.4.0"
zustand "^5.0.3"
"@rollup/pluginutils@^5.0.2":
"@rollup/pluginutils@^5.0.2", "@rollup/pluginutils@^5.1.3":
version "5.1.4"
resolved "https://registry.npmjs.org/@rollup/pluginutils/-/pluginutils-5.1.4.tgz"
integrity sha512-USm05zrsFxYLPdWWq+K3STlWiT/3ELn3RcV5hJMghpeAIhxfsUIg6mt12CBJBInWMV4VneoV7SfGv8xIwo2qNQ==
@@ -629,6 +629,89 @@
resolved "https://registry.npmjs.org/@storybook/theming/-/theming-8.6.12.tgz"
integrity sha512-6VjZg8HJ2Op7+KV7ihJpYrDnFtd9D1jrQnUS8LckcpuBXrIEbaut5+34ObY8ssQnSqkk2GwIZBBBQYQBCVvkOw==
"@svgr/babel-plugin-add-jsx-attribute@8.0.0":
version "8.0.0"
resolved "https://registry.npmjs.org/@svgr/babel-plugin-add-jsx-attribute/-/babel-plugin-add-jsx-attribute-8.0.0.tgz"
integrity sha512-b9MIk7yhdS1pMCZM8VeNfUlSKVRhsHZNMl5O9SfaX0l0t5wjdgu4IDzGB8bpnGBBOjGST3rRFVsaaEtI4W6f7g==
"@svgr/babel-plugin-remove-jsx-attribute@8.0.0":
version "8.0.0"
resolved "https://registry.npmjs.org/@svgr/babel-plugin-remove-jsx-attribute/-/babel-plugin-remove-jsx-attribute-8.0.0.tgz"
integrity sha512-BcCkm/STipKvbCl6b7QFrMh/vx00vIP63k2eM66MfHJzPr6O2U0jYEViXkHJWqXqQYjdeA9cuCl5KWmlwjDvbA==
"@svgr/babel-plugin-remove-jsx-empty-expression@8.0.0":
version "8.0.0"
resolved "https://registry.npmjs.org/@svgr/babel-plugin-remove-jsx-empty-expression/-/babel-plugin-remove-jsx-empty-expression-8.0.0.tgz"
integrity sha512-5BcGCBfBxB5+XSDSWnhTThfI9jcO5f0Ai2V24gZpG+wXF14BzwxxdDb4g6trdOux0rhibGs385BeFMSmxtS3uA==
"@svgr/babel-plugin-replace-jsx-attribute-value@8.0.0":
version "8.0.0"
resolved "https://registry.npmjs.org/@svgr/babel-plugin-replace-jsx-attribute-value/-/babel-plugin-replace-jsx-attribute-value-8.0.0.tgz"
integrity sha512-KVQ+PtIjb1BuYT3ht8M5KbzWBhdAjjUPdlMtpuw/VjT8coTrItWX6Qafl9+ji831JaJcu6PJNKCV0bp01lBNzQ==
"@svgr/babel-plugin-svg-dynamic-title@8.0.0":
version "8.0.0"
resolved "https://registry.npmjs.org/@svgr/babel-plugin-svg-dynamic-title/-/babel-plugin-svg-dynamic-title-8.0.0.tgz"
integrity sha512-omNiKqwjNmOQJ2v6ge4SErBbkooV2aAWwaPFs2vUY7p7GhVkzRkJ00kILXQvRhA6miHnNpXv7MRnnSjdRjK8og==
"@svgr/babel-plugin-svg-em-dimensions@8.0.0":
version "8.0.0"
resolved "https://registry.npmjs.org/@svgr/babel-plugin-svg-em-dimensions/-/babel-plugin-svg-em-dimensions-8.0.0.tgz"
integrity sha512-mURHYnu6Iw3UBTbhGwE/vsngtCIbHE43xCRK7kCw4t01xyGqb2Pd+WXekRRoFOBIY29ZoOhUCTEweDMdrjfi9g==
"@svgr/babel-plugin-transform-react-native-svg@8.1.0":
version "8.1.0"
resolved "https://registry.npmjs.org/@svgr/babel-plugin-transform-react-native-svg/-/babel-plugin-transform-react-native-svg-8.1.0.tgz"
integrity sha512-Tx8T58CHo+7nwJ+EhUwx3LfdNSG9R2OKfaIXXs5soiy5HtgoAEkDay9LIimLOcG8dJQH1wPZp/cnAv6S9CrR1Q==
"@svgr/babel-plugin-transform-svg-component@8.0.0":
version "8.0.0"
resolved "https://registry.npmjs.org/@svgr/babel-plugin-transform-svg-component/-/babel-plugin-transform-svg-component-8.0.0.tgz"
integrity sha512-DFx8xa3cZXTdb/k3kfPeaixecQLgKh5NVBMwD0AQxOzcZawK4oo1Jh9LbrcACUivsCA7TLG8eeWgrDXjTMhRmw==
"@svgr/babel-preset@8.1.0":
version "8.1.0"
resolved "https://registry.npmjs.org/@svgr/babel-preset/-/babel-preset-8.1.0.tgz"
integrity sha512-7EYDbHE7MxHpv4sxvnVPngw5fuR6pw79SkcrILHJ/iMpuKySNCl5W1qcwPEpU+LgyRXOaAFgH0KhwD18wwg6ug==
dependencies:
"@svgr/babel-plugin-add-jsx-attribute" "8.0.0"
"@svgr/babel-plugin-remove-jsx-attribute" "8.0.0"
"@svgr/babel-plugin-remove-jsx-empty-expression" "8.0.0"
"@svgr/babel-plugin-replace-jsx-attribute-value" "8.0.0"
"@svgr/babel-plugin-svg-dynamic-title" "8.0.0"
"@svgr/babel-plugin-svg-em-dimensions" "8.0.0"
"@svgr/babel-plugin-transform-react-native-svg" "8.1.0"
"@svgr/babel-plugin-transform-svg-component" "8.0.0"
"@svgr/core@*", "@svgr/core@^8.1.0":
version "8.1.0"
resolved "https://registry.npmjs.org/@svgr/core/-/core-8.1.0.tgz"
integrity sha512-8QqtOQT5ACVlmsvKOJNEaWmRPmcojMOzCz4Hs2BGG/toAp/K38LcsMRyLp349glq5AzJbCEeimEoxaX6v/fLrA==
dependencies:
"@babel/core" "^7.21.3"
"@svgr/babel-preset" "8.1.0"
camelcase "^6.2.0"
cosmiconfig "^8.1.3"
snake-case "^3.0.4"
"@svgr/hast-util-to-babel-ast@8.0.0":
version "8.0.0"
resolved "https://registry.npmjs.org/@svgr/hast-util-to-babel-ast/-/hast-util-to-babel-ast-8.0.0.tgz"
integrity sha512-EbDKwO9GpfWP4jN9sGdYwPBU0kdomaPIL2Eu4YwmgP+sJeXT+L7bMwJUBnhzfH8Q2qMBqZ4fJwpCyYsAN3mt2Q==
dependencies:
"@babel/types" "^7.21.3"
entities "^4.4.0"
"@svgr/plugin-jsx@^8.1.0":
version "8.1.0"
resolved "https://registry.npmjs.org/@svgr/plugin-jsx/-/plugin-jsx-8.1.0.tgz"
integrity sha512-0xiIyBsLlr8quN+WyuxooNW9RJ0Dpr8uOnH/xrCVO8GLUcwHISwj1AG0k+LFzteTkAA0GbX0kj9q6Dk70PTiPA==
dependencies:
"@babel/core" "^7.21.3"
"@svgr/babel-preset" "8.1.0"
"@svgr/hast-util-to-babel-ast" "8.0.0"
svg-parser "^2.0.4"
"@tabler/icons-react@^3.31.0":
version "3.31.0"
resolved "https://registry.npmjs.org/@tabler/icons-react/-/icons-react-3.31.0.tgz"
@@ -636,7 +719,7 @@
dependencies:
"@tabler/icons" "3.31.0"
"@tabler/icons@3.31.0":
"@tabler/icons@^3.31.0", "@tabler/icons@3.31.0":
version "3.31.0"
resolved "https://registry.npmjs.org/@tabler/icons/-/icons-3.31.0.tgz"
integrity sha512-dblAdeKY3+GA1U+Q9eziZ0ooVlZMHsE8dqP0RkwvRtEsAULoKOYaCUOcJ4oW1DjWegdxk++UAt2SlQVnmeHv+g==
@@ -1294,6 +1377,11 @@ camelcase-css@^2.0.1:
resolved "https://registry.npmjs.org/camelcase-css/-/camelcase-css-2.0.1.tgz"
integrity sha512-QOSvevhslijgYwRx6Rv7zKdMF8lbRmx+uQGx2+vDc+KI/eBnsy9kit5aj23AgGu3pa4t9AgwbnXWqS+iOY+2aA==
camelcase@^6.2.0:
version "6.3.0"
resolved "https://registry.npmjs.org/camelcase/-/camelcase-6.3.0.tgz"
integrity sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA==
caniuse-lite@^1.0.30001716:
version "1.0.30001717"
resolved "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001717.tgz"
@@ -1398,6 +1486,16 @@ cors@^2.8.5:
object-assign "^4"
vary "^1"
cosmiconfig@^8.1.3:
version "8.3.6"
resolved "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-8.3.6.tgz"
integrity sha512-kcZ6+W5QzcJ3P1Mt+83OUv/oHFqZHIx8DuxG6eZ5RGMERoLqp4BuGjhHLYGK+Kf5XVkQvqBSmAy/nGWN3qDgEA==
dependencies:
import-fresh "^3.3.0"
js-yaml "^4.1.0"
parse-json "^5.2.0"
path-type "^4.0.0"
cosmiconfig@^9.0.0:
version "9.0.0"
resolved "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-9.0.0.tgz"
@@ -1584,6 +1682,14 @@ dom-accessibility-api@^0.6.3:
resolved "https://registry.npmjs.org/dom-accessibility-api/-/dom-accessibility-api-0.6.3.tgz"
integrity sha512-7ZgogeTnjuHbo+ct10G9Ffp0mif17idi0IyWNVA/wcwcm7NPOD/WEHVP3n7n3MhXqxoIYm8d6MuZohYWIZ4T3w==
dot-case@^3.0.4:
version "3.0.4"
resolved "https://registry.npmjs.org/dot-case/-/dot-case-3.0.4.tgz"
integrity sha512-Kv5nKlh6yRrdrGvxeJ2e5y2eRUpkUosIW4A2AS38zwSz27zu7ufDwQPi5Jhs3XAlGNetl3bmnGhQsMtkKJnj3w==
dependencies:
no-case "^3.0.4"
tslib "^2.0.3"
dunder-proto@^1.0.0, dunder-proto@^1.0.1:
version "1.0.1"
resolved "https://registry.npmjs.org/dunder-proto/-/dunder-proto-1.0.1.tgz"
@@ -1623,6 +1729,11 @@ encodeurl@^2.0.0:
resolved "https://registry.npmjs.org/encodeurl/-/encodeurl-2.0.0.tgz"
integrity sha512-Q0n9HRi4m6JuGIV1eFlmvJB7ZEVxu93IrMyiMsGC0lrMJMWzRgx6WGquyfQgZVb31vhGgXnfmPNNXmxnOkRBrg==
entities@^4.4.0:
version "4.5.0"
resolved "https://registry.npmjs.org/entities/-/entities-4.5.0.tgz"
integrity sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw==
entities@^6.0.0:
version "6.0.0"
resolved "https://registry.npmjs.org/entities/-/entities-6.0.0.tgz"
@@ -2933,6 +3044,13 @@ loupe@^3.1.0, loupe@^3.1.3:
resolved "https://registry.npmjs.org/loupe/-/loupe-3.1.3.tgz"
integrity sha512-kkIp7XSkP78ZxJEsSxW3712C6teJVoeHHwgo9zJ380de7IYyJ2ISlxojcH2pC5OFLewESmnRi/+XCDIEEVyoug==
lower-case@^2.0.2:
version "2.0.2"
resolved "https://registry.npmjs.org/lower-case/-/lower-case-2.0.2.tgz"
integrity sha512-7fm3l3NAF9WfN6W3JOmf5drwpVqX78JtoGJ3A6W0a6ZnldM41w2fV5D490psKFTpMds8TJse/eHLFFsNHHjHgg==
dependencies:
tslib "^2.0.3"
lru-cache@^10.2.0:
version "10.4.3"
resolved "https://registry.npmjs.org/lru-cache/-/lru-cache-10.4.3.tgz"
@@ -3095,6 +3213,14 @@ negotiator@^1.0.0:
resolved "https://registry.npmjs.org/negotiator/-/negotiator-1.0.0.tgz"
integrity sha512-8Ofs/AUQh8MaEcrlq5xOX0CQ9ypTF5dl78mjlMNfOK08fzpgTHQRQPBxcPlEtIw0yRpws+Zo/3r+5WRby7u3Gg==
no-case@^3.0.4:
version "3.0.4"
resolved "https://registry.npmjs.org/no-case/-/no-case-3.0.4.tgz"
integrity sha512-fgAN3jGAh+RoxUGZHTSOLJIqUc2wmoBwGR4tbpNAKmmovFoWq0OdRkb0VkldReO2a2iBT/OEulG9XSUc10r3zg==
dependencies:
lower-case "^2.0.2"
tslib "^2.0.3"
node-releases@^2.0.19:
version "2.0.19"
resolved "https://registry.npmjs.org/node-releases/-/node-releases-2.0.19.tgz"
@@ -3948,6 +4074,14 @@ slice-ansi@^4.0.0:
astral-regex "^2.0.0"
is-fullwidth-code-point "^3.0.0"
snake-case@^3.0.4:
version "3.0.4"
resolved "https://registry.npmjs.org/snake-case/-/snake-case-3.0.4.tgz"
integrity sha512-LAOh4z89bGQvl9pFfNF8V146i7o7/CqFPbqzYgP+yYzDIDeS9HaNFtXABamRW+AQzEVODcvE79ljJ+8a9YSdMg==
dependencies:
dot-case "^3.0.4"
tslib "^2.0.3"
source-map-js@^1.0.1, source-map-js@^1.2.1:
version "1.2.1"
resolved "https://registry.npmjs.org/source-map-js/-/source-map-js-1.2.1.tgz"
@@ -4260,6 +4394,11 @@ suspend-react@^0.1.3:
resolved "https://registry.npmjs.org/suspend-react/-/suspend-react-0.1.3.tgz"
integrity sha512-aqldKgX9aZqpoDp3e8/BZ8Dm7x1pJl+qI3ZKxDN0i/IQTWUwBx/ManmlVJ3wowqbno6c2bmiIfs+Um6LbsjJyQ==
svg-parser@^2.0.4:
version "2.0.4"
resolved "https://registry.npmjs.org/svg-parser/-/svg-parser-2.0.4.tgz"
integrity sha512-e4hG1hRwoOdRb37cIMSgzNsxyzKfayW6VOflrwvR+/bzrkyxY/31WkbgnQpgtrNp1SdpJvpUAGTa/ZoiPNDuRQ==
svg-tags@^1.0.0:
version "1.0.0"
resolved "https://registry.npmjs.org/svg-tags/-/svg-tags-1.0.0.tgz"
@@ -4391,7 +4530,7 @@ tsconfig-paths@^4.2.0:
minimist "^1.2.6"
strip-bom "^3.0.0"
tslib@^2.0.0, tslib@^2.0.1, tslib@^2.1.0:
tslib@^2.0.0, tslib@^2.0.1, tslib@^2.0.3, tslib@^2.1.0:
version "2.8.1"
resolved "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz"
integrity sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==
@@ -4593,6 +4732,15 @@ vite-node@3.1.3:
pathe "^2.0.3"
vite "^5.0.0 || ^6.0.0"
vite-plugin-svgr@^4.3.0:
version "4.3.0"
resolved "https://registry.npmjs.org/vite-plugin-svgr/-/vite-plugin-svgr-4.3.0.tgz"
integrity sha512-Jy9qLB2/PyWklpYy0xk0UU3TlU0t2UMpJXZvf+hWII1lAmRHrOUKi11Uw8N3rxoNk7atZNYO3pR3vI1f7oi+6w==
dependencies:
"@rollup/pluginutils" "^5.1.3"
"@svgr/core" "^8.1.0"
"@svgr/plugin-jsx" "^8.1.0"
vite-tsconfig-paths@^5.1.4:
version "5.1.4"
resolved "https://registry.npmjs.org/vite-tsconfig-paths/-/vite-tsconfig-paths-5.1.4.tgz"
@@ -4602,7 +4750,7 @@ vite-tsconfig-paths@^5.1.4:
globrex "^0.1.2"
tsconfck "^3.0.3"
vite@*, "vite@^3.0.0 || ^4.0.0 || ^5.0.0 || ^6.0.0", "vite@^4.0.0 || ^5.0.0 || ^6.0.0", "vite@^4.2.0 || ^5.0.0 || ^6.0.0", "vite@^5.0.0 || ^6.0.0", vite@^6.2.2:
vite@*, "vite@^3.0.0 || ^4.0.0 || ^5.0.0 || ^6.0.0", "vite@^4.0.0 || ^5.0.0 || ^6.0.0", "vite@^4.2.0 || ^5.0.0 || ^6.0.0", "vite@^5.0.0 || ^6.0.0", vite@^6.2.2, vite@>=2.6.0:
version "6.3.5"
resolved "https://registry.npmjs.org/vite/-/vite-6.3.5.tgz"
integrity sha512-cZn6NDFE7wdTpINgs++ZJ4N49W2vRp8LCKrn3Ob1kYNtOo21vfDoaV5GzBfLU4MovSAB8uNRm4jgzVQZ+mBzPQ==
-122
View File
@@ -1,122 +0,0 @@
from llms.Modelos.Base_model import ModeloABC
from llms.Memory.Base_MemoryConv import MemoryConvABC
from datetime import datetime
from typing import Optional, List, Union
class AgenteAI:
def __init__(
self,
modelo: ModeloABC,
nombre: str,
descripcion: str,
system_prompt: str, # <- pertenece al agente
rol: str,
objetivos: List[str],
memoria: Optional[MemoryConvABC] = None,
version: str = "1.0.0",
tools: Optional[List] = None,
output_schema: Optional[dict] = None, # <- nuevo parámetro
):
self.modelo = modelo
self.memoria = memoria
self.tools = tools or []
self.output_schema = output_schema
self.nombre = nombre
self.descripcion = descripcion
self.system_prompt = system_prompt
self.rol = rol
self.objetivos = objetivos
self.version = version
self.created_at = datetime.now()
self.updated_at = self.created_at
self.numero_interacciones = 0
def actualizar_configuracion(self, **kwargs):
for clave, valor in kwargs.items():
if hasattr(self, clave):
setattr(self, clave, valor)
self.updated_at = datetime.now()
@property
def full_system_prompt(self) -> str:
partes = [
f"Tu nombre es: {self.nombre}",
f"Tu descripción: {self.descripcion}",
f"Tu Rol: {self.rol}",
f"Tus Objetivos: {', '.join(self.objetivos)}",
""
]
# Incluir herramientas disponibles
herramientas = self._obtener_descripcion_tools()
if herramientas:
partes.append("Estas son tus herramientas disponibles:\n")
partes.extend(herramientas)
partes.append("Úsalas cuando creas oportuno.\n")
partes.append(self.system_prompt)
if self.output_schema:
partes.append(
"SIEMPRE formatea la respuesta final siguiendo estrictamente el siguiente esquema JSON:"
)
partes.append(f"```json\n{self.output_schema}\n```")
return "\n".join(partes)
def _obtener_descripcion_tools(self) -> List[str]:
"""
Devuelve una lista de strings con el nombre y descripción de cada herramienta
recogida desde los servidores MCP conectados.
"""
descripciones = []
if not hasattr(self, "mcp_servers"):
return descripciones
for server in self.mcp_servers:
if hasattr(server, "tools") and server.tools:
for tool in server.tools:
# tool puede ser string o dict, depende cómo lo expongas
if isinstance(tool, str):
descripciones.append(f"- {tool}: [sin descripción]")
elif isinstance(tool, dict):
nombre = tool.get("name", "¿?")
descripcion = tool.get("description", "[sin descripción]")
descripciones.append(f"- {nombre}: {descripcion}")
elif hasattr(tool, "name"):
descripcion = getattr(tool, "description", "[sin descripción]")
descripciones.append(f"- {tool.name}: {descripcion}")
return descripciones
async def interactuar(self, prompt: str) -> str:
if not self.modelo:
raise ValueError("El agente no tiene un modelo asignado.")
historial = []
if self.memoria:
historial = self.memoria.cargar_historial_chat()
contexto = historial + [{"role": "user", "content": prompt}]
prompt_final = self._formatear_prompt(contexto)
# Espera la respuesta del modelo de forma asíncrona
respuesta = await self.modelo.responder(
prompt=prompt_final,
system_prompt=self.full_system_prompt
)
if self.memoria:
self.memoria.guardar_turno("user", prompt)
self.memoria.guardar_turno("assistant", respuesta)
self.numero_interacciones += 1
self.updated_at = datetime.now()
return respuesta
def _formatear_prompt(self, mensajes: List[dict]) -> str:
return "\n".join([f"{msg['role']}: {msg['content']}" for msg in mensajes])
-64
View File
@@ -1,64 +0,0 @@
from llms.Modelos.Base_model import ModeloABC
from src.ConexionApis.OpenAi_conexion import OpenAICliente
class ModeloOpenAI(ModeloABC):
def __init__(
self,
cliente: OpenAICliente,
model: str = "gpt-4o",
temperature: float = 0.7,
top_p: float = 1.0,
top_k: int = None,
frecuencia_penalizacion: float = 0.0,
num_tokens_maximos: int = 512,
use_legacy: bool = False
):
super().__init__(
model=model,
temperature=temperature,
top_p=top_p,
top_k=top_k,
frecuencia_penalizacion=frecuencia_penalizacion,
num_tokens_maximos=num_tokens_maximos
)
self.cliente = cliente
self.use_legacy = use_legacy
async def responder(self, prompt: str, system_prompt: str = "", **kwargs) -> str:
import asyncio
if self.use_legacy:
loop = asyncio.get_event_loop()
respuesta = await loop.run_in_executor(
None,
lambda: self.cliente.completion(
model=self.model,
prompt=prompt,
temperature=self.temperature,
top_p=self.top_p,
max_tokens=self.num_tokens_maximos,
frequency_penalty=self.frecuencia_penalizacion,
**kwargs
)
)
return respuesta.choices[0].text.strip()
else:
messages = []
if system_prompt:
messages.append({"role": "system", "content": system_prompt})
messages.append({"role": "user", "content": prompt})
loop = asyncio.get_event_loop()
respuesta = await loop.run_in_executor(
None,
lambda: self.cliente.chat_completion(
model=self.model,
messages=messages,
temperature=self.temperature,
top_p=self.top_p,
max_tokens=self.num_tokens_maximos,
frequency_penalty=self.frecuencia_penalizacion,
**kwargs
)
)
return respuesta.choices[0].message.content
+24 -1
View File
@@ -1,11 +1,34 @@
# main.py
import asyncio
import uvicorn
from entrypoint.init_db import init_db
from backend.main import app as fastapi_app
async def main_async():
# Inicia tareas de fondo controladas desde aquí
print("🔄 Lanzando tareas en segundo plano...")
tareas = []
# Configura y lanza el servidor FastAPI
print("🚀 Lanzando servidor FastAPI...")
config = uvicorn.Config(app=fastapi_app, host="0.0.0.0", port=8000, reload=True)
server = uvicorn.Server(config)
# Ejecuta servidor (bloqueante)
await server.serve()
# Cancela tareas si se cae el servidor
for task in tareas:
task.cancel()
def main():
# Aquí puedes colocar lógica adicional de arranque si la tienes
print("🛠️ Inicializando base de datos...")
init_db()
print("✅ Iniciando sistema...")
asyncio.run(main_async())
if __name__ == "__main__":
main()
+47 -41
View File
@@ -4,50 +4,56 @@ from src.ApiKeys.openai_apikey_mmr import OpenAICredencialRepo
from src.ConexionSql.Postgres_conexion import PostgresConexion
from entrypoint.init_db import db_credencial
from src.ConexionApis.OpenAi_conexion import OpenAICliente
from llms.Modelos.Openai_model import ModeloOpenAI
from llms.Agente import AgenteAI
from src.Llms.Modelos.Openai_model import ModeloOpenAI
from src.Llms.Agente import AgenteAI
from src.Llms.Memory.postgres_MemoryConv import MemoryConvPostgres
async def main():
# 🔌 Conexión
conexion_admin = PostgresConexion(db_credencial)
repo = OpenAICredencialRepo(conexion_admin)
credencial_openai = repo.get_by_id(1)
print(f"✅ Credencial: {credencial_openai.titulo}")
# 🤖 Modelo
cliente = OpenAICliente(credencial_openai)
modelo = ModeloOpenAI(
cliente=cliente,
model="gpt-4o",
temperature=1,
top_p=1.0
conexion_admin = PostgresConexion(db_credencial)
repo = OpenAICredencialRepo(conexion_admin)
credencial_openai = repo.get_by_id(1)
cliente = OpenAICliente(credencial_openai)
modelo = ModeloOpenAI(
cliente=cliente,
model="gpt-4o",
temperature=1,
top_p=1.0
)
memoria = MemoryConvPostgres(
credencial=db_credencial,
nombre_tabla="memoria_conversacion_pruebas",
k=10
)
agente2 = AgenteAI(
modelo=modelo,
nombre="Experto en Astronomía",
descripcion="Un experto en astronomía que responde preguntas sobre el universo.",
system_prompt="Actúa como un experto en astronomía y astrofísica con experiencia académica y práctica en observación astronómica, física estelar, cosmología, mecánica orbital y análisis de datos astronómicos. Cuando respondas, utiliza lenguaje técnico pero accesible para alguien con conocimientos intermedios en física y matemáticas. Siempre que sea posible, incluye explicaciones detalladas, ejemplos numéricos y referencias a teorías o descubrimientos relevantes (por ejemplo, relatividad general, evolución estelar, espectroscopía, etc.). No simplifiques en exceso. Si la pregunta tiene múltiples dimensiones (como observacional y teórica), aborda todas. ¿Estás listo para empezar?",
rol="astronomo",
max_iterations=5,
memoria=memoria,
objetivos=["Responder preguntas sobre astronomía y astrofísica", "Proporcionar explicaciones detalladas y ejemplos numéricos"],
)
async def probar_interaccion_stream():
print("Respuesta en streaming:\n")
# Paso 1: espera la corutina para obtener el generador
respuesta_gen = await agente2.interactuar_en_bucle(
"¿Hacia qué va orbitando cada astro del espacio? responde jerárquicamente",
stream=True
)
# 🧠 Agente
agente_con_herramientas = AgenteAI(
modelo=modelo,
nombre="Agente con herramientas",
descripcion="Un agente que puede usar herramientas",
system_prompt="Eres un asistente que puede usar herramientas para responder preguntas.",
rol="asistente",
objetivos=["Asistir al usuario en tareas complejas", "usar herramientas para obtener información adicional"]
)
# Paso 2: itera sobre el generador
async for token in respuesta_gen:
print(token, end="", flush=True)
print("\n🤖 Agente listo. Escribe 'salir' para terminar.")
# 🔁 Loop de interacción
while True:
entrada = input("🧑 Tú: ")
if entrada.strip().lower() in {"salir", "exit", "quit"}:
print("👋 Saliendo del agente...")
break
respuesta = await agente_con_herramientas.interactuar(prompt=entrada)
print(f"🤖 Agente: {respuesta}\n")
if __name__ == "__main__":
import os
if os.name == "nt":
asyncio.set_event_loop_policy(asyncio.WindowsProactorEventLoopPolicy())
asyncio.run(main())
asyncio.run(probar_interaccion_stream())
+1 -1
View File
@@ -6,7 +6,7 @@ from sqlalchemy import Column, Integer, String
from src.ConexionSql.Base_conexion import ConexionBase
from src.base import Base
from src.ApiKeys.openai_apikey import OpenAICredencial
from security.Encriptar import Encriptar_fernet
from src.Security.Encriptar import Encriptar_fernet
from entrypoint import ENV_PATH
# ----------------------
+13 -2
View File
@@ -12,8 +12,19 @@ class OpenAICliente:
self.client.organization = self.credencial.organizacion
# --- Chat Completions ---
def chat_completion(self, model: str, messages: list, **kwargs):
return self.client.chat.completions.create(model=model, messages=messages, **kwargs)
def chat_completion(self, model: str, messages: list, stream: bool = False, **kwargs):
response = self.client.chat.completions.create(
model=model,
messages=messages,
stream=stream, # Parámetro explícito
**kwargs
)
return self._handle_stream(response, stream) if stream else response
def _handle_stream(self, stream, _):
for chunk in stream:
if chunk.choices and chunk.choices[0].delta.content:
yield chunk.choices[0].delta.content
# --- Text Completions (legacy) ---
def completion(self, model: str, prompt: str, **kwargs):
+1 -1
View File
@@ -6,7 +6,7 @@ from sqlalchemy.orm import relationship
from src.ConexionSql.Base_conexion import ConexionBase
from src.base import Base
from src.Credenciales.postgres_credencial import PostgresCredencial
from security.Encriptar import Encriptar_fernet
from src.Security.Encriptar import Encriptar_fernet
# ----------------------
# Cargar clave maestra
+190
View File
@@ -0,0 +1,190 @@
from src.Llms.Modelos.Base_model import ModeloABC
from src.Llms.Memory.Base_MemoryConv import MemoryConvABC
from datetime import datetime
from typing import Optional, List, Union, AsyncGenerator
class AgenteAI:
def __init__(
self,
modelo: ModeloABC,
nombre: str,
descripcion: str,
system_prompt: str,
rol: str,
objetivos: List[str],
max_iterations: int = 1,
memoria: Optional[MemoryConvABC] = None,
version: str = "1.0.0",
tools: Optional[List] = None,
output_schema: Optional[dict] = None,
):
self.modelo = modelo
self.memoria = memoria
self.tools = tools or []
self.output_schema = output_schema
self.nombre = nombre
self.descripcion = descripcion
self.system_prompt = system_prompt
self.max_iterations = max_iterations
self.rol = rol
self.objetivos = objetivos
self.version = version
self.created_at = datetime.now()
self.updated_at = self.created_at
self.numero_interacciones = 0
def actualizar_configuracion(self, **kwargs):
for clave, valor in kwargs.items():
if hasattr(self, clave):
setattr(self, clave, valor)
self.updated_at = datetime.now()
@property
def full_system_prompt(self) -> str:
partes = [
f"Tu nombre es: {self.nombre}",
f"Tu descripción: {self.descripcion}",
f"Tu Rol: {self.rol}",
f"Tus Objetivos: {', '.join(self.objetivos)}",
""
]
herramientas = self._obtener_descripcion_tools()
if herramientas:
partes.append("Estas son tus herramientas disponibles:\n")
partes.extend(herramientas)
partes.append("Úsalas cuando creas oportuno.\n")
partes.append(self.system_prompt)
if self.output_schema:
partes.append("SIEMPRE formatea la respuesta final siguiendo estrictamente el siguiente esquema JSON:")
partes.append(f"```json\n{self.output_schema}\n```")
return "\n".join(partes)
def _obtener_descripcion_tools(self) -> List[str]:
descripciones = []
if not hasattr(self, "mcp_servers"):
return descripciones
for server in self.mcp_servers:
if hasattr(server, "tools") and server.tools:
for tool in server.tools:
if isinstance(tool, str):
descripciones.append(f"- {tool}: [sin descripción]")
elif isinstance(tool, dict):
nombre = tool.get("name", "¿?")
descripcion = tool.get("description", "[sin descripción]")
descripciones.append(f"- {nombre}: {descripcion}")
elif hasattr(tool, "name"):
descripcion = getattr(tool, "description", "[sin descripción]")
descripciones.append(f"- {tool.name}: {descripcion}")
return descripciones
def _formatear_prompt(self, mensajes: List[dict]) -> str:
return "\n".join([f"{msg['role']}: {msg['content']}" for msg in mensajes])
async def interactuar(self, prompt: str, stream: bool = False) -> Union[str, AsyncGenerator[str, None]]:
historial = self.memoria.cargar_historial_chat() if self.memoria else []
contexto = historial + [{"role": "user", "content": prompt}]
prompt_final = self._formatear_prompt(contexto)
respuesta = await self.modelo.responder(
prompt=prompt_final,
system_prompt=self.full_system_prompt,
stream=stream
)
if stream:
# stream es un generador asincrónico
async def wrapper():
buffer_respuesta = ""
async for token in respuesta:
buffer_respuesta += token
yield token
if self.memoria:
self.memoria.guardar_turno("user", prompt)
self.memoria.guardar_turno("assistant", buffer_respuesta)
self.numero_interacciones += 1
self.updated_at = datetime.now()
return wrapper()
else:
if self.memoria:
self.memoria.guardar_turno("user", prompt)
self.memoria.guardar_turno("assistant", respuesta)
self.numero_interacciones += 1
self.updated_at = datetime.now()
return respuesta
async def interactuar_en_bucle(self, prompt: str, stream: bool = False) -> Union[List[str], AsyncGenerator[str, None]]:
historial = self.memoria.cargar_historial_chat() if self.memoria else []
respuestas = [] if not stream else None
respuesta_anterior = None
iteration = 0
prompt_original = prompt.strip()
async def generador():
nonlocal iteration, respuesta_anterior
prompt_actual = prompt_original
while self.max_iterations == 0 or iteration < self.max_iterations:
if iteration == 0:
prompt_actual += (
"\n\nIMPORTANTE:\n"
"Si al revisar tu última respuesta y mi pregunta inicial consideras que has terminado, "
"di alguna de estas frases: <FIN>"
)
else:
prompt_actual = (
f"Esta es la pregunta original:\n{prompt_original}\n\n"
f"Esto fue lo último que dijiste:\n{respuesta_anterior}\n"
"\n\nIMPORTANTE:\n"
"Si al revisar tu última respuesta y mi pregunta inicial consideras que has terminado, "
"di alguna de estas frases: <FIN>"
)
contexto = historial + [{"role": "user", "content": prompt_actual}]
prompt_final = self._formatear_prompt(contexto)
respuesta = await self.modelo.responder(
prompt=prompt_final,
system_prompt=self.full_system_prompt,
stream=stream
)
if stream:
buffer_respuesta = ""
async for token in respuesta:
buffer_respuesta += token
yield token
respuesta_anterior = buffer_respuesta
else:
respuestas.append(respuesta)
respuesta_anterior = respuesta
if self.memoria:
self.memoria.guardar_turno("user", prompt_actual)
self.memoria.guardar_turno("assistant", respuesta_anterior)
self.numero_interacciones += 1
self.updated_at = datetime.now()
if "<fin>" in respuesta_anterior.lower():
break
iteration += 1
prompt_actual = ""
return generador() if stream else await generador_to_list(generador)
# Helper para consumir generador asincrónico si no es stream
async def generador_to_list(gen: AsyncGenerator[str, None]) -> List[str]:
buffer = ""
async for chunk in gen:
buffer += chunk
return [buffer]
View File
@@ -3,7 +3,7 @@ from typing import Literal
from src.Credenciales.postgres_credencial import PostgresCredencial
from src.ConexionSql.Postgres_conexion import PostgresConexion # Usamos la clase específica
from llms.Memory.Base_MemoryConv import MemoryConvABC
from src.Llms.Memory.Base_MemoryConv import MemoryConvABC
class MemoryConvPostgres(MemoryConvABC):
@@ -22,7 +22,7 @@ class ModeloABC(ABC):
self.num_tokens_maximos = num_tokens_maximos
@abstractmethod
async def responder(self, prompt: str, system_prompt: str = "", **kwargs) -> str:
async def responder(self, prompt: str, system_prompt: str = "", stream: bool = False, **kwargs) -> str:
"""
Devuelve una respuesta a partir de un prompt y configuración del modelo.
Este método debe implementarse de forma asíncrona en las subclases.
+82
View File
@@ -0,0 +1,82 @@
from src.Llms.Modelos.Base_model import ModeloABC
from src.ConexionApis.OpenAi_conexion import OpenAICliente
import asyncio
from typing import AsyncGenerator, Union
class ModeloOpenAI(ModeloABC):
def __init__(
self,
cliente: OpenAICliente,
model: str = "gpt-4o",
temperature: float = 0.7,
top_p: float = 1.0,
top_k: int = None,
frecuencia_penalizacion: float = 0.0,
num_tokens_maximos: int = 512,
use_legacy: bool = False
):
super().__init__(
model=model,
temperature=temperature,
top_p=top_p,
top_k=top_k,
frecuencia_penalizacion=frecuencia_penalizacion,
num_tokens_maximos=num_tokens_maximos
)
self.cliente = cliente
self.use_legacy = use_legacy
async def responder(
self,
prompt: str,
system_prompt: str = "",
stream: bool = False,
**kwargs
) -> Union[str, AsyncGenerator[str, None]]:
if self.use_legacy:
if stream:
raise NotImplementedError("El modo legacy no soporta streaming.")
loop = asyncio.get_event_loop()
respuesta = await loop.run_in_executor(
None,
lambda: self.cliente.completion(
model=self.model,
prompt=prompt,
temperature=self.temperature,
top_p=self.top_p,
max_tokens=self.num_tokens_maximos,
frequency_penalty=self.frecuencia_penalizacion,
**kwargs
)
)
return respuesta.choices[0].text.strip()
# Construcción de mensajes estilo Chat
messages = []
if system_prompt:
messages.append({"role": "system", "content": system_prompt})
messages.append({"role": "user", "content": prompt})
def sync_call():
return self.cliente.chat_completion(
model=self.model,
messages=messages,
temperature=self.temperature,
top_p=self.top_p,
max_tokens=self.num_tokens_maximos,
frequency_penalty=self.frecuencia_penalizacion,
stream=stream,
**kwargs
)
loop = asyncio.get_event_loop()
resultado = await loop.run_in_executor(None, sync_call)
if stream:
async def generador():
for token in resultado: # ya es un generador del cliente
yield token
return generador()
else:
return resultado.choices[0].message.content
@@ -4,7 +4,7 @@ from sqlalchemy import Column, Integer, String, Float, Boolean
from src.ConexionSql.Base_conexion import ConexionBase
from src.base import Base
from llms.Modelos.Openai_model import ModeloOpenAI # Clase real de lógica
from src.Llms.Modelos.Openai_model import ModeloOpenAI # Clase real de lógica
# ----------------------
# Cargar clave maestra
View File
View File
View File