roseyai/Chat-GPT-LangChain
7
1import io2import os3from contextlib import closing4from typing import Optional, Tuple5import datetime6 7import boto38import gradio as gr9import requests10 11# UNCOMMENT TO USE WHISPER12import warnings13import whisper14 15from langchain import ConversationChain, LLMChain16 17from langchain.agents import load_tools, initialize_agent18from langchain.chains.conversation.memory import ConversationBufferMemory19from langchain.llms import OpenAI20from threading import Lock21 22 23# Console to variable24from io import StringIO25import sys26import re27 28from openai.error import AuthenticationError, InvalidRequestError, RateLimitError29 30# Pertains to Express-inator functionality31from langchain.prompts import PromptTemplate32 33from polly_utils import PollyVoiceData, NEURAL_ENGINE34 35openai_api_key_textbox = "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"36 37news_api_key = os.environ["NEWS_API_KEY"]38tmdb_bearer_token = os.environ["TMDB_BEARER_TOKEN"]39 40TOOLS_LIST = ['serpapi', 'wolfram-alpha', 'google-search', 'pal-math', 'pal-colored-objects', 'news-api', 'tmdb-api',41 'open-meteo-api']42TOOLS_DEFAULT_LIST = ['serpapi', 'wolfram-alpha', 'pal-math', 'pal-colored-objects', 'news-api', 'tmdb-api',43 'open-meteo-api']44BUG_FOUND_MSG = "Congratulations, you've found a bug in this application!"45AUTH_ERR_MSG = "Please paste your OpenAI key."46MAX_TOKENS = 51247 48# Pertains to Express-inator functionality49NUM_WORDS_DEFAULT = 050MAX_WORDS = 40051FORMALITY_DEFAULT = "N/A"52TEMPERATURE_DEFAULT = 0.553EMOTION_DEFAULT = "N/A"54TRANSLATE_TO_DEFAULT = "N/A"55LITERARY_STYLE_DEFAULT = "N/A"56PROMPT_TEMPLATE = PromptTemplate(57 input_variables=["original_words", "num_words", "formality", "emotions", "translate_to", "literary_style"],58 template="Restate {num_words}{formality}{emotions}{translate_to}{literary_style}the following: \n{original_words}\n",59)60 61POLLY_VOICE_DATA = PollyVoiceData()62 63 64# UNCOMMENT TO USE WHISPER65warnings.filterwarnings("ignore")66WHISPER_MODEL = whisper.load_model("tiny")67print("WHISPER_MODEL", WHISPER_MODEL)68 69 70# UNCOMMENT TO USE WHISPER71def transcribe(aud_inp):72 if aud_inp is None:73 return ""74 aud = whisper.load_audio(aud_inp)75 aud = whisper.pad_or_trim(aud)76 mel = whisper.log_mel_spectrogram(aud).to(WHISPER_MODEL.device)77 _, probs = WHISPER_MODEL.detect_language(mel)78 options = whisper.DecodingOptions()79 # options = whisper.DecodingOptions(language="ja")80 result = whisper.decode(WHISPER_MODEL, mel, options)81 print("result.text", result.text)82 result_text = ""83 if result and result.text:84 result_text = result.text85 return result_text86 87 88# Pertains to Express-inator functionality89def transform_text(desc, express_chain, num_words, formality,90 anticipation_level, joy_level, trust_level,91 fear_level, surprise_level, sadness_level, disgust_level, anger_level,92 translate_to, literary_style):93 num_words_prompt = ""94 if num_words and int(num_words) != 0:95 num_words_prompt = "using up to " + str(num_words) + " words, "96 97 # Change some arguments to lower case98 formality = formality.lower()99 anticipation_level = anticipation_level.lower()100 joy_level = joy_level.lower()101 trust_level = trust_level.lower()102 fear_level = fear_level.lower()103 surprise_level = surprise_level.lower()104 sadness_level = sadness_level.lower()105 disgust_level = disgust_level.lower()106 anger_level = anger_level.lower()107 108 formality_str = ""109 if formality != "n/a":110 formality_str = "in a " + formality + " manner, "111 112 # put all emotions into a list113 emotions = []114 if anticipation_level != "n/a":115 emotions.append(anticipation_level)116 if joy_level != "n/a":117 emotions.append(joy_level)118 if trust_level != "n/a":119 emotions.append(trust_level)120 if fear_level != "n/a":121 emotions.append(fear_level)122 if surprise_level != "n/a":123 emotions.append(surprise_level)124 if sadness_level != "n/a":125 emotions.append(sadness_level)126 if disgust_level != "n/a":127 emotions.append(disgust_level)128 if anger_level != "n/a":129 emotions.append(anger_level)130 131 emotions_str = ""132 if len(emotions) > 0:133 if len(emotions) == 1:134 emotions_str = "with emotion of " + emotions[0] + ", "135 else:136 emotions_str = "with emotions of " + ", ".join(emotions[:-1]) + " and " + emotions[-1] + ", "137 138 translate_to_str = ""139 if translate_to != TRANSLATE_TO_DEFAULT:140 translate_to_str = "translated to " + translate_to + ", "141 142 literary_style_str = ""143 if literary_style != LITERARY_STYLE_DEFAULT:144 if literary_style == "Prose":145 literary_style_str = "as prose, "146 elif literary_style == "Summary":147 literary_style_str = "as a summary, "148 elif literary_style == "Outline":149 literary_style_str = "as an outline numbers and lower case letters, "150 elif literary_style == "Bullets":151 literary_style_str = "as bullet points using bullets, "152 elif literary_style == "Poetry":153 literary_style_str = "as a poem, "154 elif literary_style == "Haiku":155 literary_style_str = "as a haiku, "156 elif literary_style == "Limerick":157 literary_style_str = "as a limerick, "158 elif literary_style == "Joke":159 literary_style_str = "as a very funny joke with a setup and punchline, "160 elif literary_style == "Knock-knock":161 literary_style_str = "as a very funny knock-knock joke, "162 163 formatted_prompt = PROMPT_TEMPLATE.format(164 original_words=desc,165 num_words=num_words_prompt,166 formality=formality_str,167 emotions=emotions_str,168 translate_to=translate_to_str,169 literary_style=literary_style_str170 )171 172 trans_instr = num_words_prompt + formality_str + emotions_str + translate_to_str + literary_style_str173 if express_chain and len(trans_instr.strip()) > 0:174 generated_text = express_chain.run(175 {'original_words': desc, 'num_words': num_words_prompt, 'formality': formality_str,176 'emotions': emotions_str, 'translate_to': translate_to_str,177 'literary_style': literary_style_str}).strip()178 else:179 print("Not transforming text")180 generated_text = desc181 182 # replace all newlines with <br> in generated_text183 generated_text = generated_text.replace("\n", "\n\n")184 185 prompt_plus_generated = "GPT prompt: " + formatted_prompt + "\n\n" + generated_text186 187 print("\n==== date/time: " + str(datetime.datetime.now() - datetime.timedelta(hours=5)) + " ====")188 print("prompt_plus_generated: " + prompt_plus_generated)189 190 return generated_text191 192 193def load_chain(tools_list, llm):194 chain = None195 express_chain = None196 if llm:197 print("\ntools_list", tools_list)198 tool_names = tools_list199 tools = load_tools(tool_names, llm=llm, news_api_key=news_api_key, tmdb_bearer_token=tmdb_bearer_token)200 201 memory = ConversationBufferMemory(memory_key="chat_history")202 203 chain = initialize_agent(tools, llm, agent="conversational-react-description", verbose=True, memory=memory)204 express_chain = LLMChain(llm=llm, prompt=PROMPT_TEMPLATE, verbose=True)205 206 return chain, express_chain207 208 209def set_openai_api_key(api_key):210 """Set the api key and return chain.211 If no api_key, then None is returned.212 """213 print("set openai api")214 print(openai_api_key_textbox)215 api_key = "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"216 print("api key: "+ api_key)217 if api_key and api_key.startswith("sk-") and len(api_key) > 50:218 print("if statement passed")219 os.environ["OPENAI_API_KEY"] = api_key220 llm = OpenAI(temperature=0, max_tokens=MAX_TOKENS)221 chain, express_chain = load_chain(TOOLS_DEFAULT_LIST, llm)222 os.environ["OPENAI_API_KEY"] = ""223 return chain, express_chain, llm224 return None, None, None225 226 227def run_chain(chain, inp, capture_hidden_text):228 output = ""229 hidden_text = None230 if capture_hidden_text:231 error_msg = None232 tmp = sys.stdout233 hidden_text_io = StringIO()234 sys.stdout = hidden_text_io235 236 try:237 output = chain.run(input=inp)238 except AuthenticationError as ae:239 error_msg = AUTH_ERR_MSG240 except RateLimitError as rle:241 error_msg = "\n\nRateLimitError: " + str(rle)242 except ValueError as ve:243 error_msg = "\n\nValueError: " + str(ve)244 except InvalidRequestError as ire:245 error_msg = "\n\nInvalidRequestError: " + str(ire)246 except Exception as e:247 error_msg = "\n\n" + BUG_FOUND_MSG + ":\n\n" + str(e)248 249 sys.stdout = tmp250 hidden_text = hidden_text_io.getvalue()251 252 # remove escape characters from hidden_text253 hidden_text = re.sub(r'\x1b[^m]*m', '', hidden_text)254 255 # remove "Entering new AgentExecutor chain..." from hidden_text256 hidden_text = re.sub(r"Entering new AgentExecutor chain...\n", "", hidden_text)257 258 # remove "Finished chain." from hidden_text259 hidden_text = re.sub(r"Finished chain.", "", hidden_text)260 261 # Add newline after "Thought:" "Action:" "Observation:" "Input:" and "AI:"262 hidden_text = re.sub(r"Thought:", "\n\nThought:", hidden_text)263 hidden_text = re.sub(r"Action:", "\n\nAction:", hidden_text)264 hidden_text = re.sub(r"Observation:", "\n\nObservation:", hidden_text)265 hidden_text = re.sub(r"Input:", "\n\nInput:", hidden_text)266 hidden_text = re.sub(r"AI:", "\n\nAI:", hidden_text)267 268 if error_msg:269 hidden_text += error_msg270 271 print("hidden_text: ", hidden_text)272 else:273 try:274 output = chain.run(input=inp)275 except AuthenticationError as ae:276 output = AUTH_ERR_MSG277 except RateLimitError as rle:278 output = "\n\nRateLimitError: " + str(rle)279 except ValueError as ve:280 output = "\n\nValueError: " + str(ve)281 except InvalidRequestError as ire:282 output = "\n\nInvalidRequestError: " + str(ire)283 except Exception as e:284 output = "\n\n" + BUG_FOUND_MSG + ":\n\n" + str(e)285 286 return output, hidden_text287 288 289class ChatWrapper:290 291 def __init__(self):292 print("init")293 set_openai_api_key("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")294 print("api key 2: " + openai_api_key_textbox)295 self.lock = Lock()296 297 def __call__(298 self, api_key: str, inp: str, history: Optional[Tuple[str, str]], chain: Optional[ConversationChain],299 trace_chain: bool, speak_text: bool, express_chain: Optional[LLMChain],300 num_words, formality, anticipation_level, joy_level, trust_level,301 fear_level, surprise_level, sadness_level, disgust_level, anger_level,302 translate_to, literary_style303 ):304 """Execute the chat functionality."""305 self.lock.acquire()306 307 try:308 api_key = "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"309 print("api key: " + api_key)310 print("\n==== date/time: " + str(datetime.datetime.now()) + " ====")311 print("inp: " + inp)312 print("trace_chain: ", trace_chain)313 print("speak_text: ", speak_text)314 315 316 history = history or []317 # If chain is None, that is because no API key was provided.318 output = "Please paste your OpenAI key to use this application."319 hidden_text = output320 321 if chain and chain != "":322 # Set OpenAI key323 import openai324 openai.api_key = api_key325 output, hidden_text = run_chain(chain, inp, capture_hidden_text=trace_chain)326 327 output = transform_text(output, express_chain, num_words, formality, anticipation_level, joy_level, trust_level,328 fear_level, surprise_level, sadness_level, disgust_level, anger_level,329 translate_to, literary_style)330 331 text_to_display = output332 if trace_chain:333 text_to_display = hidden_text + "\n\n" + output334 history.append((inp, text_to_display))335 336 # html_video, temp_file = do_html_video_speak(output)337 html_audio, temp_aud_file = None, None338 if speak_text:339 html_audio, temp_aud_file = do_html_audio_speak(output, translate_to)340 except Exception as e:341 raise e342 finally:343 self.lock.release()344 # return history, history, html_video, temp_file, ""345 return history, history, html_audio, temp_aud_file, ""346 347 348chat = ChatWrapper()349 350 351def do_html_audio_speak(words_to_speak, polly_language):352 polly_client = boto3.Session(353 aws_access_key_id=os.environ["AWS_ACCESS_KEY_ID"],354 aws_secret_access_key=os.environ["AWS_SECRET_ACCESS_KEY"],355 region_name=os.environ["AWS_DEFAULT_REGION"]356 ).client('polly')357 358 voice_id, language_code, engine = POLLY_VOICE_DATA.get_voice(polly_language, "Female")359 if not voice_id:360 voice_id = "Joanna"361 language_code = "en-US"362 engine = NEURAL_ENGINE363 response = polly_client.synthesize_speech(364 Text=words_to_speak,365 OutputFormat='mp3',366 VoiceId=voice_id,367 LanguageCode=language_code,368 Engine=engine369 )370 371 html_audio = '<pre>no audio</pre>'372 373 # Save the audio stream returned by Amazon Polly on Lambda's temp directory374 if "AudioStream" in response:375 with closing(response["AudioStream"]) as stream:376 # output = os.path.join("/tmp/", "speech.mp3")377 378 try:379 with open('audios/tempfile.mp3', 'wb') as f:380 f.write(stream.read())381 temp_aud_file = gr.File("audios/tempfile.mp3")382 temp_aud_file_url = "/file=" + temp_aud_file.value['name']383 html_audio = f'<audio autoplay><source src={temp_aud_file_url} type="audio/mp3"></audio>'384 except IOError as error:385 # Could not write to file, exit gracefully386 print(error)387 return None, None388 else:389 # The response didn't contain audio data, exit gracefully390 print("Could not stream audio")391 return None, None392 393 return html_audio, "audios/tempfile.mp3"394 395 396def do_html_video_speak(words_to_speak):397 headers = {"Authorization": f"Bearer {os.environ['EXHUMAN_API_KEY']}"}398 body = {399 'bot_name': 'Masahiro',400 'bot_response': words_to_speak,401 'voice_name': 'Masahiro-EN'402 }403 api_endpoint = "https://api.exh.ai/animations/v1/generate_lipsync"404 res = requests.post(api_endpoint, json=body, headers=headers)405 406 html_video = '<pre>no video</pre>'407 if isinstance(res.content, bytes):408 response_stream = io.BytesIO(res.content)409 with open('videos/tempfile.mp4', 'wb') as f:410 f.write(response_stream.read())411 temp_file = gr.File("videos/tempfile.mp4")412 temp_file_url = "/file=" + temp_file.value['name']413 html_video = f'<video width="256" height="256" autoplay><source src={temp_file_url} type="video/mp4" poster="Masahiro.png"></video>'414 else:415 print('video url unknown')416 return html_video, "videos/tempfile.mp4"417 418 419def update_selected_tools(widget, state, llm):420 if widget:421 state = widget422 chain, express_chain = load_chain(state, llm)423 return state, llm, chain, express_chain424 425 426def update_foo(widget, state):427 if widget:428 state = widget429 return state430 431 432with gr.Blocks(css=".gradio-container {background-color: lightgray}") as block:433 llm_state = gr.State()434 history_state = gr.State()435 chain_state = gr.State()436 express_chain_state = gr.State()437 tools_list_state = gr.State(TOOLS_DEFAULT_LIST)438 trace_chain_state = gr.State(False)439 speak_text_state = gr.State(False)440 441 # Pertains to Express-inator functionality442 num_words_state = gr.State(NUM_WORDS_DEFAULT)443 formality_state = gr.State(FORMALITY_DEFAULT)444 anticipation_level_state = gr.State(EMOTION_DEFAULT)445 joy_level_state = gr.State(EMOTION_DEFAULT)446 trust_level_state = gr.State(EMOTION_DEFAULT)447 fear_level_state = gr.State(EMOTION_DEFAULT)448 surprise_level_state = gr.State(EMOTION_DEFAULT)449 sadness_level_state = gr.State(EMOTION_DEFAULT)450 disgust_level_state = gr.State(EMOTION_DEFAULT)451 anger_level_state = gr.State(EMOTION_DEFAULT)452 translate_to_state = gr.State(TRANSLATE_TO_DEFAULT)453 literary_style_state = gr.State(LITERARY_STYLE_DEFAULT)454 455 with gr.Tab("Chat"):456 with gr.Row():457 with gr.Column():458 gr.Markdown("<h4><center>Conversational Agent using GPT-3.5 & LangChain</center></h4>")459 460 openai_api_key_textbox = gr.Textbox(placeholder="Paste your OpenAI API key here (sk-...)",461 show_label=False, lines=1, type='password')462 463 with gr.Row():464 with gr.Column(scale=1, min_width=100, visible=False):465 my_file = gr.File(label="Upload a file", type="file", visible=False)466 tmp_file = gr.File("videos/Masahiro.mp4", visible=False)467 tmp_file_url = "/file=" + tmp_file.value['name']468 htm_video = f'<video width="256" height="256" autoplay muted loop><source src={tmp_file_url} type="video/mp4" poster="Masahiro.png"></video>'469 video_html = gr.HTML(htm_video)470 471 # my_aud_file = gr.File(label="Audio file", type="file", visible=True)472 tmp_aud_file = gr.File("audios/tempfile.mp3", visible=False)473 tmp_aud_file_url = "/file=" + tmp_aud_file.value['name']474 htm_audio = f'<audio><source src={tmp_aud_file_url} type="audio/mp3"></audio>'475 audio_html = gr.HTML(htm_audio)476 477 with gr.Column(scale=3):478 chatbot = gr.Chatbot()479 480 with gr.Row():481 message = gr.Textbox(label="What's on your mind??",482 placeholder="What's the answer to life, the universe, and everything?",483 lines=1)484 submit = gr.Button(value="Send", variant="secondary").style(full_width=False)485 486 # UNCOMMENT TO USE WHISPER487 with gr.Row():488 audio_comp = gr.Microphone(source="microphone", type="filepath", label="Just say it!",489 interactive=True, streaming=False)490 audio_comp.change(transcribe, inputs=[audio_comp], outputs=[message])491 492 gr.Examples(493 examples=["How many people live in Canada?",494 "What is 2 to the 30th power?",495 "If x+y=10 and x-y=4, what are x and y?",496 "How much did it rain in SF today?",497 "Get me information about the movie 'Avatar'",498 "What are the top tech headlines in the US?",499 "On the desk, you see two blue booklets, two purple booklets, and two yellow pairs of sunglasses - "500 "if I remove all the pairs of sunglasses from the desk, how many purple items remain on it?"],501 inputs=message502 )503 504 with gr.Tab("Settings"):505 tools_cb_group = gr.CheckboxGroup(label="Tools:", choices=TOOLS_LIST,506 value=TOOLS_DEFAULT_LIST)507 tools_cb_group.change(update_selected_tools,508 inputs=[tools_cb_group, tools_list_state, llm_state],509 outputs=[tools_list_state, llm_state, chain_state, express_chain_state])510 511 trace_chain_cb = gr.Checkbox(label="Show reasoning chain in chat bubble", value=False)512 trace_chain_cb.change(update_foo, inputs=[trace_chain_cb, trace_chain_state],513 outputs=[trace_chain_state])514 515 speak_text_cb = gr.Checkbox(label="Speak text from agent", value=False)516 speak_text_cb.change(update_foo, inputs=[speak_text_cb, speak_text_state],517 outputs=[speak_text_state])518 519 with gr.Tab("Formality"):520 formality_radio = gr.Radio(label="Formality:",521 choices=[FORMALITY_DEFAULT, "Casual", "Polite", "Honorific"],522 value=FORMALITY_DEFAULT)523 formality_radio.change(update_foo,524 inputs=[formality_radio, formality_state],525 outputs=[formality_state])526 527 with gr.Tab("Translate to"):528 translate_to_radio = gr.Radio(label="Translate to:", choices=[529 TRANSLATE_TO_DEFAULT, "Arabic", "Arabic (Gulf)", "Catalan", "Chinese (Cantonese)", "Chinese (Mandarin)",530 "Danish", "Dutch", "English (Australian)", "English (British)", "English (Indian)", "English (New Zealand)",531 "English (South African)", "English (US)", "English (Welsh)", "Finnish", "French", "French (Canadian)",532 "German", "German (Austrian)", "Georgian", "Hindi", "Icelandic", "Indonesian", "Italian", "Japanese", "Korean", "Norwegian", "Polish",533 "Portuguese (Brazilian)", "Portuguese (European)", "Romanian", "Russian", "Spanish (European)",534 "Spanish (Mexican)", "Spanish (US)", "Swedish", "Turkish", "Ukrainian", "Welsh",535 "emojis", "Gen Z slang", "how the stereotypical Karen would say it", "Klingon",536 "Pirate", "Strange Planet expospeak technical talk", "Yoda"],537 value=TRANSLATE_TO_DEFAULT)538 539 translate_to_radio.change(update_foo,540 inputs=[translate_to_radio, translate_to_state],541 outputs=[translate_to_state])542 543 with gr.Tab("Lit style"):544 literary_style_radio = gr.Radio(label="Literary style:", choices=[545 LITERARY_STYLE_DEFAULT, "Prose", "Summary", "Outline", "Bullets", "Poetry", "Haiku", "Limerick", "Joke",546 "Knock-knock"],547 value=LITERARY_STYLE_DEFAULT)548 549 literary_style_radio.change(update_foo,550 inputs=[literary_style_radio, literary_style_state],551 outputs=[literary_style_state])552 553 with gr.Tab("Emotions"):554 anticipation_level_radio = gr.Radio(label="Anticipation level:",555 choices=[EMOTION_DEFAULT, "Interest", "Anticipation", "Vigilance"],556 value=EMOTION_DEFAULT)557 anticipation_level_radio.change(update_foo,558 inputs=[anticipation_level_radio, anticipation_level_state],559 outputs=[anticipation_level_state])560 561 joy_level_radio = gr.Radio(label="Joy level:",562 choices=[EMOTION_DEFAULT, "Serenity", "Joy", "Ecstasy"],563 value=EMOTION_DEFAULT)564 joy_level_radio.change(update_foo,565 inputs=[joy_level_radio, joy_level_state],566 outputs=[joy_level_state])567 568 trust_level_radio = gr.Radio(label="Trust level:",569 choices=[EMOTION_DEFAULT, "Acceptance", "Trust", "Admiration"],570 value=EMOTION_DEFAULT)571 trust_level_radio.change(update_foo,572 inputs=[trust_level_radio, trust_level_state],573 outputs=[trust_level_state])574 575 fear_level_radio = gr.Radio(label="Fear level:",576 choices=[EMOTION_DEFAULT, "Apprehension", "Fear", "Terror"],577 value=EMOTION_DEFAULT)578 fear_level_radio.change(update_foo,579 inputs=[fear_level_radio, fear_level_state],580 outputs=[fear_level_state])581 582 surprise_level_radio = gr.Radio(label="Surprise level:",583 choices=[EMOTION_DEFAULT, "Distraction", "Surprise", "Amazement"],584 value=EMOTION_DEFAULT)585 surprise_level_radio.change(update_foo,586 inputs=[surprise_level_radio, surprise_level_state],587 outputs=[surprise_level_state])588 589 sadness_level_radio = gr.Radio(label="Sadness level:",590 choices=[EMOTION_DEFAULT, "Pensiveness", "Sadness", "Grief"],591 value=EMOTION_DEFAULT)592 sadness_level_radio.change(update_foo,593 inputs=[sadness_level_radio, sadness_level_state],594 outputs=[sadness_level_state])595 596 disgust_level_radio = gr.Radio(label="Disgust level:",597 choices=[EMOTION_DEFAULT, "Boredom", "Disgust", "Loathing"],598 value=EMOTION_DEFAULT)599 disgust_level_radio.change(update_foo,600 inputs=[disgust_level_radio, disgust_level_state],601 outputs=[disgust_level_state])602 603 anger_level_radio = gr.Radio(label="Anger level:",604 choices=[EMOTION_DEFAULT, "Annoyance", "Anger", "Rage"],605 value=EMOTION_DEFAULT)606 anger_level_radio.change(update_foo,607 inputs=[anger_level_radio, anger_level_state],608 outputs=[anger_level_state])609 610 with gr.Tab("Max words"):611 num_words_slider = gr.Slider(label="Max number of words to generate (0 for don't care)",612 value=NUM_WORDS_DEFAULT, minimum=0, maximum=MAX_WORDS, step=10)613 num_words_slider.change(update_foo,614 inputs=[num_words_slider, num_words_state],615 outputs=[num_words_state])616 617 gr.HTML("""618 This application, developed by <a href='https://www.linkedin.com/in/javafxpert/'>James L. Weaver</a>, 619 demonstrates a conversational agent implemented with OpenAI GPT-3.5 and LangChain. 620 When necessary, it leverages tools for complex math, searching the internet, and accessing news and weather.""")621 622 gr.HTML("<center>Powered by <a href='https://github.com/hwchase17/langchain'>LangChain ๐ฆ๏ธ๐</a></center>")623 624 message.submit(chat, inputs=[openai_api_key_textbox, message, history_state, chain_state, trace_chain_state, speak_text_state,625 express_chain_state, num_words_state, formality_state,626 anticipation_level_state, joy_level_state, trust_level_state, fear_level_state,627 surprise_level_state, sadness_level_state, disgust_level_state, anger_level_state,628 translate_to_state, literary_style_state],629 # outputs=[chatbot, history_state, video_html, my_file, message])630 outputs=[chatbot, history_state, audio_html, tmp_aud_file, message]631 )632 633 634 635 submit.click(chat, inputs=[openai_api_key_textbox, message, history_state, chain_state, trace_chain_state, speak_text_state,636 express_chain_state, num_words_state, formality_state,637 anticipation_level_state, joy_level_state, trust_level_state, fear_level_state,638 surprise_level_state, sadness_level_state, disgust_level_state, anger_level_state,639 translate_to_state, literary_style_state],640 # outputs=[chatbot, history_state, video_html, my_file, message])641 outputs=[chatbot, history_state, audio_html, tmp_aud_file, message])642 643 message.change(set_openai_api_key,644 inputs=[openai_api_key_textbox],645 outputs=[chain_state, express_chain_state, llm_state])646 647 openai_api_key_textbox.change(set_openai_api_key,648 inputs=[openai_api_key_textbox],649 outputs=[chain_state, express_chain_state, llm_state])650 651block.launch(debug=True)