CoolFace
Apppublic

roseyai/Chat-GPT-LangChain

sourceHugging Faceapache-2.0updated 4y agoView on Hugging Face
7likes
app.py651 linesDownload Raw Back to root
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)