Sales-AI-Core / sellme_smart.py
Romanchello-bit's picture
gemini api added
7b43e9f
import json
import os
import sys
import google.generativeai as genai
from graph_module import Graph
from algorithms import bellman_ford_list
# --- ФІКС КОДУВАННЯ ДЛЯ WINDOWS ---
sys.stdout.reconfigure(encoding='utf-8')
# --- ТВОЯ МОДЕЛЬ ---
MODEL_NAME = "gemini-2.5-flash"
def configure_genai():
"""Налаштування API ключа"""
api_key = os.environ.get("GOOGLE_API_KEY")
if not api_key:
print("--- Налаштування API ---")
api_key = input("Встав свій Google API Key (права кнопка миші -> Paste): ").strip()
try:
genai.configure(api_key=api_key)
return True
except Exception as e:
print(f"Error configuring Gemini: {e}")
return False
def load_data():
"""Завантажує скрипт і будує граф"""
script_file = "sales_script_learned.json" if os.path.exists("sales_script_learned.json") else "sales_script.json"
with open(script_file, "r", encoding="utf-8") as f:
data = json.load(f)
nodes = data["nodes"]
edges = data["edges"]
node_to_id = {name: i for i, name in enumerate(nodes.keys())}
id_to_node = {i: name for i, name in enumerate(nodes.keys())}
graph = Graph(len(nodes), directed=True)
for edge in edges:
u, v = edge["from"], edge["to"]
if u in node_to_id and v in node_to_id:
graph.add_edge(node_to_id[u], node_to_id[v], edge["weight"])
return graph, node_to_id, id_to_node, nodes
def analyze_intent(model, user_input, current_step_text):
"""
Визначає наміри клієнта (MOVE або STAY).
"""
prompt = f"""
ROLE: Sales Logic Engine.
CONTEXT:
Bot said: "{current_step_text}"
User said: "{user_input}"
TASK: Determine if the user allows moving forward.
RULES:
- Agreement / Positive answer / Neutral info -> RETURN 'MOVE'
- Objection / Question / Confusion / Anger -> RETURN 'STAY'
- "Stop" / "Bye" -> RETURN 'EXIT'
OUTPUT: Just one word: MOVE, STAY, or EXIT.
"""
try:
# Використовуємо саме твою модель
response = model.generate_content(prompt)
decision = response.text.strip().upper()
if "EXIT" in decision: return "EXIT"
if "MOVE" in decision: return "MOVE"
return "STAY"
except Exception as e:
print(f"[API Error on Intent: {e}]")
return "STAY"
def generate_smart_response(model, context, user_input, intent):
"""Генерує відповідь"""
if intent == "STAY":
prompt = f"""
Role: Polite Sales Assistant.
Context: You are at step "{context}". User objected: "{user_input}".
Task: Handle the objection politely. Do NOT move to the next step.
Language: Ukrainian.
"""
else:
prompt = f"""
Role: Sales Assistant.
Goal: Transition to: "{context}". User said: "{user_input}".
Task: Create a natural bridge phrase.
Language: Ukrainian.
"""
try:
response = model.generate_content(prompt)
return response.text.strip()
except Exception as e:
return f"[API Error on Generation: {e}]"
def main():
if not configure_genai(): return
print(f"\n[INFO] Connecting to model: {MODEL_NAME}...")
try:
model = genai.GenerativeModel(MODEL_NAME)
except Exception as e:
print(f"[CRITICAL ERROR] Could not initialize {MODEL_NAME}: {e}")
return
try:
graph, node_to_id, id_to_node, node_texts = load_data()
except FileNotFoundError:
print("Помилка: Не знайдено sales_script.json")
return
current_node = "start"
print("\n" + "="*50)
print(f"🚀 SellMe Smart Bot ({MODEL_NAME})")
print("="*50 + "\n")
print(f"Bot: {node_texts[current_node]}")
while True:
user_input = input("\nYou: ").strip()
if not user_input: continue
# 1. АНАЛІЗ
print(f"... ({MODEL_NAME} думає) ...")
intent = analyze_intent(model, user_input, node_texts[current_node])
if intent == "EXIT":
print("Bot: До побачення!")
break
elif intent == "STAY":
print(f" [🛑 Логіка: Заперечення -> Стоїмо на '{current_node}']")
response = generate_smart_response(model, node_texts[current_node], user_input, "STAY")
print(f"Bot: {response}")
elif intent == "MOVE":
print(f" [✅ Логіка: Згода -> Рухаємось далі]")
curr_id = node_to_id[current_node]
best_next = None
min_w = float('inf')
for neighbor, weight in graph.adj_list[curr_id]:
if weight < min_w:
min_w = weight
best_next = neighbor
if best_next is None:
print("Bot: Дякую за розмову!")
break
current_node = id_to_node[best_next]
response = generate_smart_response(model, node_texts[current_node], user_input, "MOVE")
print(f"Bot: {response}")
if current_node in ["close_deal", "exit_bad"]:
break
if __name__ == "__main__":
main()