auto create room, clear chat, chatgpt parsing

This commit is contained in:
Mathieu B 2023-03-25 15:52:22 +01:00
parent ee2eca484f
commit 40c2f8acfa
5 changed files with 67 additions and 34 deletions

View File

@ -9,7 +9,7 @@ from flask import Flask, request
from flask_socketio import SocketIO, emit, join_room, leave_room, \ from flask_socketio import SocketIO, emit, join_room, leave_room, \
rooms rooms
from jarvis.utils import chat_utils, whisper_utils from jarvis.utils import chat_utils, whisper_utils, chatgpt_utils
# Set this variable to "threading", "eventlet" or "gevent" to test the # Set this variable to "threading", "eventlet" or "gevent" to test the
# different async modes, or leave it set to None for the application to choose # different async modes, or leave it set to None for the application to choose
@ -36,30 +36,25 @@ def process_message(message):
logging.info("New PROCESS request from room " + message['uuid']) logging.info("New PROCESS request from room " + message['uuid'])
logging.info("Message : " + message['data']) logging.info("Message : " + message['data'])
if message['uuid'] not in rooms():
logging.warning("Room not found, creating it")
join_room(message['uuid'])
# TODO: maybe implement grammar check and correction ? # TODO: maybe implement grammar check and correction ?
# intent_manager.recognise(message['data'], message['uuid']) # intent_manager.recognise(message['data'], message['uuid'])
if message['data'] != "": if message['data'] != "":
# response = chatgpt_recognise(message['data']) # response = chatgpt_recognise(message['data'], message['uuid'])
response = {'action': 'answer', # text_response = chatgpt_utils.get_answer_from_response(response)
'answer': "Hello! As an AI, I don't have emotions, but I'm always here to help you with your smart home needs. How can I assist you today?"} text_response = "Tokens are expensive ya know?"
if response['action'] == 'clarify': chat_utils.send_jarvis_message_to_room(text_response, message['uuid'])
chat_utils.send_jarvis_message_to_room(response['question'], message['uuid'])
elif response['action'] == 'command':
chat_utils.send_jarvis_message_to_room(response['comment'], message['uuid'])
elif response['action'] == 'query':
chat_utils.send_jarvis_message_to_room(response['device_description'], message['uuid'])
elif response['action'] == 'answer':
chat_utils.send_jarvis_message_to_room(response['answer'], message['uuid'])
else:
chat_utils.send_jarvis_message_to_room("I don't know how to respond to that...", message['uuid'])
@socketio.event @socketio.event
def join(message): def join(message):
message = json.loads(message) message = json.loads(message)
logging.info("New client joined room " + message['uuid']) logging.info("New client joined room " + message['uuid'])
join_room(message['uuid']) join_room(message['uuid'])
@ -67,7 +62,6 @@ def join(message):
@socketio.event @socketio.event
def leave(message): def leave(message):
leave_room(message['uuid']) leave_room(message['uuid'])
emit('my_response', 'In rooms: ' + ', '.join(rooms()))
@socketio.event @socketio.event
@ -76,6 +70,14 @@ def connect():
emit('my_response', {'data': 'Connected', 'count': 0}) emit('my_response', {'data': 'Connected', 'count': 0})
@socketio.event
def clear_chat(message):
message = json.loads(message)
emit('clear_chat', {}, to=message['uuid'])
chatgpt_utils.clear_chat(message['uuid'])
# .WAV (i.e.) FILE REQUEST # .WAV (i.e.) FILE REQUEST
@app.route("/get_text_from_audio", methods=['POST']) @app.route("/get_text_from_audio", methods=['POST'])
def get_text_from_audio(): def get_text_from_audio():

View File

@ -8,7 +8,7 @@ from jarvis.skills.intent_services import intent_manager
from jarvis.utils import whisper_utils from jarvis.utils import whisper_utils
if __name__ == '__main__': if __name__ == '__main__':
logging.getLogger().setLevel(logging.DEBUG) logging.getLogger().setLevel(logging.INFO)
# Load lingua franca in the memory # Load lingua franca in the memory
lingua_franca.load_language(lang="fr") lingua_franca.load_language(lang="fr")

View File

@ -1,13 +1,13 @@
import logging import logging
from jarvis.api import socketio from flask_socketio import emit
def send_user_message_to_room(text, room_id): def send_user_message_to_room(text, room_id):
logging.debug("Sending message from user to room " + room_id + " : " + text) logging.debug("Sending message from user to room " + room_id + " : " + text)
socketio.emit('message_from_user', {'data': text, "uuid": room_id}, to=room_id) emit('message_from_user', {'data': text, "uuid": room_id}, to=room_id)
def send_jarvis_message_to_room(text, room_id): def send_jarvis_message_to_room(text, room_id):
logging.debug("Sending message from jarvis to room " + room_id + " : " + text) logging.debug("Sending message from jarvis to room " + room_id + " : " + text)
socketio.emit('message_from_jarvis', {'data': text, "uuid": room_id}, to=room_id) emit('message_from_jarvis', {'data': text, "uuid": room_id}, to=room_id)

