Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Get Response from LLM on demand #44

Merged
merged 3 commits into from
Jul 28, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
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
34 changes: 24 additions & 10 deletions GPTResponder.py
Original file line number Diff line number Diff line change
@@ -1,20 +1,20 @@
import openai
import datetime
import time
import GlobalVars
import prompts
import time
import openai
import conversation
import constants
import configuration
import app_logging as al


# Number of phrases to use for generating a response
MAX_PHRASES = 20
root_logger = al.get_logger()


class GPTResponder:
"""Handles all interactions with openAI LLM / ChatGPT
"""
def __init__(self, convo: conversation.Conversation):
root_logger.info(GPTResponder.__name__)
self.response = prompts.INITIAL_RESPONSE
Expand All @@ -25,12 +25,16 @@ def __init__(self, convo: conversation.Conversation):
self.config = configuration.Config().get_data()
self.model = self.config['OpenAI']['ai_model']

def generate_response_from_transcript_no_check(self, transcript):
def generate_response_from_transcript_no_check(self, transcript) -> str:
"""Ping LLM to get a suggested response right away.
Gets a response even if the continuous suggestion option is disabled.
"""
try:
# prompt_content = create_prompt(transcript)
# prompt_api_message = [{"role": "system", "content": prompt_content}]
prompt_api_message = prompts.create_single_turn_prompt_message(transcript)
multiturn_prompt_content = self.conversation.get_merged_conversation(length=MAX_PHRASES)
multiturn_prompt_content = self.conversation.get_merged_conversation(
length=constants.MAX_TRANSCRIPTION_PHRASES_FOR_LLM)
multiturn_prompt_api_message = prompts.create_multiturn_prompt(multiturn_prompt_content)
# print(f'Usual prompt api message: {prompt_api_message}')
# print(f'Multiturn prompt: {multiturn_prompt_api_message}')
Expand All @@ -42,12 +46,17 @@ def generate_response_from_transcript_no_check(self, transcript):

except Exception as exception:
print(exception)
return ''
root_logger.error('Error when attempting to get a response from LLM.')
abhinavuppal1 marked this conversation as resolved.
Show resolved Hide resolved
root_logger.exception(exception)
return prompts.INITIAL_RESPONSE

usual_full_response = usual_response.choices[0].message.content
try:
return usual_full_response.split('[')[1].split(']')[0]
except:
return ''
except Exception as exception:
root_logger.error('Error parsing response from LLM.')
root_logger.exception(exception)
return prompts.INITIAL_RESPONSE

