AgriXpert / app.py
Adeptschneider's picture
Update app.py
4d8a8c2 verified
import streamlit as st
from streamlit_chat import message
from chatbot import DualChatbot
import time
from gtts import gTTS
from io import BytesIO
# Define the language type settings
LANGUAGES = ['English', 'German', 'Spanish', 'French', 'Swahili']
SESSION_LENGTHS = ['Short', 'Long']
PROFICIENCY_LEVELS = ['Beginner', 'Intermediate', 'Advanced']
MAX_EXCHANGE_COUNTS = {
'Short': {'Conversation': 4, 'Debate': 4},
'Long': {'Conversation': 8, 'Debate': 8}
}
AUDIO_SPEECH = {
'English': 'en',
'German': 'de',
'Spanish': 'es',
'French': 'fr',
'Swahili': 'sw'
}
AVATAR_SEED = [123, 42]
# Define backbone llm
engine = 'OpenAI'
# Set the title of the app
st.title('Agrixpert Bot πŸ€–')
# Set the description of the app
st.markdown("""
This app generates a dialogue between a farmer and an agricultural expert to help farmers make better farming decisions.
Choose your desired settings and press 'Generate' to start πŸš€
""")
# Add a selectbox for learning mode
learning_mode = st.sidebar.selectbox('Interaction Mode πŸ“–', ('Conversation', 'Debate'))
if learning_mode == 'Conversation':
role1 = st.sidebar.text_input('Role 1 🎭')
action1 = st.sidebar.text_input('Action 1 πŸ—£οΈ')
role2 = st.sidebar.text_input('Role 2 🎭')
action2 = st.sidebar.text_input('Action 2 πŸ—£οΈ')
scenario = st.sidebar.text_input('Scenario πŸŽ₯')
time_delay = 2
# Configure role dictionary
role_dict = {
'role1': {'name': role1, 'action': action1},
'role2': {'name': role2, 'action': action2}
}
else:
scenario = st.sidebar.text_input('Debate Topic πŸ’¬')
# Configure role dictionary
role_dict = {
'role1': {'name': 'Proponent'},
'role2': {'name': 'Opponent'}
}
time_delay = 5
language = st.sidebar.selectbox('Target Language πŸ”€', LANGUAGES)
session_length = st.sidebar.selectbox('Session Length ⏰', SESSION_LENGTHS)
proficiency_level = st.sidebar.selectbox('Proficiency Level πŸ†', PROFICIENCY_LEVELS)
if "bot1_mesg" not in st.session_state:
st.session_state["bot1_mesg"] = []
if "bot2_mesg" not in st.session_state:
st.session_state["bot2_mesg"] = []
if 'batch_flag' not in st.session_state:
st.session_state["batch_flag"] = False
if 'translate_flag' not in st.session_state:
st.session_state["translate_flag"] = False
if 'audio_flag' not in st.session_state:
st.session_state["audio_flag"] = False
if 'message_counter' not in st.session_state:
st.session_state["message_counter"] = 0
def show_messages(mesg_1, mesg_2, message_counter,
time_delay, batch=False, audio=False,
translation=False):
"""Display conversation exchanges. This helper function supports
displaying original texts, translated texts, and audio speech.
Args:
--------
mesg1: messages spoken by the first bot
mesg2: messages spoken by the second bot
message_counter: create unique ID key for chat messages
time_delay: time interval between conversations
batch: True/False to indicate if conversations will be shown
all together or with a certain time delay.
audio: True/False to indicate if the audio speech need to
be appended to the texts
translation: True/False to indicate if the translated texts need to
be displayed
Output:
-------
message_counter: updated counter for ID key
"""
for i, mesg in enumerate([mesg_1, mesg_2]):
# Show original exchange ()
message(f"{mesg['content']}", is_user=i==1, avatar_style="bottts",
seed=AVATAR_SEED[i],
key=message_counter)
message_counter += 1
# Mimic time interval between conversations
# (this time delay only appears when generating
# the conversation script for the first time)
if not batch:
time.sleep(time_delay)
# Show translated exchange
if translation:
message(f"{mesg['translation']}", is_user=i==1, avatar_style="bottts",
seed=AVATAR_SEED[i],
key=message_counter)
message_counter += 1
# Append autio to the exchange
if audio:
tts = gTTS(text=mesg['content'], lang=AUDIO_SPEECH[language])
sound_file = BytesIO()
tts.write_to_fp(sound_file)
st.audio(sound_file)
return message_counter
# Define the button layout at the beginning
translate_col, original_col, audio_col = st.columns(3)
# Create the conversation container
conversation_container = st.container()
if 'dual_chatbots' not in st.session_state:
if st.sidebar.button('Generate'):
# Add flag to indicate if this is the first time running the script
st.session_state["first_time_exec"] = True
with conversation_container:
if learning_mode == 'Conversation':
st.write(f"""#### The following conversation happens between
{role1} and {role2} {scenario} 🎭""")
else:
st.write(f"""#### Debate πŸ’¬: {scenario}""")
# Instantiate dual-chatbot system
dual_chatbots = DualChatbot(engine, role_dict, language, scenario,
proficiency_level, learning_mode, session_length)
st.session_state['dual_chatbots'] = dual_chatbots
# Start exchanges
for _ in range(MAX_EXCHANGE_COUNTS[session_length][learning_mode]):
output1, output2, translate1, translate2 = dual_chatbots.step()
mesg_1 = {"role": dual_chatbots.chatbots['role1']['name'],
"content": output1, "translation": translate1}
mesg_2 = {"role": dual_chatbots.chatbots['role2']['name'],
"content": output2, "translation": translate2}
new_count = show_messages(mesg_1, mesg_2,
st.session_state["message_counter"],
time_delay=time_delay, batch=False,
audio=False, translation=False)
st.session_state["message_counter"] = new_count
# Update session state
st.session_state.bot1_mesg.append(mesg_1)
st.session_state.bot2_mesg.append(mesg_2)
if 'dual_chatbots' in st.session_state:
# Show translation
if translate_col.button('Translate to English'):
st.session_state['translate_flag'] = True
st.session_state['batch_flag'] = True
# Show original text
if original_col.button('Show original'):
st.session_state['translate_flag'] = False
st.session_state['batch_flag'] = True
# Append audio
if audio_col.button('Play audio'):
st.session_state['audio_flag'] = True
st.session_state['batch_flag'] = True
# Retrieve generated conversation & chatbots
mesg1_list = st.session_state.bot1_mesg
mesg2_list = st.session_state.bot2_mesg
dual_chatbots = st.session_state['dual_chatbots']
# Control message appear
if st.session_state["first_time_exec"]:
st.session_state['first_time_exec'] = False
else:
# Show complete message
with conversation_container:
if learning_mode == 'Conversation':
st.write(f"""#### {role1} and {role2} {scenario} 🎭""")
else:
st.write(f"""#### Debate πŸ’¬: {scenario}""")
for mesg_1, mesg_2 in zip(mesg1_list, mesg2_list):
new_count = show_messages(mesg_1, mesg_2,
st.session_state["message_counter"],
time_delay=time_delay,
batch=st.session_state['batch_flag'],
audio=st.session_state['audio_flag'],
translation=st.session_state['translate_flag'])
st.session_state["message_counter"] = new_count
# # Create summary for key learning points
# summary_expander = st.expander('Key Learning Points')
# scripts = []
# for mesg_1, mesg_2 in zip(mesg1_list, mesg2_list):
# for i, mesg in enumerate([mesg_1, mesg_2]):
# scripts.append(mesg['role'] + ': ' + mesg['content'])
# # Compile summary
# if "summary" not in st.session_state:
# summary = dual_chatbots.summary(scripts)
# st.session_state["summary"] = summary
# else:
# summary = st.session_state["summary"]
# with summary_expander:
# st.markdown(f"**Here is the learning summary:**")
# st.write(summary)