update update

This commit is contained in:
gpatruno
2026-04-28 21:06:26 +02:00
parent 7b2135bfed
commit b4254c9e06
28 changed files with 2032 additions and 547 deletions
+96 -16
View File
@@ -63,8 +63,10 @@ class InteractionRule:
from_username: Optional[str] = None
mention_account: Optional[str] = None
contains_text: Optional[str] = None
action: str = "response" # response | tgpt | clip
response_text: str = ""
tgpt_preprompt: Optional[str] = None
clip_has_delay: bool = False
@staticmethod
def from_dict(d: Dict[str, Any]) -> "InteractionRule":
@@ -74,8 +76,10 @@ class InteractionRule:
from_username=d.get("from_username") or None,
mention_account=d.get("mention_account") or None,
contains_text=d.get("contains_text") or None,
action=str(d.get("action") or d.get("mode") or "response"),
response_text=str(d.get("response_text") or ""),
tgpt_preprompt=d.get("tgpt_preprompt") or None,
clip_has_delay=bool(d.get("clip_has_delay", False)),
)
def to_dict(self) -> Dict[str, Any]:
@@ -85,8 +89,10 @@ class InteractionRule:
"from_username": self.from_username,
"mention_account": self.mention_account,
"contains_text": self.contains_text,
"action": self.action,
"response_text": self.response_text,
"tgpt_preprompt": self.tgpt_preprompt,
"clip_has_delay": self.clip_has_delay,
}
def matches(self, *, username: str, message: str, mentioned_accounts: List[str]) -> bool:
@@ -109,8 +115,10 @@ class InteractionChatConfig:
def __init__(self, data: Optional[Dict[str, Any]] = None):
data = data or {}
self.enabled: bool = bool(data.get("enabled", True))
self.mode: str = str(data.get("mode", "predefined")) # predefined | tgpt (inactive by default)
self.tgpt_enabled: bool = bool(data.get("tgpt_enabled", False))
# Mode principal: predefined (réponses) ou tgpt (IA)
self.mode: str = str(data.get("mode", "predefined")) # predefined | tgpt
# Backward compat: si tgpt_enabled est fourni, on le garde, sinon on déduit du mode.
self.tgpt_enabled: bool = bool(data.get("tgpt_enabled", self.mode == "tgpt"))
self.tgpt_preprompt: str = str(data.get("tgpt_preprompt", "") or "")
self.tgpt_max_chars: int = int(data.get("tgpt_max_chars", 100))
self.cooldown_seconds: int = int(data.get("cooldown_seconds", 8))
@@ -174,12 +182,14 @@ class InteractionChatProcessor:
get_registered_accounts: callable,
get_account_policies: Optional[callable] = None,
send_message_as: callable,
create_clip_as: Optional[callable] = None,
storage: Optional[InteractionChatStorage] = None,
):
self.channel_name = channel_name
self._get_registered_accounts = get_registered_accounts
self._get_account_policies = get_account_policies
self._send_message_as = send_message_as
self._create_clip_as = create_clip_as
self._storage = storage or InteractionChatStorage()
self._config_file = "interaction_chat_config"
@@ -330,11 +340,14 @@ class InteractionChatProcessor:
matched_rule_id: Optional[str] = None
responder_account: Optional[str] = None
rule_tgpt_preprompt: Optional[str] = None
rule_action: Optional[str] = None
rule_clip_has_delay: bool = False
for r in cfg.rules:
if r.matches(username=username, message=content, mentioned_accounts=mentioned):
response_text = (r.response_text or "").strip()
matched_rule_id = r.id
rule_action = (r.action or "response").strip().lower()
if r.mention_account:
ma = r.mention_account.strip()
if ma.startswith("@"):
@@ -342,6 +355,7 @@ class InteractionChatProcessor:
responder_account = ma.lower() if ma else None
if r.tgpt_preprompt:
rule_tgpt_preprompt = str(r.tgpt_preprompt)
rule_clip_has_delay = bool(getattr(r, "clip_has_delay", False))
break
# Choisir le compte expéditeur
@@ -350,20 +364,85 @@ class InteractionChatProcessor:
# Priorité aux règles: si une règle match, on n'exécute QUE la règle.
if matched_rule_id is not None:
if not response_text:
self.append_log(
{
"ts": _now_iso(),
"type": "rule_empty_response",
"channel": self.channel_name,
"from": username,
"content": content,
"mentioned_accounts": mentioned,
"responder_account": responder_account,
"rule_id": matched_rule_id,
}
)
continue
action = (rule_action or "response").strip().lower()
if action == "tgpt":
preprompt = (rule_tgpt_preprompt or cfg.tgpt_preprompt or "").strip()
cleaned_for_tgpt = _strip_registered_mentions(content, registered_accounts)
response_text = self._tgpt_generate(preprompt=preprompt, message=cleaned_for_tgpt)
response_text = self._truncate(response_text, cfg.tgpt_max_chars)
if not response_text:
self.append_log(
{
"ts": _now_iso(),
"type": "tgpt_empty",
"channel": self.channel_name,
"from": username,
"content": content,
"content_sent_to_tgpt": cleaned_for_tgpt,
"responder_account": responder_account,
"rule_id": matched_rule_id,
"mode": "rule_tgpt",
}
)
continue
elif action == "clip":
if not responder_account:
responder_account = mentioned[0].lower()
if not self._create_clip_as:
self.append_log(
{
"ts": _now_iso(),
"type": "clip_error",
"channel": self.channel_name,
"from": username,
"content": content,
"mentioned_accounts": mentioned,
"responder_account": responder_account,
"rule_id": matched_rule_id,
"error": "create_clip_not_configured",
}
)
continue
try:
clip = self._create_clip_as(
responder_account, # auth as responder account
self.channel_name, # clip current channel
rule_clip_has_delay,
)
clip_url = (clip or {}).get("url") or ""
response_text = f"Clip créé: {clip_url}".strip()
except Exception as e:
self.append_log(
{
"ts": _now_iso(),
"type": "clip_error",
"channel": self.channel_name,
"from": username,
"content": content,
"mentioned_accounts": mentioned,
"responder_account": responder_account,
"rule_id": matched_rule_id,
"error": str(e),
}
)
continue
else:
# response (préenregistrée)
if not response_text:
self.append_log(
{
"ts": _now_iso(),
"type": "rule_empty_response",
"channel": self.channel_name,
"from": username,
"content": content,
"mentioned_accounts": mentioned,
"responder_account": responder_account,
"rule_id": matched_rule_id,
"action": action,
}
)
continue
else:
if cfg.mode == "tgpt" and cfg.tgpt_enabled:
preprompt = (rule_tgpt_preprompt or cfg.tgpt_preprompt or "").strip()
@@ -409,6 +488,7 @@ class InteractionChatProcessor:
"response": outgoing,
"rule_id": matched_rule_id,
"mode": cfg.mode,
"action": rule_action or ("tgpt" if (cfg.mode == "tgpt" and cfg.tgpt_enabled) else "response"),
}
)