Add soft French voice and contact saving

This commit is contained in:
2026-04-27 08:31:10 +02:00
parent f876b3a635
commit 94e14a3674
8 changed files with 99 additions and 19 deletions

41
app.py
View File

@@ -15,7 +15,7 @@ load_dotenv()
ROOT = Path(__file__).resolve().parent
STATIC_DIR = ROOT / "static"
CONTACTS_FILE = ROOT / "contacts.json"
CONTACTS_FILE = Path(os.getenv("CONTACTS_FILE", ROOT / "contacts.json"))
GROQ_API_KEY = os.getenv("GROQ_API_KEY", "")
GMAIL_EMAIL = os.getenv("GMAIL_EMAIL", "")
@@ -42,6 +42,10 @@ destinataire, sujet, contenu.
Quand tu as toutes les informations pour envoyer un email, reponds uniquement avec ce JSON :
{"action": "envoyer_email", "destinataire": "...", "sujet": "...", "corps": "..."}
Quand l'utilisateur veut ajouter, memoriser ou modifier un contact email, collecte le nom et l'adresse email.
Quand tu as les deux informations, reponds uniquement avec ce JSON :
{"action": "ajouter_contact", "nom": "...", "email": "..."}
Pour tout le reste, reponds en francais naturel, avec des phrases courtes.
N'utilise pas d'anglais sauf si l'utilisateur le demande explicitement.
En mode voiture, sois bref : une ou deux phrases maximum."""
@@ -54,6 +58,14 @@ def charger_contacts():
return {"laurent": "barontil@hotmail.com"}
def sauvegarder_contacts(contacts):
CONTACTS_FILE.parent.mkdir(parents=True, exist_ok=True)
CONTACTS_FILE.write_text(
json.dumps(contacts, ensure_ascii=False, indent=2) + "\n",
encoding="utf-8",
)
def construire_system_prompt():
contacts = charger_contacts()
lignes = [f"- {nom.title()} : {email}" for nom, email in contacts.items()]
@@ -66,7 +78,7 @@ def resoudre_contact(destinataire):
return contacts.get(valeur.lower(), valeur)
def extraire_action_email(reponse):
def extraire_action(reponse):
decodeur = json.JSONDecoder()
for index, caractere in enumerate(reponse):
if caractere != "{":
@@ -75,11 +87,24 @@ def extraire_action_email(reponse):
data, _ = decodeur.raw_decode(reponse[index:])
except json.JSONDecodeError:
continue
if isinstance(data, dict) and data.get("action") == "envoyer_email":
if isinstance(data, dict) and data.get("action") in {"envoyer_email", "ajouter_contact"}:
return data
return None
def ajouter_contact(nom, email):
contacts = charger_contacts()
nom_normalise = " ".join(nom.strip().lower().split())
email_normalise = email.strip()
if not nom_normalise or "@" not in email_normalise:
raise ValueError("Contact incomplet")
contacts[nom_normalise] = email_normalise
sauvegarder_contacts(contacts)
return nom_normalise, email_normalise
def envoyer_email(destinataire, sujet, corps):
destinataire = resoudre_contact(destinataire)
msg = MIMEMultipart()
@@ -163,13 +188,18 @@ def generer_audio(texte):
def traiter_message(session_id, texte, avec_audio=False):
reponse = demander_au_llm(session_id, texte)
action = extraire_action_email(reponse)
action = extraire_action(reponse)
email_sent = False
contact_saved = False
if action:
if action and action.get("action") == "envoyer_email":
destinataire = envoyer_email(action["destinataire"], action["sujet"], action["corps"])
reponse = f"Email envoye a {destinataire}."
email_sent = True
elif action and action.get("action") == "ajouter_contact":
nom, email = ajouter_contact(action["nom"], action["email"])
reponse = f"Contact ajoute : {nom.title()}."
contact_saved = True
audio_url = None
if avec_audio and TTS_PROVIDER == "groq":
@@ -179,6 +209,7 @@ def traiter_message(session_id, texte, avec_audio=False):
"reply": reponse,
"audioUrl": audio_url,
"emailSent": email_sent,
"contactSaved": contact_saved,
}