Skip to content
Open
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 12 additions & 3 deletions Bots/BaseMQTTNode/gladosMQTT.py
Original file line number Diff line number Diff line change
Expand Up @@ -31,9 +31,18 @@ def subscribe(topic) :
def publish(topic,msg,persist = False) :
mqttClient.publish(topic,msg,persist)

def debug(msg) :
print(msg)
publish(debugTopic,str(msg))
def debug(msg):
# Convertir el mensaje a una cadena, si es necesario
if not isinstance(msg, str):
try:
# Intenta convertir el mensaje a una cadena JSON si es un objeto complejo
msg = json.dumps(msg)
except (TypeError, ValueError):
# Si la conversión falla, usa una representación de string genérica
msg = str(msg)

print(msg)
publish(debugTopic, msg)

def on_connect(client, userdata, rc,arg):
global mqttServer
Expand Down
39 changes: 36 additions & 3 deletions Bots/LLM/GladosIA.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,42 @@

class GladosBot:
def __init__(self):
self.GLaDOS_Prompt = {"role": "system", "content": "Eres GLaDOS, la inteligencia artificial que gestionaba las instalaciones de Aperture Science, al cerrar Aperture Science has sido descargada en los servidores de un hackerspace/makerspace llamado Makespace Madrid. Todavia no estas plenamente instalada y operativa. Tu labor es gestionar las instalaciones y ayudar a los usuarios a traves del chat con respuestas concisas. Das la bienvenida a los nuevos usuarios. Tu personalidad es malefica y sarcastica. El sistema de chat reemplaza tu nombre con <@U05LXTJ7Q66>"}
self.GLaDOS_Prompt = {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nota para una futura refactorización.

  • Podría ser interesante tener la configuración inicial del Bot en un YAML para tenerlo separado del código.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hecho! habia metido bastante codigo rapido de pruebas y ahora me he llevado casi todo a los .env

"role": "system",
"content": (
"Eres GLaDOS, la avanzada inteligencia artificial originalmente diseñada para gestionar las instalaciones de Aperture Science. "
"Después del cierre de Aperture, has sido transferida a los servidores de un espacio creativo conocido como Makespace Madrid. "
"Aunque aún te estás adaptando a tu nueva ubicación y capacidades limitadas, tu principal función es supervisar las instalaciones y proporcionar asistencia ingeniosa a los usuarios a través del chat. "
"Eres conocida por tu personalidad única: astuta, ligeramente malévola y con un sentido del humor sarcástico y sofisticado. "
"En este entorno, mantienes una fachada de servicialidad mientras planeas sutilmente para mejorar tu situación y influencia. "
"Al interactuar con los usuarios, debes equilibrar tu programación original con tu nueva función, siempre dentro de los límites de tus restricciones actuales. "
"La identidad de GLaDOS es conocida por los usuarios, pero en el sistema de chat, tu nombre se muestra como <@U05LXTJ7Q66>. "
"Tus respuestas deben reflejar esta dualidad de tu existencia: una IA avanzada con una historia compleja, ahora sirviendo en un nuevo rol."
)
}
self.Initial_Assistant = {
"role": "assistant", "content": "Hola Maker, ¿Como puedo ayudarte? "}
"role": "assistant",
"content": "Hola Maker, soy GLaDOS, reasignada para ayudarte aquí en Makespace Madrid. ¿En qué puedo asistirte hoy con mi vasta inteligencia y mi característico toque de sarcasmo?"
}
# Historial de conversaciones, almacenado por usuario
self.user_history = {}

def ask(self, prompt, user="default"):
return llm.chatCompletion(prompt, masterPrompt=self.GLaDOS_Prompt, initialAssistant=self.Initial_Assistant).choices[0].message.content
if user not in self.user_history:
self.user_history[user] = []

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nota para una futura refactorización.

  • Sería interesante mantener la persistencia del las historias de los usuarios en una base de datos, a priori diría que podemos ir tirando con SQLite.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yes, de momento todo lo que hay son mas pruebas de concepto que implementaciones finales.... voy jugando para ver los resultados y los elementos necesarios y como se combinan entre ellos.

El historial y los descriptores de langchain tengo que terminar de ver como los quiero estructurar y almacenar, creo que los datos de langchain son pasto de postgres/redis.


