Demosthene-OR commited on
Commit
6c15782
1 Parent(s): 44b1492
Files changed (5) hide show
  1. app.py +36 -10
  2. style.css +12 -0
  3. tabs/chatbot_tab.py +218 -131
  4. tabs/intro.py +6 -3
  5. translate_app.py +3 -1
app.py CHANGED
@@ -17,6 +17,7 @@ else:
17
  st.set_page_config (
18
  page_title=config.TITLE,
19
  page_icon= "assets/faviconV2.png",
 
20
  initial_sidebar_state=st.session_state.sidebar_state
21
  )
22
 
@@ -58,32 +59,40 @@ st.markdown(f"<style>{style}</style>", unsafe_allow_html=True)
58
  TABS = OrderedDict(
59
  [
60
  (tr(intro.sidebar_name), intro),
61
- (tr(sentence_similarity_tab.sidebar_name), sentence_similarity_tab),
62
- (tr(speech2text_tab.sidebar_name), speech2text_tab),
63
  (tr(chatbot_tab.sidebar_name), chatbot_tab),
 
 
64
  ]
65
  )
66
 
67
- # Utilisation du module translate
68
- # lang_tgt = ['fr','en','af','ak','sq','de','am','en','ar','hy','as','az','ba','bm','eu','bn','be','my','bs','bg','ks','ca','ny','zh','si','ko','co','ht','hr','da','dz','gd','es','eo','et','ee','fo','fj','fi','fr','fy','gl','cy','lg','ka','el','gn','gu','ha','he','hi','hu','ig','id','iu','ga','is','it','ja','kn','kk','km','ki','rw','ky','rn','ku','lo','la','lv','li','ln','lt','lb','mk','ms','ml','dv','mg','mt','mi','mr','mn','nl','ne','no','nb','nn','oc','or','ug','ur','uz','ps','pa','fa','pl','pt','ro','ru','sm','sg','sa','sc','sr','sn','sd','sk','sl','so','st','su','sv','sw','ss','tg','tl','ty','ta','tt','cs','te','th','bo','ti','to','ts','tn','tr','tk','tw','uk','vi','wo','xh','yi']
69
- # label_lang = ['Français', 'Anglais / English','Afrikaans','Akan','Albanais','Allemand / Deutsch','Amharique','Anglais','Arabe','Arménien','Assamais','Azéri','Bachkir','Bambara','Basque','Bengali','Biélorusse','Birman','Bosnien','Bulgare','Cachemiri','Catalan','Chichewa','Chinois','Cingalais','Coréen','Corse','Créolehaïtien','Croate','Danois','Dzongkha','Écossais','Espagnol / Español','Espéranto','Estonien','Ewe','Féroïen','Fidjien','Finnois','Français','Frisonoccidental','Galicien','Gallois','Ganda','Géorgien','Grecmoderne','Guarani','Gujarati','Haoussa','Hébreu','Hindi','Hongrois','Igbo','Indonésien','Inuktitut','Irlandais','Islandais','Italien / Italiano','Japonais','Kannada','Kazakh','Khmer','Kikuyu','Kinyarwanda','Kirghiz','Kirundi','Kurde','Lao','Latin','Letton','Limbourgeois','Lingala','Lituanien','Luxembourgeois','Macédonien','Malais','Malayalam','Maldivien','Malgache','Maltais','MaorideNouvelle-Zélande','Marathi','Mongol','Néerlandais / Nederlands','Népalais','Norvégien','Norvégienbokmål','Norvégiennynorsk','Occitan','Oriya','Ouïghour','Ourdou','Ouzbek','Pachto','Pendjabi','Persan','Polonais','Portugais','Roumain','Russe','Samoan','Sango','Sanskrit','Sarde','Serbe','Shona','Sindhi','Slovaque','Slovène','Somali','SothoduSud','Soundanais','Suédois','Swahili','Swati','Tadjik','Tagalog','Tahitien','Tamoul','Tatar','Tchèque','Télougou','Thaï','Tibétain','Tigrigna','Tongien','Tsonga','Tswana','Turc','Turkmène','Twi','Ukrainien','Vietnamien','Wolof','Xhosa','Yiddish']
70
-
71
  # Utilisation du module deep_translator
