Spaces:
Sleeping
Sleeping
Upload 13 files
Browse files- .env +2 -0
- .gitattributes +1 -0
- .gitignore +0 -0
- Bella.pdf +0 -0
- Holybiblie.jpg +0 -0
- LICENSE +21 -0
- README.md +57 -13
- botidinamix-g.json +13 -0
- chat.py +249 -0
- index.html +10 -0
- ngrok.exe +3 -0
- pinocho.pdf +0 -0
- requirements.txt +57 -0
- style.css +54 -0
.env
ADDED
|
@@ -0,0 +1,2 @@
|
|
|
|
|
|
|
|
|
|
| 1 |
+
OPENAI_API_KEY ='sk-proj-xN6oRtJ4swcDBU7EX3wfT3BlbkFJlONaZmIrH4O89wKfrmhh'
|
| 2 |
+
GOOGLE_APPLICATION_CREDENTIALS='botidinamix-g.json'
|
.gitattributes
CHANGED
|
@@ -33,3 +33,4 @@ saved_model/**/* filter=lfs diff=lfs merge=lfs -text
|
|
| 33 |
*.zip filter=lfs diff=lfs merge=lfs -text
|
| 34 |
*.zst filter=lfs diff=lfs merge=lfs -text
|
| 35 |
*tfevents* filter=lfs diff=lfs merge=lfs -text
|
|
|
|
|
|
| 33 |
*.zip filter=lfs diff=lfs merge=lfs -text
|
| 34 |
*.zst filter=lfs diff=lfs merge=lfs -text
|
| 35 |
*tfevents* filter=lfs diff=lfs merge=lfs -text
|
| 36 |
+
ngrok.exe filter=lfs diff=lfs merge=lfs -text
|
.gitignore
ADDED
|
File without changes
|
Bella.pdf
ADDED
|
Binary file (71.1 kB). View file
|
|
|
Holybiblie.jpg
ADDED
|
LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
MIT License
|
| 2 |
+
|
| 3 |
+
Copyright (c) 2024 _J_V_
|
| 4 |
+
|
| 5 |
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
| 6 |
+
of this software and associated documentation files (the "Software"), to deal
|
| 7 |
+
in the Software without restriction, including without limitation the rights
|
| 8 |
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
| 9 |
+
copies of the Software, and to permit persons to whom the Software is
|
| 10 |
+
furnished to do so, subject to the following conditions:
|
| 11 |
+
|
| 12 |
+
The above copyright notice and this permission notice shall be included in all
|
| 13 |
+
copies or substantial portions of the Software.
|
| 14 |
+
|
| 15 |
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
| 16 |
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
| 17 |
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
| 18 |
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
| 19 |
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
| 20 |
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
| 21 |
+
SOFTWARE.
|
README.md
CHANGED
|
@@ -1,13 +1,57 @@
|
|
| 1 |
-
|
| 2 |
-
|
| 3 |
-
|
| 4 |
-
|
| 5 |
-
|
| 6 |
-
|
| 7 |
-
|
| 8 |
-
|
| 9 |
-
|
| 10 |
-
|
| 11 |
-
|
| 12 |
-
|
| 13 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# Chatbot con OpenAI
|
| 2 |
+
|
| 3 |
+
Este proyecto consiste en un chatbot desarrollado utilizando la API de OpenAI. El chatbot es capaz de responder preguntas sobre un texto proporcionado por el usuario, utilizando modelos de lenguaje avanzados de OpenAI.
|
| 4 |
+
|
| 5 |
+
## Descripción
|
| 6 |
+
|
| 7 |
+
El chatbot puede cargar un documento PDF, extraer su contenido de texto, preprocesarlo y luego responder preguntas sobre ese texto utilizando la API de OpenAI. Los usuarios pueden seleccionar diferentes modelos de lenguaje de OpenAI para generar respuestas.
|
| 8 |
+
|
| 9 |
+
## Instalación
|
| 10 |
+
|
| 11 |
+
Para ejecutar este proyecto localmente, sigue estos pasos:
|
| 12 |
+
|
| 13 |
+
1. Clona este repositorio en tu máquina local utilizando Git:
|
| 14 |
+
|
| 15 |
+
```bash
|
| 16 |
+
git clone https://github.com/tu_usuario/tu_repositorio.git
|
| 17 |
+
```
|
| 18 |
+
|
| 19 |
+
2. Navega al directorio del proyecto:
|
| 20 |
+
|
| 21 |
+
```bash
|
| 22 |
+
cd tu_repositorio
|
| 23 |
+
```
|
| 24 |
+
|
| 25 |
+
3. Instala las dependencias necesarias utilizando pip:
|
| 26 |
+
|
| 27 |
+
```bash
|
| 28 |
+
pip install -r requirements.txt
|
| 29 |
+
```
|
| 30 |
+
|
| 31 |
+
4. Configura tu clave de API de OpenAI. Puedes hacerlo estableciendo la variable de entorno `OPENAI_API_KEY` o directamente en el archivo `chat.py`.
|
| 32 |
+
|
| 33 |
+
## Uso
|
| 34 |
+
|
| 35 |
+
Una vez que hayas configurado el proyecto y las dependencias, puedes ejecutar el chatbot utilizando el siguiente comando:
|
| 36 |
+
|
| 37 |
+
```bash
|
| 38 |
+
streamlit run chat.py
|
| 39 |
+
```
|
| 40 |
+
## Dependencias
|
| 41 |
+
|
| 42 |
+
Este proyecto utiliza las siguientes dependencias de Python:
|
| 43 |
+
|
| 44 |
+
- Streamlit: Para la interfaz de usuario interactiva.
|
| 45 |
+
- OpenAI: Para acceder a la API de OpenAI y obtener respuestas del chatbot.
|
| 46 |
+
- NLTK: Para el preprocesamiento de texto, incluyendo tokenización y eliminación de palabras vacías.
|
| 47 |
+
- PyPDF2: Para extraer texto de documentos PDF.
|
| 48 |
+
|
| 49 |
+
Puedes encontrar las versiones específicas de las dependencias en el archivo `requirements.txt`.
|
| 50 |
+
|
| 51 |
+
## Contribuciones
|
| 52 |
+
|
| 53 |
+
Las contribuciones son bienvenidas. Si deseas contribuir a este proyecto, por favor, abre un issue para discutir los cambios propuestos antes de enviar un pull request.
|
| 54 |
+
|
| 55 |
+
## Licencia
|
| 56 |
+
|
| 57 |
+
Este proyecto está bajo la Licencia MIT. Para más detalles, consulta el archivo `LICENSE`.
|
botidinamix-g.json
ADDED
|
@@ -0,0 +1,13 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
{
|
| 2 |
+
"type": "service_account",
|
| 3 |
+
"project_id": "assistant-9nteod",
|
| 4 |
+
"private_key_id": "2a6b434c79db1c61fd01a4aa0fdb4581abd03134",
|
| 5 |
+
"private_key": "-----BEGIN PRIVATE KEY-----\nMIIEvAIBADANBgkqhkiG9w0BAQEFAASCBKYwggSiAgEAAoIBAQDf3Kus0HiXPybh\n06C05KvyuM/LfHBQXIMdMRDHaCp8Wj17h8HOmND7P+e/DcM45AevY2xfvq5ZOMCa\nCEFGXQHaiy6kDYpBiEzBYaLK2mfamUdkURejsE4yZr3piZkhJ4+lGke+jouAey01\nxwM5bVaCUSP1iWcryHrohaOr9rhbniCDheXu4J7d+q/ajyC8iw2UHKbL2RXwuK1y\nl7BAUxEGxLtu4yREWBo3dK0f9z/s3Vpva4zUuDbXqflgazDm0ak5ruRqAk/x6Xqy\nz9jhX3IuJc+MDlGiGDtNo40obT9jyknkbD03lmdRLlPeFNqNoiOeUOWIFX+YtsA0\noB0LixiHAgMBAAECggEAHdKn8PUG6Qip6pIxydeK9reF60hv2AIzGhZOyMSeSwRk\nm3U0WGHFuYBuebvgzaPx8tIj08Td35dZb/Z4kmH9R2WdDZBGN8EWOfmtYSk5MQc+\n2mTulB5+lGVZQz2oWkvgbZuI16CQLMomyuVxObB7bWSs4zRDu91Qo8h7S63/Kn6F\nwt41fHsJmRwSV21ZMzrYtFXrmYuNZxsfhzLV1JFiPF+LgJT+AojhZO1r4FtDS+kI\nBtoD8QZn+T5+TDgj7NLDL+kMn8EWQU2o+PQDtbi69hQxHTo4rxdXB5z6BmZbPt9B\n7jLIRS/rfeaPgvdjSi0z7IsJWEbZlu9KSeUfkgZoxQKBgQD1XU/7sGZqiF7GO9yr\ncm2rAvFh1e+/jOd1iwQ48KJ8lITO52lEyLq53T+OAJbULWseHXi0VQNsd7kzs0Zl\nIVImOuHsG087vXVrxk75yzJBuwPCBMakBKRtkcpETEti477yo+Szw3mKEmsBfHYr\nMW5+MISaWbPzqQ7O51Fx0h1MjQKBgQDpkMFs7ID+ski1sRm4K1Szo+RWhm1ag8Mb\nIYJhcL0K1WRFfIyTyzm5krrXsUQTydX/oNinMtv/hS379CgyqobWO85+YBh3kYbZ\nn8FOJOhJ176sE4soti8p5aktyQSpqjVVtsf7OKw50CgGE5lAxxGOolQTD4d8zYjL\n9y7o8QP2YwKBgEvRYLS6Rntm1jpVJxQHUOIGD8aWj/XVuXP12AEsQllSn1M76Khr\nil+CgXAEuJapzi7JFpJKrrsmp6DVJcx8JmFP0p3dtncUTSNXbPH9GvN6sWeTiDoI\ngTKmWSUPmj/ddhSOFk6B+Z1zoYMdDXq9VJJDtcXoMBX7yGqgyebs8UbFAoGAAY6y\ni3xkO86Kh5OfvUekr/H20tDgp8rbITIvAWFUEV9s5L243j9rqh4dWtTWxF8DK0oy\nR6MiLmj/7n8pSXUzovgRH2yanSl+QbM8Ab5jQiLLJbCXq/TTCa97Wk/N1SfKZUDr\nwnQVSelmauv0iKcLKe1RLDNdTuq778g9KtZ4lUsCgYBebKvZbG8S9xHZcUNBxEty\nKCtknf2DoO3cvQ6zCEaIaMbdRH+NEuBxgGYKX2brHLSxJSOaAWoX+yiIxFlHdAAz\n0BiMkgqnJThevrfEs30zTYQBU78HP8WUnzUqsqwooqr7ry4hq5z78RXL0NP8BepH\nBavhIQYovXSFy6l0m6JFng==\n-----END PRIVATE KEY-----\n",
|
| 6 |
+
"client_email": "botidinamix@assistant-9nteod.iam.gserviceaccount.com",
|
| 7 |
+
"client_id": "104652076455278864571",
|
| 8 |
+
"auth_uri": "https://accounts.google.com/o/oauth2/auth",
|
| 9 |
+
"token_uri": "https://oauth2.googleapis.com/token",
|
| 10 |
+
"auth_provider_x509_cert_url": "https://www.googleapis.com/oauth2/v1/certs",
|
| 11 |
+
"client_x509_cert_url": "https://www.googleapis.com/robot/v1/metadata/x509/botidinamix%40assistant-9nteod.iam.gserviceaccount.com",
|
| 12 |
+
"universe_domain": "googleapis.com"
|
| 13 |
+
}
|
chat.py
ADDED
|
@@ -0,0 +1,249 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
import streamlit as st
|
| 2 |
+
import openai
|
| 3 |
+
from dotenv import load_dotenv
|
| 4 |
+
import nltk
|
| 5 |
+
import os
|
| 6 |
+
import tempfile
|
| 7 |
+
from nltk.tokenize import word_tokenize
|
| 8 |
+
from nltk.corpus import stopwords
|
| 9 |
+
from nltk.stem import SnowballStemmer
|
| 10 |
+
import PyPDF2
|
| 11 |
+
import time
|
| 12 |
+
from google.cloud import texttospeech
|
| 13 |
+
from Historial.historial_chat import cargar_historial, guardar_historial # Importa las funciones
|
| 14 |
+
from streamlit_webrtc import webrtc_streamer, WebRtcMode
|
| 15 |
+
import av
|
| 16 |
+
|
| 17 |
+
# Configuración de NLTK
|
| 18 |
+
nltk.download('punkt')
|
| 19 |
+
nltk.download('stopwords')
|
| 20 |
+
|
| 21 |
+
# Función para cargar el texto del PDF
|
| 22 |
+
def extraer_texto_pdf(archivo):
|
| 23 |
+
texto = ""
|
| 24 |
+
if archivo:
|
| 25 |
+
with tempfile.NamedTemporaryFile(delete=False) as temp_file:
|
| 26 |
+
temp_file.write(archivo.read())
|
| 27 |
+
temp_file_path = temp_file.name
|
| 28 |
+
with open(temp_file_path, 'rb') as file:
|
| 29 |
+
reader = PyPDF2.PdfReader(file)
|
| 30 |
+
for page in range(len(reader.pages)):
|
| 31 |
+
texto += reader.pages[page].extract_text()
|
| 32 |
+
os.unlink(temp_file_path)
|
| 33 |
+
return texto
|
| 34 |
+
|
| 35 |
+
# Función para preprocesar texto
|
| 36 |
+
def preprocesar_texto(texto):
|
| 37 |
+
tokens = word_tokenize(texto, language='spanish')
|
| 38 |
+
tokens = [word.lower() for word in tokens if word.isalpha()]
|
| 39 |
+
stopwords_es = set(stopwords.words('spanish'))
|
| 40 |
+
tokens = [word for word in tokens if word not in stopwords_es]
|
| 41 |
+
stemmer = SnowballStemmer('spanish')
|
| 42 |
+
tokens = [stemmer.stem(word) for word in tokens]
|
| 43 |
+
return " ".join(tokens)
|
| 44 |
+
|
| 45 |
+
# Cargar la clave API desde el archivo .env
|
| 46 |
+
load_dotenv()
|
| 47 |
+
os.environ["GOOGLE_APPLICATION_CREDENTIALS"] = "botidinamix-g.json" # Reemplaza 'key.json' con el nombre de tu archivo de credenciales
|
| 48 |
+
openai.api_key = os.getenv("OPENAI_API_KEY")
|
| 49 |
+
|
| 50 |
+
# Instancia el cliente de Text-to-Speech
|
| 51 |
+
client = texttospeech.TextToSpeechClient()
|
| 52 |
+
|
| 53 |
+
# Función para obtener respuesta de OpenAI usando el modelo GPT y convertir a audio
|
| 54 |
+
def obtener_respuesta(pregunta, texto_preprocesado, modelo, temperatura=0.5):
|
| 55 |
+
try:
|
| 56 |
+
response = openai.ChatCompletion.create(
|
| 57 |
+
model=modelo,
|
| 58 |
+
messages=[
|
| 59 |
+
{"role": "system", "content": "Actua como Elias un Teologo y psicologo capacitado, en la interpretacion de la palabra de Dios. tienes un tono muy amable y cordial"},
|
| 60 |
+
{"role": "user", "content": f"{pregunta}\n\nContexto: {texto_preprocesado}"}
|
| 61 |
+
],
|
| 62 |
+
temperature=temperatura
|
| 63 |
+
)
|
| 64 |
+
respuesta = response.choices[0].message['content'].strip()
|
| 65 |
+
|
| 66 |
+
# Configura la solicitud de síntesis de voz
|
| 67 |
+
input_text = texttospeech.SynthesisInput(text=respuesta)
|
| 68 |
+
voice = texttospeech.VoiceSelectionParams(
|
| 69 |
+
language_code="es-ES", ssml_gender=texttospeech.SsmlVoiceGender.MALE,
|
| 70 |
+
)
|
| 71 |
+
audio_config = texttospeech.AudioConfig(
|
| 72 |
+
audio_encoding=texttospeech.AudioEncoding.MP3
|
| 73 |
+
)
|
| 74 |
+
|
| 75 |
+
# Realiza la solicitud de síntesis de voz
|
| 76 |
+
response = client.synthesize_speech(
|
| 77 |
+
input=input_text, voice=voice, audio_config=audio_config
|
| 78 |
+
)
|
| 79 |
+
|
| 80 |
+
# Reproduce el audio en Streamlit
|
| 81 |
+
st.audio(response.audio_content, format="audio/mp3")
|
| 82 |
+
return respuesta
|
| 83 |
+
|
| 84 |
+
except openai.OpenAIError as e:
|
| 85 |
+
st.error(f"Error al comunicarse con OpenAI: {e}")
|
| 86 |
+
return "Lo siento, no puedo procesar tu solicitud en este momento."
|
| 87 |
+
|
| 88 |
+
def main():
|
| 89 |
+
# --- Diseño general ---
|
| 90 |
+
st.set_page_config(page_title="Asistente Virtual", page_icon="🤖")
|
| 91 |
+
|
| 92 |
+
# --- Barra lateral ---
|
| 93 |
+
with st.sidebar:
|
| 94 |
+
st.image("Holybiblie.jpg")
|
| 95 |
+
st.title("🤖 LOS CODIGOS DE DIOS-BOTIDINAMIX AI")
|
| 96 |
+
st.markdown("---")
|
| 97 |
+
# --- Estilos CSS personalizados ---
|
| 98 |
+
st.markdown(
|
| 99 |
+
"""
|
| 100 |
+
<style>
|
| 101 |
+
body {
|
| 102 |
+
background-image: linear-gradient(to right, #4B0082, #0000FF); /* Fondo degradado */
|
| 103 |
+
}
|
| 104 |
+
.stChatFloatingInputContainer { /* Estilos para el contenedor del input del chat */
|
| 105 |
+
background-color: rgba(255, 255, 255, 0.8); /* Fondo blanco con opacidad */
|
| 106 |
+
border-radius: 10px; /* Bordes redondeados */
|
| 107 |
+
}
|
| 108 |
+
.stTextInput > div > div > input { /* Input de texto del chat */
|
| 109 |
+
color: #333; /* Color de texto más oscuro */
|
| 110 |
+
}
|
| 111 |
+
[data-testid="stChatMessage"] { /* Burbujas de chat */
|
| 112 |
+
background-color: black !important; /* Color de fondo negro */
|
| 113 |
+
color: gold !important; /* Color de texto dorado */
|
| 114 |
+
border-radius: 10px;
|
| 115 |
+
}
|
| 116 |
+
[data-testid="stChatMessage"] p { /* Párrafos dentro de las burbujas */
|
| 117 |
+
color: gold !important;
|
| 118 |
+
}
|
| 119 |
+
</style>
|
| 120 |
+
""",
|
| 121 |
+
unsafe_allow_html=True,
|
| 122 |
+
)
|
| 123 |
+
# --- Botones de historial ---
|
| 124 |
+
if st.button("Buscar Historial"):
|
| 125 |
+
st.session_state.mostrar_historial = True
|
| 126 |
+
if st.button("Borrar Historial"):
|
| 127 |
+
st.session_state.mensajes = []
|
| 128 |
+
st.session_state.mostrar_historial = False
|
| 129 |
+
st.success("Historial borrado correctamente")
|
| 130 |
+
# --- Chatbot ---
|
| 131 |
+
if 'mensajes' not in st.session_state:
|
| 132 |
+
st.session_state.mensajes = cargar_historial()
|
| 133 |
+
|
| 134 |
+
for mensaje in st.session_state.mensajes:
|
| 135 |
+
with st.chat_message(mensaje["role"]):
|
| 136 |
+
st.markdown(mensaje["content"])
|
| 137 |
+
# Función para manejar la entrada de audio
|
| 138 |
+
def on_audio(audio_bytes):
|
| 139 |
+
with st.spinner("Transcribiendo..."):
|
| 140 |
+
transcript = openai.Audio.transcribe("whisper-1", audio_bytes)
|
| 141 |
+
pregunta_usuario = transcript["text"]
|
| 142 |
+
st.session_state.mensajes.append({"role": "user", "content": pregunta_usuario, "timestamp": time.time()})
|
| 143 |
+
with st.chat_message("user"):
|
| 144 |
+
st.markdown(pregunta_usuario)
|
| 145 |
+
|
| 146 |
+
st.subheader("🎤 Captura de voz")
|
| 147 |
+
st.info("Haz clic en el micrófono y comienza a hablar. Tu pregunta se transcribirá automáticamente.")
|
| 148 |
+
with st.container():
|
| 149 |
+
if st.button("Grabar 🎙️"):
|
| 150 |
+
st.session_state.run_webrtc = True
|
| 151 |
+
if st.session_state.get("run_webrtc", False):
|
| 152 |
+
webrtc_streamer(
|
| 153 |
+
key="speech-to-text",
|
| 154 |
+
mode=WebRtcMode.SENDONLY,
|
| 155 |
+
rtc_configuration={"iceServers": [{"urls": ["stun:stun.l.google.com:19302"]}]},
|
| 156 |
+
media_stream_constraints={"video": False, "audio": True},
|
| 157 |
+
on_audio=on_audio,
|
| 158 |
+
)
|
| 159 |
+
st.session_state["run_webrtc"] = False
|
| 160 |
+
|
| 161 |
+
# Mostrar historial si el botón fue presionado
|
| 162 |
+
if st.session_state.get("mostrar_historial", False):
|
| 163 |
+
st.subheader("Historial de Chat:")
|
| 164 |
+
if st.session_state.mensajes:
|
| 165 |
+
for mensaje in st.session_state.mensajes:
|
| 166 |
+
with st.chat_message(mensaje["role"]):
|
| 167 |
+
st.markdown(mensaje["content"])
|
| 168 |
+
else:
|
| 169 |
+
st.info("No hay mensajes en el historial.")
|
| 170 |
+
else:
|
| 171 |
+
for mensaje in st.session_state.mensajes:
|
| 172 |
+
with st.chat_message(mensaje["role"]):
|
| 173 |
+
st.markdown(mensaje["content"])
|
| 174 |
+
|
| 175 |
+
# Selección de modelo de lenguaje
|
| 176 |
+
st.subheader("🧠 Configuración del Modelo")
|
| 177 |
+
modelo = st.selectbox(
|
| 178 |
+
"Selecciona el modelo:",
|
| 179 |
+
["gpt-3.5-turbo", "gpt-4"],
|
| 180 |
+
index=0,
|
| 181 |
+
help="Elige el modelo de lenguaje de OpenAI que prefieras."
|
| 182 |
+
)
|
| 183 |
+
|
| 184 |
+
# --- Opciones adicionales ---
|
| 185 |
+
st.markdown("---")
|
| 186 |
+
temperatura = st.slider("🌡️ Temperatura", min_value=0.0, max_value=1.0, value=0.5, step=0.1)
|
| 187 |
+
|
| 188 |
+
# --- Video de fondo ---
|
| 189 |
+
with st.container():
|
| 190 |
+
st.markdown(
|
| 191 |
+
f"""
|
| 192 |
+
<style>
|
| 193 |
+
#video-container {{
|
| 194 |
+
position: relative;
|
| 195 |
+
width: 100%;
|
| 196 |
+
padding-bottom: 56.25%;
|
| 197 |
+
background-color: lightblue;
|
| 198 |
+
overflow: hidden;
|
| 199 |
+
}}
|
| 200 |
+
#background-video {{
|
| 201 |
+
position: absolute;
|
| 202 |
+
top: 0;
|
| 203 |
+
left: 0;
|
| 204 |
+
width: 100%;
|
| 205 |
+
height: 100%;
|
| 206 |
+
}}
|
| 207 |
+
</style>
|
| 208 |
+
<div id="video-container">
|
| 209 |
+
<video id="background-video" autoplay loop muted playsinline>
|
| 210 |
+
<source src="https://cdn.pika.art/v1/f41adf48-a6db-4c6e-a93e-cd8db88f469d/movimiento_del_cuerpo_sutil_seed902109641145783.mp4" type="video/mp4">
|
| 211 |
+
</video>
|
| 212 |
+
</div>
|
| 213 |
+
""",
|
| 214 |
+
unsafe_allow_html=True,
|
| 215 |
+
)
|
| 216 |
+
|
| 217 |
+
# --- Área principal de la aplicación ---
|
| 218 |
+
st.header("💬 Relexionar con Elias")
|
| 219 |
+
|
| 220 |
+
# Carga de archivo PDF
|
| 221 |
+
archivo_pdf = st.file_uploader("📂 Cargar PDF", type='pdf')
|
| 222 |
+
|
| 223 |
+
# --- Chatbot ---
|
| 224 |
+
if 'mensajes' not in st.session_state:
|
| 225 |
+
st.session_state.mensajes = []
|
| 226 |
+
|
| 227 |
+
for mensaje in st.session_state.mensajes:
|
| 228 |
+
with st.chat_message(mensaje["role"]):
|
| 229 |
+
st.markdown(mensaje["content"])
|
| 230 |
+
|
| 231 |
+
pregunta_usuario = st.chat_input("Pregunta:")
|
| 232 |
+
if pregunta_usuario:
|
| 233 |
+
st.session_state.mensajes.append({"role": "user", "content": pregunta_usuario})
|
| 234 |
+
with st.chat_message("user"):
|
| 235 |
+
st.markdown(pregunta_usuario)
|
| 236 |
+
|
| 237 |
+
if archivo_pdf:
|
| 238 |
+
texto_pdf = extraer_texto_pdf(archivo_pdf)
|
| 239 |
+
texto_preprocesado = preprocesar_texto(texto_pdf)
|
| 240 |
+
else:
|
| 241 |
+
texto_preprocesado = "" # Sin contexto de PDF si no se carga un archivo
|
| 242 |
+
|
| 243 |
+
respuesta = obtener_respuesta(pregunta_usuario, texto_preprocesado, modelo, temperatura)
|
| 244 |
+
st.session_state.mensajes.append({"role": "assistant", "content": respuesta})
|
| 245 |
+
with st.chat_message("assistant"):
|
| 246 |
+
st.markdown(respuesta)
|
| 247 |
+
|
| 248 |
+
if __name__ == "__main__":
|
| 249 |
+
main()
|
index.html
ADDED
|
@@ -0,0 +1,10 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
<!DOCTYPE html>
|
| 2 |
+
<html>
|
| 3 |
+
<head>
|
| 4 |
+
<title>Mi Chatbot Personalizado</title>
|
| 5 |
+
<link rel="stylesheet" href="style.css">
|
| 6 |
+
</head>
|
| 7 |
+
<body>
|
| 8 |
+
<div id="root"></div>
|
| 9 |
+
</body>
|
| 10 |
+
</html>
|
ngrok.exe
ADDED
|
@@ -0,0 +1,3 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
version https://git-lfs.github.com/spec/v1
|
| 2 |
+
oid sha256:3e20143e3e6346e09009109c997e91ce135eafc20496a02b2d5bad4a0b2a823c
|
| 3 |
+
size 29527784
|
pinocho.pdf
ADDED
|
Binary file (80.7 kB). View file
|
|
|
requirements.txt
ADDED
|
@@ -0,0 +1,57 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
altair==5.3.0
|
| 2 |
+
annotated-types==0.6.0
|
| 3 |
+
anyio==4.3.0
|
| 4 |
+
attrs==23.2.0
|
| 5 |
+
blinker==1.7.0
|
| 6 |
+
cachetools==5.3.3
|
| 7 |
+
certifi==2024.2.2
|
| 8 |
+
charset-normalizer==3.3.2
|
| 9 |
+
click==8.1.7
|
| 10 |
+
distro==1.9.0
|
| 11 |
+
exceptiongroup==1.2.0
|
| 12 |
+
gitdb==4.0.11
|
| 13 |
+
GitPython==3.1.43
|
| 14 |
+
h11==0.14.0
|
| 15 |
+
httpcore==1.0.5
|
| 16 |
+
httpx==0.27.0
|
| 17 |
+
idna==3.6
|
| 18 |
+
Jinja2==3.1.3
|
| 19 |
+
joblib==1.3.2
|
| 20 |
+
jsonschema==4.21.1
|
| 21 |
+
jsonschema-specifications==2023.12.1
|
| 22 |
+
markdown-it-py==3.0.0
|
| 23 |
+
MarkupSafe==2.1.5
|
| 24 |
+
mdurl==0.1.2
|
| 25 |
+
nltk==3.8.1
|
| 26 |
+
numpy==1.26.4
|
| 27 |
+
openai==1.16.1
|
| 28 |
+
packaging==23.2
|
| 29 |
+
pandas==2.2.1
|
| 30 |
+
pillow==10.3.0
|
| 31 |
+
protobuf==4.25.3
|
| 32 |
+
pyarrow==15.0.2
|
| 33 |
+
pydantic==2.6.4
|
| 34 |
+
pydantic_core==2.16.3
|
| 35 |
+
pydeck==0.8.1b0
|
| 36 |
+
Pygments==2.17.2
|
| 37 |
+
PyPDF2==3.0.1
|
| 38 |
+
python-dateutil==2.9.0.post0
|
| 39 |
+
pytz==2024.1
|
| 40 |
+
referencing==0.34.0
|
| 41 |
+
regex==2023.12.25
|
| 42 |
+
requests==2.31.0
|
| 43 |
+
rich==13.7.1
|
| 44 |
+
rpds-py==0.18.0
|
| 45 |
+
six==1.16.0
|
| 46 |
+
smmap==5.0.1
|
| 47 |
+
sniffio==1.3.1
|
| 48 |
+
streamlit==1.32.2
|
| 49 |
+
tenacity==8.2.3
|
| 50 |
+
toml==0.10.2
|
| 51 |
+
toolz==0.12.1
|
| 52 |
+
tornado==6.4
|
| 53 |
+
tqdm==4.66.2
|
| 54 |
+
typing_extensions==4.10.0
|
| 55 |
+
tzdata==2024.1
|
| 56 |
+
urllib3==2.2.1
|
| 57 |
+
watchdog==4.0.0
|
style.css
ADDED
|
@@ -0,0 +1,54 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
/* Estilos generales */
|
| 2 |
+
body {
|
| 3 |
+
font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
|
| 4 |
+
background-color: #f4f4f4;
|
| 5 |
+
margin: 0;
|
| 6 |
+
padding: 0;
|
| 7 |
+
}
|
| 8 |
+
|
| 9 |
+
/* Estilos para el contenedor del chat */
|
| 10 |
+
.stApp {
|
| 11 |
+
max-width: 800px;
|
| 12 |
+
margin: 20px auto;
|
| 13 |
+
padding: 20px;
|
| 14 |
+
border-radius: 10px;
|
| 15 |
+
box-shadow: 0 2px 5px rgba(0, 0, 0, 0.1);
|
| 16 |
+
}
|
| 17 |
+
|
| 18 |
+
/* Estilos para los mensajes del chat */
|
| 19 |
+
.stChatMessage {
|
| 20 |
+
padding: 15px;
|
| 21 |
+
border-radius: 8px;
|
| 22 |
+
margin-bottom: 10px;
|
| 23 |
+
box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1); /* Sombra sutil */
|
| 24 |
+
}
|
| 25 |
+
|
| 26 |
+
/* Estilos para los mensajes del usuario */
|
| 27 |
+
.stChatMessage [data-testid="chat-message-text"]:first-of-type {
|
| 28 |
+
background-color: #e0f2f1; /* Color de fondo claro para el usuario */
|
| 29 |
+
color: #333; /* Texto oscuro */
|
| 30 |
+
text-align: left;
|
| 31 |
+
}
|
| 32 |
+
|
| 33 |
+
/* Estilos para los mensajes del asistente */
|
| 34 |
+
.stChatMessage:not([data-testid="chat-message-text"]:first-of-type) {
|
| 35 |
+
background-color: #fff; /* Color de fondo blanco para el asistente */
|
| 36 |
+
color: #333; /* Texto oscuro */
|
| 37 |
+
text-align: left;
|
| 38 |
+
}
|
| 39 |
+
|
| 40 |
+
/* Estilos para el área de entrada de texto */
|
| 41 |
+
.stChatInputContainer {
|
| 42 |
+
padding: 10px;
|
| 43 |
+
background-color: #fff;
|
| 44 |
+
border-top: 1px solid #ddd;
|
| 45 |
+
}
|
| 46 |
+
|
| 47 |
+
.stChatInputContainer textarea {
|
| 48 |
+
width: 100%;
|
| 49 |
+
padding: 10px;
|
| 50 |
+
border: 1px solid #ccc;
|
| 51 |
+
border-radius: 5px;
|
| 52 |
+
resize: vertical;
|
| 53 |
+
}
|
| 54 |
+
|