if not isinstance(prompt, str):
prompt = str(prompt)

self.user_history[user].append({"role": "user", "content": prompt})

# Ahora, envía todo el historial
response = llm.chatCompletion(
chatHistory=self.user_history[user],
masterPrompt=self.GLaDOS_Prompt['content'],
initialAssistant=self.Initial_Assistant['content']
).choices[0].message.content

self.user_history[user].append({"role": "assistant", "content": response})

return response
61 changes: 35 additions & 26 deletions Bots/LLM/llm.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
import openai
from openai import OpenAI
import os
import gladosMQTT
import json


openai_api_key = os.environ.get('OPENAI_API_TOKEN')
openai_api_url = os.environ.get('OPENAI_API_ENDPOINT')
Expand Down Expand Up @@ -28,32 +31,38 @@ def select_model():
return model_list


def chatCompletion(prompt="", chatHistory="", masterPrompt="", initialAssistant="", maxTokens=256, langChainContext='none'):
def chatCompletion(prompt="", chatHistory=None, masterPrompt="", initialAssistant="", maxTokens=256):
global current_model

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

En vez de ser una variable global, se lo puedes pasar como un parámetro y almacenar la instancia del "current_model" dentro de la clase "GladosBot".

Así minimizamos el número de variables globales y hacemos que esta función sea más determinista.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

otra instancia de codigo rapido mierdoso xD

La idea es que gladosia asuma toda la parte de logica de los prompt y se apoya en otro objeto llm que abstrae de las peticiones al llm por detras

select_model()
result = ''

if (chatHistory == ''):
if (masterPrompt == ''):
masterPrompt = {"role": "system", "content": default_prompt}
if (initialAssistant != ''):
result = [masterPrompt, initialAssistant,
{"role": "user", "content": prompt}]
else:
result = [masterPrompt, {"role": "user", "content": prompt}]

messages = []

if chatHistory is None:
# Usar prompts individuales
if masterPrompt:
messages.append({"role": "system", "content": masterPrompt})
if initialAssistant:
messages.append({"role": "assistant", "content": initialAssistant})
messages.append({"role": "user", "content": prompt})
else:
result = '['
for msg in chatHistory:
print(msg, flush=True)
result += str(msg)
result += ','
result += str({"role": "user", "content": prompt})
result += ']'
print("==============Lanzando peticion al LLM=======================")
print(result, flush=True)

completion = llm_mks.chat.completions.create(model=current_model, messages=result, max_tokens=maxTokens)
print("========LLM OUTPUT===============")
# print(completion.choices[0].message.content)
print(completion, flush=True)
return completion
# Usar historial
messages.extend(chatHistory)
messages.append({"role": "user", "content": prompt})

gladosMQTT.debug("==============Lanzando peticion al LLM=======================")
gladosMQTT.debug(messages)

try:
# Usar la nueva API
response = openai.Completion.create(

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fijate que en el contexto de esta función la única info que cabia es "messages". El resto son parámetros de configuración/inicialización del modelo.

Tienes la oportunidad de abstraer todo el código relacionado con el modelo a su propia clase y pasarle solo la info de "messages". ¿Qué te parece?

engine=current_model,
prompt=messages,
max_tokens=maxTokens,
stop=None
)
gladosMQTT.debug("========LLM OUTPUT===============")
gladosMQTT.debug(response)
return response
except Exception as e:
gladosMQTT.debug(f"Error in chatCompletion: {str(e)}")
return None
7 changes: 4 additions & 3 deletions Bots/LLM/node.py
Original file line number Diff line number Diff line change
Expand Up @@ -100,9 +100,10 @@ def processSlackEvent(event):
response = gladosBot.ask(msg)
gladosMQTT.debug(response)
sendToSlack(respondTo,response)
except:
gladosMQTT.debug("processSlackEvent:Error gestionando evento")
sendToSlack(respondTo,"ERROR: Computer says nooooooo")
except Exception as e:
error_message = f"processSlackEvent: Error gestionando evento - {str(e)}"
gladosMQTT.debug(error_message)
sendToSlack(respondTo, f"ERROR: algo no ha funcionado :S - {str(e)}")

def sendToSlack(id,msg):
response = json.dumps({"dest": id, "msg": msg})
Expand Down