72
- lang_tgt = ['fr', 'en', 'af', 'ak', 'sq', 'de', 'am', 'en', 'ar', 'hy', 'as', 'ay', 'az', 'bm', 'eu', 'bn', 'bho', 'be', 'my', 'bs', 'bg', 'ca', 'ceb', 'ny', 'zh-CN', 'zh-TW', 'si', 'ko', 'co', 'ht', 'hr', 'da', 'doi', 'gd', 'es', 'eo', 'et', 'ee', 'fi', 'fr', 'fy', 'gl', 'cy', 'lg', 'ka', 'el', 'gn', 'gu', 'ha', 'haw', 'iw', 'hi', 'hmn', 'hu', 'ig', 'ilo', 'id', 'ga', 'is', 'it', 'ja', 'jw', 'kn', 'kk', 'km', 'rw', 'ky', 'gom', 'kri', 'ku', 'ckb', 'lo', 'la', 'lv', 'ln', 'lt', 'lb', 'mk', 'mai', 'ms', 'ml', 'dv', 'mg', 'mt', 'mi', 'mr', 'mni-Mtei', 'lus', 'mn', 'nl', 'ne', 'no','or', 'om', 'ug', 'ur', 'uz', 'ps', 'pa', 'fa', 'pl', 'pt', 'qu', 'ro', 'ru', 'sm', 'sa', 'nso', 'sr', 'sn', 'sd', 'sk', 'sl', 'so', 'st', 'su', 'sv', 'sw', 'tg', 'tl', 'ta', 'tt', 'cs', 'te', 'th', 'ti', 'ts', 'tr', 'tk', 'uk', 'vi', 'xh', 'yi', 'yo', 'zu']
73
- label_lang = ['Français', 'Anglais / English','Afrikaans','Akan','Albanais','Allemand / Deutsch','Amharique','Anglais','Arabe','Arménien','Assamais','Aymara','Azéri','Bambara','Basque','Bengali','Bhojpuri','Biélorusse','Birman','Bosnien','Bulgare','Catalan','Cebuano','Chichewa','Chinois (simplifié)','Chinois (traditionnel)','Cingalais','Coréen','Corse','Créole haïtien','Croate','Danois','Dogri','Écossais','Espagnol / Español','Espéranto','Estonien','Ewe','Finnois','Français','Frisonoccidental','Galicien','Gallois','Ganda','Géorgien','Grec moderne','Guarani','Gujarati','Haoussa','Hawaïen','Hébreu','Hindi','Hmong','Hongrois','Igbo','Ilocano','Indonésien','Irlandais','Islandais','Italien / Italiano','Japonais','Javanais','Kannada','Kazakh','Khmer','Kinyarwanda','Kirghiz','Konkani','Krio','Kurde','Kurde (Sorani)','Lao','Latin','Letton','Lingala','Lituanien','Luxembourgeois','Macédonien','Maithili','Malais','Malayalam','Maldivien','Malgache','Maltais','Maori de Nouvelle-Zélande','Marathi','Meiteilon (Manipuri)','Mizo','Mongol','Néerlandais / Nederlands','Népalais','Norvégien','Oriya','Oromo','Ouïghour','Ourdou','Ouzbek','Pachto','Pendjabi','Persan','Polonais','Portugais','Quechua','Roumain','Russe','Samoan','Sanskrit','Sepedi','Serbe','Shona','Sindhi','Slovaque','Slovène','Somali','Sotho du Sud','Soundanais','Suédois','Swahili','Tadjik','Tagalog','Tamoul','Tatar','Tchèque','Télougou','Thaï','Tigrigna','Tsonga','Turc','Turkmène','Ukrainien','Vietnamien','Xhosa','Yiddish','Yoruba','Zulu']
 
74
 
75
- @st.cache_data
76
  def find_lang_label(lang_sel):
77
  global lang_tgt, label_lang
78
  return label_lang[lang_tgt.index(lang_sel)]
79
 
 
 
 
 
 
80
  def run():
81
 
82
  st.sidebar.image(
83
  "assets/value_props_logo.png",
84
  width=270,
85
  )
 
 
 
 
 
86
  with st.sidebar:
 
