Beta/core/response_handler.py

75 lines
No EOL
2.5 KiB
Python

"""Response processing: cleaning, JSON parsing, and reply sending."""
import re
import json
import logging
from typing import Optional, List, Tuple
logger = logging.getLogger('Beta')
def clean_response_text(raw_reply: str, json_str: Optional[str]) -> str:
"""Nettoie le texte de réponse LLM en supprimant les artefacts JSON et techniques."""
clean = raw_reply
# Retirer le bloc JSON identifié
if json_str:
clean = clean.replace(json_str, "").strip()
# Suppression des balises hallucinées (<|channel|>, thought, etc.)
clean = re.sub(r'<[^>]+?>', '', clean)
# Nettoyage des résidus de formatage
clean = clean.replace('```json', '').replace('```', '').strip()
# Suppression des clés orphelines si le modèle a foiré le JSON
orphan_pattern = (
r'[\u201c\u201d\u2018\u2019"\'](thought|action|response)'
r'[\u201c\u201d\u2018\u2019"\']\s*:\s*'
r'[\u201c\u201d\u2018\u2019"\'].*?'
r'[\u201c\u201d\u2018\u2019"\'],?'
)
clean = re.sub(orphan_pattern, '', clean, flags=re.DOTALL | re.IGNORECASE)
# Retrait ultime des accolades
if clean.strip().startswith('{') or clean.strip().endswith('}'):
clean = clean.strip('{}').strip()
return clean.strip()
def parse_json_actions(json_str: Optional[str]) -> Tuple[list, list, bool]:
"""Parse le JSON extrait et retourne (actions_list, responses_list, is_explicit_none)."""
if not json_str:
return [], [], False
try:
# Normalisation JSON (guillemets typographiques)
json_str_norm = (
json_str
.replace('\u201c', '"')
.replace('\u201d', '"')
.replace('\u2018', "'")
.replace('\u2019', "'")
)
data = json.loads(json_str_norm)
actions_list = data if isinstance(data, list) else [data]
responses = []
is_explicit_none = False
for action_data in actions_list:
norm_data = {k.lower(): v for k, v in action_data.items()}
if norm_data.get('action', '').upper() == 'NONE' and not norm_data.get('response'):
is_explicit_none = True
if norm_data.get('response'):
resp_text = re.sub(r'<[^>]+?>', '', str(norm_data.get('response'))).strip()
if resp_text:
responses.append(resp_text)
return actions_list, responses, is_explicit_none
except Exception as e:
logger.debug(f"JSON parsing error: {e}")
return [], [], False