feat: /claude et /mammouth one-shot API, fix admins persistance et work_hours

- Commandes /claude-apikey, /claude-models, /claude-model, /claude
- Commandes /mammouth-apikey, /mammouth-models, /mammouth-model, /mammouth
- Clés et modèles persistés dans config.json (apis.claude / apis.mammouth)
- B11: _save_admins_to_config() persiste admin_jids dans config.json
- B12: delegate.py vérifie work_hours avant délégation
- README mis à jour

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-03-23 19:09:07 +00:00
parent b46b0726b9
commit e668fe694f
5 changed files with 237 additions and 5 deletions
+22
View File
@@ -6,6 +6,7 @@ Usage LLM : SKILL:delegate ARGS:<agent_id> | <tâche>
"""
import threading
import uuid
from datetime import datetime
DESCRIPTION = "Déléguer une tâche à un agent spécialisé et retourner son résultat"
USAGE = "SKILL:delegate ARGS:<agent_id> | <tâche>"
@@ -13,6 +14,21 @@ USAGE = "SKILL:delegate ARGS:<agent_id> | <tâche>"
TIMEOUT = 120 # secondes max d'attente de la réponse
def _is_within_work_hours(work_hours: str) -> bool:
"""Vérifie si l'heure actuelle est dans la plage HH:MM-HH:MM."""
try:
start_str, end_str = work_hours.strip().split("-")
now = datetime.now().time()
start = datetime.strptime(start_str.strip(), "%H:%M").time()
end = datetime.strptime(end_str.strip(), "%H:%M").time()
if start <= end:
return start <= now <= end
# Plage qui chevauche minuit (ex: 22:00-06:00)
return now >= start or now <= end
except Exception:
return True # En cas de format invalide, on laisse passer
def run(args: str, context) -> str:
if "|" not in args:
return "Format invalide. Usage : SKILL:delegate ARGS:<agent_id> | <tâche>"
@@ -27,6 +43,12 @@ def run(args: str, context) -> str:
known = [a.agent_id for a in context.registry.all_agents()]
return f"Agent '{agent_id}' inconnu. Agents connus : {', '.join(known)}"
# Vérifier les horaires de travail
work_hours = getattr(caps, "work_hours", "00:00-23:59")
if not _is_within_work_hours(work_hours):
now_str = datetime.now().strftime("%H:%M")
return f"⏰ Agent '{agent_id}' hors horaires ({work_hours}). Heure actuelle : {now_str}."
# Préparer la réception de la réponse
corr_id = str(uuid.uuid4())
reply_topic = context.mqtt.topic_results(corr_id)
+1 -1
View File
@@ -147,7 +147,7 @@ def run(args: str, context) -> str:
return "Format : save <nom> | <contenu du script>"
name_raw, content = rest.split("|", 1)
name = _safe_name(name_raw)
content = content.strip().replace("\\n", "\n")
content = content.strip().replace("\\n", "\n").replace('\\"', '"').replace("\\'", "'")
if not name:
return "Nom de script invalide."