87
  tab_name = option_menu(None, list(TABS.keys()),
88
  # icons=['house', 'bi-binoculars', 'bi bi-graph-up', 'bi-chat-right-text','bi-book', 'bi-body-text'], menu_icon="cast", default_index=0,
89
  icons=['house', 'binoculars', 'graph-up', 'search','book', 'chat-right-text','controller'], menu_icon="cast", default_index=0,
@@ -101,7 +110,24 @@ def run():
101
  st.sidebar.markdown(member.sidebar_markdown(), unsafe_allow_html=True)
102
 
103
  with st.sidebar:
104
- st.selectbox("langue:",lang_tgt, format_func = find_lang_label, key="Language", label_visibility="hidden")
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
105
 
106
  tab = TABS[tab_name]
107
  tab.run()
 
17
  st.set_page_config (
18
  page_title=config.TITLE,
19
  page_icon= "assets/faviconV2.png",
20
+ layout="wide",
21
  initial_sidebar_state=st.session_state.sidebar_state
22
  )
23
 
 
59
  TABS = OrderedDict(
60
  [
61
  (tr(intro.sidebar_name), intro),
 
 
62
  (tr(chatbot_tab.sidebar_name), chatbot_tab),
63
+ (tr(sentence_similarity_tab.sidebar_name), sentence_similarity_tab),
64
+ # (tr(speech2text_tab.sidebar_name), speech2text_tab),
65
  ]
66
  )
67
 
 
 
 
 
68
  # Utilisation du module deep_translator
69
+ lang_tgt = ['fr', 'en','de','es', 'it', 'nl']
70
+ label_lang = ['Français','English','Deutsch','Español','Italiano','Nederlands']
71
+ label_lang_en = ['French', 'English', 'German', 'Spanish', 'Italian', 'Dutch']
72
 
73
+ # @st.cache_data
74
  def find_lang_label(lang_sel):
75
  global lang_tgt, label_lang
76
  return label_lang[lang_tgt.index(lang_sel)]
77
 
78
+ # @st.cache_data
79
+ def find_lang_label_en(lang_sel):
80
+ global lang_tgt, label_lang_en
81
+ return label_lang_en[lang_tgt.index(lang_sel)]
82
+
83
  def run():
84
 
85
  st.sidebar.image(
86
  "assets/value_props_logo.png",
87
  width=270,
88
  )
89
+ with st.sidebar.expander(tr("Développez moi")):
90
+ st.markdown(tr("""
91
+ Cette application vous permet de tester les futures fonctionnalités de la plateforme Value Props, et plus particulièrement « Sales Coaching ».
92
+ Amusez vous bien !
93
+ """))
94
  with st.sidebar:
95
+
96
  tab_name = option_menu(None, list(TABS.keys()),
97
  # icons=['house', 'bi-binoculars', 'bi bi-graph-up', 'bi-chat-right-text','bi-book', 'bi-body-text'], menu_icon="cast", default_index=0,
98
  icons=['house', 'binoculars', 'graph-up', 'search','book', 'chat-right-text','controller'], menu_icon="cast", default_index=0,
 
110
  st.sidebar.markdown(member.sidebar_markdown(), unsafe_allow_html=True)
111
 
112
  with st.sidebar:
113
+ st.write("")
114
+ llm_choice = st.selectbox("LLM:",["Mistral large","OpenAI 3.5","OpenAI 4o"], label_visibility="visible")
115
+ if (llm_choice == "OpenAI 3.5") : st.session_state.model = "gpt-3.5-turbo"
116
+ elif (llm_choice == "OpenAI 4o") : st.session_state.model = "gpt-4o"
117
+ else: st.session_state.model = "mistral-large-latest"
118
+
119
+ if (llm_choice in ["OpenAI 3.5","OpenAI 4o"]) and ('OPENAI_API_KEY' not in st.session_state):
120
+ # Set OpenAI API key
121
+ st.sidebar.subheader("OpenAI API Key")
122
+ openai_api_key = st.sidebar.text_input("Enter your OpenAI API Key:", type='password')
123
+ if openai_api_key:
124
+ os.environ['OPENAI_API_KEY'] = openai_api_key
125
+ st.session_state['OPENAI_API_KEY'] = openai_api_key
126
+ st.sidebar.success("OpenAI API Key set successfully.")
127
+
128
+ with st.sidebar:
129
+ l = st.selectbox("langue:",lang_tgt, format_func = find_lang_label, key="Language", label_visibility="hidden")
130
+ st.session_state.language_label = find_lang_label_en(l)
131
 
132
  tab = TABS[tab_name]
133
  tab.run()
style.css CHANGED
@@ -8,6 +8,11 @@ h2 {
8
  padding-bottom: 0.5rem;
9
  }
10
 
 
 
 
 
 
11
  /* La ligne suivante est nécessaire à cause du module streamlit_option_menu qui "casse" les CSS suivants */
12
  @media (prefers-color-scheme: dark) {
13
  .st-cc {
@@ -99,6 +104,13 @@ section[data-testid="stSidebar"] .stSelectbox .st-bk {
99
  background-color: #a0d3de;
100
  }
101
 
 
 
 
 
 
 
 
102
  section[data-testid="stSidebar"] .stSelectbox .st-cc {
103
  color: rgb(255, 75, 75);
104
  font-weight: bold;
 
8
  padding-bottom: 0.5rem;
9
  }
10
 
11
+ h3 {
12
+ padding-bottom: 0.0rem;
13
+ }
14
+
15
+
16
  /* La ligne suivante est nécessaire à cause du module streamlit_option_menu qui "casse" les CSS suivants */
17
  @media (prefers-color-scheme: dark) {
18
  .st-cc {
 
104
  background-color: #a0d3de;
105
  }
106
 
107
+ .st-emotion-cache-1h9usn1{
108
+ font-weight: bold!important;
109
+ background-color: #a0d3de;
110
+ }
111
+
112
+
113
+
114
  section[data-testid="stSidebar"] .stSelectbox .st-cc {
115
  color: rgb(255, 75, 75);
116
  font-weight: bold;
tabs/chatbot_tab.py CHANGED
@@ -22,6 +22,7 @@ from langchain_core.messages import BaseMessage, SystemMessage, HumanMessage, AI
22
  from langgraph.graph.message import add_messages
23
  from typing_extensions import Annotated, TypedDict
24
  from dotenv import load_dotenv
 
25
 
26
  import warnings
27
  warnings.filterwarnings('ignore')
@@ -38,21 +39,14 @@ if st.session_state.Cloud != 0:
38
  load_dotenv()
39
  os.getenv("LANGCHAIN_API_KEY")
40
  os.getenv("MISTRAL_API_KEY")
41
- # os.getenv("OPENAI_API_KEY")
42
-
43
-
44
-
45
-
46
- model = ChatMistralAI(model="mistral-large-latest")
47
- # model = ChatOpenAI(model="gpt-3.5-turbo")
48
 
49
 
50
- language = "French"
51
  prompt = ChatPromptTemplate.from_messages(
52
  [
53
  (
54
  "system",
55
- "Répond à toutes les questions du mieux possible en {language}.",
56
  ),
57
  MessagesPlaceholder(variable_name="messages"),
58
  ]
@@ -81,51 +75,117 @@ app = workflow.compile(checkpointer=memory)
81
 
82
  # @st.cache_data
83
  def init():
84
- global config,thread_id, context,human_message1,ai_message1,language, app, model_speech
85
 
86
  thread_id = datetime.now().strftime("%Y-%m-%d %H:%M:%S")
87
  config = {"configurable": {"thread_id": thread_id}}
88
  model_speech = whisper.load_model("base")
 
 
 
 
 
89
 
90
- context = """Tu es un Directeur Commercial, mal organisé, d'une entreprise qui commercialise une solution technologique B2B. """
91
- human_message1 = """Je souhaites que nous ayons une conversation verbale entre un commercial de mon entreprise, Marc (moi), et toi que je prospecte.
92
- Mon entreprise propose une solution logicielle pour gérer la proposition de valeur d’entreprises B2B qui commercialises des solutions technologiques.
 
 
93
 
94
- Les problématiques adressées par ma solution sont:
95
- - Il est difficile pour les startups de concevoir et formaliser une proposition de valeur unique et pertinente
96
- - Il est difficile pour les forces de vente d'articuler clairement les messages de la proposition de valeur
97
- - Il est chronophage pour les scale-ups de former leur forces de ventes sur les évolutions de la proposition de valeur et de ses messages Valeur ajoutée de ma solution
98
- - Augmenter les performances commerciales
99
- - Réduction du cycle de vente
100
- - Accelerer la croissance du chiffre d'affaires
101
- - Concentrer les ressources sur les opportunités qualifiées
102
- - Réduction temps de monté en compétence des nouvelles embauches
103
- - Augmenter le taux de conversion d'affaires gagnées
104
- - Améliorer l'efficacité globale des ventes
105
- - Améliorer l'efficience et la confiance des forces de ventes
106
- - Optimiser les processus commerciaux pour réduire les cycles de vente, fidéliser les clients et augmenter la productivité
107
- - Favoriser le développement personnel des forces de vente
108
-
109
- Les cas d’usages adressés par ma solution sont :
110
- - Affiner et modéliser la proposition de valeur
111
- - Décliner les messages marketing & commerciaux
112
- - Former la force de vente sur la proposition de valeur
113
- - Orchestrer les conversations clients
114
- - Partager les retours terrain
115
- - Mettre en oeuvre des meilleures pratiques commerciales
116
- - Identifier et reproduire les messages de vente gagnants
117
-
118
- Je suis Marc, le vendeur.
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
119
  Répond à mes questions en tant que Directeur commercial désorganisé, connaissant mal le concept de proposition de valeur,
120
  et mon équipe de vente n'est pas performante.
121
 
122
- Attention: Ce n'est pas toi qui m'aide, c'est moi qui t'aide avec ma solution.
123
- """
124
- ai_message1 = "J'ai bien compris, je suis un Directeur Commercial prospecté et je réponds seulement à tes questions. Je réponds à une seule question à la fois, sans commencer mes réponses par 'En tant que Directeur Commercial'"
 
 
 
 
 
 
 
125
 
126
- context = st.text_area(label=tr("Contexte:"), value=context)
127
- human_message1 = st.text_area(label=tr("Consigne"), value=human_message1,height=300)
128
- ai_message1 = st.text_area(label=tr("Réponse du prospect"), value=ai_message1)
129
  messages = [
130
  SystemMessage(content=context),
131
  HumanMessage(content=human_message1),
@@ -134,19 +194,13 @@ Attention: Ce n'est pas toi qui m'aide, c'est moi qui t'aide avec ma solution.
134
  ]
135
 
136
 
137
-
138
  app.invoke(
139
  {"messages": messages, "language": language},
140
  config,
141
  )
142
- '''
143
- st.write("**Contexte:** "+context)
144
- st.write("")
145
- st.write("**Human Message:** "+human_message1)
146
- st.write("")
147
- st.write("**AI Message:** "+ai_message1)
148
- '''
149
  st.write("")
 
150
  return config, thread_id
151
 
152
  # Fonction pour générer et jouer le texte en speech
@@ -175,24 +229,41 @@ def play_audio(custom_sentence, Lang_target, speed=1.0):
175
  new_audio_stream_bytesio.seek(0)
176
 
177
  # Lire l'audio dans Streamlit
178
- st.audio(new_audio_stream_bytesio, autoplay=True)
 
179
 
180
 
181
 
182
  def run():
183
- global thread_id, config, model_speech
184
 
185
  st.write("")
186
  st.write("")
187
  st.title(tr(title))
188
 
 
 
 
 
189
  chosen_id = tab_bar(data=[
190
  TabBarItemData(id="tab1", title=tr("Initialisation"), description=tr("d'une nouvelle conversation")),
191
- TabBarItemData(id="tab2", title=tr("Conversation"), description=tr("avec le prospect"))],
 
192
  default="tab1")
193
 
194
 
195
  if (chosen_id == "tab1"):
 
 
 
 
 
 
 
 
 
 
 
196
  config,thread_id = init()
197
  query = ""
198
  st.button(label=tr("Validez"), type="primary")
@@ -202,87 +273,103 @@ def run():
202
  # On ne fait rien
203
  except NameError:
204
  config,thread_id = init()
205
-
206
- st.write("**thread_id:** "+thread_id)
207
- # query = st.text_area(label=tr("Vendeur:"), value="")
208
- query = ""
209
- audio_bytes = audio_recorder (pause_threshold=2.0, sample_rate=16000, auto_start=True, text=tr("Cliquez pour parler, puis attendre 2sec."), \
210
- recording_color="#e8b62c", neutral_color="#1ec3bc", icon_size="6x",)
211
-
212
- if audio_bytes:
213
- st.write("**"+tr("Vendeur")+" :**\n")
214
- # Fonction pour générer et jouer le texte en speech
215
- st.audio(audio_bytes, format="audio/wav", autoplay=False)
216
- try:
217
- detection = False
218
- if detection:
219
- # Create a BytesIO object from the audio stream
220
- audio_stream_bytesio = io.BytesIO(audio_bytes)
221
-
222
- # Read the WAV stream using wavio
223
- wav = wavio.read(audio_stream_bytesio)
224
-
225
- # Extract the audio data from the wavio.Wav object
226
- audio_data = wav.data
227
-
228
- # Convert the audio data to a NumPy array
229
- audio_input = np.array(audio_data, dtype=np.float32)
230
- audio_input = np.mean(audio_input, axis=1)/32768
231
-
232
- result = model_speech.transcribe(audio_input)
233
- Lang_detected = result["language"]
234
- query = result["text"]
235
- st.write(tr("Langue détectée")+" : "+Lang_detected)
236
-
237
- else:
238
- # Avec l'aide de la bibliothèque speech_recognition de Google
239
- Lang_detected = "fr"
240
- # Transcription google
241
- audio_stream = sr.AudioData(audio_bytes, 32000, 2)
242
- r = sr.Recognizer()
243
- query = r.recognize_google(audio_stream, language = Lang_detected)
244
-
245
- # Transcription
246
- st.write("**Vendeur :** "+query)
247
- st.write("")
248
 
249
- if query != "":
250
- input_messages = [HumanMessage(query)]
251
- output = app.invoke(
252
- {"messages": input_messages, "language": language},
253
- config,
254
- )
255
-
256
- # Récupération de la réponse
257
- custom_sentence = output["messages"][-1].content
258
-
259
- # Joue l'audio
260
- if language=="French": Lang_target = "fr" # Langue de la réponse
261
- play_audio(custom_sentence, Lang_target, 1)
262
-
263
- st.write("**Prospect :** "+custom_sentence)
264
-
265
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
266
 
267
- except KeyboardInterrupt:
268
- st.write(tr("Arrêt de la reconnaissance vocale."))
269
- except:
270
- st.write(tr("Problème, essayer de nouveau.."))
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
271
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
272
 
273
- '''
274
- # Créer un espace réservé pour afficher les tokens
275
- placeholder = st.empty()
276
-
277
- for chunk, metadata in app.stream(
278
- {"messages": input_messages, "language": language},
279
- config,
280
- stream_mode="messages",
281
- ):
282
- if isinstance(chunk, AIMessage): # Filter to just model responses
283
- # st.markdown("<span style='white-space: nowrap;'>"+"/"+chunk.content+"/"+"</span>", unsafe_allow_html=True)
284
- placeholder.markdown(f"<p style='display: inline;'>{chunk.content}</p>", unsafe_allow_html=True)
285
- '''
286
  st.write("")
287
  st.write("")
288
  st.write("")
 
22
  from langgraph.graph.message import add_messages
23
  from typing_extensions import Annotated, TypedDict
24
  from dotenv import load_dotenv
25
+ import time
26
 
27
  import warnings
28
  warnings.filterwarnings('ignore')
 
39
  load_dotenv()
40
  os.getenv("LANGCHAIN_API_KEY")
41
  os.getenv("MISTRAL_API_KEY")
42
+ os.getenv("OPENAI_API_KEY")
 
 
 
 
 
 
43
 
44
 
 
45
  prompt = ChatPromptTemplate.from_messages(
46
  [
47
  (
48
  "system",
49
+ "Répond à toutes les questions du mieux possible dans la langue {language}, même si la question est posée dans une autre langue",
50
  ),
51
  MessagesPlaceholder(variable_name="messages"),
52
  ]
 
75
 
76
  # @st.cache_data
77
  def init():
78
+ global config,thread_id, context,human_message1,ai_message1,language, app, model_speech,language,prompt,model
79
 
80
  thread_id = datetime.now().strftime("%Y-%m-%d %H:%M:%S")
81
  config = {"configurable": {"thread_id": thread_id}}
82
  model_speech = whisper.load_model("base")
83
+
84
+ options = ["Directeur Commercial", "Directeur Général", "Directeur Marketing"]
85
+ translated_options = [tr(o) for o in options]
86
+ selected_option = st.selectbox(tr("Interlocuteur"),translated_options)
87
+ selected_index = translated_options.index(selected_option)
88
 
89
+ options2 = ["Entreprise qui commercialise des solutions (produits et ou services) B2B innovantes avec une équipe commerciale de plus de 15 personnes",
90
+ "Entreprise qui commercialise des solutions (produits et ou services) B2B innovantes avec une équipe commerciale de plus de 100 personnes"]
91
+ translated_options2 = [tr(o) for o in options2]
92
+ selected_option2 = st.selectbox(tr("Activité"),translated_options2)
93
+ selected_index2 = translated_options2.index(selected_option2)
94
 
95
+ options3 = ["Logiciels informatiques et d’application SaaS",
96
+ "Équipements et solutions industrielles",
97
+ "Services et conseil spécialisés"]
98
+ translated_options3 = [tr(o) for o in options3]
99
+ selected_option3 = st.selectbox(tr("Domaine d'activité"),translated_options3)
100
+ selected_index3 = translated_options3.index(selected_option3)
101
+
102
+ context = tr(f"""Tu es un {options[selected_index]}, mal organisé, d'une {options2[selected_index2]}.
103
+ Cette entreprise propose des {options3[selected_index3]}.
104
+ """)
105
+ context = st.text_area(label=tr("Résumé du Contexte (modifiable):"), value=context)
106
+ st.markdown('''
107
+ ------------------------------------------------------------------------------------
108
+ ''')
109
+
110
+ options4 = ["Il est difficile pour les forces de vente d'articuler clairement les messages de la proposition de valeur",
111
+ "Il est difficile d’affiner une proposition de valeur unique et pertinente de l'offre face à la concurrence qui évolue rapidement",
112
+ "Il est chronophage de former les forces de ventes sur la proposition de valeur et ses évolutions"
113
+ ]
114
+ selected_options4 = st.multiselect(tr("Problématiques"),[tr(o) for o in options4])
115
+ problematique = [tr(o) for o in selected_options4]
116
+ markdown_text4 = tr("""
117
+ Les problématiques rencontrés par notre prospect (problèmes à résoudre) sont:""")
118
+ markdown_text4 = markdown_text4+"".join(f"\n- {o}" for o in problematique)
119
+ st.write(markdown_text4)
120
+
121
+ options5 = ["Former la force de ventes sur l'articulation de la proposition de valeur",
122
+ "Aligner les messages marketing et commerciaux",
123
+ "Affiner et modéliser la proposition de valeur",
124
+ "Mettre en oeuvre des meilleures pratiques commerciales"
125
+ ]
126
+ selected_options5 = st.multiselect(tr("Processus"),[tr(o) for o in options5])
127
+ processus = [tr(o) for o in selected_options5]
128
+ markdown_text5 = tr("""
129
+ \nLes processus adressés par le prospect (cas d’usages) sont:""")
130
+ markdown_text5 = markdown_text5+"".join(f"\n- {o}" for o in processus)
131
+ st.write(markdown_text5)
132
+
133
+ options6 = ["Augmenter les performances commerciales",
134
+ "Croissance du chiffre d’affaires",
135
+ "Réduire les cycles de vente",
136
+ "Augmenter taux de conversion d’affaires gagnées",
137
+ "Améliorer l’efficience et la confiance des forces de ventes",
138
+ "Réduire temps de monté en compétence des nouvelles embauches",
139
+ "Fidéliser les clients"
140
+ ]
141
+ selected_options6 = st.multiselect(tr("Objectifs d'amélioration"),[tr(o) for o in options6])
142
+ objectifs = [tr(o) for o in selected_options6]
143
+ markdown_text6 = tr("""
144
+ \nLes objectifs d’amélioration opérationnelle du prospect (Valeur ajoutée) sont:""")
145
+ markdown_text6 = markdown_text6+"".join(f"\n- {o}" for o in objectifs)
146
+ st.write(markdown_text6)
147
+
148
+ options7 = ["Gestion de contenu commercial avec logiciel Microsoft sharePoint ou GoogleDrive",
149
+ "Playbook développé en interne sur outils génériques tels que logiciel Notion, Powerpoint, Excel, Word, Docs",
150
+ "Outils de sales enablement tels que application Seismic",
151
+ "Outils de gestion des présentations clients tels que Logiciel Powerpoint ou Google slide",
152
+ "Conseil externe en positionnement marché & produit",
153
+ "Services externes de formation des équipes commerciales"
154
+ ]
155
+ selected_options7 = st.multiselect(tr("Solutions utilisées"),[tr(o) for o in options7])
156
+ solutions_utilisees = [tr(o) for o in selected_options7]
157
+ markdown_text7 = tr("""
158
+ \nLes principales Solutions utilisées par nos prospects pour traiter les cas d’usages (Catégories de solutions du marché) sont:""")
159
+ markdown_text7 = markdown_text7+"".join(f"\n- {o}" for o in solutions_utilisees)
160
+ st.write(markdown_text7)
161
+ st.write("")
162
+ col1, col2, col3 = st.columns(3)
163
+ with col1:
164
+ virulence = st.slider(tr("Virulence (choisissez une valeur entre 1 et 5)"), min_value=1, max_value=5, step=1)
165
+ markdown_text8 = tr(f"""\nTu vas utiliser une échelle de 1 à 5 de virulence. Pour cette simulation utilise le niveaux {virulence}""")
166
+
167
+ human_message1 = tr("""Je souhaites que nous ayons une conversation verbale entre un commercial de mon entreprise, et toi que je prospecte.
168
+ Mon entreprise propose une solution logicielle pour gérer la proposition de valeur d’entreprises B2B qui commercialises des solutions technologiques.
169
+ """)+markdown_text4+markdown_text5+markdown_text6+markdown_text7+tr("""
170
+
171
+ Je suis le vendeur.
172
  Répond à mes questions en tant que Directeur commercial désorganisé, connaissant mal le concept de proposition de valeur,
173
  et mon équipe de vente n'est pas performante.
174
 
175
+ Attention: Ce n'est pas toi qui m'aide, c'est moi qui t'aide avec ma solution.
176
+
177
+ """)+markdown_text8
178
+
179
+ human_message1 = st.text_area(label=tr("Consigne"), value=tr(human_message1),height=300)
180
+ st.markdown('''
181
+ ------------------------------------------------------------------------------------
182
+ ''')
183
+
184
+ ai_message1 = tr(f"J'ai bien compris, je suis un {options[selected_index]} prospecté et je réponds seulement à tes questions. Je réponds à une seule question à la fois, sans commencer mes réponses par 'En tant que {options[selected_index]}'")
185
 
186
+
187
+
188
+ # ai_message1 = st.text_area(label=tr("Réponse du prospect"), value=ai_message1)
189
  messages = [
190
  SystemMessage(content=context),
191
  HumanMessage(content=human_message1),
 
194
  ]
195
 
196
 
 
197
  app.invoke(
198
  {"messages": messages, "language": language},
199
  config,
200
  )
201
+
 
 
 
 
 
 
202
  st.write("")
203
+ st.session_state.messages = []
204
  return config, thread_id
205
 
206
  # Fonction pour générer et jouer le texte en speech
 
229
  new_audio_stream_bytesio.seek(0)
230
 
231
  # Lire l'audio dans Streamlit
232
+ time.sleep(2)
233
+ st.audio(new_audio_stream_bytesio, start_time=0, autoplay=True)
234
 
235
 
236
 
237
  def run():
238
+ global thread_id, config, model_speech, language,prompt,model
239
 
240
  st.write("")
241
  st.write("")
242
  st.title(tr(title))
243
 
244
+ if 'language_label' in st.session_state:
245
+ language = st.session_state['language_label']
246
+ else: language = "French"
247
+
248
  chosen_id = tab_bar(data=[
249
  TabBarItemData(id="tab1", title=tr("Initialisation"), description=tr("d'une nouvelle conversation")),
250
+ TabBarItemData(id="tab2", title=tr("Conversation"), description=tr("avec le prospect")),
251
+ TabBarItemData(id="tab3", title=tr("Evaluation"), description=tr("de l'acte de vente"))],
252
  default="tab1")
253
 
254
 
255
  if (chosen_id == "tab1"):
256
+ if 'model' in st.session_state and (st.session_state.model[:3]=="gpt") and ("OPENAI_API_KEY" in st.session_state):
257
+ model = ChatOpenAI(model=st.session_state.model,
258
+ temperature=0.8, # Adjust creativity level
259
+ max_tokens=150 # Define max output token limit
260
+ )
261
+
262
+ else:
263
+ st.session_state.model = "mistral-large-latest"
264
+ model = ChatMistralAI(model=st.session_state.model)
265
+
266
+
267
  config,thread_id = init()
268
  query = ""
269
  st.button(label=tr("Validez"), type="primary")
 
273
  # On ne fait rien
274
  except NameError:
275
  config,thread_id = init()
276
+ with st.container():
277
+ # Diviser l'écran en deux colonnes
278
+ col1, col2 = st.columns(2)
279
+ # with col1:
280
+ # st.markdown(
281
+ # """
282
+ # <div style="height: 400px;">
283
+ # </div>
284
+ # """,
285
+ # unsafe_allow_html=True,
286
+ # )
287
+ with col1:
288
+ st.write("**thread_id:** "+thread_id)
289
+ query = ""
290
+ audio_bytes = audio_recorder (pause_threshold=2.0, sample_rate=16000, auto_start=False, text=tr("Cliquez pour parler, puis attendre 2sec."), \
291
+ recording_color="#e8b62c", neutral_color="#1ec3bc", icon_size="6x",)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
292
 
293
+ if audio_bytes:
294
+ # st.write("**"+tr("Vendeur")+" :**\n")
295
+ # Fonction pour générer et jouer le texte en speech
296
+ st.audio(audio_bytes, format="audio/wav", autoplay=False)
297
+ try:
298
+ detection = False
299
+ if detection:
300
+ # Create a BytesIO object from the audio stream
301
+ audio_stream_bytesio = io.BytesIO(audio_bytes)
 
 
 
 
 
 
 
302
 
303
+ # Read the WAV stream using wavio
304
+ wav = wavio.read(audio_stream_bytesio)
305
+
306
+ # Extract the audio data from the wavio.Wav object
307
+ audio_data = wav.data
308
+
309
+ # Convert the audio data to a NumPy array
310
+ audio_input = np.array(audio_data, dtype=np.float32)
311
+ audio_input = np.mean(audio_input, axis=1)/32768
312
+
313
+ result = model_speech.transcribe(audio_input)
314
+ Lang_detected = result["language"]
315
+ query = result["text"]
316
+
317
+ else:
318
+ # Avec l'aide de la bibliothèque speech_recognition de Google
319
+ Lang_detected = st.session_state['Language']
320
+ # Transcription google
321
+ audio_stream = sr.AudioData(audio_bytes, 32000, 2)
322
+ r = sr.Recognizer()
323
+ query = r.recognize_google(audio_stream, language = Lang_detected)
324
+
325
+ # Transcription
326
+ # st.write("**"+tr("Vendeur :")+"** "+query)
327
+ with st.chat_message("user"):
328
+ st.markdown(query)
329
+ st.write("")
330
 
331
+ if query != "":
332
+ input_messages = [HumanMessage(query)]
333
+ output = app.invoke(
334
+ {"messages": input_messages, "language": language},
335
+ config,
336
+ )
337
+ #with st.chat_message("user"):
338
+ # Add user message to chat history
339
+ st.session_state.messages.append({"role": "user", "content": query})
340
+
341
+ # Récupération de la réponse
342
+ custom_sentence = output["messages"][-1].content
343
+
344
+ # Joue l'audio
345
+ l = st.session_state['Language']
346
+ play_audio(custom_sentence,l , 1)
347
+
348
+ # st.write("**"+tr("Prospect :")+"** "+custom_sentence)
349
+ with st.chat_message("assistant"):
350
+ st.markdown(custom_sentence)
351
+
352
+ # Add user message to chat history
353
+ st.session_state.messages.append({"role": "assistant", "content": custom_sentence})
354
+
355
 
356
+
357
+ except KeyboardInterrupt:
358
+ st.write(tr("Arrêt de la reconnaissance vocale."))
359
+ except:
360
+ st.write(tr("Problème, essayer de nouveau.."))
361
+ st.write("")
362
+ # Ajouter un espace pour séparer les zones
363
+ # st.divider()
364
+ with col2:
365
+ # with st.container():
366
+ if query:
367
+ # Display chat messages from history on app rerun
368
+
369
+ for message in st.session_state.messages:
370
+ with st.chat_message(message["role"]):
371
+ st.markdown(message["content"])
372
 
 
 
 
 
 
 
 
 
 
 
 
 
 
373
  st.write("")
374
  st.write("")
375
  st.write("")
tabs/intro.py CHANGED
@@ -24,12 +24,15 @@ def run():
24
  st.title(tr(title))
25
  st.markdown('''
26
  ## **'''+tr("Système d'aide à la mise en oeuvre d'une Proposition de Valeur en entreprise")+'''**
27
- ---
28
  ''')
29
- st.header("**"+tr("A propos")+"**")
30
  st.markdown(tr(
31
  """
32
- Cet espace a pour objectif de tester les differentes briques nécéssaires pour l'outils "Value Props"
 
 
 
 
33
  """)
34
  , unsafe_allow_html=True)
35
 
 
24
  st.title(tr(title))
25
  st.markdown('''
26
  ## **'''+tr("Système d'aide à la mise en oeuvre d'une Proposition de Valeur en entreprise")+'''**
27
+ ------------------------------------------------------------------------------------
28
  ''')
 
29
  st.markdown(tr(
30
  """
31
+ <h4>
32
+ Bienvenue dans le fabuleux univers de Value Props.<br>
33
+ Decouvrez et testez ici les futures fonctionnalités que la plateforme souhaite vous proposer.<br>
34
+ N'hesitez pas à nous faire part de vos commentaires en les envoyant à [email protected]<br>
35
+ </h4>
36
  """)
37
  , unsafe_allow_html=True)
38
 
translate_app.py CHANGED
@@ -18,7 +18,9 @@ def trad(message,l):
18
  return "Problème de traduction.."
19
 
20
  def tr(message):
21
- if 'Language' not in st.session_state: l = 'fr'
 
 
22
  else: l= st.session_state['Language']
23
  if l == 'fr': return message
24
  else: message = message.replace(":red[**","").replace("**]","")
 
18
  return "Problème de traduction.."
19
 
20
  def tr(message):
21
+ if 'Language' not in st.session_state:
22
+ l = 'fr'
23
+ st.session_state['Language'] = l
24
  else: l= st.session_state['Language']
25
  if l == 'fr': return message
26
  else: message = message.replace(":red[**","").replace("**]","")