projekt-rising-ai's picture
Added talking head functionality back in
dfc3ca7
raw
history blame
71.4 kB
import io
import os
import ssl
from contextlib import closing
from typing import Optional, Tuple
import datetime
import boto3
import gradio as gr
import requests
# UNCOMMENT TO USE WHISPER
import warnings
import whisper
from langchain import ConversationChain, LLMChain
from langchain.agents import load_tools, initialize_agent
from langchain.chains.conversation.memory import ConversationBufferMemory
from langchain.llms import OpenAI
from threading import Lock
# Console to variable
from io import StringIO
import sys
import re
from openai.error import AuthenticationError, InvalidRequestError, RateLimitError
# Pertains to Express-inator functionality
from langchain.prompts import PromptTemplate
from polly_utils import PollyVoiceData, NEURAL_ENGINE
from azure_utils import AzureVoiceData
# Pertains to question answering functionality
from langchain.embeddings.openai import OpenAIEmbeddings
from langchain.text_splitter import CharacterTextSplitter
from langchain.vectorstores.faiss import FAISS
from langchain.docstore.document import Document
from langchain.chains.question_answering import load_qa_chain
news_api_key = os.environ["NEWS_API_KEY"]
tmdb_bearer_token = os.environ["TMDB_BEARER_TOKEN"]
TOOLS_LIST = ['serpapi', 'wolfram-alpha', 'pal-math', 'pal-colored-objects']
# TOOLS_DEFAULT_LIST = ['serpapi', 'pal-math']
TOOLS_DEFAULT_LIST = []
BUG_FOUND_MSG = "Congratulations, you've found a bug in this application!"
# AUTH_ERR_MSG = "Please paste your OpenAI key from openai.com to use this application. It is not necessary to hit a button or key after pasting it."
AUTH_ERR_MSG = "Please paste your OpenAI key from openai.com to use this application. "
MAX_TOKENS = 512
LOOPING_TALKING_HEAD = "videos/Marc.mp4"
TALKING_HEAD_WIDTH = "192"
MAX_TALKING_HEAD_TEXT_LENGTH = 155
# Pertains to Express-inator functionality
NUM_WORDS_DEFAULT = 0
MAX_WORDS = 400
FORMALITY_DEFAULT = "N/A"
TEMPERATURE_DEFAULT = 0.5
EMOTION_DEFAULT = "N/A"
LANG_LEVEL_DEFAULT = "N/A"
TRANSLATE_TO_DEFAULT = "N/A"
LITERARY_STYLE_DEFAULT = "N/A"
PROMPT_TEMPLATE = PromptTemplate(
input_variables=["original_words", "num_words", "formality", "emotions", "lang_level", "translate_to",
"literary_style"],
template="Restate {num_words}{formality}{emotions}{lang_level}{translate_to}{literary_style}the following: \n{original_words}\n",
)
POLLY_VOICE_DATA = PollyVoiceData()
AZURE_VOICE_DATA = AzureVoiceData()
# Pertains to WHISPER functionality
WHISPER_DETECT_LANG = "Detect language"
# UNCOMMENT TO USE WHISPER
warnings.filterwarnings("ignore")
WHISPER_MODEL = whisper.load_model("tiny")
print("WHISPER_MODEL", WHISPER_MODEL)
# UNCOMMENT TO USE WHISPER
def transcribe(aud_inp, whisper_lang):
if aud_inp is None:
return ""
aud = whisper.load_audio(aud_inp)
aud = whisper.pad_or_trim(aud)
mel = whisper.log_mel_spectrogram(aud).to(WHISPER_MODEL.device)
_, probs = WHISPER_MODEL.detect_language(mel)
options = whisper.DecodingOptions()
if whisper_lang != WHISPER_DETECT_LANG:
whisper_lang_code = POLLY_VOICE_DATA.get_whisper_lang_code(whisper_lang)
options = whisper.DecodingOptions(language=whisper_lang_code)
result = whisper.decode(WHISPER_MODEL, mel, options)
print("result.text", result.text)
result_text = ""
if result and result.text:
result_text = result.text
return result_text
# Temporarily address Wolfram Alpha SSL certificate issue
ssl._create_default_https_context = ssl._create_unverified_context
# TEMPORARY FOR TESTING
def transcribe_dummy(aud_inp_tb, whisper_lang):
if aud_inp_tb is None:
return ""
# aud = whisper.load_audio(aud_inp)
# aud = whisper.pad_or_trim(aud)
# mel = whisper.log_mel_spectrogram(aud).to(WHISPER_MODEL.device)
# _, probs = WHISPER_MODEL.detect_language(mel)
# options = whisper.DecodingOptions()
# options = whisper.DecodingOptions(language="ja")
# result = whisper.decode(WHISPER_MODEL, mel, options)
result_text = "Whisper will detect language"
if whisper_lang != WHISPER_DETECT_LANG:
whisper_lang_code = POLLY_VOICE_DATA.get_whisper_lang_code(whisper_lang)
result_text = f"Whisper will use lang code: {whisper_lang_code}"
print("result_text", result_text)
return aud_inp_tb
# Pertains to Express-inator functionality
def transform_text(desc, express_chain, num_words, formality,
anticipation_level, joy_level, trust_level,
fear_level, surprise_level, sadness_level, disgust_level, anger_level,
lang_level, translate_to, literary_style):
num_words_prompt = ""
if num_words and int(num_words) != 0:
num_words_prompt = "using up to " + str(num_words) + " words, "
# Change some arguments to lower case
formality = formality.lower()
anticipation_level = anticipation_level.lower()
joy_level = joy_level.lower()
trust_level = trust_level.lower()
fear_level = fear_level.lower()
surprise_level = surprise_level.lower()
sadness_level = sadness_level.lower()
disgust_level = disgust_level.lower()
anger_level = anger_level.lower()
formality_str = ""
if formality != "n/a":
formality_str = "in a " + formality + " manner, "
# put all emotions into a list
emotions = []
if anticipation_level != "n/a":
emotions.append(anticipation_level)
if joy_level != "n/a":
emotions.append(joy_level)
if trust_level != "n/a":
emotions.append(trust_level)
if fear_level != "n/a":
emotions.append(fear_level)
if surprise_level != "n/a":
emotions.append(surprise_level)
if sadness_level != "n/a":
emotions.append(sadness_level)
if disgust_level != "n/a":
emotions.append(disgust_level)
if anger_level != "n/a":
emotions.append(anger_level)
emotions_str = ""
if len(emotions) > 0:
if len(emotions) == 1:
emotions_str = "with emotion of " + emotions[0] + ", "
else:
emotions_str = "with emotions of " + ", ".join(emotions[:-1]) + " and " + emotions[-1] + ", "
lang_level_str = ""
if lang_level != LANG_LEVEL_DEFAULT:
lang_level_str = "at a " + lang_level + " level, " if translate_to == TRANSLATE_TO_DEFAULT else ""
translate_to_str = ""
if translate_to != TRANSLATE_TO_DEFAULT:
translate_to_str = "translated to " + (
"" if lang_level == TRANSLATE_TO_DEFAULT else lang_level + " level ") + translate_to + ", "
literary_style_str = ""
if literary_style != LITERARY_STYLE_DEFAULT:
if literary_style == "Prose":
literary_style_str = "as prose, "
if literary_style == "Story":
literary_style_str = "as a story, "
elif literary_style == "Summary":
literary_style_str = "as a summary, "
elif literary_style == "Outline":
literary_style_str = "as an outline numbers and lower case letters, "
elif literary_style == "Bullets":
literary_style_str = "as bullet points using bullets, "
elif literary_style == "Poetry":
literary_style_str = "as a poem, "
elif literary_style == "Haiku":
literary_style_str = "as a haiku, "
elif literary_style == "Limerick":
literary_style_str = "as a limerick, "
elif literary_style == "Rap":
literary_style_str = "as a rap, "
elif literary_style == "Joke":
literary_style_str = "as a very funny joke with a setup and punchline, "
elif literary_style == "Knock-knock":
literary_style_str = "as a very funny knock-knock joke, "
elif literary_style == "FAQ":
literary_style_str = "as a FAQ with several questions and answers, "
formatted_prompt = PROMPT_TEMPLATE.format(
original_words=desc,
num_words=num_words_prompt,
formality=formality_str,
emotions=emotions_str,
lang_level=lang_level_str,
translate_to=translate_to_str,
literary_style=literary_style_str
)
trans_instr = num_words_prompt + formality_str + emotions_str + lang_level_str + translate_to_str + literary_style_str
if express_chain and len(trans_instr.strip()) > 0:
generated_text = express_chain.run(
{'original_words': desc, 'num_words': num_words_prompt, 'formality': formality_str,
'emotions': emotions_str, 'lang_level': lang_level_str, 'translate_to': translate_to_str,
'literary_style': literary_style_str}).strip()
else:
print("Not transforming text")
generated_text = desc
# replace all newlines with <br> in generated_text
generated_text = generated_text.replace("\n", "\n\n")
prompt_plus_generated = "GPT prompt: " + formatted_prompt + "\n\n" + generated_text
print("\n==== date/time: " + str(datetime.datetime.now() - datetime.timedelta(hours=5)) + " ====")
print("prompt_plus_generated: " + prompt_plus_generated)
return generated_text
def load_chain(tools_list, llm):
chain = None
express_chain = None
memory = None
if llm:
print("\ntools_list", tools_list)
tool_names = tools_list
tools = load_tools(tool_names, llm=llm, news_api_key=news_api_key, tmdb_bearer_token=tmdb_bearer_token, serpapi_api_key=os.environ["SERP_API_KEY"])
memory = ConversationBufferMemory(memory_key="chat_history")
chain = initialize_agent(tools, llm, agent="conversational-react-description", verbose=True, memory=memory)
express_chain = LLMChain(llm=llm, prompt=PROMPT_TEMPLATE, verbose=True)
return chain, express_chain, memory
def set_openai_api_key(api_key):
"""Set the api key and return chain.
If no api_key, then None is returned.
"""
if api_key and api_key.startswith("sk-") and len(api_key) > 50:
os.environ["OPENAI_API_KEY"] = api_key
print("\n\n ++++++++++++++ Setting OpenAI API key ++++++++++++++ \n\n")
print(str(datetime.datetime.now()) + ": Before OpenAI, OPENAI_API_KEY length: " + str(
len(os.environ["OPENAI_API_KEY"])))
llm = OpenAI(temperature=0, max_tokens=MAX_TOKENS)
print(str(datetime.datetime.now()) + ": After OpenAI, OPENAI_API_KEY length: " + str(
len(os.environ["OPENAI_API_KEY"])))
chain, express_chain, memory = load_chain(TOOLS_DEFAULT_LIST, llm)
# Pertains to question answering functionality
embeddings = OpenAIEmbeddings()
qa_chain = load_qa_chain(OpenAI(temperature=0), chain_type="stuff")
print(str(datetime.datetime.now()) + ": After load_chain, OPENAI_API_KEY length: " + str(
len(os.environ["OPENAI_API_KEY"])))
os.environ["OPENAI_API_KEY"] = ""
return chain, express_chain, llm, embeddings, qa_chain, memory
return None, None, None, None, None, None
def run_chain(chain, inp, capture_hidden_text):
output = ""
hidden_text = None
if capture_hidden_text:
error_msg = None
tmp = sys.stdout
hidden_text_io = StringIO()
sys.stdout = hidden_text_io
try:
output = chain.run(input=inp)
except AuthenticationError as ae:
error_msg = AUTH_ERR_MSG + str(datetime.datetime.now()) + ". " + str(ae)
print("error_msg", error_msg)
except RateLimitError as rle:
error_msg = "\n\nRateLimitError: " + str(rle)
except ValueError as ve:
error_msg = "\n\nValueError: " + str(ve)
except InvalidRequestError as ire:
error_msg = "\n\nInvalidRequestError: " + str(ire)
except Exception as e:
error_msg = "\n\n" + BUG_FOUND_MSG + ":\n\n" + str(e)
sys.stdout = tmp
hidden_text = hidden_text_io.getvalue()
# remove escape characters from hidden_text
hidden_text = re.sub(r'\x1b[^m]*m', '', hidden_text)
# remove "Entering new AgentExecutor chain..." from hidden_text
hidden_text = re.sub(r"Entering new AgentExecutor chain...\n", "", hidden_text)
# remove "Finished chain." from hidden_text
hidden_text = re.sub(r"Finished chain.", "", hidden_text)
# Add newline after "Thought:" "Action:" "Observation:" "Input:" and "AI:"
hidden_text = re.sub(r"Thought:", "\n\nThought:", hidden_text)
hidden_text = re.sub(r"Action:", "\n\nAction:", hidden_text)
hidden_text = re.sub(r"Observation:", "\n\nObservation:", hidden_text)
hidden_text = re.sub(r"Input:", "\n\nInput:", hidden_text)
hidden_text = re.sub(r"AI:", "\n\nAI:", hidden_text)
if error_msg:
hidden_text += error_msg
print("hidden_text: ", hidden_text)
else:
try:
output = chain.run(input=inp)
except AuthenticationError as ae:
output = AUTH_ERR_MSG + str(datetime.datetime.now()) + ". " + str(ae)
print("output", output)
except RateLimitError as rle:
output = "\n\nRateLimitError: " + str(rle)
except ValueError as ve:
output = "\n\nValueError: " + str(ve)
except InvalidRequestError as ire:
output = "\n\nInvalidRequestError: " + str(ire)
except Exception as e:
output = "\n\n" + BUG_FOUND_MSG + ":\n\n" + str(e)
return output, hidden_text
def reset_memory(history, memory):
memory.clear()
history = []
return history, history, memory
class ChatWrapper:
def __init__(self):
self.lock = Lock()
def __call__(
self, api_key: str, inp: str, history: Optional[Tuple[str, str]], chain: Optional[ConversationChain],
trace_chain: bool, speak_text: bool, talking_head: bool, monologue: bool, express_chain: Optional[LLMChain],
num_words, formality, anticipation_level, joy_level, trust_level,
fear_level, surprise_level, sadness_level, disgust_level, anger_level,
lang_level, translate_to, literary_style, qa_chain, docsearch, use_embeddings
):
"""Execute the chat functionality."""
self.lock.acquire()
try:
print("\n==== date/time: " + str(datetime.datetime.now()) + " ====")
print("inp: " + inp)
print("trace_chain: ", trace_chain)
print("speak_text: ", speak_text)
print("talking_head: ", talking_head)
print("monologue: ", monologue)
history = history or []
# If chain is None, that is because no API key was provided.
output = "Please paste your OpenAI key from openai.com to use this app. " + str(datetime.datetime.now())
hidden_text = output
if chain:
# Set OpenAI key
import openai
openai.api_key = api_key
if not monologue:
if use_embeddings:
if inp and inp.strip() != "":
if docsearch:
docs = docsearch.similarity_search(inp)
output = str(qa_chain.run(input_documents=docs, question=inp))
else:
output, hidden_text = "Please supply some text in the the Embeddings tab.", None
else:
output, hidden_text = "What's on your mind?", None
else:
output, hidden_text = run_chain(chain, inp, capture_hidden_text=trace_chain)
else:
output, hidden_text = inp, None
output = transform_text(output, express_chain, num_words, formality, anticipation_level, joy_level,
trust_level,
fear_level, surprise_level, sadness_level, disgust_level, anger_level,
lang_level, translate_to, literary_style)
text_to_display = output
if trace_chain:
text_to_display = hidden_text + "\n\n" + output
history.append((inp, text_to_display))
html_video, temp_file, html_audio, temp_aud_file = None, None, None, None
"""
if speak_text:
if talking_head:
if len(output) <= MAX_TALKING_HEAD_TEXT_LENGTH:
html_video, temp_file = do_html_video_speak(output, translate_to)
else:
temp_file = LOOPING_TALKING_HEAD
html_video = create_html_video(temp_file, TALKING_HEAD_WIDTH)
html_audio, temp_aud_file = do_html_audio_speak(output, translate_to)
else:
html_audio, temp_aud_file = do_html_audio_speak(output, translate_to)
else:
if talking_head:
temp_file = LOOPING_TALKING_HEAD
html_video = create_html_video(temp_file, TALKING_HEAD_WIDTH)
else:
# html_audio, temp_aud_file = do_html_audio_speak(output, translate_to)
# html_video = create_html_video(temp_file, "128")
pass
"""
except Exception as e:
raise e
finally:
self.lock.release()
return history, history, html_video, temp_file, html_audio, temp_aud_file, ""
# return history, history, html_audio, temp_aud_file, ""
chat = ChatWrapper()
def do_html_audio_speak(words_to_speak, polly_language):
polly_client = boto3.Session(
aws_access_key_id=os.environ["AWS_ACCESS_KEY_ID"],
aws_secret_access_key=os.environ["AWS_SECRET_ACCESS_KEY"],
region_name='eu-west-2'
).client('polly')
# voice_id, language_code, engine = POLLY_VOICE_DATA.get_voice(polly_language, "Female")
voice_id, language_code, engine = POLLY_VOICE_DATA.get_voice(polly_language, "Male")
if not voice_id:
# voice_id = "Joanna"
voice_id = "Matthew"
language_code = "en-US"
engine = NEURAL_ENGINE
response = polly_client.synthesize_speech(
Text=words_to_speak,
OutputFormat='mp3',
VoiceId=voice_id,
LanguageCode=language_code,
Engine=engine
)
html_audio = '<pre>no audio</pre>'
# Save the audio stream returned by Amazon Polly on Lambda's temp directory
if "AudioStream" in response:
with closing(response["AudioStream"]) as stream:
# output = os.path.join("/tmp/", "speech.mp3")
try:
with open('audios/tempfile.mp3', 'wb') as f:
f.write(stream.read())
temp_aud_file = gr.File("audios/tempfile.mp3")
temp_aud_file_url = "/file=" + temp_aud_file.value['name']
html_audio = f'<audio autoplay><source src={temp_aud_file_url} type="audio/mp3"></audio>'
except IOError as error:
# Could not write to file, exit gracefully
print(error)
return None, None
else:
# The response didn't contain audio data, exit gracefully
print("Could not stream audio")
return None, None
return html_audio, "audios/tempfile.mp3"
def create_html_video(file_name, width):
temp_file_url = "/file=" + tmp_file.value['name']
html_video = f'<video width={width} height={width} autoplay muted loop><source src={temp_file_url} type="video/mp4" poster="Masahiro.png"></video>'
return html_video
def do_html_video_speak(words_to_speak, azure_language):
azure_voice = AZURE_VOICE_DATA.get_voice(azure_language, "Male")
if not azure_voice:
azure_voice = "en-US-ChristopherNeural"
headers = {"Authorization": f"Bearer {os.environ['EXHUMAN_API_KEY']}"}
body = {
'bot_name': 'Marc',
'bot_response': words_to_speak,
'azure_voice': azure_voice,
'azure_style': 'friendly',
'animation_pipeline': 'high_speed',
}
api_endpoint = "https://api.exh.ai/animations/v1/generate_lipsync"
res = requests.post(api_endpoint, json=body, headers=headers)
print("res.status_code: ", res.status_code)
html_video = '<pre>no video</pre>'
if isinstance(res.content, bytes):
response_stream = io.BytesIO(res.content)
print("len(res.content)): ", len(res.content))
with open('videos/tempfile.mp4', 'wb') as f:
f.write(response_stream.read())
temp_file = gr.File("videos/tempfile.mp4")
temp_file_url = "/file=" + temp_file.value['name']
html_video = f'<video width={TALKING_HEAD_WIDTH} height={TALKING_HEAD_WIDTH} autoplay><source src={temp_file_url} type="video/mp4" poster="Marc.png"></video>'
else:
print('video url unknown')
return html_video, "videos/tempfile.mp4"
def update_selected_tools(widget, state, llm):
if widget:
state = widget
chain, express_chain, memory = load_chain(state, llm)
return state, llm, chain, express_chain
def update_talking_head(widget, state):
if widget:
state = widget
video_html_talking_head = create_html_video(LOOPING_TALKING_HEAD, TALKING_HEAD_WIDTH)
return state, video_html_talking_head
else:
# return state, create_html_video(LOOPING_TALKING_HEAD, "32")
return None, "<pre></pre>"
def update_foo(widget, state):
if widget:
state = widget
return state
# Pertains to question answering functionality
def update_embeddings(embeddings_text, embeddings, qa_chain):
if embeddings_text:
text_splitter = CharacterTextSplitter(chunk_size=1000, chunk_overlap=0)
texts = text_splitter.split_text(embeddings_text)
docsearch = FAISS.from_texts(texts, embeddings)
print("Embeddings updated")
return docsearch
# Pertains to question answering functionality
def update_use_embeddings(widget, state):
if widget:
state = widget
return state
with gr.Blocks(css="css/custom_css.css") as block:
llm_state = gr.State()
history_state = gr.State()
chain_state = gr.State()
express_chain_state = gr.State()
tools_list_state = gr.State(TOOLS_DEFAULT_LIST)
trace_chain_state = gr.State(False)
speak_text_state = gr.State(False)
talking_head_state = gr.State(True)
monologue_state = gr.State(False) # Takes the input and repeats it back to the user, optionally transforming it.
memory_state = gr.State()
# Pertains to Express-inator functionality
num_words_state = gr.State(NUM_WORDS_DEFAULT)
formality_state = gr.State(FORMALITY_DEFAULT)
anticipation_level_state = gr.State(EMOTION_DEFAULT)
joy_level_state = gr.State(EMOTION_DEFAULT)
trust_level_state = gr.State(EMOTION_DEFAULT)
fear_level_state = gr.State(EMOTION_DEFAULT)
surprise_level_state = gr.State(EMOTION_DEFAULT)
sadness_level_state = gr.State(EMOTION_DEFAULT)
disgust_level_state = gr.State(EMOTION_DEFAULT)
anger_level_state = gr.State(EMOTION_DEFAULT)
lang_level_state = gr.State(LANG_LEVEL_DEFAULT)
translate_to_state = gr.State(TRANSLATE_TO_DEFAULT)
literary_style_state = gr.State(LITERARY_STYLE_DEFAULT)
# Pertains to WHISPER functionality
whisper_lang_state = gr.State(WHISPER_DETECT_LANG)
# Pertains to question answering functionality
embeddings_state = gr.State()
qa_chain_state = gr.State()
docsearch_state = gr.State()
use_embeddings_state = gr.State(False)
gr.HTML("""
<h1><img alt="" src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAABWsAAAClCAYAAAAqCq+KAAAAAXNSR0IArs4c6QAAAERlWElmTU0AKgAAAAgAAYdpAAQAAAABAAAAGgAAAAAAA6ABAAMAAAABAAEAAKACAAQAAAABAAAFa6ADAAQAAAABAAAApQAAAADZtk0YAABAAElEQVR4AeydB4AURfbG3waWnCVnkCxIkCgCgopZMCeUExOnnsgZT/9mTGfgPMOZE2YwHCeooCIGEIkKqCBZguS8y6b511dLL729VT09YXdn2a90mZnq6qrqX1enr1+9lyQiIfXHRAIkQAIkQAIkQAIkQAIkQAIkQAIkQAIkQAIkQAIkUIIEkkuwbTZNAiRAAiRAAiRAAiRAAiRAAiRAAiRAAiRAAiRAAiRwgADFWg4FEiABEiABEiABEiABEiABEiABEiABEiABEiABEkgAAhRrE2AnsAskQAIkQAIkQAIkQAIkQAIkQAIkQAIkQAIkQAIkQLGWY4AESIAESIAESIAESIAESIAESIAESIAESIAESIAEEoAAxdoE2AnsAgmQAAmQAAmQAAmQAAmQAAmQAAmQAAmQAAmQAAlQrOUYIAESIAESIAESIAESIAESIAESIAESIAESIAESIIEEIECxNgF2ArtAAiRAAiRAAiRAAiRAAiRAAiRAAiRAAiRAAiRAAhRrOQZIgARIgARIgARIgARIgARIgARIgARIgARIgARIIAEIUKxNgJ3ALpAACZAACZAACZAACZAACZAACZAACZAACZAACZAAxVqOARIgARIgARIgARIgARIgARIgARIgARIgARIgARJIAAIUaxNgJ7ALJEACJEACJEACJEACJEACJEACJEACJEACJEACJECxlmOABEiABEiABEiABEiABEiABEiABEiABEiABEiABBKAAMXaBNgJ7AIJkAAJkAAJkAAJkAAJkAAJkAAJkAAJkAAJkAAJUKzlGCABEiABEiABEiABEiABEiABEiABEiABEiABEiCBBCBAsTYBdgK7QAIkQAIkQAIkQAIkQAIkQAIkQAIkQAIkQAIkQAIUazkGSIAESIAESIAESIAESIAESIAESIAESIAESIAESCABCFCsTYCdwC6QAAmQAAmQAAmQAAmQAAmQAAmQAAmQAAmQAAmQAMVajgESIAESIAESIAESIAESIAESIAESIAESIAESIAES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AQIECBAgQIAAAQIECBAgQIAAAQJNKCCsbcJJN2QCBAgQIECAAAECBAgQIECAAAECBMonIKwt35zoEQECBAgQIECAAAECBAgQIECAAAECTSggrG3CSTdkAgQIECBAgAABAgQIECBAgAABAgTKJyCsLd+c6BEBAgQIECBAgAABAgQIECBAgAABAk0oIKxtwkk3ZAIECBAgQIAAAQIECBAgQIAAAQIEyicgrC3fnOgRAQIECBAgQIAAAQIECBAgQIAAAQJNKCCsbcJJN2QCBAgQIECAAAECBAgQIECAAAECBMonIKwt35zoEQECBAgQIECAAAECBAgQIECAAAECTSggrG3CSTdkAgQIECBAgAABAgQIECBAgAABAgTKJyCsLd+c6BEBAgQIECBAgAABAgQIECBAgAABAk0oIKxtwkk3ZAIECBAgQIAAAQIECBAgQIAAAQIEyicgrC3fnOgRAQIECBAgQIAAAQIECBAgQIAAAQJNKCCsbcJJN2QCBAgQIECAAAECBAgQIECAAAECBMonIKwt35zoEQECBAgQIECAAAECBAgQIECAAAECTSggrG3CSTdkAgQIECBAgAABAgQIECBAgAABAgTKJyCsLd+c6BEBAgQIECBAgAABAgQIECBAgAABAk0oIKxtwkk3ZAIECBAgQIAAAQIECBAgQIAAAQIEyicgrC3fnOgRAQIECBAgQIAAAQIECBAgQIAAAQJNKCCsbcJJN2QCBAgQIECAAAECBAgQIECAAAECBMonIKwt35zoEQECBAgQIECAAAECBAgQIECAAAECTSggrG3CSTdkAgQIECBAgAABAgQIECBAgAABAgTKJyCsLd+c6BEBAgQIECBAgAABAgQIECBAgAABAk0oIKxtwkk3ZAIECBAgQIAAAQIECBAgQIAAAQIEyicgrC3fnOgRAQIECBAgQIAAAQIECBAgQIAAAQJNKCCsbcJJN2QCBAgQIECAAAECBAgQIECAAAECBMonIKwt35zoEQECBAgQIECAAAECBAgQIECAAAECTSggrG3CSTdkAgQIECBAgAABAgQIECBAgAABAgTKJyCsLd+c6BEBAgQIECBAgAABAgQIECBAgAABAk0o8P/qA070JRjwngAAAABJRU5ErkJggg==" /></h1>""")
with gr.Tab("Chat"):
with gr.Row():
openai_api_key_textbox = gr.Textbox(placeholder="Paste your OpenAI API key (sk-...)",
show_label=False, lines=1, type='password', elem_id="gr-component")
with gr.Row():
with gr.Column(scale=1, min_width=TALKING_HEAD_WIDTH, visible=True):
speak_text_cb = gr.Checkbox(label="Enable speech", value=False)
speak_text_cb.change(update_foo, inputs=[speak_text_cb, speak_text_state],
outputs=[speak_text_state])
my_file = gr.File(label="Upload a file", type="file", visible=False)
tmp_file = gr.File(LOOPING_TALKING_HEAD, visible=False)
# tmp_file_url = "/file=" + tmp_file.value['name']
htm_video = create_html_video(LOOPING_TALKING_HEAD, TALKING_HEAD_WIDTH)
video_html = gr.HTML(htm_video)
# my_aud_file = gr.File(label="Audio file", type="file", visible=True)
tmp_aud_file = gr.File("audios/tempfile.mp3", visible=False)
tmp_aud_file_url = "/file=" + tmp_aud_file.value['name']
htm_audio = f'<audio><source src={tmp_aud_file_url} type="audio/mp3"></audio>'
audio_html = gr.HTML(htm_audio)
with gr.Column(scale=7):
chatbot = gr.Chatbot(elem_id="gr-component")
with gr.Row():
message = gr.Textbox(label="What's on your mind?",
placeholder="What's the answer to life, the universe, and everything?",
lines=1,
elem_id="gr-component")
submit = gr.Button(value="Send", variant="secondary").style(full_width=False)
with gr.Tab("Settings"):
tools_cb_group = gr.CheckboxGroup(label="Tools:", choices=TOOLS_LIST,
value=TOOLS_DEFAULT_LIST, elem_id="gr-component")
tools_cb_group.change(update_selected_tools,
inputs=[tools_cb_group, tools_list_state, llm_state],
outputs=[tools_list_state, llm_state, chain_state, express_chain_state])
trace_chain_cb = gr.Checkbox(label="Show reasoning chain in chat bubble", value=False, elem_id="gr-component")
trace_chain_cb.change(update_foo, inputs=[trace_chain_cb, trace_chain_state],
outputs=[trace_chain_state])
speak_text_cb = gr.Checkbox(label="Speak text from agent", value=False)
speak_text_cb.change(update_foo, inputs=[speak_text_cb, speak_text_state],
outputs=[speak_text_state])
talking_head_cb = gr.Checkbox(label="Show talking head", value=True)
talking_head_cb.change(update_talking_head, inputs=[talking_head_cb, talking_head_state],
outputs=[talking_head_state, video_html])
# monologue_cb = gr.Checkbox(label="Babel fish mode (translate/restate what you enter, no conversational agent)",
# value=False)
# monologue_cb.change(update_foo, inputs=[monologue_cb, monologue_state],
# outputs=[monologue_state])
reset_btn = gr.Button(value="Reset chat", variant="secondary").style(full_width=False)
reset_btn.click(reset_memory, inputs=[history_state, memory_state], outputs=[chatbot, history_state, memory_state])
message.submit(chat, inputs=[openai_api_key_textbox, message, history_state, chain_state, trace_chain_state,
speak_text_state, talking_head_state, monologue_state,
express_chain_state, num_words_state, formality_state,
anticipation_level_state, joy_level_state, trust_level_state, fear_level_state,
surprise_level_state, sadness_level_state, disgust_level_state, anger_level_state,
lang_level_state, translate_to_state, literary_style_state,
qa_chain_state, docsearch_state, use_embeddings_state],
outputs=[chatbot, history_state, video_html, my_file, audio_html, tmp_aud_file, message])
# outputs=[chatbot, history_state, message])
# outputs=[chatbot, history_state, audio_html, tmp_aud_file, message])
submit.click(chat, inputs=[openai_api_key_textbox, message, history_state, chain_state, trace_chain_state,
speak_text_state, talking_head_state, monologue_state,
express_chain_state, num_words_state, formality_state,
anticipation_level_state, joy_level_state, trust_level_state, fear_level_state,
surprise_level_state, sadness_level_state, disgust_level_state, anger_level_state,
lang_level_state, translate_to_state, literary_style_state,
qa_chain_state, docsearch_state, use_embeddings_state],
outputs=[chatbot, history_state, video_html, my_file, audio_html, tmp_aud_file, message])
# outputs=[chatbot, history_state, message])
# outputs=[chatbot, history_state, audio_html, tmp_aud_file, message])
openai_api_key_textbox.change(set_openai_api_key,
inputs=[openai_api_key_textbox],
outputs=[chain_state, express_chain_state, llm_state, embeddings_state,
qa_chain_state, memory_state])
block.launch(debug=True)