|
@@ -417,7 +417,7 @@ async def call_openai_api(user_text, user_name, voice=False):
|
|
|
# Assembler les messages avec le prompt de personnalité en premier
|
|
# Assembler les messages avec le prompt de personnalité en premier
|
|
|
messages = [
|
|
messages = [
|
|
|
{"role": "system", "content": PERSONALITY_PROMPT}
|
|
{"role": "system", "content": PERSONALITY_PROMPT}
|
|
|
- ] + conversation_history + [message_to_send]
|
|
|
|
|
|
|
+ ] + (conversation_history[-5:] if voice else conversation_history) + [message_to_send]
|
|
|
|
|
|
|
|
# Le contexte web reste limité à cet appel, sans remplir l'historique.
|
|
# Le contexte web reste limité à cet appel, sans remplir l'historique.
|
|
|
web_results = await search_web(user_text)
|
|
web_results = await search_web(user_text)
|
|
@@ -445,15 +445,19 @@ async def call_openai_api(user_text, user_name, voice=False):
|
|
|
"Il peut contenir des erreurs de reconnaissance, notamment sur les noms propres. "
|
|
"Il peut contenir des erreurs de reconnaissance, notamment sur les noms propres. "
|
|
|
"Interprète les petites erreurs à l'aide du contexte sans inventer les propos. "
|
|
"Interprète les petites erreurs à l'aide du contexte sans inventer les propos. "
|
|
|
"Si une ambiguïté change le sens, demande une précision. "
|
|
"Si une ambiguïté change le sens, demande une précision. "
|
|
|
- "Réponds naturellement à l'ensemble des interventions, en distinguant les personnes."
|
|
|
|
|
|
|
+ "Réponds naturellement à l'ensemble des interventions, en distinguant les personnes. "
|
|
|
|
|
+ "Réponds en une à trois phrases courtes, sauf demande explicite de détails."
|
|
|
)
|
|
)
|
|
|
|
|
|
|
|
|
|
+ voice_options = {"extra_body": {"options": {"think": False}}} if voice else {}
|
|
|
|
|
+
|
|
|
try:
|
|
try:
|
|
|
response = await openai_client.chat.completions.create(
|
|
response = await openai_client.chat.completions.create(
|
|
|
model=MODEL,
|
|
model=MODEL,
|
|
|
stream=False,
|
|
stream=False,
|
|
|
messages=messages,
|
|
messages=messages,
|
|
|
temperature=TEMPERATURE,
|
|
temperature=TEMPERATURE,
|
|
|
|
|
+ **voice_options,
|
|
|
**search_options
|
|
**search_options
|
|
|
)
|
|
)
|
|
|
|
|
|
|
@@ -480,6 +484,7 @@ async def call_openai_api(user_text, user_name, voice=False):
|
|
|
# Permettre de préciser la recherche, puis imposer une réponse à la limite.
|
|
# Permettre de préciser la recherche, puis imposer une réponse à la limite.
|
|
|
response = await openai_client.chat.completions.create(
|
|
response = await openai_client.chat.completions.create(
|
|
|
model=MODEL, stream=False, messages=messages, temperature=TEMPERATURE,
|
|
model=MODEL, stream=False, messages=messages, temperature=TEMPERATURE,
|
|
|
|
|
+ **voice_options,
|
|
|
**(search_options if search_count < 3 and _ < 2 else {})
|
|
**(search_options if search_count < 3 and _ < 2 else {})
|
|
|
)
|
|
)
|
|
|
|
|
|
|
@@ -544,6 +549,21 @@ async def on_ready():
|
|
|
|
|
|
|
|
voice_command_lock = asyncio.Lock()
|
|
voice_command_lock = asyncio.Lock()
|
|
|
|
|
|
|
|
|
|
+async def handle_status(message):
|
|
|
|
|
+ voice = message.guild.voice_client if message.guild else None
|
|
|
|
|
+ sink = getattr(voice, 'sink', None) if voice else None
|
|
|
|
|
+ lines = [f"Satoko {BOT_VERSION} — modèle : {MODEL}",
|
|
|
|
|
+ f"Vocal : {'connecté' if voice and voice.is_connected() else 'déconnecté'}"]
|
|
|
|
|
+ if sink:
|
|
|
|
|
+ def duration(value):
|
|
|
|
|
+ return f"{value:.1f} s" if value is not None else "pas encore mesuré"
|
|
|
|
|
+ lines += [f"Réponse en cours : {'oui' if sink.responding else 'non'}",
|
|
|
|
|
+ f"Audio en attente STT : {sink.queue.qsize()} — transcriptions en attente : {len(sink.pending)}",
|
|
|
|
|
+ f"Dernier STT réussi : {duration(sink.last_stt_seconds)}",
|
|
|
|
|
+ f"Dernier traitement de réponse : {duration(sink.last_reply_seconds)}"]
|
|
|
|
|
+ await message.channel.send("\n".join(lines), allowed_mentions=discord.AllowedMentions.none())
|
|
|
|
|
+
|
|
|
|
|
+
|
|
|
async def handle_voice_command(message):
|
|
async def handle_voice_command(message):
|
|
|
if not VOICE_ENABLED:
|
|
if not VOICE_ENABLED:
|
|
|
await message.channel.send("Le vocal est désactivé (VOICE_ENABLED=false).")
|
|
await message.channel.send("Le vocal est désactivé (VOICE_ENABLED=false).")
|
|
@@ -639,6 +659,9 @@ async def on_message(message):
|
|
|
return
|
|
return
|
|
|
|
|
|
|
|
user_text = message.content.strip()
|
|
user_text = message.content.strip()
|
|
|
|
|
+ if user_text.lower() == '!status':
|
|
|
|
|
+ await handle_status(message)
|
|
|
|
|
+ return
|
|
|
if user_text.lower() in ('!join', '!quit'):
|
|
if user_text.lower() in ('!join', '!quit'):
|
|
|
await handle_voice_command(message)
|
|
await handle_voice_command(message)
|
|
|
return
|
|
return
|