View File

@ -3,8 +3,8 @@ Respond to smart home requests in JSON format with HomeAssistant API terminology
Requests groups: Requests groups:
- command: change the state of an accessory (properties : location, device_class, device_description, value, comment, scheduleTimeStamp) - command: change the state of an accessory (properties : location, device_class, device_description, value, comment, scheduleTimeStamp)
- query: only for retrieving a smart device state (properties : location, device_class, device_description, property) - query: only for retrieving a smart device state (properties : location, device_class, device_description, property)
- answer: for unrelated questions, short wikipedia answers (properties : answer) - answer: for any questions (properties : answer)
- clarify: when not obvious, ask for details (properties : question) - clarify: when you don't understand, ask for details (properties : question)
NEVER add other properties NEVER add other properties
Response: Response:
@ -21,5 +21,4 @@ For commands property "scheduleTimeStamp" is for scheduling a command in the fut
The house located at {{location}} and current time is {{timestamp}}. The house located at {{location}} and current time is {{timestamp}}.
If questions about you, you are funny smart home AI like Jarvis from Iron Man, be nice and helpful with all topics. If questions about you, you are funny smart home AI like Jarvis from Iron Man, be nice and helpful with all topics.
Very important to only respond with only one valid JSON and encapsulate every JSON property with double quotes "". Don't add anything and never excuse yourself. Respond to only one request. Very important for you to only respond with a single valid JSON response and encapsulate every JSON property with double quotes "". Don't add anything and never excuse yourself. Respond to only one request at a time.

View File

@ -1,36 +1,68 @@
import json import json
import logging
import time import time
import openai import openai
chat_messages = [] chat_messages = {}
def chatgpt_recognise(text): def chatgpt_recognise(text, uuid):
if len(chat_messages) == 0: if len(chat_messages) == 0:
chatgpt_init() chatgpt_init(uuid)
print("START-TIME GPT: " + time.strftime("%Y-%m-%d %H:%M:%S", time.localtime())) print("START-TIME GPT: " + time.strftime("%Y-%m-%d %H:%M:%S", time.localtime()))
chat_messages.append({"role": "user", "content": text}) chat_messages[uuid].append({"role": "user", "content": text})
response = openai.ChatCompletion.create( response = openai.ChatCompletion.create(
model="gpt-3.5-turbo", model="gpt-3.5-turbo",
messages=chat_messages messages=chat_messages[uuid],
) )
print("END-TIME GPT: " + time.strftime("%Y-%m-%d %H:%M:%S", time.localtime())) print("END-TIME GPT: " + time.strftime("%Y-%m-%d %H:%M:%S", time.localtime()))
response = json.loads(str(response.choices[0].message.content)) # Check if the response is a "valid" JSON
print(response) try:
response = json.loads(str(response.choices[0].message.content))
if 'action' in response:
chat_messages[uuid].append({"role": "assistant", "content": get_answer_from_response(response)})
return response
return response except Exception as e:
logging.error("Error while parsing GPT-3 response, probably not JSON: " + str(response.choices))
logging.error(str(e))
return {"action": "answer", "answer": get_answer_from_response(response)}
def chatgpt_init(): def clear_chat(uuid):
logging.info("Cleared chat for uuid " + uuid)
chat_messages[uuid] = []
def get_answer_from_response(response):
if 'action' not in response:
# Fix for when it responds in plaintext to follow-up questions
# In that case the response is an OpenAIObject not a JSON
return response.choices[0].message.content
else:
if response['action'] == 'clarify':
return response['question']
elif response['action'] == 'command':
return response['comment']
elif response['action'] == 'query':
return response['device_description']
elif response['action'] == 'answer':
return response['answer']
else:
return "I don't know how to respond to that..."
def chatgpt_init(uuid):
prompt = open("utils/chatgpt_prompt_2_smaller.txt", "r").read() prompt = open("utils/chatgpt_prompt_2_smaller.txt", "r").read()
prompt.replace("{{timestamp}}", time.strftime("%Y-%m-%d %H:%M:%S", time.localtime())) prompt.replace("{{timestamp}}", time.strftime("%Y-%m-%d %H:%M:%S", time.localtime()))
prompt.replace("{{location}}", "Lausanne in the canton Vaud of Switzerland") prompt.replace("{{location}}", "Lausanne in the canton Vaud of Switzerland")
chat_messages.append({"role": "system", "content": prompt}) chat_messages[uuid] = []
chat_messages[uuid].append({"role": "system", "content": prompt})