def generate_response_from_transcript(self, transcript):
"""Ping OpenAI LLM model to get response from the Assistant
Expand All @@ -59,13 +68,16 @@ def generate_response_from_transcript(self, transcript):
return self.generate_response_from_transcript_no_check(transcript)

def respond_to_transcriber(self, transcriber):
"""Thread method to continously update the transcript
"""
while True:

if transcriber.transcript_changed_event.is_set():
start_time = time.time()

transcriber.transcript_changed_event.clear()
transcript_string = transcriber.get_transcript(length=MAX_PHRASES)
transcript_string = transcriber.get_transcript(
abhinavuppal1 marked this conversation as resolved.
Show resolved Hide resolved
length=constants.MAX_TRANSCRIPTION_PHRASES_FOR_LLM)
response = self.generate_response_from_transcript(transcript_string)

end_time = time.time() # Measure end time
Expand All @@ -84,5 +96,7 @@ def respond_to_transcriber(self, transcriber):
time.sleep(0.3)

def update_response_interval(self, interval):
"""Change the interval for pinging LLM
"""
root_logger.info(GPTResponder.update_response_interval.__name__)
self.response_interval = interval
6 changes: 5 additions & 1 deletion GlobalVars.py
Original file line number Diff line number Diff line change
@@ -1,13 +1,15 @@
import queue
import tkinter as tk
import customtkinter as ctk
from AudioTranscriber import AudioTranscriber
import AudioRecorder
import customtkinter as ctk
import Singleton
import app_logging as al


root_logger = al.get_logger()


class TranscriptionGlobals(Singleton.Singleton):
"""Global constants for audio processing. It is implemented as a Singleton class.
"""
Expand All @@ -23,6 +25,8 @@ class TranscriptionGlobals(Singleton.Singleton):
freeze_state: list = None
freeze_button: ctk.CTkButton = None
api_key: str = None
filemenu: tk.Menu = None
response_textbox: ctk.CTkTextbox = None

def __init__(self, key: str = 'API_KEY'):
root_logger.info(TranscriptionGlobals.__name__)
Expand Down
1 change: 1 addition & 0 deletions constants.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,3 +7,4 @@
PERSONA_SPEAKER = 'Speaker'

LOG_NAME = 'Transcribe'
MAX_TRANSCRIPTION_PHRASES_FOR_LLM = 20
9 changes: 7 additions & 2 deletions main.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,12 @@
import argparse
from argparse import RawTextHelpFormatter
import time
import requests
import subprocess
import requests
from requests.exceptions import ConnectionError
import customtkinter as ctk
from AudioTranscriber import AudioTranscriber
from GPTResponder import GPTResponder
import customtkinter as ctk
import TranscriberModels
import interactions
import ui
Expand Down Expand Up @@ -96,7 +96,11 @@ def main():
update_interval_slider_label = ui_components[3]
global_vars.freeze_button = ui_components[4]
lang_combobox = ui_components[5]
filemenu = ui_components[6]
response_now_button = ui_components[7]

global_vars.filemenu = filemenu
global_vars.response_textbox = response_textbox
global_vars.user_audio_recorder.record_into_queue(global_vars.audio_queue)

time.sleep(2)
Expand Down Expand Up @@ -135,6 +139,7 @@ def main():

ui_cb = ui.ui_callbacks()
global_vars.freeze_button.configure(command=ui_cb.freeze_unfreeze)
response_now_button.configure(command=ui_cb.update_response_ui_now)
label_text = f'Update Response interval: {update_interval_slider.get()} seconds'
update_interval_slider_label.configure(text=label_text)

Expand Down
36 changes: 28 additions & 8 deletions ui.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
import GlobalVars
import GPTResponder
import app_logging as al
import constants


root_logger = al.get_logger()
Expand Down Expand Up @@ -40,15 +41,28 @@ def freeze_unfreeze(self):
root_logger.info(ui_callbacks.freeze_unfreeze.__name__)
self.global_vars.freeze_state[0] = not self.global_vars.freeze_state[0] # Invert the state
self.global_vars.freeze_button.configure(
text="Suggest Response" if self.global_vars.freeze_state[0] else "Do Not Suggest Response"
text="Suggest Responses Continuously" if self.global_vars.freeze_state[0] else "Do Not Suggest Responses Continuously"
)

def update_response_ui_now(self):
"""Get response from LLM right away"""
transcript_string = self.global_vars.transcriber.get_transcript(
length=constants.MAX_TRANSCRIPTION_PHRASES_FOR_LLM)

response_string = self.global_vars.responder.generate_response_from_transcript_no_check(transcript_string)
self.global_vars.response_textbox.configure(state="normal")
write_in_textbox(self.global_vars.response_textbox, response_string)
self.global_vars.response_textbox.configure(state="disabled")

def set_transcript_state(self):
"""Enables, disables transcription.
Text of menu item File -> Pause Transcription toggles accordingly"""
root_logger.info(ui_callbacks.set_transcript_state.__name__)
self.global_vars.transcriber.transcribe = not self.global_vars.transcriber.transcribe
self.global_vars.transcript_button.configure(
text="Pause Transcript" if self.global_vars.transcriber.transcribe else "Start Transcript"
)
if self.global_vars.transcriber.transcribe:
self.global_vars.filemenu.entryconfigure(1, label="Pause Transcription")
else:
self.global_vars.filemenu.entryconfigure(1, label="Start Transcription")


def write_in_textbox(textbox: ctk.CTkTextbox, text: str):
Expand Down Expand Up @@ -99,7 +113,7 @@ def update_response_ui(responder: GPTResponder,
freeze_state)


def clear_transcriber_context(transcriber: AudioTranscriber,
def clear_transcriber_context(transcriber: AudioTranscriber,
audio_queue: queue.Queue):
"""Reset the transcriber
Args:
Expand Down Expand Up @@ -151,6 +165,8 @@ def create_ui_components(root):
# Add a "Copy To Clipboard" menu item to the file menu
editmenu.add_command(label="Copy Transcript to Clipboard", command=ui_cb.copy_to_clipboard)

# See example of add_radiobutton() at https://www.plus2net.com/python/tkinter-menu.php
# Radiobutton would be a good way to display different languages
# lang_menu = tk.Menu(menubar, tearoff=False)
# for lang in LANGUAGES_DICT.values():
# model.change_lang
Expand All @@ -172,9 +188,12 @@ def create_ui_components(root):
response_textbox.grid(row=0, column=1, padx=10, pady=20, sticky="nsew")
response_textbox.insert("0.0", prompts.INITIAL_RESPONSE)

freeze_button = ctk.CTkButton(root, text="Suggest Response", command=None)
freeze_button = ctk.CTkButton(root, text="Suggest Responses Continuously", command=None)
freeze_button.grid(row=1, column=1, padx=10, pady=3, sticky="nsew")

response_now_button = ctk.CTkButton(root, text="Suggest Responses Now", command=None)
response_now_button.grid(row=2, column=1, padx=10, pady=3, sticky="nsew")

update_interval_slider_label = ctk.CTkLabel(root, text="", font=("Arial", 12),
text_color="#FFFCF2")
update_interval_slider_label.grid(row=1, column=0, padx=10, pady=3, sticky="nsew")
Expand All @@ -185,9 +204,10 @@ def create_ui_components(root):
update_interval_slider.grid(row=2, column=0, padx=10, pady=10, sticky="nsew")

lang_combobox = ctk.CTkOptionMenu(root, values=list(LANGUAGES_DICT.values()))
lang_combobox.grid(row=2, column=1, padx=200, pady=10, sticky="nsew")
lang_combobox.grid(row=3, column=0, padx=200, pady=10, sticky="nsew")

# Order of returned components is important.
# Add new components to the end
return [transcript_textbox, response_textbox, update_interval_slider,
update_interval_slider_label, freeze_button, lang_combobox]
update_interval_slider_label, freeze_button, lang_combobox,
filemenu, response_now_button]