Spaces:
Sleeping
Sleeping
Commit
·
f87d5e7
1
Parent(s):
da91f13
Add dynamic AI-generated greeting for first message
Browse filesIntroduced a generate_greeting function to create a more natural, context-aware first message using AI, based on lead and call type (B2B/B2C). Updated the setup page to collect the manager's name and improved Ukrainian localization. Modified the chat flow to use the AI-generated greeting as the initial assistant message, and updated the sales script's start node to provide a more detailed instruction for the greeting.
- app.py +57 -13
- sales_script.json +1 -1
app.py
CHANGED
|
@@ -194,6 +194,31 @@ def generate_response(model, context, user_input, intent, lead_info, archetype):
|
|
| 194 |
return model.generate_content(prompt).text.strip()
|
| 195 |
except: return "..."
|
| 196 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 197 |
# --- UI COMPONENTS ---
|
| 198 |
def draw_graph(graph_data, current_node, predicted_path):
|
| 199 |
nodes = graph_data[3]
|
|
@@ -300,21 +325,36 @@ if st.session_state.page == "dashboard":
|
|
| 300 |
|
| 301 |
# --- PAGE: SETUP ---
|
| 302 |
elif st.session_state.page == "setup":
|
| 303 |
-
st.title("👤
|
|
|
|
| 304 |
with st.form("lead_form"):
|
|
|
|
|
|
|
|
|
|
|
|
|
| 305 |
c1, c2 = st.columns(2)
|
| 306 |
-
name = c1.text_input("
|
| 307 |
-
company = c2.text_input("
|
| 308 |
-
|
| 309 |
-
|
|
|
|
| 310 |
|
| 311 |
-
|
| 312 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 313 |
st.session_state.messages = []
|
| 314 |
st.session_state.current_node = "start"
|
| 315 |
-
st.session_state.
|
| 316 |
-
st.session_state.checklist = {k:False for k in st.session_state.checklist} # Reset
|
| 317 |
st.session_state.page = "chat"
|
|
|
|
| 318 |
st.rerun()
|
| 319 |
|
| 320 |
# --- PAGE: CHAT ---
|
|
@@ -434,11 +474,15 @@ elif st.session_state.page == "chat":
|
|
| 434 |
for msg in st.session_state.messages:
|
| 435 |
with st.chat_message(msg["role"]): st.write(msg["content"])
|
| 436 |
|
|
|
|
| 437 |
if not st.session_state.messages:
|
| 438 |
-
|
| 439 |
-
|
| 440 |
-
|
| 441 |
-
|
|
|
|
|
|
|
|
|
|
| 442 |
st.session_state.messages.append({"role": "assistant", "content": greeting})
|
| 443 |
st.rerun()
|
| 444 |
|
|
|
|
| 194 |
return model.generate_content(prompt).text.strip()
|
| 195 |
except: return "..."
|
| 196 |
|
| 197 |
+
def generate_greeting(model, start_node_text, lead_info):
|
| 198 |
+
"""Генерує ПЕРШЕ повідомлення, щоб воно було живим"""
|
| 199 |
+
|
| 200 |
+
prompt = f"""
|
| 201 |
+
ROLE: Professional Sales Rep named {lead_info['bot_name']}.
|
| 202 |
+
CLIENT: {lead_info['client_name']} from {lead_info['company']}.
|
| 203 |
+
TYPE: {lead_info['type']} ({lead_info['context']}).
|
| 204 |
+
|
| 205 |
+
GOAL: Start the conversation based on this script instruction: "{start_node_text}".
|
| 206 |
+
|
| 207 |
+
INSTRUCTIONS:
|
| 208 |
+
- If B2B Cold Call: Be formal, check if this is the right company, ask for the decision maker.
|
| 209 |
+
- If B2C: Be friendly, use the client's name directly.
|
| 210 |
+
- ALWAYS state your name ({lead_info['bot_name']}) and company (SellMe AI).
|
| 211 |
+
- Make it sound natural, not robotic.
|
| 212 |
+
- Language: Ukrainian.
|
| 213 |
+
|
| 214 |
+
OUTPUT: Just the spoken greeting.
|
| 215 |
+
"""
|
| 216 |
+
try:
|
| 217 |
+
return model.generate_content(prompt).text.strip()
|
| 218 |
+
except:
|
| 219 |
+
return f"Доброго дня, це {lead_info['bot_name']} з SellMe. Маєте хвилинку?"
|
| 220 |
+
|
| 221 |
+
|
| 222 |
# --- UI COMPONENTS ---
|
| 223 |
def draw_graph(graph_data, current_node, predicted_path):
|
| 224 |
nodes = graph_data[3]
|
|
|
|
| 325 |
|
| 326 |
# --- PAGE: SETUP ---
|
| 327 |
elif st.session_state.page == "setup":
|
| 328 |
+
st.title("👤 Налаштування Дзвінка")
|
| 329 |
+
|
| 330 |
with st.form("lead_form"):
|
| 331 |
+
st.markdown("### 👨💼 Хто дзвонить?")
|
| 332 |
+
bot_name = st.text_input("Ваше ім'я (Менеджера)", "Олексій")
|
| 333 |
+
|
| 334 |
+
st.markdown("### 📞 Кому дзвонимо?")
|
| 335 |
c1, c2 = st.columns(2)
|
| 336 |
+
name = c1.text_input("Ім'я Клієнта", "Олександр")
|
| 337 |
+
company = c2.text_input("Компанія (для B2B)", "SoftServe")
|
| 338 |
+
|
| 339 |
+
type_ = c1.selectbox("Тип бізнесу", ["B2B", "B2C"])
|
| 340 |
+
context = c2.selectbox("Контекст", ["Холодний дзвінок", "Теплий лід (заявка)", "Повторний дзвінок"])
|
| 341 |
|
| 342 |
+
submitted = st.form_submit_button("🚀 Почати розмову")
|
| 343 |
+
|
| 344 |
+
if submitted:
|
| 345 |
+
# Зберігаємо все, включаючи ім'я бота
|
| 346 |
+
st.session_state.lead_info = {
|
| 347 |
+
"bot_name": bot_name,
|
| 348 |
+
"client_name": name,
|
| 349 |
+
"company": company,
|
| 350 |
+
"type": type_,
|
| 351 |
+
"context": context
|
| 352 |
+
}
|
| 353 |
st.session_state.messages = []
|
| 354 |
st.session_state.current_node = "start"
|
| 355 |
+
st.session_state.checklist = {k:False for k in st.session_state.checklist}
|
|
|
|
| 356 |
st.session_state.page = "chat"
|
| 357 |
+
st.session_state.visited_history = []
|
| 358 |
st.rerun()
|
| 359 |
|
| 360 |
# --- PAGE: CHAT ---
|
|
|
|
| 474 |
for msg in st.session_state.messages:
|
| 475 |
with st.chat_message(msg["role"]): st.write(msg["content"])
|
| 476 |
|
| 477 |
+
# --- ГЕНЕРАЦІЯ ПЕРШОГО ПОВІДОМЛЕННЯ ---
|
| 478 |
if not st.session_state.messages:
|
| 479 |
+
with st.spinner("AI готується до дзвінка..."):
|
| 480 |
+
start_instruction = nodes["start"]
|
| 481 |
+
# Викликаємо AI для генерації живого привітання
|
| 482 |
+
# lead_info keys might differ if coming from very old session, but setup ensures keys exist.
|
| 483 |
+
# Just in case, defaults from setup form are used.
|
| 484 |
+
greeting = generate_greeting(model, start_instruction, st.session_state.lead_info)
|
| 485 |
+
|
| 486 |
st.session_state.messages.append({"role": "assistant", "content": greeting})
|
| 487 |
st.rerun()
|
| 488 |
|
sales_script.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
| 1 |
{
|
| 2 |
"nodes": {
|
| 3 |
-
"start": "
|
| 4 |
"objection_busy": "Розумію, часу обмаль. Але це займе всього 30 секунд, а зекономить вам години. Тільки одне питання: як ви зараз шукаєте клієнтів?",
|
| 5 |
"qualification": "Скажіть, ви зараз використовуєте якусь CRM чи ведете все в Excel/блокноті?",
|
| 6 |
"tech_shame": "Ох, Excel — це класика, але ж уявіть, скільки лідів там губиться! А якби система сама нагадувала про кожного клієнта?",
|
|
|
|
| 1 |
{
|
| 2 |
"nodes": {
|
| 3 |
+
"start": "ПРИВІТАННЯ. Мета: Представитися, переконатися, що говоримо з ЛПР (особою, що приймає рішення), і зачепити увагу інтригою (згадати про ріст продажів).",
|
| 4 |
"objection_busy": "Розумію, часу обмаль. Але це займе всього 30 секунд, а зекономить вам години. Тільки одне питання: як ви зараз шукаєте клієнтів?",
|
| 5 |
"qualification": "Скажіть, ви зараз використовуєте якусь CRM чи ведете все в Excel/блокноті?",
|
| 6 |
"tech_shame": "Ох, Excel — це класика, але ж уявіть, скільки лідів там губиться! А якби система сама нагадувала про кожного клієнта?",
|