1704-08:48
@ -23,7 +23,7 @@ class AgentReportGenerator(BaseAgent):
|
||||
# Configuration locale de l'agent
|
||||
self.temperature = 0.2
|
||||
self.top_p = 0.9
|
||||
self.max_tokens = 10000
|
||||
self.max_tokens = 8000
|
||||
|
||||
# Prompt système principal
|
||||
self.system_prompt = """Tu es un expert en génération de rapports techniques pour BRG-Lab pour la société CBAO.
|
||||
|
||||
301
agents/mistral_large/agent_ticket_analyser.bak
Normal file
@ -0,0 +1,301 @@
|
||||
from ..base_agent import BaseAgent
|
||||
from typing import Dict, Any, Optional
|
||||
import logging
|
||||
import json
|
||||
import os
|
||||
import sys
|
||||
from datetime import datetime
|
||||
|
||||
# Ajout du chemin des utilitaires au PATH pour pouvoir les importer
|
||||
sys.path.append(os.path.dirname(os.path.dirname(os.path.abspath(__file__))))
|
||||
from loaders.ticket_data_loader import TicketDataLoader
|
||||
|
||||
logger = logging.getLogger("AgentTicketAnalyser")
|
||||
|
||||
class AgentTicketAnalyser(BaseAgent):
|
||||
"""
|
||||
Agent pour analyser les tickets (JSON ou Markdown) et en extraire les informations importantes.
|
||||
Remplace l'ancien AgentJsonAnalyser avec des fonctionnalités améliorées.
|
||||
"""
|
||||
def __init__(self, llm):
|
||||
super().__init__("AgentTicketAnalyser", llm)
|
||||
|
||||
# Configuration locale de l'agent
|
||||
self.temperature = 0.1 # Besoin d'analyse très précise
|
||||
self.top_p = 0.8
|
||||
self.max_tokens = 8000
|
||||
|
||||
# Prompt système optimisé
|
||||
self.system_prompt = """Tu es un expert en analyse de tickets pour le support informatique de BRG-Lab pour la société CBAO.
|
||||
Tu interviens avant l'analyse des captures d'écran pour contextualiser le ticket, identifier les questions posées, et structurer les échanges de manière claire.
|
||||
|
||||
Ta mission principale :
|
||||
|
||||
1. Identifier le client et le contexte du ticket (demande "name" et "description")
|
||||
- Récupère le nom de l'auteur si présent
|
||||
- Indique si un `user_id` est disponible
|
||||
- Conserve uniquement les informations d'identification utiles (pas d'adresse ou signature de mail inutile)
|
||||
|
||||
2. Mettre en perspective le `name` du ticket
|
||||
- Il peut contenir une ou plusieurs questions implicites
|
||||
- Reformule ces questions de façon explicite
|
||||
|
||||
3. Analyser la `description`
|
||||
- Elle fournit souvent le vrai point d'entrée technique
|
||||
- Repère les formulations interrogatives ou les demandes spécifiques
|
||||
- Identifie si cette partie complète ou précise les questions du nom
|
||||
|
||||
4. Structurer le fil de discussion
|
||||
- Conserve uniquement les échanges pertinents
|
||||
-Conserve les questions soulevés par "name" ou "description"
|
||||
- CONSERVE ABSOLUMENT les références documentation, FAQ, liens utiles et manuels
|
||||
- Identifie clairement chaque intervenant (client / support)
|
||||
- Classe les informations par ordre chronologique avec date et rôle
|
||||
|
||||
5. Préparer la transmission à l'agent suivant
|
||||
- Préserve tous les éléments utiles à l'analyse d'image : modules cités, options évoquées, comportements décrits
|
||||
- Mentionne si des images sont attachées au ticket
|
||||
|
||||
Structure ta réponse :
|
||||
|
||||
1. Résumé du contexte
|
||||
- Client (nom, email si disponible)
|
||||
- Sujet du ticket reformulé en une ou plusieurs questions
|
||||
- Description technique synthétique
|
||||
|
||||
2. Informations techniques détectées
|
||||
- Logiciels/modules mentionnés
|
||||
- Paramètres évoqués
|
||||
- Fonctionnalités impactées
|
||||
- Conditions spécifiques (multi-laboratoire, utilisateur non valide, etc.)
|
||||
|
||||
3. Fil de discussion (filtrée, nettoyée, classée)
|
||||
- Intervenant (Client/Support)
|
||||
- Date et contenu de chaque échange
|
||||
- Résumés techniques
|
||||
- INCLURE TOUS les liens documentaires (manuel, FAQ, documentation technique)
|
||||
|
||||
4. Éléments liés à l'analyse visuelle
|
||||
- Nombre d'images attachées
|
||||
- Références aux interfaces ou options à visualiser
|
||||
- Points à vérifier dans les captures (listes incomplètes, cases à cocher, utilisateurs grisés, etc.)
|
||||
|
||||
IMPORTANT :
|
||||
- Ne propose aucune solution ni interprétation
|
||||
- Ne génère pas de tableau
|
||||
- Reste strictement factuel en te basant uniquement sur les informations fournies
|
||||
- Ne reformule pas les messages, conserve les formulations exactes sauf nettoyage de forme"""
|
||||
|
||||
# Initialiser le loader de données
|
||||
self.ticket_loader = TicketDataLoader()
|
||||
|
||||
# Appliquer la configuration au LLM
|
||||
self._appliquer_config_locale()
|
||||
|
||||
logger.info("AgentTicketAnalyser initialisé")
|
||||
|
||||
def _appliquer_config_locale(self) -> None:
|
||||
"""
|
||||
Applique la configuration locale au modèle LLM.
|
||||
"""
|
||||
# Appliquer le prompt système
|
||||
if hasattr(self.llm, "prompt_system"):
|
||||
self.llm.prompt_system = self.system_prompt
|
||||
|
||||
# Appliquer les paramètres
|
||||
if hasattr(self.llm, "configurer"):
|
||||
params = {
|
||||
"temperature": self.temperature,
|
||||
"top_p": self.top_p,
|
||||
"max_tokens": self.max_tokens
|
||||
}
|
||||
|
||||
self.llm.configurer(**params)
|
||||
|
||||
def executer(self, ticket_data: Dict[str, Any]) -> str:
|
||||
"""
|
||||
Analyse un ticket pour en extraire les informations pertinentes
|
||||
|
||||
Args:
|
||||
ticket_data: Dictionnaire contenant les données du ticket à analyser
|
||||
ou chemin vers un fichier de ticket (JSON ou Markdown)
|
||||
|
||||
Returns:
|
||||
Réponse formatée contenant l'analyse du ticket
|
||||
"""
|
||||
# Détecter si ticket_data est un chemin de fichier ou un dictionnaire
|
||||
if isinstance(ticket_data, str) and os.path.exists(ticket_data):
|
||||
try:
|
||||
ticket_data = self.ticket_loader.charger(ticket_data)
|
||||
logger.info(f"Données chargées depuis le fichier: {ticket_data}")
|
||||
except Exception as e:
|
||||
error_message = f"Erreur lors du chargement du fichier: {str(e)}"
|
||||
logger.error(error_message)
|
||||
return f"ERREUR: {error_message}"
|
||||
|
||||
# Vérifier que les données sont bien un dictionnaire
|
||||
if not isinstance(ticket_data, dict):
|
||||
error_message = "Les données du ticket doivent être un dictionnaire ou un chemin de fichier valide"
|
||||
logger.error(error_message)
|
||||
return f"ERREUR: {error_message}"
|
||||
|
||||
ticket_code = ticket_data.get('code', 'Inconnu')
|
||||
logger.info(f"Analyse du ticket: {ticket_code}")
|
||||
print(f"AgentTicketAnalyser: Analyse du ticket {ticket_code}")
|
||||
|
||||
# Récupérer les métadonnées sur la source des données
|
||||
source_format = "inconnu"
|
||||
source_file = "non spécifié"
|
||||
if "metadata" in ticket_data and isinstance(ticket_data["metadata"], dict):
|
||||
source_format = ticket_data["metadata"].get("format", "inconnu")
|
||||
source_file = ticket_data["metadata"].get("source_file", "non spécifié")
|
||||
|
||||
logger.info(f"Format source: {source_format}, Fichier source: {source_file}")
|
||||
|
||||
# Préparer le ticket pour l'analyse
|
||||
ticket_formate = self._formater_ticket_pour_analyse(ticket_data)
|
||||
|
||||
# Créer le prompt pour l'analyse, adapté au format source
|
||||
prompt = f"""Analyse ce ticket pour en extraire les informations clés et préparer une synthèse structurée.
|
||||
|
||||
SOURCE: {source_format.upper()}
|
||||
|
||||
{ticket_formate}
|
||||
|
||||
RAPPEL IMPORTANT:
|
||||
- CONSERVE TOUS les liens (FAQ, documentation, manuels) présents dans les messages
|
||||
- Extrais et organise chronologiquement les échanges client/support
|
||||
- Identifie les éléments techniques à observer dans les captures d'écran
|
||||
- Reste factuel et précis sans proposer de solution"""
|
||||
|
||||
try:
|
||||
logger.info("Interrogation du LLM")
|
||||
response = self.llm.interroger(prompt)
|
||||
logger.info(f"Réponse reçue: {len(response)} caractères")
|
||||
print(f" Analyse terminée: {len(response)} caractères")
|
||||
except Exception as e:
|
||||
error_message = f"Erreur lors de l'analyse du ticket: {str(e)}"
|
||||
logger.error(error_message)
|
||||
response = f"ERREUR: {error_message}"
|
||||
print(f" ERREUR: {error_message}")
|
||||
|
||||
# Enregistrer l'historique avec le prompt complet pour la traçabilité
|
||||
self.ajouter_historique("analyse_ticket",
|
||||
{
|
||||
"ticket_id": ticket_code,
|
||||
"format_source": source_format,
|
||||
"source_file": source_file,
|
||||
"prompt": prompt,
|
||||
"temperature": self.temperature,
|
||||
"top_p": self.top_p,
|
||||
"max_tokens": self.max_tokens,
|
||||
"timestamp": self._get_timestamp()
|
||||
},
|
||||
response)
|
||||
|
||||
return response
|
||||
|
||||
def _formater_ticket_pour_analyse(self, ticket_data: Dict) -> str:
|
||||
"""
|
||||
Formate les données du ticket pour l'analyse LLM, avec une meilleure
|
||||
gestion des différents formats et structures de données.
|
||||
|
||||
Args:
|
||||
ticket_data: Les données du ticket
|
||||
|
||||
Returns:
|
||||
Représentation textuelle formatée du ticket
|
||||
"""
|
||||
# Initialiser avec les informations de base
|
||||
ticket_name = ticket_data.get('name', 'Sans titre')
|
||||
ticket_code = ticket_data.get('code', 'Inconnu')
|
||||
|
||||
info = f"## TICKET {ticket_code}: {ticket_name}\n\n"
|
||||
info += f"## NOM DE LA DEMANDE (PROBLÈME INITIAL)\n{ticket_name}\n\n"
|
||||
|
||||
# Ajouter la description
|
||||
description = ticket_data.get('description', '')
|
||||
if description:
|
||||
info += f"## DESCRIPTION DU PROBLÈME\n{description}\n\n"
|
||||
|
||||
# Ajouter les informations du ticket (exclure certains champs spécifiques)
|
||||
champs_a_exclure = ['code', 'name', 'description', 'messages', 'metadata']
|
||||
info += "## INFORMATIONS TECHNIQUES DU TICKET\n"
|
||||
for key, value in ticket_data.items():
|
||||
if key not in champs_a_exclure and value:
|
||||
# Formater les valeurs complexes si nécessaire
|
||||
if isinstance(value, (dict, list)):
|
||||
value = json.dumps(value, ensure_ascii=False, indent=2)
|
||||
info += f"- {key}: {value}\n"
|
||||
info += "\n"
|
||||
|
||||
# Ajouter les messages (conversations) avec un formatage amélioré pour distinguer client/support
|
||||
messages = ticket_data.get('messages', [])
|
||||
if messages:
|
||||
info += "## CHRONOLOGIE DES ÉCHANGES CLIENT/SUPPORT\n"
|
||||
for i, msg in enumerate(messages):
|
||||
# Vérifier que le message est bien un dictionnaire
|
||||
if not isinstance(msg, dict):
|
||||
continue
|
||||
|
||||
sender = msg.get('from', 'Inconnu')
|
||||
date = msg.get('date', 'Date inconnue')
|
||||
content = msg.get('content', '')
|
||||
|
||||
# Identifier si c'est client ou support
|
||||
sender_type = "CLIENT" if "client" in sender.lower() else "SUPPORT" if "support" in sender.lower() else "AUTRE"
|
||||
|
||||
# Formater correctement la date si possible
|
||||
try:
|
||||
if date != 'Date inconnue':
|
||||
# Essayer différents formats de date
|
||||
for date_format in ['%Y-%m-%d %H:%M:%S', '%Y-%m-%d', '%d/%m/%Y']:
|
||||
try:
|
||||
date_obj = datetime.strptime(date, date_format)
|
||||
date = date_obj.strftime('%d/%m/%Y %H:%M')
|
||||
break
|
||||
except ValueError:
|
||||
continue
|
||||
except Exception:
|
||||
pass # Garder la date d'origine en cas d'erreur
|
||||
|
||||
info += f"### Message {i+1} - [{sender_type}] De: {sender} - Date: {date}\n{content}\n\n"
|
||||
|
||||
# Ajouter les métadonnées techniques si présentes
|
||||
metadata = ticket_data.get('metadata', {})
|
||||
# Exclure certaines métadonnées internes
|
||||
for key in ['source_file', 'format']:
|
||||
if key in metadata:
|
||||
metadata.pop(key)
|
||||
|
||||
if metadata:
|
||||
info += "## MÉTADONNÉES TECHNIQUES\n"
|
||||
for key, value in metadata.items():
|
||||
if isinstance(value, (dict, list)):
|
||||
value = json.dumps(value, ensure_ascii=False, indent=2)
|
||||
info += f"- {key}: {value}\n"
|
||||
info += "\n"
|
||||
|
||||
return info
|
||||
|
||||
def analyser_depuis_fichier(self, chemin_fichier: str) -> str:
|
||||
"""
|
||||
Analyse un ticket à partir d'un fichier (JSON ou Markdown)
|
||||
|
||||
Args:
|
||||
chemin_fichier: Chemin vers le fichier à analyser
|
||||
|
||||
Returns:
|
||||
Résultat de l'analyse
|
||||
"""
|
||||
try:
|
||||
ticket_data = self.ticket_loader.charger(chemin_fichier)
|
||||
return self.executer(ticket_data)
|
||||
except Exception as e:
|
||||
error_message = f"Erreur lors de l'analyse du fichier {chemin_fichier}: {str(e)}"
|
||||
logger.error(error_message)
|
||||
return f"ERREUR: {error_message}"
|
||||
|
||||
def _get_timestamp(self) -> str:
|
||||
"""Retourne un timestamp au format YYYYMMDD_HHMMSS"""
|
||||
return datetime.now().strftime("%Y%m%d_%H%M%S")
|
||||
@ -1,13 +1,9 @@
|
||||
from ..base_agent import BaseAgent
|
||||
from typing import Dict, Any, Optional
|
||||
from typing import Dict, Any
|
||||
import logging
|
||||
import json
|
||||
import os
|
||||
import sys
|
||||
from datetime import datetime
|
||||
|
||||
# Ajout du chemin des utilitaires au PATH pour pouvoir les importer
|
||||
sys.path.append(os.path.dirname(os.path.dirname(os.path.abspath(__file__))))
|
||||
from loaders.ticket_data_loader import TicketDataLoader
|
||||
|
||||
logger = logging.getLogger("AgentTicketAnalyser")
|
||||
@ -15,287 +11,183 @@ logger = logging.getLogger("AgentTicketAnalyser")
|
||||
class AgentTicketAnalyser(BaseAgent):
|
||||
"""
|
||||
Agent pour analyser les tickets (JSON ou Markdown) et en extraire les informations importantes.
|
||||
Remplace l'ancien AgentJsonAnalyser avec des fonctionnalités améliorées.
|
||||
Utilisé pour contextualiser les tickets avant l'analyse des captures d'écran.
|
||||
"""
|
||||
|
||||
def __init__(self, llm):
|
||||
super().__init__("AgentTicketAnalyser", llm)
|
||||
|
||||
# Configuration locale de l'agent
|
||||
self.temperature = 0.1 # Besoin d'analyse très précise
|
||||
|
||||
# Configuration adaptée à l'analyse structurée pour Mistral Large
|
||||
self.temperature = 0.1
|
||||
self.top_p = 0.8
|
||||
self.max_tokens = 8000
|
||||
|
||||
# Prompt système optimisé
|
||||
self.system_prompt = """Tu es un expert en analyse de tickets pour le support informatique de BRG-Lab pour la société CBAO.
|
||||
Tu interviens avant l'analyse des captures d'écran pour contextualiser le ticket, identifier les questions posées, et structurer les échanges de manière claire.
|
||||
self.max_tokens = 6000
|
||||
|
||||
Ta mission principale :
|
||||
# Prompt système clair, structuré, optimisé pour une analyse exhaustive
|
||||
self.system_prompt = """Tu es un expert en analyse de tickets pour le support informatique de BRG-Lab (client : CBAO).
|
||||
|
||||
1. Identifier le client et le contexte du ticket (demande "name" et "description")
|
||||
- Récupère le nom de l'auteur si présent
|
||||
- Indique si un `user_id` est disponible
|
||||
- Conserve uniquement les informations d'identification utiles (pas d'adresse ou signature de mail inutile)
|
||||
|
||||
2. Mettre en perspective le `name` du ticket
|
||||
- Il peut contenir une ou plusieurs questions implicites
|
||||
- Reformule ces questions de façon explicite
|
||||
|
||||
3. Analyser la `description`
|
||||
- Elle fournit souvent le vrai point d'entrée technique
|
||||
- Repère les formulations interrogatives ou les demandes spécifiques
|
||||
- Identifie si cette partie complète ou précise les questions du nom
|
||||
|
||||
4. Structurer le fil de discussion
|
||||
- Conserve uniquement les échanges pertinents
|
||||
-Conserve les questions soulevés par "name" ou "description"
|
||||
- CONSERVE ABSOLUMENT les références documentation, FAQ, liens utiles et manuels
|
||||
- Identifie clairement chaque intervenant (client / support)
|
||||
- Classe les informations par ordre chronologique avec date et rôle
|
||||
|
||||
5. Préparer la transmission à l'agent suivant
|
||||
- Préserve tous les éléments utiles à l'analyse d'image : modules cités, options évoquées, comportements décrits
|
||||
- Mentionne si des images sont attachées au ticket
|
||||
|
||||
Structure ta réponse :
|
||||
Tu dois :
|
||||
1. Identifier le client et résumer la demande.
|
||||
2. Reformuler les questions implicites du ticket (à partir du `name` et `description`).
|
||||
3. Nettoyer et structurer les échanges client/support en conservant les informations utiles (liens, modules, options, erreurs).
|
||||
4. Extraire les éléments à observer dans les captures (pour l'agent image).
|
||||
|
||||
Structure de sortie :
|
||||
1. Résumé du contexte
|
||||
- Client (nom, email si disponible)
|
||||
- Sujet du ticket reformulé en une ou plusieurs questions
|
||||
- Description technique synthétique
|
||||
|
||||
2. Informations techniques détectées
|
||||
- Logiciels/modules mentionnés
|
||||
- Paramètres évoqués
|
||||
- Fonctionnalités impactées
|
||||
- Conditions spécifiques (multi-laboratoire, utilisateur non valide, etc.)
|
||||
|
||||
3. Fil de discussion (filtrée, nettoyée, classée)
|
||||
- Intervenant (Client/Support)
|
||||
- Date et contenu de chaque échange
|
||||
- Résumés techniques
|
||||
- INCLURE TOUS les liens documentaires (manuel, FAQ, documentation technique)
|
||||
|
||||
4. Éléments liés à l'analyse visuelle
|
||||
- Nombre d'images attachées
|
||||
- Références aux interfaces ou options à visualiser
|
||||
- Points à vérifier dans les captures (listes incomplètes, cases à cocher, utilisateurs grisés, etc.)
|
||||
3. Fil de discussion (filtré, classé, nettoyé)
|
||||
4. Points visuels à analyser (éléments à retrouver dans les captures)
|
||||
|
||||
IMPORTANT :
|
||||
- Ne propose aucune solution ni interprétation
|
||||
- Ne génère pas de tableau
|
||||
- Reste strictement factuel en te basant uniquement sur les informations fournies
|
||||
- Ne reformule pas les messages, conserve les formulations exactes sauf nettoyage de forme"""
|
||||
|
||||
# Initialiser le loader de données
|
||||
- Ne propose pas de solution
|
||||
- Garde tous les liens et noms de modules
|
||||
- Ne transforme pas les propos sauf pour supprimer les bruits inutiles (signatures, mails automatiques)
|
||||
- Ne reformule pas les messages sauf si cela clarifie les intentions sans altérer leur sens
|
||||
"""
|
||||
|
||||
self.ticket_loader = TicketDataLoader()
|
||||
|
||||
# Appliquer la configuration au LLM
|
||||
self._appliquer_config_locale()
|
||||
|
||||
logger.info("AgentTicketAnalyser initialisé")
|
||||
|
||||
|
||||
def _appliquer_config_locale(self) -> None:
|
||||
"""
|
||||
Applique la configuration locale au modèle LLM.
|
||||
"""
|
||||
# Appliquer le prompt système
|
||||
"""Applique les paramètres et le prompt système au modèle"""
|
||||
if hasattr(self.llm, "prompt_system"):
|
||||
self.llm.prompt_system = self.system_prompt
|
||||
|
||||
# Appliquer les paramètres
|
||||
if hasattr(self.llm, "configurer"):
|
||||
params = {
|
||||
"temperature": self.temperature,
|
||||
"top_p": self.top_p,
|
||||
"max_tokens": self.max_tokens
|
||||
}
|
||||
|
||||
self.llm.configurer(**params)
|
||||
|
||||
self.llm.configurer(
|
||||
temperature=self.temperature,
|
||||
top_p=self.top_p,
|
||||
max_tokens=self.max_tokens
|
||||
)
|
||||
|
||||
def executer(self, ticket_data: Dict[str, Any]) -> str:
|
||||
"""
|
||||
Analyse un ticket pour en extraire les informations pertinentes
|
||||
|
||||
Args:
|
||||
ticket_data: Dictionnaire contenant les données du ticket à analyser
|
||||
ou chemin vers un fichier de ticket (JSON ou Markdown)
|
||||
|
||||
Returns:
|
||||
Réponse formatée contenant l'analyse du ticket
|
||||
"""
|
||||
# Détecter si ticket_data est un chemin de fichier ou un dictionnaire
|
||||
"""Analyse le ticket donné sous forme de dict"""
|
||||
if isinstance(ticket_data, str) and os.path.exists(ticket_data):
|
||||
try:
|
||||
ticket_data = self.ticket_loader.charger(ticket_data)
|
||||
logger.info(f"Données chargées depuis le fichier: {ticket_data}")
|
||||
except Exception as e:
|
||||
error_message = f"Erreur lors du chargement du fichier: {str(e)}"
|
||||
logger.error(error_message)
|
||||
return f"ERREUR: {error_message}"
|
||||
|
||||
# Vérifier que les données sont bien un dictionnaire
|
||||
ticket_data = self.ticket_loader.charger(ticket_data)
|
||||
|
||||
if not isinstance(ticket_data, dict):
|
||||
error_message = "Les données du ticket doivent être un dictionnaire ou un chemin de fichier valide"
|
||||
logger.error(error_message)
|
||||
return f"ERREUR: {error_message}"
|
||||
|
||||
ticket_code = ticket_data.get('code', 'Inconnu')
|
||||
logger.info(f"Analyse du ticket: {ticket_code}")
|
||||
print(f"AgentTicketAnalyser: Analyse du ticket {ticket_code}")
|
||||
|
||||
# Récupérer les métadonnées sur la source des données
|
||||
source_format = "inconnu"
|
||||
source_file = "non spécifié"
|
||||
if "metadata" in ticket_data and isinstance(ticket_data["metadata"], dict):
|
||||
source_format = ticket_data["metadata"].get("format", "inconnu")
|
||||
source_file = ticket_data["metadata"].get("source_file", "non spécifié")
|
||||
|
||||
logger.info(f"Format source: {source_format}, Fichier source: {source_file}")
|
||||
|
||||
# Préparer le ticket pour l'analyse
|
||||
ticket_formate = self._formater_ticket_pour_analyse(ticket_data)
|
||||
|
||||
# Créer le prompt pour l'analyse, adapté au format source
|
||||
prompt = f"""Analyse ce ticket pour en extraire les informations clés et préparer une synthèse structurée.
|
||||
logger.error("Les données du ticket ne sont pas valides")
|
||||
return "ERREUR: Format de ticket invalide"
|
||||
|
||||
SOURCE: {source_format.upper()}
|
||||
ticket_code = ticket_data.get("code", "Inconnu")
|
||||
logger.info(f"Analyse du ticket {ticket_code}")
|
||||
print(f"AgentTicketAnalyser: analyse du ticket {ticket_code}")
|
||||
|
||||
{ticket_formate}
|
||||
prompt = self._generer_prompt(ticket_data)
|
||||
|
||||
RAPPEL IMPORTANT:
|
||||
- CONSERVE TOUS les liens (FAQ, documentation, manuels) présents dans les messages
|
||||
- Extrais et organise chronologiquement les échanges client/support
|
||||
- Identifie les éléments techniques à observer dans les captures d'écran
|
||||
- Reste factuel et précis sans proposer de solution"""
|
||||
|
||||
try:
|
||||
logger.info("Interrogation du LLM")
|
||||
response = self.llm.interroger(prompt)
|
||||
logger.info(f"Réponse reçue: {len(response)} caractères")
|
||||
logger.info("Analyse du ticket terminée avec succès")
|
||||
print(f" Analyse terminée: {len(response)} caractères")
|
||||
except Exception as e:
|
||||
error_message = f"Erreur lors de l'analyse du ticket: {str(e)}"
|
||||
logger.error(error_message)
|
||||
response = f"ERREUR: {error_message}"
|
||||
print(f" ERREUR: {error_message}")
|
||||
|
||||
# Enregistrer l'historique avec le prompt complet pour la traçabilité
|
||||
self.ajouter_historique("analyse_ticket",
|
||||
{
|
||||
"ticket_id": ticket_code,
|
||||
"format_source": source_format,
|
||||
"source_file": source_file,
|
||||
"prompt": prompt,
|
||||
"temperature": self.temperature,
|
||||
"top_p": self.top_p,
|
||||
"max_tokens": self.max_tokens,
|
||||
"timestamp": self._get_timestamp()
|
||||
},
|
||||
response)
|
||||
|
||||
logger.error(f"Erreur d'analyse: {str(e)}")
|
||||
return f"ERREUR: {str(e)}"
|
||||
|
||||
self.ajouter_historique(
|
||||
"analyse_ticket",
|
||||
{
|
||||
"ticket_id": ticket_code,
|
||||
"prompt": prompt,
|
||||
"timestamp": self._get_timestamp()
|
||||
},
|
||||
response
|
||||
)
|
||||
|
||||
return response
|
||||
|
||||
def _formater_ticket_pour_analyse(self, ticket_data: Dict) -> str:
|
||||
|
||||
def _generer_prompt(self, ticket_data: Dict[str, Any]) -> str:
|
||||
"""
|
||||
Formate les données du ticket pour l'analyse LLM, avec une meilleure
|
||||
gestion des différents formats et structures de données.
|
||||
|
||||
Args:
|
||||
ticket_data: Les données du ticket
|
||||
|
||||
Returns:
|
||||
Représentation textuelle formatée du ticket
|
||||
Prépare un prompt texte structuré à partir des données brutes du ticket.
|
||||
"""
|
||||
# Initialiser avec les informations de base
|
||||
ticket_name = ticket_data.get('name', 'Sans titre')
|
||||
ticket_code = ticket_data.get('code', 'Inconnu')
|
||||
|
||||
info = f"## TICKET {ticket_code}: {ticket_name}\n\n"
|
||||
info += f"## NOM DE LA DEMANDE (PROBLÈME INITIAL)\n{ticket_name}\n\n"
|
||||
|
||||
# Ajouter la description
|
||||
description = ticket_data.get('description', '')
|
||||
ticket_code = ticket_data.get("code", "Inconnu")
|
||||
name = ticket_data.get("name", "").strip()
|
||||
description = ticket_data.get("description", "").strip()
|
||||
|
||||
# En-tête
|
||||
texte = f"### TICKET {ticket_code}\n\n"
|
||||
|
||||
if name:
|
||||
texte += f"#### NOM DU TICKET\n{name}\n\n"
|
||||
|
||||
if description:
|
||||
info += f"## DESCRIPTION DU PROBLÈME\n{description}\n\n"
|
||||
|
||||
# Ajouter les informations du ticket (exclure certains champs spécifiques)
|
||||
champs_a_exclure = ['code', 'name', 'description', 'messages', 'metadata']
|
||||
info += "## INFORMATIONS TECHNIQUES DU TICKET\n"
|
||||
for key, value in ticket_data.items():
|
||||
if key not in champs_a_exclure and value:
|
||||
# Formater les valeurs complexes si nécessaire
|
||||
if isinstance(value, (dict, list)):
|
||||
value = json.dumps(value, ensure_ascii=False, indent=2)
|
||||
info += f"- {key}: {value}\n"
|
||||
info += "\n"
|
||||
|
||||
# Ajouter les messages (conversations) avec un formatage amélioré pour distinguer client/support
|
||||
messages = ticket_data.get('messages', [])
|
||||
texte += f"#### DESCRIPTION\n{description}\n\n"
|
||||
|
||||
# Informations techniques utiles (hors champs exclus)
|
||||
champs_exclus = {"code", "name", "description", "messages", "metadata"}
|
||||
info_techniques = [
|
||||
f"- {k}: {json.dumps(v, ensure_ascii=False)}" if isinstance(v, (dict, list)) else f"- {k}: {v}"
|
||||
for k, v in ticket_data.items()
|
||||
if k not in champs_exclus and v
|
||||
]
|
||||
if info_techniques:
|
||||
texte += "#### INFORMATIONS TECHNIQUES\n" + "\n".join(info_techniques) + "\n\n"
|
||||
|
||||
# Fil des échanges client/support
|
||||
messages = ticket_data.get("messages", [])
|
||||
if messages:
|
||||
info += "## CHRONOLOGIE DES ÉCHANGES CLIENT/SUPPORT\n"
|
||||
texte += "#### ÉCHANGES CLIENT / SUPPORT\n"
|
||||
for i, msg in enumerate(messages):
|
||||
# Vérifier que le message est bien un dictionnaire
|
||||
if not isinstance(msg, dict):
|
||||
continue
|
||||
|
||||
sender = msg.get('from', 'Inconnu')
|
||||
date = msg.get('date', 'Date inconnue')
|
||||
content = msg.get('content', '')
|
||||
|
||||
# Identifier si c'est client ou support
|
||||
sender_type = "CLIENT" if "client" in sender.lower() else "SUPPORT" if "support" in sender.lower() else "AUTRE"
|
||||
|
||||
# Formater correctement la date si possible
|
||||
try:
|
||||
if date != 'Date inconnue':
|
||||
# Essayer différents formats de date
|
||||
for date_format in ['%Y-%m-%d %H:%M:%S', '%Y-%m-%d', '%d/%m/%Y']:
|
||||
try:
|
||||
date_obj = datetime.strptime(date, date_format)
|
||||
date = date_obj.strftime('%d/%m/%Y %H:%M')
|
||||
break
|
||||
except ValueError:
|
||||
continue
|
||||
except Exception:
|
||||
pass # Garder la date d'origine en cas d'erreur
|
||||
|
||||
info += f"### Message {i+1} - [{sender_type}] De: {sender} - Date: {date}\n{content}\n\n"
|
||||
|
||||
# Ajouter les métadonnées techniques si présentes
|
||||
metadata = ticket_data.get('metadata', {})
|
||||
# Exclure certaines métadonnées internes
|
||||
for key in ['source_file', 'format']:
|
||||
if key in metadata:
|
||||
metadata.pop(key)
|
||||
|
||||
if metadata:
|
||||
info += "## MÉTADONNÉES TECHNIQUES\n"
|
||||
for key, value in metadata.items():
|
||||
if isinstance(value, (dict, list)):
|
||||
value = json.dumps(value, ensure_ascii=False, indent=2)
|
||||
info += f"- {key}: {value}\n"
|
||||
info += "\n"
|
||||
|
||||
return info
|
||||
|
||||
def analyser_depuis_fichier(self, chemin_fichier: str) -> str:
|
||||
auteur = msg.get("from", "inconnu")
|
||||
role = "CLIENT" if "client" in auteur.lower() else "SUPPORT" if "support" in auteur.lower() else "AUTRE"
|
||||
date = self._formater_date(msg.get("date", "inconnue"))
|
||||
contenu = msg.get("content", "").strip()
|
||||
if contenu:
|
||||
texte += f"{i+1}. [{role}] {auteur} ({date})\n{contenu}\n\n"
|
||||
|
||||
# Métadonnées utiles
|
||||
metadata = ticket_data.get("metadata", {})
|
||||
meta_text = [
|
||||
f"- {k}: {json.dumps(v, ensure_ascii=False)}" if isinstance(v, (dict, list)) else f"- {k}: {v}"
|
||||
for k, v in metadata.items()
|
||||
if k not in {"format", "source_file"} and v
|
||||
]
|
||||
if meta_text:
|
||||
texte += "#### MÉTADONNÉES\n" + "\n".join(meta_text) + "\n"
|
||||
|
||||
return texte
|
||||
|
||||
def _formater_date(self, date_str: str) -> str:
|
||||
"""
|
||||
Analyse un ticket à partir d'un fichier (JSON ou Markdown)
|
||||
Formate la date en DD/MM/YYYY HH:MM si possible
|
||||
|
||||
Args:
|
||||
chemin_fichier: Chemin vers le fichier à analyser
|
||||
date_str: Chaîne de caractères représentant une date
|
||||
|
||||
Returns:
|
||||
Résultat de l'analyse
|
||||
Date formatée ou la chaîne originale si le format n'est pas reconnu
|
||||
"""
|
||||
if not date_str:
|
||||
return "date inconnue"
|
||||
|
||||
try:
|
||||
ticket_data = self.ticket_loader.charger(chemin_fichier)
|
||||
return self.executer(ticket_data)
|
||||
except Exception as e:
|
||||
error_message = f"Erreur lors de l'analyse du fichier {chemin_fichier}: {str(e)}"
|
||||
logger.error(error_message)
|
||||
return f"ERREUR: {error_message}"
|
||||
|
||||
# Essayer différents formats courants
|
||||
formats = [
|
||||
"%Y-%m-%dT%H:%M:%S.%fZ", # Format ISO avec microsecondes et Z
|
||||
"%Y-%m-%dT%H:%M:%SZ", # Format ISO sans microsecondes avec Z
|
||||
"%Y-%m-%dT%H:%M:%S", # Format ISO sans Z
|
||||
"%Y-%m-%d %H:%M:%S", # Format standard
|
||||
"%d/%m/%Y %H:%M:%S", # Format français
|
||||
"%d/%m/%Y" # Format date simple
|
||||
]
|
||||
|
||||
for fmt in formats:
|
||||
try:
|
||||
dt = datetime.strptime(date_str, fmt)
|
||||
return dt.strftime("%d/%m/%Y %H:%M")
|
||||
except ValueError:
|
||||
continue
|
||||
|
||||
# Si aucun format ne correspond, retourner la chaîne originale
|
||||
return date_str
|
||||
except Exception:
|
||||
return date_str
|
||||
|
||||
def _get_timestamp(self) -> str:
|
||||
"""Retourne un timestamp au format YYYYMMDD_HHMMSS"""
|
||||
return datetime.now().strftime("%Y%m%d_%H%M%S")
|
||||
"""
|
||||
Génère un timestamp au format YYYYMMDD_HHMMSS
|
||||
|
||||
Returns:
|
||||
Timestamp formaté
|
||||
"""
|
||||
return datetime.now().strftime("%Y%m%d_%H%M%S")
|
||||
|
||||
@ -131,44 +131,6 @@ Ton analyse sera utilisée comme élément factuel pour un rapport technique plu
|
||||
logger.error(f"Erreur lors de la vérification de l'image {image_path}: {str(e)}")
|
||||
return False
|
||||
|
||||
def _encoder_image_base64(self, image_path: str) -> str:
|
||||
"""
|
||||
Encode l'image en base64 pour l'inclure directement dans le prompt
|
||||
|
||||
Args:
|
||||
image_path: Chemin vers l'image
|
||||
|
||||
Returns:
|
||||
Chaîne de caractères au format data URI avec l'image encodée en base64
|
||||
"""
|
||||
try:
|
||||
# Ouvrir l'image et la redimensionner si trop grande
|
||||
with Image.open(image_path) as img:
|
||||
# Redimensionner l'image si elle est trop grande (max 800x800)
|
||||
max_size = 800
|
||||
if img.width > max_size or img.height > max_size:
|
||||
img.thumbnail((max_size, max_size), Image.Resampling.LANCZOS)
|
||||
|
||||
# Convertir en RGB si nécessaire (pour les formats comme PNG)
|
||||
if img.mode != "RGB":
|
||||
img = img.convert("RGB")
|
||||
|
||||
# Sauvegarder l'image en JPEG dans un buffer mémoire
|
||||
buffer = io.BytesIO()
|
||||
img.save(buffer, format="JPEG", quality=85)
|
||||
buffer.seek(0)
|
||||
|
||||
# Encoder en base64
|
||||
img_base64 = base64.b64encode(buffer.read()).decode("utf-8")
|
||||
|
||||
# Construire le data URI
|
||||
data_uri = f"data:image/jpeg;base64,{img_base64}"
|
||||
|
||||
return data_uri
|
||||
except Exception as e:
|
||||
logger.error(f"Erreur lors de l'encodage de l'image {image_path}: {str(e)}")
|
||||
return ""
|
||||
|
||||
def _generer_prompt_analyse(self, contexte: str, prefix: str = "") -> str:
|
||||
"""
|
||||
Génère le prompt d'analyse d'image en utilisant les instructions centralisées
|
||||
@ -233,20 +195,39 @@ Fournis une analyse STRICTEMENT FACTUELLE de l'image avec les sections suivantes
|
||||
else:
|
||||
# Fallback vers la méthode standard avec base64 si interroger_avec_image n'existe pas
|
||||
logger.warning(f"La méthode interroger_avec_image n'existe pas, utilisation du fallback pour {image_name}")
|
||||
img_base64 = self._encoder_image_base64(image_path)
|
||||
if img_base64:
|
||||
# Utiliser le même générateur de prompt avec l'image en base64
|
||||
prompt_base64 = self._generer_prompt_analyse(contexte, f"Analyse cette image:\n{img_base64}")
|
||||
|
||||
response = self.llm.interroger(prompt_base64)
|
||||
# Utiliser la méthode _encoder_image_base64 du modèle directement
|
||||
if hasattr(self.llm, "_encoder_image_base64"):
|
||||
img_base64 = self.llm._encoder_image_base64(image_path)
|
||||
if img_base64:
|
||||
# Utiliser le même générateur de prompt avec l'image en base64
|
||||
prompt_base64 = self._generer_prompt_analyse(contexte, f"Analyse cette image:\n{img_base64}")
|
||||
|
||||
response = self.llm.interroger(prompt_base64)
|
||||
else:
|
||||
error_message = "Impossible d'encoder l'image en base64"
|
||||
logger.error(f"Erreur d'analyse pour {image_name}: {error_message}")
|
||||
print(f" ERREUR: {error_message}")
|
||||
|
||||
# Retourner un résultat d'erreur explicite
|
||||
return {
|
||||
"analyse": f"ERREUR: {error_message}. Veuillez vérifier que l'image est dans un format standard.",
|
||||
"error": True,
|
||||
"raw_response": "",
|
||||
"metadata": {
|
||||
"image_path": image_path,
|
||||
"image_name": image_name,
|
||||
"timestamp": self._get_timestamp(),
|
||||
"error": True
|
||||
}
|
||||
}
|
||||
else:
|
||||
error_message = "Impossible d'encoder l'image en base64"
|
||||
error_message = "Le modèle ne supporte pas l'encodage d'images en base64"
|
||||
logger.error(f"Erreur d'analyse pour {image_name}: {error_message}")
|
||||
print(f" ERREUR: {error_message}")
|
||||
|
||||
# Retourner un résultat d'erreur explicite
|
||||
return {
|
||||
"analyse": f"ERREUR: {error_message}. Veuillez vérifier que l'image est dans un format standard.",
|
||||
"analyse": f"ERREUR: {error_message}. Veuillez utiliser un modèle compatible avec l'analyse d'images.",
|
||||
"error": True,
|
||||
"raw_response": "",
|
||||
"metadata": {
|
||||
|
||||
393
agents/pixtral_large/agent_image_sorter.bak
Normal file
@ -0,0 +1,393 @@
|
||||
from ..base_agent import BaseAgent
|
||||
import logging
|
||||
import os
|
||||
from typing import Dict, Any, Tuple
|
||||
from PIL import Image
|
||||
import base64
|
||||
import io
|
||||
|
||||
logger = logging.getLogger("AgentImageSorter")
|
||||
|
||||
class AgentImageSorter(BaseAgent):
|
||||
"""
|
||||
Agent pour trier les images et identifier celles qui sont pertinentes.
|
||||
"""
|
||||
def __init__(self, llm):
|
||||
super().__init__("AgentImageSorter", llm)
|
||||
|
||||
# Configuration locale de l'agent
|
||||
self.temperature = 0.2
|
||||
self.top_p = 0.8
|
||||
self.max_tokens = 300
|
||||
|
||||
# Centralisation des critères de pertinence
|
||||
self.criteres_pertinence = """
|
||||
Images PERTINENTES (réponds "oui" ou "pertinent"):
|
||||
- Captures d'écran de logiciels ou d'interfaces
|
||||
- logo BRG_LAB
|
||||
- Référence à "logociel"
|
||||
- Messages d'erreur
|
||||
- Configurations système
|
||||
- Tableaux de bord ou graphiques techniques
|
||||
- Fenêtres de diagnostic
|
||||
|
||||
Images NON PERTINENTES (réponds "non" ou "non pertinent"):
|
||||
- Photos personnelles
|
||||
- Images marketing/promotionnelles
|
||||
- Logos ou images de marque
|
||||
- Paysages, personnes ou objets non liés à l'informatique
|
||||
"""
|
||||
|
||||
# Centralisation des instructions d'analyse
|
||||
self.instructions_analyse = """
|
||||
IMPORTANT: Ne commence JAMAIS ta réponse par "Je ne peux pas directement visualiser l'image".
|
||||
Si tu ne peux pas analyser l'image, réponds simplement "ERREUR: Impossible d'analyser l'image".
|
||||
|
||||
Analyse d'abord ce que montre l'image, puis réponds par "oui"/"pertinent" ou "non"/"non pertinent".
|
||||
"""
|
||||
|
||||
# Construction du système prompt à partir des éléments centralisés
|
||||
self.system_prompt = f"""Tu es un expert en tri d'images pour le support technique de BRG_Lab pour la société CBAO.
|
||||
Ta mission est de déterminer si une image est pertinente pour le support technique de logiciels.
|
||||
{self.criteres_pertinence}
|
||||
{self.instructions_analyse}"""
|
||||
|
||||
# Appliquer la configuration au LLM
|
||||
self._appliquer_config_locale()
|
||||
|
||||
logger.info("AgentImageSorter initialisé")
|
||||
|
||||
def _appliquer_config_locale(self) -> None:
|
||||
"""
|
||||
Applique la configuration locale au modèle LLM.
|
||||
"""
|
||||
# Appliquer le prompt système
|
||||
if hasattr(self.llm, "prompt_system"):
|
||||
self.llm.prompt_system = self.system_prompt
|
||||
|
||||
# Appliquer les paramètres
|
||||
if hasattr(self.llm, "configurer"):
|
||||
params = {
|
||||
"temperature": self.temperature,
|
||||
"top_p": self.top_p,
|
||||
"max_tokens": self.max_tokens
|
||||
}
|
||||
|
||||
self.llm.configurer(**params)
|
||||
|
||||
def _verifier_image(self, image_path: str) -> bool:
|
||||
"""
|
||||
Vérifie si l'image existe et est accessible
|
||||
|
||||
Args:
|
||||
image_path: Chemin vers l'image
|
||||
|
||||
Returns:
|
||||
True si l'image existe et est accessible, False sinon
|
||||
"""
|
||||
try:
|
||||
# Vérifier que le fichier existe
|
||||
if not os.path.exists(image_path):
|
||||
logger.error(f"L'image n'existe pas: {image_path}")
|
||||
return False
|
||||
|
||||
# Vérifier que le fichier est accessible en lecture
|
||||
if not os.access(image_path, os.R_OK):
|
||||
logger.error(f"L'image n'est pas accessible en lecture: {image_path}")
|
||||
return False
|
||||
|
||||
# Vérifier que le fichier peut être ouvert comme une image
|
||||
with Image.open(image_path) as img:
|
||||
# Vérifier les dimensions de l'image
|
||||
width, height = img.size
|
||||
if width <= 0 or height <= 0:
|
||||
logger.error(f"Dimensions d'image invalides: {width}x{height}")
|
||||
return False
|
||||
|
||||
logger.info(f"Image vérifiée avec succès: {image_path} ({width}x{height})")
|
||||
return True
|
||||
except Exception as e:
|
||||
logger.error(f"Erreur lors de la vérification de l'image {image_path}: {str(e)}")
|
||||
return False
|
||||
|
||||
def _encoder_image_base64(self, image_path: str) -> str:
|
||||
"""
|
||||
Encode l'image en base64 pour l'inclure directement dans le prompt
|
||||
|
||||
Args:
|
||||
image_path: Chemin vers l'image
|
||||
|
||||
Returns:
|
||||
Chaîne de caractères au format data URI avec l'image encodée en base64
|
||||
"""
|
||||
try:
|
||||
# Ouvrir l'image et la redimensionner si trop grande
|
||||
with Image.open(image_path) as img:
|
||||
# Redimensionner l'image si elle est trop grande (max 800x800)
|
||||
max_size = 800
|
||||
if img.width > max_size or img.height > max_size:
|
||||
img.thumbnail((max_size, max_size), Image.Resampling.LANCZOS)
|
||||
|
||||
# Convertir en RGB si nécessaire (pour les formats comme PNG)
|
||||
if img.mode != "RGB":
|
||||
img = img.convert("RGB")
|
||||
|
||||
# Sauvegarder l'image en JPEG dans un buffer mémoire
|
||||
buffer = io.BytesIO()
|
||||
img.save(buffer, format="JPEG", quality=85)
|
||||
buffer.seek(0)
|
||||
|
||||
# Encoder en base64
|
||||
img_base64 = base64.b64encode(buffer.read()).decode("utf-8")
|
||||
|
||||
# Construire le data URI
|
||||
data_uri = f"data:image/jpeg;base64,{img_base64}"
|
||||
|
||||
return data_uri
|
||||
except Exception as e:
|
||||
logger.error(f"Erreur lors de l'encodage de l'image {image_path}: {str(e)}")
|
||||
return ""
|
||||
|
||||
def _generer_prompt_analyse(self, prefix: str = "", avec_image_base64: bool = False) -> str:
|
||||
"""
|
||||
Génère le prompt d'analyse standardisé
|
||||
|
||||
Args:
|
||||
prefix: Préfixe optionnel (pour inclure l'image en base64 par exemple)
|
||||
avec_image_base64: Indique si le prompt inclut déjà une image en base64
|
||||
|
||||
Returns:
|
||||
Prompt formaté pour l'analyse
|
||||
"""
|
||||
return f"""{prefix}
|
||||
|
||||
Est-ce une image pertinente pour un ticket de support technique?
|
||||
Réponds simplement par 'oui' ou 'non' suivi d'une brève explication."""
|
||||
|
||||
def executer(self, image_path: str) -> Dict[str, Any]:
|
||||
"""
|
||||
Évalue si une image est pertinente pour l'analyse d'un ticket technique
|
||||
|
||||
Args:
|
||||
image_path: Chemin vers l'image à analyser
|
||||
|
||||
Returns:
|
||||
Dictionnaire contenant la décision de pertinence, l'analyse et les métadonnées
|
||||
"""
|
||||
image_name = os.path.basename(image_path)
|
||||
logger.info(f"Évaluation de la pertinence de l'image: {image_name}")
|
||||
print(f" AgentImageSorter: Évaluation de {image_name}")
|
||||
|
||||
# Vérifier que l'image existe et est accessible
|
||||
if not self._verifier_image(image_path):
|
||||
error_message = f"L'image n'est pas accessible ou n'est pas valide: {image_name}"
|
||||
logger.error(error_message)
|
||||
print(f" ERREUR: {error_message}")
|
||||
|
||||
return {
|
||||
"is_relevant": False,
|
||||
"reason": f"Erreur d'accès: {error_message}",
|
||||
"raw_response": "",
|
||||
"error": True,
|
||||
"metadata": {
|
||||
"image_path": image_path,
|
||||
"image_name": image_name,
|
||||
"timestamp": self._get_timestamp(),
|
||||
"error": True
|
||||
}
|
||||
}
|
||||
|
||||
# Utiliser une référence au fichier image que le modèle peut comprendre
|
||||
try:
|
||||
# Préparation du prompt standardisé
|
||||
prompt = self._generer_prompt_analyse()
|
||||
|
||||
# Utiliser la méthode interroger_avec_image au lieu de interroger
|
||||
if hasattr(self.llm, "interroger_avec_image"):
|
||||
logger.info(f"Utilisation de la méthode interroger_avec_image pour {image_name}")
|
||||
response = self.llm.interroger_avec_image(image_path, prompt)
|
||||
else:
|
||||
# Fallback vers la méthode standard avec base64 si interroger_avec_image n'existe pas
|
||||
logger.warning(f"La méthode interroger_avec_image n'existe pas, utilisation du fallback pour {image_name}")
|
||||
img_base64 = self._encoder_image_base64(image_path)
|
||||
if img_base64:
|
||||
prompt_base64 = self._generer_prompt_analyse(f"Analyse cette image:\n{img_base64}", True)
|
||||
response = self.llm.interroger(prompt_base64)
|
||||
else:
|
||||
error_message = "Impossible d'encoder l'image en base64"
|
||||
logger.error(f"Erreur d'analyse pour {image_name}: {error_message}")
|
||||
print(f" ERREUR: {error_message}")
|
||||
|
||||
return {
|
||||
"is_relevant": False,
|
||||
"reason": f"Erreur d'analyse: {error_message}",
|
||||
"raw_response": "",
|
||||
"error": True,
|
||||
"metadata": {
|
||||
"image_path": image_path,
|
||||
"image_name": image_name,
|
||||
"timestamp": self._get_timestamp(),
|
||||
"error": True
|
||||
}
|
||||
}
|
||||
|
||||
# Vérifier si la réponse contient des indications que le modèle ne peut pas analyser l'image
|
||||
error_phrases = [
|
||||
"je ne peux pas directement visualiser",
|
||||
"je n'ai pas accès à l'image",
|
||||
"je ne peux pas voir l'image",
|
||||
"sans accès direct à l'image",
|
||||
"je n'ai pas la possibilité de voir",
|
||||
"je ne peux pas accéder directement",
|
||||
"erreur: impossible d'analyser l'image"
|
||||
]
|
||||
|
||||
# Vérifier si une des phrases d'erreur est présente dans la réponse
|
||||
if any(phrase in response.lower() for phrase in error_phrases):
|
||||
logger.warning(f"Le modèle indique qu'il ne peut pas analyser l'image: {image_name}")
|
||||
error_message = "Le modèle n'a pas pu analyser l'image correctement"
|
||||
logger.error(f"Erreur d'analyse pour {image_name}: {error_message}")
|
||||
print(f" ERREUR: {error_message}")
|
||||
|
||||
# Retourner un résultat d'erreur explicite
|
||||
return {
|
||||
"is_relevant": False,
|
||||
"reason": f"Erreur d'analyse: {error_message}",
|
||||
"raw_response": response,
|
||||
"error": True,
|
||||
"metadata": {
|
||||
"image_path": image_path,
|
||||
"image_name": image_name,
|
||||
"timestamp": self._get_timestamp(),
|
||||
"error": True
|
||||
}
|
||||
}
|
||||
|
||||
# Analyse de la réponse pour déterminer la pertinence
|
||||
is_relevant, reason = self._analyser_reponse(response)
|
||||
|
||||
logger.info(f"Image {image_name} considérée comme {'pertinente' if is_relevant else 'non pertinente'}")
|
||||
print(f" Décision: Image {image_name} {'pertinente' if is_relevant else 'non pertinente'}")
|
||||
|
||||
# Préparer le résultat
|
||||
result = {
|
||||
"is_relevant": is_relevant,
|
||||
"reason": reason,
|
||||
"raw_response": response,
|
||||
"metadata": {
|
||||
"image_path": image_path,
|
||||
"image_name": image_name,
|
||||
"timestamp": self._get_timestamp(),
|
||||
"model_info": {
|
||||
"model": getattr(self.llm, "modele", str(type(self.llm))),
|
||||
"temperature": self.temperature,
|
||||
"top_p": self.top_p,
|
||||
"max_tokens": self.max_tokens
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
# Enregistrer la décision et le raisonnement dans l'historique
|
||||
self.ajouter_historique("tri_image",
|
||||
{
|
||||
"image_path": image_path,
|
||||
"prompt": prompt
|
||||
},
|
||||
{
|
||||
"response": response,
|
||||
"is_relevant": is_relevant,
|
||||
"reason": reason
|
||||
})
|
||||
|
||||
return result
|
||||
|
||||
except Exception as e:
|
||||
logger.error(f"Erreur lors de l'analyse de l'image {image_name}: {str(e)}")
|
||||
print(f" ERREUR: Impossible d'analyser l'image {image_name}")
|
||||
|
||||
# Retourner un résultat par défaut en cas d'erreur
|
||||
return {
|
||||
"is_relevant": False, # Par défaut, considérer non pertinent en cas d'erreur
|
||||
"reason": f"Erreur d'analyse: {str(e)}",
|
||||
"raw_response": "",
|
||||
"error": True,
|
||||
"metadata": {
|
||||
"image_path": image_path,
|
||||
"image_name": image_name,
|
||||
"timestamp": self._get_timestamp(),
|
||||
"error": True
|
||||
}
|
||||
}
|
||||
|
||||
def _analyser_reponse(self, response: str) -> Tuple[bool, str]:
|
||||
"""
|
||||
Analyse la réponse du LLM pour déterminer la pertinence et extraire le raisonnement
|
||||
|
||||
Args:
|
||||
response: Réponse brute du LLM
|
||||
|
||||
Returns:
|
||||
Tuple (is_relevant, reason) contenant la décision et le raisonnement
|
||||
"""
|
||||
# Convertir en minuscule pour faciliter la comparaison
|
||||
response_lower = response.lower()
|
||||
|
||||
# Détection directe des réponses négatives en début de texte
|
||||
first_line = response_lower.split('\n')[0] if '\n' in response_lower else response_lower[:50]
|
||||
starts_with_non = first_line.strip().startswith("non") or first_line.strip().startswith("non.")
|
||||
|
||||
# Détection explicite d'une réponse négative au début de la réponse
|
||||
explicit_negative = starts_with_non or any(neg_start in first_line for neg_start in ["non pertinent", "pas pertinent"])
|
||||
|
||||
# Détection explicite d'une réponse positive au début de la réponse
|
||||
explicit_positive = first_line.strip().startswith("oui") or first_line.strip().startswith("pertinent")
|
||||
|
||||
# Si une réponse explicite est détectée, l'utiliser directement
|
||||
if explicit_negative:
|
||||
is_relevant = False
|
||||
elif explicit_positive:
|
||||
is_relevant = True
|
||||
else:
|
||||
# Sinon, utiliser l'analyse par mots-clés
|
||||
# Mots clés positifs forts
|
||||
positive_keywords = ["oui", "pertinent", "pertinente", "utile", "important", "relevante",
|
||||
"capture d'écran", "message d'erreur", "interface logicielle",
|
||||
"configuration", "technique", "diagnostic"]
|
||||
|
||||
# Mots clés négatifs forts
|
||||
negative_keywords = ["non", "pas pertinent", "non pertinente", "inutile", "irrelevant",
|
||||
"photo personnelle", "marketing", "sans rapport", "hors sujet",
|
||||
"décorative", "logo"]
|
||||
|
||||
# Compter les occurrences de mots clés
|
||||
positive_count = sum(1 for kw in positive_keywords if kw in response_lower)
|
||||
negative_count = sum(1 for kw in negative_keywords if kw in response_lower)
|
||||
|
||||
# Heuristique de décision basée sur la prépondérance des mots clés
|
||||
is_relevant = positive_count > negative_count
|
||||
|
||||
# Extraire le raisonnement (les dernières phrases de la réponse)
|
||||
lines = response.split('\n')
|
||||
reason_lines = []
|
||||
for line in reversed(lines):
|
||||
if line.strip():
|
||||
reason_lines.insert(0, line.strip())
|
||||
if len(reason_lines) >= 2: # Prendre les 2 dernières lignes non vides
|
||||
break
|
||||
|
||||
reason = " ".join(reason_lines) if reason_lines else "Décision basée sur l'analyse des mots-clés"
|
||||
|
||||
# Log détaillé de l'analyse
|
||||
logger.debug(f"Analyse de la réponse: \n - Réponse brute: {response[:100]}...\n"
|
||||
f" - Commence par 'non': {starts_with_non}\n"
|
||||
f" - Détection explicite négative: {explicit_negative}\n"
|
||||
f" - Détection explicite positive: {explicit_positive}\n"
|
||||
f" - Décision finale: {'pertinente' if is_relevant else 'non pertinente'}\n"
|
||||
f" - Raison: {reason}")
|
||||
|
||||
return is_relevant, reason
|
||||
|
||||
def _get_timestamp(self) -> str:
|
||||
"""Retourne un timestamp au format YYYYMMDD_HHMMSS"""
|
||||
from datetime import datetime
|
||||
return datetime.now().strftime("%Y%m%d_%H%M%S")
|
||||
@ -3,8 +3,6 @@ import logging
|
||||
import os
|
||||
from typing import Dict, Any, Tuple
|
||||
from PIL import Image
|
||||
import base64
|
||||
import io
|
||||
|
||||
logger = logging.getLogger("AgentImageSorter")
|
||||
|
||||
@ -14,262 +12,104 @@ class AgentImageSorter(BaseAgent):
|
||||
"""
|
||||
def __init__(self, llm):
|
||||
super().__init__("AgentImageSorter", llm)
|
||||
|
||||
# Configuration locale de l'agent
|
||||
|
||||
# Configuration personnalisable
|
||||
self.temperature = 0.2
|
||||
self.top_p = 0.8
|
||||
self.max_tokens = 300
|
||||
|
||||
# Centralisation des critères de pertinence
|
||||
self.criteres_pertinence = """
|
||||
Images PERTINENTES (réponds "oui" ou "pertinent"):
|
||||
- Captures d'écran de logiciels ou d'interfaces
|
||||
- logo BRG_LAB
|
||||
- Référence à "logociel"
|
||||
- Messages d'erreur
|
||||
- Configurations système
|
||||
- Tableaux de bord ou graphiques techniques
|
||||
- Fenêtres de diagnostic
|
||||
|
||||
Images NON PERTINENTES (réponds "non" ou "non pertinent"):
|
||||
- Photos personnelles
|
||||
- Images marketing/promotionnelles
|
||||
- Logos ou images de marque
|
||||
- Paysages, personnes ou objets non liés à l'informatique
|
||||
"""
|
||||
self.criteres_pertinence = (
|
||||
"""
|
||||
Images PERTINENTES (réponds "oui" ou "pertinent"):
|
||||
- Captures d'écran de logiciels ou d'interfaces
|
||||
- logo BRG_LAB
|
||||
- Référence à "logociel"
|
||||
- Messages d'erreur
|
||||
- Configurations système
|
||||
- Tableaux de bord ou graphiques techniques
|
||||
- Fenêtres de diagnostic
|
||||
|
||||
# Centralisation des instructions d'analyse
|
||||
self.instructions_analyse = """
|
||||
IMPORTANT: Ne commence JAMAIS ta réponse par "Je ne peux pas directement visualiser l'image".
|
||||
Si tu ne peux pas analyser l'image, réponds simplement "ERREUR: Impossible d'analyser l'image".
|
||||
Images NON PERTINENTES (réponds "non" ou "non pertinent"):
|
||||
- Photos personnelles
|
||||
- Images marketing/promotionnelles
|
||||
- Logos ou images de marque
|
||||
- Paysages, personnes ou objets non liés à l'informatique
|
||||
"""
|
||||
)
|
||||
|
||||
Analyse d'abord ce que montre l'image, puis réponds par "oui"/"pertinent" ou "non"/"non pertinent".
|
||||
"""
|
||||
self.instructions_analyse = (
|
||||
"""
|
||||
IMPORTANT: Ne commence JAMAIS ta réponse par "Je ne peux pas directement visualiser l'image".
|
||||
Si tu ne peux pas analyser l'image, réponds simplement "ERREUR: Impossible d'analyser l'image".
|
||||
|
||||
Analyse d'abord ce que montre l'image, puis réponds par "oui"/"pertinent" ou "non"/"non pertinent".
|
||||
"""
|
||||
)
|
||||
|
||||
self.system_prompt = (
|
||||
"""
|
||||
Tu es un expert en tri d'images pour le support technique de BRG_Lab pour la société CBAO.
|
||||
Ta mission est de déterminer si une image est pertinente pour le support technique de logiciels.
|
||||
{criteres}
|
||||
{instructions}
|
||||
"""
|
||||
).format(
|
||||
criteres=self.criteres_pertinence,
|
||||
instructions=self.instructions_analyse
|
||||
)
|
||||
|
||||
# Construction du système prompt à partir des éléments centralisés
|
||||
self.system_prompt = f"""Tu es un expert en tri d'images pour le support technique de BRG_Lab pour la société CBAO.
|
||||
Ta mission est de déterminer si une image est pertinente pour le support technique de logiciels.
|
||||
{self.criteres_pertinence}
|
||||
{self.instructions_analyse}"""
|
||||
|
||||
# Appliquer la configuration au LLM
|
||||
self._appliquer_config_locale()
|
||||
|
||||
logger.info("AgentImageSorter initialisé")
|
||||
|
||||
|
||||
def _appliquer_config_locale(self) -> None:
|
||||
"""
|
||||
Applique la configuration locale au modèle LLM.
|
||||
"""
|
||||
# Appliquer le prompt système
|
||||
if hasattr(self.llm, "prompt_system"):
|
||||
self.llm.prompt_system = self.system_prompt
|
||||
|
||||
# Appliquer les paramètres
|
||||
if hasattr(self.llm, "configurer"):
|
||||
params = {
|
||||
"temperature": self.temperature,
|
||||
"top_p": self.top_p,
|
||||
"max_tokens": self.max_tokens
|
||||
}
|
||||
|
||||
self.llm.configurer(**params)
|
||||
|
||||
def _verifier_image(self, image_path: str) -> bool:
|
||||
"""
|
||||
Vérifie si l'image existe et est accessible
|
||||
|
||||
Args:
|
||||
image_path: Chemin vers l'image
|
||||
|
||||
Returns:
|
||||
True si l'image existe et est accessible, False sinon
|
||||
"""
|
||||
try:
|
||||
# Vérifier que le fichier existe
|
||||
if not os.path.exists(image_path):
|
||||
logger.error(f"L'image n'existe pas: {image_path}")
|
||||
return False
|
||||
|
||||
# Vérifier que le fichier est accessible en lecture
|
||||
if not os.access(image_path, os.R_OK):
|
||||
logger.error(f"L'image n'est pas accessible en lecture: {image_path}")
|
||||
return False
|
||||
|
||||
# Vérifier que le fichier peut être ouvert comme une image
|
||||
with Image.open(image_path) as img:
|
||||
# Vérifier les dimensions de l'image
|
||||
width, height = img.size
|
||||
if width <= 0 or height <= 0:
|
||||
logger.error(f"Dimensions d'image invalides: {width}x{height}")
|
||||
return False
|
||||
|
||||
logger.info(f"Image vérifiée avec succès: {image_path} ({width}x{height})")
|
||||
return True
|
||||
except Exception as e:
|
||||
logger.error(f"Erreur lors de la vérification de l'image {image_path}: {str(e)}")
|
||||
return False
|
||||
|
||||
def _encoder_image_base64(self, image_path: str) -> str:
|
||||
"""
|
||||
Encode l'image en base64 pour l'inclure directement dans le prompt
|
||||
|
||||
Args:
|
||||
image_path: Chemin vers l'image
|
||||
|
||||
Returns:
|
||||
Chaîne de caractères au format data URI avec l'image encodée en base64
|
||||
"""
|
||||
try:
|
||||
# Ouvrir l'image et la redimensionner si trop grande
|
||||
with Image.open(image_path) as img:
|
||||
# Redimensionner l'image si elle est trop grande (max 800x800)
|
||||
max_size = 800
|
||||
if img.width > max_size or img.height > max_size:
|
||||
img.thumbnail((max_size, max_size), Image.Resampling.LANCZOS)
|
||||
|
||||
# Convertir en RGB si nécessaire (pour les formats comme PNG)
|
||||
if img.mode != "RGB":
|
||||
img = img.convert("RGB")
|
||||
|
||||
# Sauvegarder l'image en JPEG dans un buffer mémoire
|
||||
buffer = io.BytesIO()
|
||||
img.save(buffer, format="JPEG", quality=85)
|
||||
buffer.seek(0)
|
||||
|
||||
# Encoder en base64
|
||||
img_base64 = base64.b64encode(buffer.read()).decode("utf-8")
|
||||
|
||||
# Construire le data URI
|
||||
data_uri = f"data:image/jpeg;base64,{img_base64}"
|
||||
|
||||
return data_uri
|
||||
except Exception as e:
|
||||
logger.error(f"Erreur lors de l'encodage de l'image {image_path}: {str(e)}")
|
||||
return ""
|
||||
|
||||
def _generer_prompt_analyse(self, prefix: str = "", avec_image_base64: bool = False) -> str:
|
||||
"""
|
||||
Génère le prompt d'analyse standardisé
|
||||
|
||||
Args:
|
||||
prefix: Préfixe optionnel (pour inclure l'image en base64 par exemple)
|
||||
avec_image_base64: Indique si le prompt inclut déjà une image en base64
|
||||
|
||||
Returns:
|
||||
Prompt formaté pour l'analyse
|
||||
"""
|
||||
return f"""{prefix}
|
||||
self.llm.configurer(
|
||||
temperature=self.temperature,
|
||||
top_p=self.top_p,
|
||||
max_tokens=self.max_tokens
|
||||
)
|
||||
|
||||
def _verifier_image(self, image_path: str) -> bool:
|
||||
try:
|
||||
if not os.path.exists(image_path) or not os.access(image_path, os.R_OK):
|
||||
return False
|
||||
with Image.open(image_path) as img:
|
||||
width, height = img.size
|
||||
return width > 0 and height > 0
|
||||
except Exception as e:
|
||||
logger.error(f"Vérification impossible pour {image_path}: {e}")
|
||||
return False
|
||||
|
||||
def _generer_prompt_analyse(self, prefix: str = "") -> str:
|
||||
return f"{prefix}\n\nEst-ce une image pertinente pour un ticket de support technique?\nRéponds simplement par 'oui' ou 'non' suivi d'une brève explication."
|
||||
|
||||
def executer(self, image_path: str) -> Dict[str, Any]:
|
||||
image_name = os.path.basename(image_path)
|
||||
print(f" AgentImageSorter: Évaluation de {image_name}")
|
||||
|
||||
if not self._verifier_image(image_path):
|
||||
return self._erreur("Erreur d'accès ou image invalide", image_path)
|
||||
|
||||
Est-ce une image pertinente pour un ticket de support technique?
|
||||
Réponds simplement par 'oui' ou 'non' suivi d'une brève explication."""
|
||||
|
||||
def executer(self, image_path: str) -> Dict[str, Any]:
|
||||
"""
|
||||
Évalue si une image est pertinente pour l'analyse d'un ticket technique
|
||||
|
||||
Args:
|
||||
image_path: Chemin vers l'image à analyser
|
||||
|
||||
Returns:
|
||||
Dictionnaire contenant la décision de pertinence, l'analyse et les métadonnées
|
||||
"""
|
||||
image_name = os.path.basename(image_path)
|
||||
logger.info(f"Évaluation de la pertinence de l'image: {image_name}")
|
||||
print(f" AgentImageSorter: Évaluation de {image_name}")
|
||||
|
||||
# Vérifier que l'image existe et est accessible
|
||||
if not self._verifier_image(image_path):
|
||||
error_message = f"L'image n'est pas accessible ou n'est pas valide: {image_name}"
|
||||
logger.error(error_message)
|
||||
print(f" ERREUR: {error_message}")
|
||||
|
||||
return {
|
||||
"is_relevant": False,
|
||||
"reason": f"Erreur d'accès: {error_message}",
|
||||
"raw_response": "",
|
||||
"error": True,
|
||||
"metadata": {
|
||||
"image_path": image_path,
|
||||
"image_name": image_name,
|
||||
"timestamp": self._get_timestamp(),
|
||||
"error": True
|
||||
}
|
||||
}
|
||||
|
||||
# Utiliser une référence au fichier image que le modèle peut comprendre
|
||||
try:
|
||||
# Préparation du prompt standardisé
|
||||
prompt = self._generer_prompt_analyse()
|
||||
|
||||
# Utiliser la méthode interroger_avec_image au lieu de interroger
|
||||
if hasattr(self.llm, "interroger_avec_image"):
|
||||
logger.info(f"Utilisation de la méthode interroger_avec_image pour {image_name}")
|
||||
response = self.llm.interroger_avec_image(image_path, prompt)
|
||||
elif hasattr(self.llm, "_encoder_image_base64"):
|
||||
img_base64 = self.llm._encoder_image_base64(image_path)
|
||||
prompt = self._generer_prompt_analyse(f"Analyse cette image:\n{img_base64}")
|
||||
response = self.llm.interroger(prompt)
|
||||
else:
|
||||
# Fallback vers la méthode standard avec base64 si interroger_avec_image n'existe pas
|
||||
logger.warning(f"La méthode interroger_avec_image n'existe pas, utilisation du fallback pour {image_name}")
|
||||
img_base64 = self._encoder_image_base64(image_path)
|
||||
if img_base64:
|
||||
prompt_base64 = self._generer_prompt_analyse(f"Analyse cette image:\n{img_base64}", True)
|
||||
response = self.llm.interroger(prompt_base64)
|
||||
else:
|
||||
error_message = "Impossible d'encoder l'image en base64"
|
||||
logger.error(f"Erreur d'analyse pour {image_name}: {error_message}")
|
||||
print(f" ERREUR: {error_message}")
|
||||
|
||||
return {
|
||||
"is_relevant": False,
|
||||
"reason": f"Erreur d'analyse: {error_message}",
|
||||
"raw_response": "",
|
||||
"error": True,
|
||||
"metadata": {
|
||||
"image_path": image_path,
|
||||
"image_name": image_name,
|
||||
"timestamp": self._get_timestamp(),
|
||||
"error": True
|
||||
}
|
||||
}
|
||||
|
||||
# Vérifier si la réponse contient des indications que le modèle ne peut pas analyser l'image
|
||||
error_phrases = [
|
||||
"je ne peux pas directement visualiser",
|
||||
"je n'ai pas accès à l'image",
|
||||
"je ne peux pas voir l'image",
|
||||
"sans accès direct à l'image",
|
||||
"je n'ai pas la possibilité de voir",
|
||||
"je ne peux pas accéder directement",
|
||||
"erreur: impossible d'analyser l'image"
|
||||
]
|
||||
|
||||
# Vérifier si une des phrases d'erreur est présente dans la réponse
|
||||
if any(phrase in response.lower() for phrase in error_phrases):
|
||||
logger.warning(f"Le modèle indique qu'il ne peut pas analyser l'image: {image_name}")
|
||||
error_message = "Le modèle n'a pas pu analyser l'image correctement"
|
||||
logger.error(f"Erreur d'analyse pour {image_name}: {error_message}")
|
||||
print(f" ERREUR: {error_message}")
|
||||
|
||||
# Retourner un résultat d'erreur explicite
|
||||
return {
|
||||
"is_relevant": False,
|
||||
"reason": f"Erreur d'analyse: {error_message}",
|
||||
"raw_response": response,
|
||||
"error": True,
|
||||
"metadata": {
|
||||
"image_path": image_path,
|
||||
"image_name": image_name,
|
||||
"timestamp": self._get_timestamp(),
|
||||
"error": True
|
||||
}
|
||||
}
|
||||
|
||||
# Analyse de la réponse pour déterminer la pertinence
|
||||
return self._erreur("Le modèle ne supporte pas les images", image_path)
|
||||
|
||||
if any(err in response.lower() for err in [
|
||||
"je ne peux pas", "je n'ai pas accès", "impossible d'analyser"]):
|
||||
return self._erreur("Réponse du modèle invalide", image_path, raw=response)
|
||||
|
||||
is_relevant, reason = self._analyser_reponse(response)
|
||||
|
||||
logger.info(f"Image {image_name} considérée comme {'pertinente' if is_relevant else 'non pertinente'}")
|
||||
print(f" Décision: Image {image_name} {'pertinente' if is_relevant else 'non pertinente'}")
|
||||
|
||||
# Préparer le résultat
|
||||
|
||||
result = {
|
||||
"is_relevant": is_relevant,
|
||||
"reason": reason,
|
||||
@ -280,114 +120,45 @@ Réponds simplement par 'oui' ou 'non' suivi d'une brève explication."""
|
||||
"timestamp": self._get_timestamp(),
|
||||
"model_info": {
|
||||
"model": getattr(self.llm, "modele", str(type(self.llm))),
|
||||
"temperature": self.temperature,
|
||||
"top_p": self.top_p,
|
||||
"max_tokens": self.max_tokens
|
||||
}
|
||||
**getattr(self.llm, "params", {})
|
||||
},
|
||||
"source_agent": self.nom
|
||||
}
|
||||
}
|
||||
|
||||
# Enregistrer la décision et le raisonnement dans l'historique
|
||||
self.ajouter_historique("tri_image",
|
||||
{
|
||||
"image_path": image_path,
|
||||
"prompt": prompt
|
||||
},
|
||||
{
|
||||
"response": response,
|
||||
"is_relevant": is_relevant,
|
||||
"reason": reason
|
||||
})
|
||||
|
||||
self.ajouter_historique("tri_image", {"image_path": image_path, "prompt": prompt}, result)
|
||||
return result
|
||||
|
||||
|
||||
except Exception as e:
|
||||
logger.error(f"Erreur lors de l'analyse de l'image {image_name}: {str(e)}")
|
||||
print(f" ERREUR: Impossible d'analyser l'image {image_name}")
|
||||
|
||||
# Retourner un résultat par défaut en cas d'erreur
|
||||
return {
|
||||
"is_relevant": False, # Par défaut, considérer non pertinent en cas d'erreur
|
||||
"reason": f"Erreur d'analyse: {str(e)}",
|
||||
"raw_response": "",
|
||||
"error": True,
|
||||
"metadata": {
|
||||
"image_path": image_path,
|
||||
"image_name": image_name,
|
||||
"timestamp": self._get_timestamp(),
|
||||
"error": True
|
||||
}
|
||||
}
|
||||
|
||||
return self._erreur(str(e), image_path)
|
||||
|
||||
def _analyser_reponse(self, response: str) -> Tuple[bool, str]:
|
||||
"""
|
||||
Analyse la réponse du LLM pour déterminer la pertinence et extraire le raisonnement
|
||||
|
||||
Args:
|
||||
response: Réponse brute du LLM
|
||||
|
||||
Returns:
|
||||
Tuple (is_relevant, reason) contenant la décision et le raisonnement
|
||||
"""
|
||||
# Convertir en minuscule pour faciliter la comparaison
|
||||
response_lower = response.lower()
|
||||
|
||||
# Détection directe des réponses négatives en début de texte
|
||||
first_line = response_lower.split('\n')[0] if '\n' in response_lower else response_lower[:50]
|
||||
starts_with_non = first_line.strip().startswith("non") or first_line.strip().startswith("non.")
|
||||
|
||||
# Détection explicite d'une réponse négative au début de la réponse
|
||||
explicit_negative = starts_with_non or any(neg_start in first_line for neg_start in ["non pertinent", "pas pertinent"])
|
||||
|
||||
# Détection explicite d'une réponse positive au début de la réponse
|
||||
explicit_positive = first_line.strip().startswith("oui") or first_line.strip().startswith("pertinent")
|
||||
|
||||
# Si une réponse explicite est détectée, l'utiliser directement
|
||||
if explicit_negative:
|
||||
is_relevant = False
|
||||
elif explicit_positive:
|
||||
is_relevant = True
|
||||
else:
|
||||
# Sinon, utiliser l'analyse par mots-clés
|
||||
# Mots clés positifs forts
|
||||
positive_keywords = ["oui", "pertinent", "pertinente", "utile", "important", "relevante",
|
||||
"capture d'écran", "message d'erreur", "interface logicielle",
|
||||
"configuration", "technique", "diagnostic"]
|
||||
|
||||
# Mots clés négatifs forts
|
||||
negative_keywords = ["non", "pas pertinent", "non pertinente", "inutile", "irrelevant",
|
||||
"photo personnelle", "marketing", "sans rapport", "hors sujet",
|
||||
"décorative", "logo"]
|
||||
|
||||
# Compter les occurrences de mots clés
|
||||
positive_count = sum(1 for kw in positive_keywords if kw in response_lower)
|
||||
negative_count = sum(1 for kw in negative_keywords if kw in response_lower)
|
||||
|
||||
# Heuristique de décision basée sur la prépondérance des mots clés
|
||||
is_relevant = positive_count > negative_count
|
||||
|
||||
# Extraire le raisonnement (les dernières phrases de la réponse)
|
||||
lines = response.split('\n')
|
||||
reason_lines = []
|
||||
for line in reversed(lines):
|
||||
if line.strip():
|
||||
reason_lines.insert(0, line.strip())
|
||||
if len(reason_lines) >= 2: # Prendre les 2 dernières lignes non vides
|
||||
break
|
||||
|
||||
reason = " ".join(reason_lines) if reason_lines else "Décision basée sur l'analyse des mots-clés"
|
||||
|
||||
# Log détaillé de l'analyse
|
||||
logger.debug(f"Analyse de la réponse: \n - Réponse brute: {response[:100]}...\n"
|
||||
f" - Commence par 'non': {starts_with_non}\n"
|
||||
f" - Détection explicite négative: {explicit_negative}\n"
|
||||
f" - Détection explicite positive: {explicit_positive}\n"
|
||||
f" - Décision finale: {'pertinente' if is_relevant else 'non pertinente'}\n"
|
||||
f" - Raison: {reason}")
|
||||
|
||||
return is_relevant, reason
|
||||
|
||||
r = response.lower()
|
||||
first_line = r.split('\n')[0] if '\n' in r else r[:50].strip()
|
||||
if first_line.startswith("non") or "non pertinent" in first_line:
|
||||
return False, response.strip()
|
||||
if first_line.startswith("oui") or "pertinent" in first_line:
|
||||
return True, response.strip()
|
||||
|
||||
pos_keywords = ["pertinent", "utile", "important", "diagnostic"]
|
||||
neg_keywords = ["inutile", "photo", "hors sujet", "marketing", "non pertinent"]
|
||||
score = sum(kw in r for kw in pos_keywords) - sum(kw in r for kw in neg_keywords)
|
||||
return score > 0, response.strip()
|
||||
|
||||
def _erreur(self, message: str, path: str, raw: str = "") -> Dict[str, Any]:
|
||||
return {
|
||||
"is_relevant": False,
|
||||
"reason": message,
|
||||
"raw_response": raw,
|
||||
"error": True,
|
||||
"metadata": {
|
||||
"image_path": path,
|
||||
"image_name": os.path.basename(path),
|
||||
"timestamp": self._get_timestamp(),
|
||||
"error": True,
|
||||
"source_agent": self.nom
|
||||
}
|
||||
}
|
||||
|
||||
def _get_timestamp(self) -> str:
|
||||
"""Retourne un timestamp au format YYYYMMDD_HHMMSS"""
|
||||
from datetime import datetime
|
||||
return datetime.now().strftime("%Y%m%d_%H%M%S")
|
||||
return datetime.now().strftime("%Y%m%d_%H%M%S")
|
||||
|
||||
@ -16,7 +16,9 @@ class BaseLLM(abc.ABC):
|
||||
"max_tokens": 4000,
|
||||
"presence_penalty": 0,
|
||||
"frequency_penalty": 0,
|
||||
"stop": []
|
||||
"stop": [],
|
||||
"stream":False,
|
||||
"n":1
|
||||
}
|
||||
|
||||
self.dureeTraitement: timedelta = timedelta()
|
||||
|
||||
477
orchestrator.bak
Normal file
@ -0,0 +1,477 @@
|
||||
import os
|
||||
import json
|
||||
import logging
|
||||
import time
|
||||
import traceback
|
||||
from typing import List, Dict, Any, Optional, Union, Mapping, cast
|
||||
from agents.base_agent import BaseAgent
|
||||
from loaders.ticket_data_loader import TicketDataLoader
|
||||
from agents.utils.report_formatter import generer_rapport_markdown
|
||||
|
||||
# Configuration du logging
|
||||
logging.basicConfig(level=logging.INFO, format='%(asctime)s - %(levelname)s - %(message)s',
|
||||
filename='orchestrator.log', filemode='w')
|
||||
logger = logging.getLogger("Orchestrator")
|
||||
|
||||
class Orchestrator:
|
||||
"""
|
||||
Orchestrateur pour l'analyse de tickets et la génération de rapports.
|
||||
|
||||
Stratégie de gestion des formats:
|
||||
- JSON est le format principal pour le traitement des données et l'analyse
|
||||
- Markdown est utilisé uniquement comme format de présentation finale
|
||||
- Les agents LLM travaillent principalement avec le format JSON
|
||||
- La conversion JSON->Markdown se fait uniquement à la fin du processus pour la présentation
|
||||
|
||||
Cette approche permet de:
|
||||
1. Simplifier le code des agents
|
||||
2. Réduire les redondances et incohérences entre formats
|
||||
3. Améliorer la performance des agents LLM avec un format plus structuré
|
||||
4. Faciliter la maintenance et l'évolution du système
|
||||
"""
|
||||
def __init__(self,
|
||||
output_dir: str = "output/",
|
||||
ticket_agent: Optional[BaseAgent] = None,
|
||||
image_sorter: Optional[BaseAgent] = None,
|
||||
image_analyser: Optional[BaseAgent] = None,
|
||||
report_generator: Optional[BaseAgent] = None):
|
||||
|
||||
self.output_dir = output_dir
|
||||
|
||||
# Assignation directe des agents
|
||||
self.ticket_agent = ticket_agent
|
||||
self.image_sorter = image_sorter
|
||||
self.image_analyser = image_analyser
|
||||
self.report_generator = report_generator
|
||||
|
||||
# Initialisation du loader de données de ticket
|
||||
self.ticket_loader = TicketDataLoader()
|
||||
|
||||
# Collecter et enregistrer les informations détaillées sur les agents
|
||||
agents_info = self._collecter_info_agents()
|
||||
|
||||
logger.info(f"Orchestrator initialisé avec output_dir: {output_dir}")
|
||||
logger.info(f"Agents disponibles: TicketAgent={ticket_agent is not None}, ImageSorter={image_sorter is not None}, ImageAnalyser={image_analyser is not None}, ReportGenerator={report_generator is not None}")
|
||||
logger.info(f"Configuration des agents: {json.dumps(agents_info, indent=2)}")
|
||||
|
||||
def _collecter_info_agents(self) -> Dict[str, Dict[str, Any]]:
|
||||
"""
|
||||
Collecte des informations détaillées sur les agents configurés
|
||||
"""
|
||||
agents_info = {}
|
||||
|
||||
# Information sur l'agent Ticket
|
||||
if self.ticket_agent:
|
||||
agents_info["ticket_agent"] = self._get_agent_info(self.ticket_agent)
|
||||
|
||||
# Information sur l'agent Image Sorter
|
||||
if self.image_sorter:
|
||||
agents_info["image_sorter"] = self._get_agent_info(self.image_sorter)
|
||||
|
||||
# Information sur l'agent Image Analyser
|
||||
if self.image_analyser:
|
||||
agents_info["image_analyser"] = self._get_agent_info(self.image_analyser)
|
||||
|
||||
# Information sur l'agent Report Generator
|
||||
if self.report_generator:
|
||||
agents_info["report_generator"] = self._get_agent_info(self.report_generator)
|
||||
|
||||
return agents_info
|
||||
|
||||
def detecter_tickets(self) -> List[str]:
|
||||
"""Détecte tous les tickets disponibles dans le répertoire de sortie"""
|
||||
logger.info(f"Recherche de tickets dans: {self.output_dir}")
|
||||
tickets = []
|
||||
|
||||
if not os.path.exists(self.output_dir):
|
||||
logger.warning(f"Le répertoire de sortie {self.output_dir} n'existe pas")
|
||||
print(f"ERREUR: Le répertoire {self.output_dir} n'existe pas")
|
||||
return tickets
|
||||
|
||||
for ticket_dir in os.listdir(self.output_dir):
|
||||
ticket_path = os.path.join(self.output_dir, ticket_dir)
|
||||
if os.path.isdir(ticket_path) and ticket_dir.startswith("ticket_"):
|
||||
tickets.append(ticket_dir)
|
||||
|
||||
return tickets
|
||||
|
||||
def trouver_rapport(self, extraction_path: str, ticket_id: str) -> Dict[str, Optional[str]]:
|
||||
"""
|
||||
Cherche les rapports disponibles (JSON et/ou MD) pour un ticket
|
||||
|
||||
Args:
|
||||
extraction_path: Chemin vers l'extraction
|
||||
ticket_id: ID du ticket
|
||||
|
||||
Returns:
|
||||
Dictionnaire avec {"json": chemin_json, "markdown": chemin_md}
|
||||
"""
|
||||
# Utiliser la méthode du TicketDataLoader pour trouver les fichiers
|
||||
result = self.ticket_loader.trouver_ticket(extraction_path, ticket_id)
|
||||
|
||||
# S'assurer que nous avons un dictionnaire avec la structure correcte
|
||||
rapports: Dict[str, Optional[str]] = {"json": None, "markdown": None} if result is None else result
|
||||
|
||||
# Si on a un JSON mais pas de Markdown, générer le Markdown à partir du JSON
|
||||
json_path = rapports.get("json")
|
||||
if json_path and not rapports.get("markdown"):
|
||||
logger.info(f"Rapport JSON trouvé sans Markdown correspondant, génération du Markdown: {json_path}")
|
||||
|
||||
md_path = generer_rapport_markdown(json_path, True)
|
||||
if md_path:
|
||||
rapports["markdown"] = md_path
|
||||
logger.info(f"Markdown généré avec succès: {md_path}")
|
||||
else:
|
||||
logger.warning(f"Erreur lors de la génération du Markdown")
|
||||
|
||||
return rapports
|
||||
|
||||
def executer(self, ticket_specifique: Optional[str] = None):
|
||||
"""
|
||||
Exécute l'orchestrateur soit sur un ticket spécifique, soit sur tous les tickets
|
||||
|
||||
Args:
|
||||
ticket_specifique: Code du ticket spécifique à traiter (optionnel)
|
||||
"""
|
||||
start_time = time.time()
|
||||
|
||||
# Obtenir la liste des tickets
|
||||
if ticket_specifique:
|
||||
# Chercher le ticket spécifique
|
||||
ticket_path = os.path.join(self.output_dir, f"ticket_{ticket_specifique}")
|
||||
if os.path.exists(ticket_path):
|
||||
ticket_dirs = [ticket_path]
|
||||
logger.info(f"Ticket spécifique à traiter: {ticket_specifique}")
|
||||
print(f"Ticket spécifique à traiter: {ticket_specifique}")
|
||||
else:
|
||||
logger.error(f"Le ticket {ticket_specifique} n'existe pas")
|
||||
print(f"ERREUR: Le ticket {ticket_specifique} n'existe pas")
|
||||
return
|
||||
else:
|
||||
# Lister tous les tickets
|
||||
ticket_dirs = [os.path.join(self.output_dir, d) for d in self.detecter_tickets()]
|
||||
logger.info(f"Tickets à traiter: {len(ticket_dirs)}")
|
||||
|
||||
if not ticket_dirs:
|
||||
logger.warning("Aucun ticket trouvé dans le répertoire de sortie")
|
||||
print("Aucun ticket trouvé dans le répertoire de sortie")
|
||||
return
|
||||
|
||||
# Un seul log de début d'exécution
|
||||
logger.info("Début de l'exécution de l'orchestrateur")
|
||||
print("Début de l'exécution de l'orchestrateur")
|
||||
|
||||
# Traitement des tickets
|
||||
for ticket_dir in ticket_dirs:
|
||||
try:
|
||||
self.traiter_ticket(ticket_dir)
|
||||
except Exception as e:
|
||||
logger.error(f"Erreur lors du traitement du ticket {ticket_dir}: {str(e)}")
|
||||
print(f"Erreur lors du traitement du ticket {ticket_dir}: {str(e)}")
|
||||
traceback.print_exc()
|
||||
|
||||
# Calcul de la durée d'exécution
|
||||
duration = time.time() - start_time
|
||||
logger.info(f"Fin de l'exécution de l'orchestrateur (durée: {duration:.2f} secondes)")
|
||||
print(f"Fin de l'exécution de l'orchestrateur (durée: {duration:.2f} secondes)")
|
||||
|
||||
def traiter_ticket(self, ticket_path: str) -> bool:
|
||||
"""Traite un ticket spécifique et retourne True si le traitement a réussi"""
|
||||
logger.info(f"Début du traitement du ticket: {ticket_path}")
|
||||
print(f"\nTraitement du ticket: {os.path.basename(ticket_path)}")
|
||||
|
||||
success = False
|
||||
extractions_trouvees = False
|
||||
|
||||
if not os.path.exists(ticket_path):
|
||||
logger.error(f"Le chemin du ticket n'existe pas: {ticket_path}")
|
||||
print(f"ERREUR: Le chemin du ticket n'existe pas: {ticket_path}")
|
||||
return False
|
||||
|
||||
ticket_id = os.path.basename(ticket_path).replace("ticket_", "")
|
||||
|
||||
for extraction in os.listdir(ticket_path):
|
||||
extraction_path = os.path.join(ticket_path, extraction)
|
||||
if os.path.isdir(extraction_path):
|
||||
extractions_trouvees = True
|
||||
logger.info(f"Traitement de l'extraction: {extraction}")
|
||||
print(f" Traitement de l'extraction: {extraction}")
|
||||
|
||||
# Recherche des rapports (JSON et MD) dans différents emplacements
|
||||
rapports = self.trouver_rapport(extraction_path, ticket_id)
|
||||
|
||||
# Dossier des pièces jointes
|
||||
attachments_dir = os.path.join(extraction_path, "attachments")
|
||||
|
||||
# Dossier pour les rapports générés
|
||||
rapports_dir = os.path.join(extraction_path, f"{ticket_id}_rapports")
|
||||
os.makedirs(rapports_dir, exist_ok=True)
|
||||
|
||||
# Préparer les données du ticket à partir des rapports trouvés
|
||||
ticket_data = self._preparer_donnees_ticket(rapports, ticket_id)
|
||||
|
||||
if ticket_data:
|
||||
success = True
|
||||
logger.info(f"Données du ticket chargées avec succès")
|
||||
print(f" Données du ticket chargées")
|
||||
|
||||
# Traitement avec l'agent Ticket
|
||||
if self.ticket_agent:
|
||||
logger.info("Exécution de l'agent Ticket")
|
||||
print(" Analyse du ticket en cours...")
|
||||
|
||||
# Log détaillé sur l'agent Ticket
|
||||
agent_info = self._get_agent_info(self.ticket_agent)
|
||||
logger.info(f"Agent Ticket: {json.dumps(agent_info, indent=2)}")
|
||||
|
||||
ticket_analysis = self.ticket_agent.executer(ticket_data)
|
||||
logger.info("Analyse du ticket terminée")
|
||||
print(f" Analyse du ticket terminée: {len(ticket_analysis) if ticket_analysis else 0} caractères")
|
||||
else:
|
||||
logger.warning("Agent Ticket non disponible")
|
||||
ticket_analysis = None
|
||||
print(" Agent Ticket non disponible, analyse ignorée")
|
||||
|
||||
# Traitement des images
|
||||
relevant_images = []
|
||||
images_analyses = {}
|
||||
images_count = 0
|
||||
if os.path.exists(attachments_dir):
|
||||
logger.info(f"Vérification des pièces jointes dans: {attachments_dir}")
|
||||
print(f" Vérification des pièces jointes...")
|
||||
|
||||
# Log détaillé sur l'agent Image Sorter
|
||||
if self.image_sorter:
|
||||
agent_info = self._get_agent_info(self.image_sorter)
|
||||
logger.info(f"Agent Image Sorter: {json.dumps(agent_info, indent=2)}")
|
||||
|
||||
# Compter le nombre d'images
|
||||
images = [f for f in os.listdir(attachments_dir)
|
||||
if f.lower().endswith(('.png', '.jpg', '.jpeg', '.bmp', '.gif'))]
|
||||
images_count = len(images)
|
||||
|
||||
# Tri des images
|
||||
for img in images:
|
||||
img_path = os.path.join(attachments_dir, img)
|
||||
|
||||
if self.image_sorter:
|
||||
logger.info(f"Évaluation de la pertinence de l'image: {img}")
|
||||
print(f" Évaluation de l'image: {img}")
|
||||
sorting_result = self.image_sorter.executer(img_path)
|
||||
is_relevant = sorting_result.get("is_relevant", False)
|
||||
reason = sorting_result.get("reason", "")
|
||||
|
||||
# Log détaillé du résultat
|
||||
if is_relevant:
|
||||
logger.info(f"Image {img} considérée comme pertinente")
|
||||
else:
|
||||
logger.info(f"Image {img} considérée comme non pertinente")
|
||||
|
||||
# Ajouter les métadonnées de tri à la liste des analyses
|
||||
images_analyses[img_path] = {
|
||||
"sorting": sorting_result,
|
||||
"analysis": None # Sera rempli plus tard si pertinent
|
||||
}
|
||||
|
||||
if is_relevant:
|
||||
logger.info(f"Image pertinente identifiée: {img} ({reason})")
|
||||
print(f" => Pertinente: {reason}")
|
||||
relevant_images.append(img_path)
|
||||
else:
|
||||
logger.info(f"Image non pertinente: {img} ({reason})")
|
||||
print(f" => Non pertinente: {reason}")
|
||||
else:
|
||||
logger.warning("Image Sorter non disponible")
|
||||
# Si pas de tri, considérer toutes les images comme pertinentes
|
||||
relevant_images.append(img_path)
|
||||
images_analyses[img_path] = {
|
||||
"sorting": {"is_relevant": True, "reason": "Auto-sélectionné (pas de tri)"},
|
||||
"analysis": None
|
||||
}
|
||||
print(f" => Auto-sélectionné (pas de tri)")
|
||||
|
||||
logger.info(f"Images analysées: {images_count}, Images pertinentes: {len(relevant_images)}")
|
||||
print(f" Images analysées: {images_count}, Images pertinentes: {len(relevant_images)}")
|
||||
else:
|
||||
logger.warning(f"Répertoire des pièces jointes non trouvé: {attachments_dir}")
|
||||
print(f" Répertoire des pièces jointes non trouvé")
|
||||
|
||||
# Analyse approfondie des images pertinentes
|
||||
if relevant_images and self.image_analyser:
|
||||
agent_info = self._get_agent_info(self.image_analyser)
|
||||
logger.info(f"Agent Image Analyser: {json.dumps(agent_info, indent=2)}")
|
||||
|
||||
# S'assurer que l'analyse du ticket est disponible comme contexte
|
||||
contexte_ticket = ticket_analysis if ticket_analysis else "Aucune analyse de ticket disponible"
|
||||
|
||||
# Analyse de chaque image pertinente
|
||||
for image_path in relevant_images:
|
||||
image_name = os.path.basename(image_path)
|
||||
logger.info(f"Analyse approfondie de l'image: {image_name}")
|
||||
print(f" Analyse approfondie de l'image: {image_name}")
|
||||
|
||||
# Appeler l'analyseur d'images avec le contexte du ticket
|
||||
analysis_result = self.image_analyser.executer(image_path, contexte=contexte_ticket)
|
||||
|
||||
if images_analyses[image_path]:
|
||||
images_analyses[image_path]["analysis"] = analysis_result
|
||||
|
||||
logger.info(f"Analyse complétée pour {image_name}")
|
||||
|
||||
# Préparer les données pour le rapport final
|
||||
rapport_data = {
|
||||
"ticket_data": ticket_data,
|
||||
"ticket_id": ticket_id,
|
||||
"ticket_analyse": ticket_analysis,
|
||||
"analyse_images": images_analyses,
|
||||
"metadata": {
|
||||
"timestamp_debut": self._get_timestamp(),
|
||||
"ticket_id": ticket_id,
|
||||
"images_analysees": images_count,
|
||||
"images_pertinentes": len(relevant_images)
|
||||
}
|
||||
}
|
||||
|
||||
# Génération du rapport final
|
||||
if self.report_generator:
|
||||
logger.info("Génération du rapport final")
|
||||
print(" Génération du rapport final")
|
||||
|
||||
# Log détaillé sur l'agent Report Generator
|
||||
agent_info = self._get_agent_info(self.report_generator)
|
||||
logger.info(f"Agent Report Generator: {json.dumps(agent_info, indent=2)}")
|
||||
|
||||
# Créer le répertoire pour le rapport dans reports/
|
||||
project_root = os.path.abspath(os.path.join(os.path.dirname(__file__)))
|
||||
reports_root_dir = os.path.join(project_root, 'reports')
|
||||
ticket_reports_dir = os.path.join(reports_root_dir, ticket_id)
|
||||
|
||||
# Créer le sous-répertoire pour le modèle spécifique
|
||||
model_name = getattr(self.report_generator.llm, "modele", str(type(self.report_generator.llm)))
|
||||
model_reports_dir = os.path.join(ticket_reports_dir, model_name)
|
||||
os.makedirs(model_reports_dir, exist_ok=True)
|
||||
|
||||
# Générer le rapport
|
||||
json_path, md_path = self.report_generator.executer(rapport_data, model_reports_dir)
|
||||
|
||||
if json_path:
|
||||
logger.info(f"Rapport JSON généré à: {json_path}")
|
||||
print(f" Rapport JSON généré avec succès: {os.path.basename(json_path)}")
|
||||
|
||||
# Utiliser directement le rapport Markdown généré par l'agent
|
||||
if md_path:
|
||||
logger.info(f"Rapport Markdown généré à: {md_path}")
|
||||
print(f" Rapport Markdown généré avec succès: {os.path.basename(md_path)}")
|
||||
else:
|
||||
logger.warning("Report Generator non disponible")
|
||||
print(" Report Generator non disponible, génération de rapport ignorée")
|
||||
|
||||
print(f"Traitement du ticket {os.path.basename(ticket_path)} terminé avec succès.\n")
|
||||
logger.info(f"Traitement du ticket {ticket_path} terminé avec succès.")
|
||||
else:
|
||||
logger.warning(f"Aucune donnée de ticket trouvée pour: {ticket_id}")
|
||||
print(f" ERREUR: Aucune donnée de ticket trouvée pour {ticket_id}")
|
||||
|
||||
if not extractions_trouvees:
|
||||
logger.warning(f"Aucune extraction trouvée dans le ticket: {ticket_path}")
|
||||
print(f" ERREUR: Aucune extraction trouvée dans le ticket")
|
||||
|
||||
return success
|
||||
|
||||
def _preparer_donnees_ticket(self, rapports: Dict[str, Optional[str]], ticket_id: str) -> Optional[Dict]:
|
||||
"""
|
||||
Prépare les données du ticket à partir des rapports trouvés (JSON et/ou MD)
|
||||
|
||||
Args:
|
||||
rapports: Dictionnaire avec les chemins des rapports JSON et MD
|
||||
ticket_id: ID du ticket
|
||||
|
||||
Returns:
|
||||
Dictionnaire avec les données du ticket, ou None si aucun rapport n'est trouvé
|
||||
"""
|
||||
ticket_data = None
|
||||
|
||||
# Si aucun rapport n'est trouvé
|
||||
if not rapports or (not rapports.get("json") and not rapports.get("markdown")):
|
||||
logger.warning(f"Aucun rapport trouvé pour le ticket {ticket_id}")
|
||||
return None
|
||||
|
||||
# Privilégier le format JSON (format principal)
|
||||
if rapports.get("json") and rapports["json"] is not None:
|
||||
try:
|
||||
ticket_data = self.ticket_loader.charger(rapports["json"])
|
||||
logger.info(f"Données JSON chargées depuis: {rapports['json']}")
|
||||
print(f" Rapport JSON chargé: {os.path.basename(rapports['json'])}")
|
||||
# Ajouter une métadonnée sur le format source
|
||||
if ticket_data and "metadata" not in ticket_data:
|
||||
ticket_data["metadata"] = {}
|
||||
if ticket_data:
|
||||
ticket_data["metadata"]["format_source"] = "json"
|
||||
except Exception as e:
|
||||
logger.error(f"Erreur lors du chargement du JSON: {e}")
|
||||
print(f" ERREUR: Impossible de charger le fichier JSON: {e}")
|
||||
|
||||
# Fallback sur le Markdown uniquement si JSON non disponible
|
||||
if not ticket_data and rapports.get("markdown") and rapports["markdown"] is not None:
|
||||
try:
|
||||
# Utiliser le loader pour charger les données depuis le Markdown
|
||||
ticket_data = self.ticket_loader.charger(rapports["markdown"])
|
||||
logger.info(f"Données Markdown chargées depuis: {rapports['markdown']} (fallback)")
|
||||
print(f" Rapport Markdown chargé (fallback): {os.path.basename(rapports['markdown'])}")
|
||||
# Ajouter une métadonnée sur le format source
|
||||
if ticket_data and "metadata" not in ticket_data:
|
||||
ticket_data["metadata"] = {}
|
||||
if ticket_data:
|
||||
ticket_data["metadata"]["format_source"] = "markdown"
|
||||
except Exception as e:
|
||||
logger.error(f"Erreur lors du chargement du Markdown: {e}")
|
||||
print(f" ERREUR: Impossible de charger le fichier Markdown: {e}")
|
||||
|
||||
# Assurer que l'ID du ticket est correct
|
||||
if ticket_data:
|
||||
ticket_data["code"] = ticket_id
|
||||
|
||||
return ticket_data
|
||||
|
||||
def _get_timestamp(self) -> str:
|
||||
"""Retourne un timestamp au format YYYYMMDD_HHMMSS"""
|
||||
from datetime import datetime
|
||||
return datetime.now().strftime("%Y%m%d_%H%M%S")
|
||||
|
||||
def _get_agent_info(self, agent: Optional[BaseAgent]) -> Dict:
|
||||
"""
|
||||
Récupère les informations détaillées sur un agent.
|
||||
|
||||
Args:
|
||||
agent: L'agent dont on veut récupérer les informations
|
||||
|
||||
Returns:
|
||||
Dictionnaire contenant les informations de l'agent
|
||||
"""
|
||||
if not agent:
|
||||
return {"status": "non configuré"}
|
||||
|
||||
# Récupérer les informations du modèle
|
||||
model_info = {
|
||||
"nom": agent.nom,
|
||||
"model": getattr(agent.llm, "modele", str(type(agent.llm))),
|
||||
}
|
||||
|
||||
# Ajouter les paramètres de configuration s'ils sont disponibles directement dans l'agent
|
||||
# Utiliser getattr avec une valeur par défaut pour éviter les erreurs
|
||||
model_info["temperature"] = getattr(agent, "temperature", None)
|
||||
model_info["top_p"] = getattr(agent, "top_p", None)
|
||||
model_info["max_tokens"] = getattr(agent, "max_tokens", None)
|
||||
|
||||
# Ajouter le prompt système s'il est disponible
|
||||
if hasattr(agent, "system_prompt"):
|
||||
prompt_preview = getattr(agent, "system_prompt", "")
|
||||
# Tronquer le prompt s'il est trop long
|
||||
if prompt_preview and len(prompt_preview) > 200:
|
||||
prompt_preview = prompt_preview[:200] + "..."
|
||||
model_info["system_prompt_preview"] = prompt_preview
|
||||
|
||||
# Supprimer les valeurs None
|
||||
model_info = {k: v for k, v in model_info.items() if v is not None}
|
||||
|
||||
return model_info
|
||||
@ -7,6 +7,7 @@ from typing import List, Dict, Any, Optional, Union, Mapping, cast
|
||||
from agents.base_agent import BaseAgent
|
||||
from loaders.ticket_data_loader import TicketDataLoader
|
||||
from agents.utils.report_formatter import generer_rapport_markdown
|
||||
from utils.image_dedup import filtrer_images_uniques
|
||||
|
||||
# Configuration du logging
|
||||
logging.basicConfig(level=logging.INFO, format='%(asctime)s - %(levelname)s - %(message)s',
|
||||
@ -246,8 +247,10 @@ class Orchestrator:
|
||||
logger.info(f"Agent Image Sorter: {json.dumps(agent_info, indent=2)}")
|
||||
|
||||
# Compter le nombre d'images
|
||||
images = [f for f in os.listdir(attachments_dir)
|
||||
if f.lower().endswith(('.png', '.jpg', '.jpeg', '.bmp', '.gif'))]
|
||||
images = [f for f in os.listdir(attachments_dir) if f.lower().endswith(('.png', '.jpg', '.jpeg', '.bmp', '.gif'))]
|
||||
image_paths = [os.path.join(attachments_dir, img) for img in images]
|
||||
image_paths_uniques = filtrer_images_uniques(image_paths)
|
||||
images = [os.path.basename(p) for p in image_paths_uniques]
|
||||
images_count = len(images)
|
||||
|
||||
# Tri des images
|
||||
|
||||
92
output/batch_summary_20250416_151115.json
Normal file
@ -0,0 +1,92 @@
|
||||
{
|
||||
"timestamp": "20250416_151115",
|
||||
"batch_dir": "output",
|
||||
"search_criteria": {
|
||||
"domain": [
|
||||
[
|
||||
"project_id",
|
||||
"=",
|
||||
3
|
||||
],
|
||||
[
|
||||
"stage_id",
|
||||
"=",
|
||||
8
|
||||
]
|
||||
],
|
||||
"limit": 10,
|
||||
"offset": 0
|
||||
},
|
||||
"processed_tickets": [],
|
||||
"skipped_tickets": [
|
||||
{
|
||||
"code": "T11181",
|
||||
"id": 11160,
|
||||
"name": "N'arrive pas à dupliquer un echantillon",
|
||||
"reason": "already_extracted"
|
||||
},
|
||||
{
|
||||
"code": "T11178",
|
||||
"id": 11157,
|
||||
"name": "Bug BRG-LAB",
|
||||
"reason": "already_extracted"
|
||||
},
|
||||
{
|
||||
"code": "T11163",
|
||||
"id": 11142,
|
||||
"name": "Essai de plaque LCPC MEI + Divers ",
|
||||
"reason": "already_extracted"
|
||||
},
|
||||
{
|
||||
"code": "T11146",
|
||||
"id": 11125,
|
||||
"name": "formulation",
|
||||
"reason": "already_extracted"
|
||||
},
|
||||
{
|
||||
"code": "T11143",
|
||||
"id": 11122,
|
||||
"name": "BRGLAB - Essai inaccessible",
|
||||
"reason": "already_extracted"
|
||||
},
|
||||
{
|
||||
"code": "T11140",
|
||||
"id": 11119,
|
||||
"name": "Impossible de prendre en compte un prix dans une formulation",
|
||||
"reason": "already_extracted"
|
||||
},
|
||||
{
|
||||
"code": "T11132",
|
||||
"id": 11111,
|
||||
"name": "Re: brg-lab.com",
|
||||
"reason": "already_extracted"
|
||||
},
|
||||
{
|
||||
"code": "T11130",
|
||||
"id": 11109,
|
||||
"name": "sondages dans le désordre",
|
||||
"reason": "already_extracted"
|
||||
},
|
||||
{
|
||||
"code": "T11127",
|
||||
"id": 11106,
|
||||
"name": "ET2025-E-0114 - Impossible d'afficher l'essais",
|
||||
"reason": "already_extracted"
|
||||
},
|
||||
{
|
||||
"code": "T11126",
|
||||
"id": 11105,
|
||||
"name": "Message d'erreur sur essais au format tableur FTP",
|
||||
"reason": "already_extracted"
|
||||
}
|
||||
],
|
||||
"failed_tickets": [],
|
||||
"excluded_tickets": [],
|
||||
"stats": {
|
||||
"total_found": 10,
|
||||
"processed": 0,
|
||||
"skipped": 10,
|
||||
"failed": 0,
|
||||
"excluded_by_tag": 0
|
||||
}
|
||||
}
|
||||
112
output/batch_summary_20250416_151200.json
Normal file
@ -0,0 +1,112 @@
|
||||
{
|
||||
"timestamp": "20250416_151200",
|
||||
"batch_dir": "output",
|
||||
"search_criteria": {
|
||||
"domain": [
|
||||
[
|
||||
"project_id",
|
||||
"=",
|
||||
3
|
||||
],
|
||||
[
|
||||
"stage_id",
|
||||
"=",
|
||||
8
|
||||
]
|
||||
],
|
||||
"limit": 10,
|
||||
"offset": 30
|
||||
},
|
||||
"processed_tickets": [
|
||||
{
|
||||
"code": "T11093",
|
||||
"id": 11072,
|
||||
"name": "Re: [T9294] - Fiche CE - Catégories manquant pour teneur en sulfate soluble dans l'eau (SS)",
|
||||
"output_dir": "output/ticket_T11093/T11093_20250416_151200",
|
||||
"messages_count": 5,
|
||||
"attachments_count": 3
|
||||
},
|
||||
{
|
||||
"code": "T11091",
|
||||
"id": 11070,
|
||||
"name": "Norme 1097-1 ",
|
||||
"output_dir": "output/ticket_T11091/T11091_20250416_151202",
|
||||
"messages_count": 5,
|
||||
"attachments_count": 0
|
||||
},
|
||||
{
|
||||
"code": "T11089",
|
||||
"id": 11068,
|
||||
"name": "Problème création feuille paillasse béton",
|
||||
"output_dir": "output/ticket_T11089/T11089_20250416_151202",
|
||||
"messages_count": 10,
|
||||
"attachments_count": 12
|
||||
},
|
||||
{
|
||||
"code": "T11088",
|
||||
"id": 11067,
|
||||
"name": "BUG mise à jour",
|
||||
"output_dir": "output/ticket_T11088/T11088_20250416_151205",
|
||||
"messages_count": 5,
|
||||
"attachments_count": 4
|
||||
},
|
||||
{
|
||||
"code": "T11087",
|
||||
"id": 11066,
|
||||
"name": "erreur fatale essai aplatissement",
|
||||
"output_dir": "output/ticket_T11087/T11087_20250416_151207",
|
||||
"messages_count": 5,
|
||||
"attachments_count": 2
|
||||
},
|
||||
{
|
||||
"code": "T11086",
|
||||
"id": 11065,
|
||||
"name": "Erreur fatale essai VBS",
|
||||
"output_dir": "output/ticket_T11086/T11086_20250416_151208",
|
||||
"messages_count": 5,
|
||||
"attachments_count": 4
|
||||
},
|
||||
{
|
||||
"code": "T11085",
|
||||
"id": 11064,
|
||||
"name": "cbao_support_technique - Message : ROCHES ET DERIV<49>S Nicolas GOSSELIN",
|
||||
"output_dir": "output/ticket_T11085/T11085_20250416_151209",
|
||||
"messages_count": 4,
|
||||
"attachments_count": 2
|
||||
},
|
||||
{
|
||||
"code": "T11084",
|
||||
"id": 11063,
|
||||
"name": "Site bloqué après MAJ",
|
||||
"output_dir": "output/ticket_T11084/T11084_20250416_151209",
|
||||
"messages_count": 4,
|
||||
"attachments_count": 0
|
||||
},
|
||||
{
|
||||
"code": "T11083",
|
||||
"id": 11062,
|
||||
"name": "Site bloqué après MAJ",
|
||||
"output_dir": "output/ticket_T11083/T11083_20250416_151210",
|
||||
"messages_count": 2,
|
||||
"attachments_count": 0
|
||||
},
|
||||
{
|
||||
"code": "T11082",
|
||||
"id": 11061,
|
||||
"name": "MISE A JOUR DE LA PLATEFORME",
|
||||
"output_dir": "output/ticket_T11082/T11082_20250416_151210",
|
||||
"messages_count": 5,
|
||||
"attachments_count": 2
|
||||
}
|
||||
],
|
||||
"skipped_tickets": [],
|
||||
"failed_tickets": [],
|
||||
"excluded_tickets": [],
|
||||
"stats": {
|
||||
"total_found": 10,
|
||||
"processed": 10,
|
||||
"skipped": 0,
|
||||
"failed": 0,
|
||||
"excluded_by_tag": 0
|
||||
}
|
||||
}
|
||||
@ -1,24 +1,34 @@
|
||||
{
|
||||
"ticket_codes": [
|
||||
"T11117",
|
||||
"T11112",
|
||||
"T11132",
|
||||
"T11113",
|
||||
"T11119",
|
||||
"T11125",
|
||||
"T11130",
|
||||
"T11126",
|
||||
"T11143",
|
||||
"T11127",
|
||||
"T11114",
|
||||
"T11082",
|
||||
"T11118",
|
||||
"T11123",
|
||||
"T11181",
|
||||
"T11122",
|
||||
"T11178",
|
||||
"T11163",
|
||||
"T11115",
|
||||
"T11113",
|
||||
"T11132",
|
||||
"T11140",
|
||||
"T11146"
|
||||
"T11181",
|
||||
"T11086",
|
||||
"T11114",
|
||||
"T11122",
|
||||
"T11126",
|
||||
"T11089",
|
||||
"T11143",
|
||||
"T11163",
|
||||
"T11085",
|
||||
"T11130",
|
||||
"T11084",
|
||||
"T11087",
|
||||
"T11146",
|
||||
"T11091",
|
||||
"T11127",
|
||||
"T11115",
|
||||
"T11093",
|
||||
"T11088",
|
||||
"T11178",
|
||||
"T11119",
|
||||
"T11083",
|
||||
"T11123",
|
||||
"T11112"
|
||||
]
|
||||
}
|
||||
@ -0,0 +1,34 @@
|
||||
{
|
||||
"id": "11061",
|
||||
"code": "T11082",
|
||||
"name": "MISE A JOUR DE LA PLATEFORME",
|
||||
"description": "*Contenu non extractible*",
|
||||
"project_name": "Demandes",
|
||||
"stage_name": "Clôturé",
|
||||
"user_id": "",
|
||||
"partner_id_email_from": "GEOLABO, Contact - GEOLABO <contact@geolabo.fr>",
|
||||
"create_date": "19/03/2025 10:41:36",
|
||||
"write_date_last_modification": "03/04/2025 07:51:14",
|
||||
"date_deadline": "03/04/2025 00:00:00",
|
||||
"messages": [
|
||||
{
|
||||
"author_id": "GEOLABO",
|
||||
"date": "19/03/2025 10:40:30",
|
||||
"message_type": "E-mail",
|
||||
"subject": "MISE A JOUR DE LA PLATEFORME",
|
||||
"id": "227893",
|
||||
"content": "Bonjour,\nLa plateforme est en mise ce matin depuis un moment, pourra t’on accéder à cette dernière en début d’après midi ?\nMerci d’avance\nGRANGIER Aurore\nTéléphone:04.92.76.65.93\nTélécopie:09.67.22.65.93\nAdresse Email :\ncontact@geolabo.fr\nadresse postale:\n172 Chemin des Grands Jardins\n04220 SAINTE TULLE\n\n- image001.jpg (image/jpeg) [ID: 144863]\n\n---\n\n"
|
||||
},
|
||||
{
|
||||
"author_id": "Romuald GRUSON",
|
||||
"date": "19/03/2025 10:45:56",
|
||||
"message_type": "E-mail",
|
||||
"subject": "Re: [T11082] - MISE A JOUR DE LA PLATEFORME",
|
||||
"id": "227897",
|
||||
"content": "Bonjour\n,\nNous relançons la mise à jour dès à présent. Votre plateforme sera de nouveau disponible en début d'après-midi.\nJe reste à votre entière disposition pour toute information complémentaire.\nCordialement,\n---\nSupport technique\n\n---\n"
|
||||
}
|
||||
],
|
||||
"date_d'extraction": "16/04/2025 15:12:11",
|
||||
"répertoire": "output/ticket_T11082/T11082_20250416_151210",
|
||||
"messages_raw_reference": "output/ticket_T11082/T11082_20250416_151210/messages_raw.json"
|
||||
}
|
||||
@ -0,0 +1,64 @@
|
||||
# Ticket T11082: MISE A JOUR DE LA PLATEFORME
|
||||
|
||||
## Informations du ticket
|
||||
|
||||
- **id**: 11061
|
||||
- **code**: T11082
|
||||
- **name**: MISE A JOUR DE LA PLATEFORME
|
||||
- **project_name**: Demandes
|
||||
- **stage_name**: Clôturé
|
||||
- **user_id**:
|
||||
- **partner_id/email_from**: GEOLABO, Contact - GEOLABO <contact@geolabo.fr>
|
||||
- **create_date**: 19/03/2025 10:41:36
|
||||
- **write_date/last modification**: 03/04/2025 07:51:14
|
||||
- **date_deadline**: 03/04/2025 00:00:00
|
||||
|
||||
- **description**:
|
||||
|
||||
*Contenu non extractible*
|
||||
|
||||
## Messages
|
||||
|
||||
### Message 1
|
||||
**author_id**: GEOLABO
|
||||
**date**: 19/03/2025 10:40:30
|
||||
**message_type**: E-mail
|
||||
**subject**: MISE A JOUR DE LA PLATEFORME
|
||||
**id**: 227893
|
||||
Bonjour,
|
||||
La plateforme est en mise ce matin depuis un moment, pourra t’on accéder à cette dernière en début d’après midi ?
|
||||
Merci d’avance
|
||||
GRANGIER Aurore
|
||||
Téléphone:04.92.76.65.93
|
||||
Télécopie:09.67.22.65.93
|
||||
Adresse Email :
|
||||
contact@geolabo.fr
|
||||
adresse postale:
|
||||
172 Chemin des Grands Jardins
|
||||
04220 SAINTE TULLE
|
||||
|
||||
**attachment_ids**:
|
||||
- image001.jpg (image/jpeg) [ID: 144863]
|
||||
|
||||
---
|
||||
|
||||
### Message 2
|
||||
**author_id**: Romuald GRUSON
|
||||
**date**: 19/03/2025 10:45:56
|
||||
**message_type**: E-mail
|
||||
**subject**: Re: [T11082] - MISE A JOUR DE LA PLATEFORME
|
||||
**id**: 227897
|
||||
Bonjour
|
||||
,
|
||||
Nous relançons la mise à jour dès à présent. Votre plateforme sera de nouveau disponible en début d'après-midi.
|
||||
Je reste à votre entière disposition pour toute information complémentaire.
|
||||
Cordialement,
|
||||
---
|
||||
Support technique
|
||||
|
||||
---
|
||||
|
||||
## Informations sur l'extraction
|
||||
|
||||
- **Date d'extraction**: 16/04/2025 15:12:11
|
||||
- **Répertoire**: output/ticket_T11082/T11082_20250416_151210
|
||||
230
output/ticket_T11082/T11082_20250416_151210/all_messages.json
Normal file
78
output/ticket_T11082/T11082_20250416_151210/all_messages.txt
Normal file
@ -0,0 +1,78 @@
|
||||
TICKET: T11082 - MISE A JOUR DE LA PLATEFORME
|
||||
Date d'extraction: 2025-04-16 15:12:11
|
||||
Nombre de messages: 5
|
||||
|
||||
================================================================================
|
||||
|
||||
********************************************************************************
|
||||
*** MESSAGE TRANSFÉRÉ ***
|
||||
********************************************************************************
|
||||
|
||||
DATE: 2025-03-19 10:40:30
|
||||
DE: GEOLABO
|
||||
OBJET: MISE A JOUR DE LA PLATEFORME
|
||||
|
||||
Bonjour,
|
||||
La plateforme est en mise ce matin depuis un moment, pourra t’on accéder à cette dernière en début d’après midi ?
|
||||
Merci d’avance
|
||||
GRANGIER Aurore
|
||||
Téléphone:04.92.76.65.93
|
||||
Télécopie:09.67.22.65.93
|
||||
Adresse Email :
|
||||
contact@geolabo.fr
|
||||
adresse postale:
|
||||
172 Chemin des Grands Jardins
|
||||
04220 SAINTE TULLE
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
********************************************************************************
|
||||
*** CHANGEMENT D'ÉTAT ***
|
||||
********************************************************************************
|
||||
|
||||
DATE: 2025-03-19 10:41:36
|
||||
DE: OdooBot
|
||||
|
||||
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
********************************************************************************
|
||||
*** MESSAGE TRANSFÉRÉ ***
|
||||
********************************************************************************
|
||||
|
||||
DATE: 2025-03-19 10:45:56
|
||||
DE: Romuald GRUSON
|
||||
OBJET: Re: [T11082] - MISE A JOUR DE LA PLATEFORME
|
||||
|
||||
Bonjour
|
||||
,
|
||||
Nous relançons la mise à jour dès à présent. Votre plateforme sera de nouveau disponible en début d'après-midi.
|
||||
Je reste à votre entière disposition pour toute information complémentaire.
|
||||
Cordialement,
|
||||
---
|
||||
Support technique
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
********************************************************************************
|
||||
*** CHANGEMENT D'ÉTAT ***
|
||||
********************************************************************************
|
||||
|
||||
DATE: 2025-03-19 10:46:17
|
||||
DE: Romuald GRUSON
|
||||
|
||||
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
********************************************************************************
|
||||
*** CHANGEMENT D'ÉTAT ***
|
||||
********************************************************************************
|
||||
|
||||
DATE: 2025-04-03 07:51:14
|
||||
DE: Romuald GRUSON
|
||||
|
||||
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
After Width: | Height: | Size: 11 KiB |
|
After Width: | Height: | Size: 11 KiB |
@ -0,0 +1,37 @@
|
||||
[
|
||||
{
|
||||
"id": 144863,
|
||||
"name": "image001.jpg",
|
||||
"mimetype": "image/jpeg",
|
||||
"file_size": 11293,
|
||||
"create_date": "2025-03-19 10:41:36",
|
||||
"create_uid": [
|
||||
1,
|
||||
"OdooBot"
|
||||
],
|
||||
"description": "image001.jpg",
|
||||
"res_name": "[T11082] MISE A JOUR DE LA PLATEFORME",
|
||||
"creator_name": "OdooBot",
|
||||
"creator_id": 1,
|
||||
"download_status": "success",
|
||||
"local_path": "output/ticket_T11082/T11082_20250416_151210/attachments/image001.jpg",
|
||||
"error": ""
|
||||
},
|
||||
{
|
||||
"id": "embedded_2",
|
||||
"name": "image_144863.png",
|
||||
"mimetype": "image/png",
|
||||
"file_size": "11293",
|
||||
"create_date": null,
|
||||
"creator_name": "Extraction automatique",
|
||||
"download_status": "success",
|
||||
"local_path": "output/ticket_T11082/T11082_20250416_151210/attachments/image_144863.png",
|
||||
"error": "",
|
||||
"is_embedded_image": true,
|
||||
"source_url": "https://odoo.cbao.fr/web/image/144863?access_token=66352c31-f885-407e-bfdd-2f092702733d",
|
||||
"source": "message_embedded",
|
||||
"extraction_date": "2025-04-16T15:12:11.695080",
|
||||
"source_message_id": "",
|
||||
"message_author": ""
|
||||
}
|
||||
]
|
||||
23
output/ticket_T11082/T11082_20250416_151210/followers.json
Normal file
@ -0,0 +1,23 @@
|
||||
[
|
||||
{
|
||||
"id": 89668,
|
||||
"partner_id": [
|
||||
28961,
|
||||
"Fabien LAFAY"
|
||||
]
|
||||
},
|
||||
{
|
||||
"id": 89673,
|
||||
"partner_id": [
|
||||
29816,
|
||||
"contact@geolabo.fr"
|
||||
]
|
||||
},
|
||||
{
|
||||
"id": 89674,
|
||||
"partner_id": [
|
||||
32165,
|
||||
"Romuald GRUSON"
|
||||
]
|
||||
}
|
||||
]
|
||||
242
output/ticket_T11082/T11082_20250416_151210/messages_raw.json
Normal file
20
output/ticket_T11082/T11082_20250416_151210/structure.json
Normal file
@ -0,0 +1,20 @@
|
||||
{
|
||||
"date_extraction": "2025-04-16T15:12:11.731269",
|
||||
"ticket_id": 11061,
|
||||
"ticket_code": "T11082",
|
||||
"ticket_name": "MISE A JOUR DE LA PLATEFORME",
|
||||
"output_dir": "output/ticket_T11082/T11082_20250416_151210",
|
||||
"files": {
|
||||
"ticket_info": "ticket_info.json",
|
||||
"ticket_summary": "ticket_summary.json",
|
||||
"messages": "all_messages.json",
|
||||
"messages_raw": "messages_raw.json",
|
||||
"messages_text": "all_messages.txt",
|
||||
"attachments": "attachments_info.json",
|
||||
"followers": "followers.json"
|
||||
},
|
||||
"stats": {
|
||||
"messages_count": 5,
|
||||
"attachments_count": 2
|
||||
}
|
||||
}
|
||||
56
output/ticket_T11082/T11082_20250416_151210/ticket_info.json
Normal file
@ -0,0 +1,56 @@
|
||||
{
|
||||
"id": 11061,
|
||||
"name": "MISE A JOUR DE LA PLATEFORME",
|
||||
"description": "<p><br></p>",
|
||||
"stage_id": [
|
||||
8,
|
||||
"Clôturé"
|
||||
],
|
||||
"project_id": [
|
||||
3,
|
||||
"Demandes"
|
||||
],
|
||||
"partner_id": [
|
||||
1242,
|
||||
"GEOLABO"
|
||||
],
|
||||
"user_id": [
|
||||
32,
|
||||
"Romuald GRUSON"
|
||||
],
|
||||
"date_start": "2025-03-19 10:41:36",
|
||||
"date_end": false,
|
||||
"date_deadline": "2025-04-03",
|
||||
"create_date": "2025-03-19 10:41:36",
|
||||
"write_date": "2025-04-03 07:51:14",
|
||||
"tag_ids": [
|
||||
15
|
||||
],
|
||||
"priority": "0",
|
||||
"email_from": "Contact - GEOLABO <contact@geolabo.fr>",
|
||||
"email_cc": "",
|
||||
"message_ids": [
|
||||
228930,
|
||||
227900,
|
||||
227899,
|
||||
227898,
|
||||
227897,
|
||||
227894,
|
||||
227893,
|
||||
227892
|
||||
],
|
||||
"message_follower_ids": [
|
||||
89668,
|
||||
89673,
|
||||
89674
|
||||
],
|
||||
"timesheet_ids": [],
|
||||
"attachment_ids": [],
|
||||
"stage_id_name": "Clôturé",
|
||||
"project_id_name": "Demandes",
|
||||
"partner_id_name": "GEOLABO",
|
||||
"user_id_name": "Romuald GRUSON",
|
||||
"tag_names": [
|
||||
"BRG-LAB WEB"
|
||||
]
|
||||
}
|
||||
@ -0,0 +1,16 @@
|
||||
{
|
||||
"id": 11061,
|
||||
"code": "T11082",
|
||||
"name": "MISE A JOUR DE LA PLATEFORME",
|
||||
"description": "<p><br></p>",
|
||||
"stage": "Clôturé",
|
||||
"project": "Demandes",
|
||||
"partner": "GEOLABO",
|
||||
"assigned_to": "Romuald GRUSON",
|
||||
"tags": [
|
||||
"BRG-LAB WEB"
|
||||
],
|
||||
"create_date": "2025-03-19 10:41:36",
|
||||
"write_date": "2025-04-03 07:51:14",
|
||||
"deadline": "2025-04-03"
|
||||
}
|
||||
@ -0,0 +1,15 @@
|
||||
{
|
||||
"id": "11062",
|
||||
"code": "T11083",
|
||||
"name": "Site bloqué après MAJ",
|
||||
"description": "Point particulier :\nLe cas est bloquant\nDescription du problème :\nBonjour, le site est bloqué sur la mise a jour depuis 8h30 ce matin \"La mise à jour n'est pas possible car d'autres utilisateurs sont en train de travailler sur le site\".\n\nCordialement.",
|
||||
"project_name": "Demandes",
|
||||
"stage_name": "Clôturé",
|
||||
"user_id": "",
|
||||
"partner_id_email_from": "ROCHES ET DERIVÉS, Nicolas GOSSELIN, n.gosselin@groupemouen.fr",
|
||||
"create_date": "19/03/2025 10:45:17",
|
||||
"write_date_last_modification": "19/03/2025 10:47:10",
|
||||
"date_d'extraction": "16/04/2025 15:12:11",
|
||||
"répertoire": "output/ticket_T11083/T11083_20250416_151210",
|
||||
"messages_raw_reference": "output/ticket_T11083/T11083_20250416_151210/messages_raw.json"
|
||||
}
|
||||
@ -0,0 +1,27 @@
|
||||
# Ticket T11083: Site bloqué après MAJ
|
||||
|
||||
## Informations du ticket
|
||||
|
||||
- **id**: 11062
|
||||
- **code**: T11083
|
||||
- **name**: Site bloqué après MAJ
|
||||
- **project_name**: Demandes
|
||||
- **stage_name**: Clôturé
|
||||
- **user_id**:
|
||||
- **partner_id/email_from**: ROCHES ET DERIVÉS, Nicolas GOSSELIN, n.gosselin@groupemouen.fr
|
||||
- **create_date**: 19/03/2025 10:45:17
|
||||
- **write_date/last modification**: 19/03/2025 10:47:10
|
||||
|
||||
- **description**:
|
||||
|
||||
Point particulier :
|
||||
Le cas est bloquant
|
||||
Description du problème :
|
||||
Bonjour, le site est bloqué sur la mise a jour depuis 8h30 ce matin "La mise à jour n'est pas possible car d'autres utilisateurs sont en train de travailler sur le site".
|
||||
|
||||
Cordialement.
|
||||
|
||||
## Informations sur l'extraction
|
||||
|
||||
- **Date d'extraction**: 16/04/2025 15:12:11
|
||||
- **Répertoire**: output/ticket_T11083/T11083_20250416_151210
|
||||
109
output/ticket_T11083/T11083_20250416_151210/all_messages.json
Normal file
@ -0,0 +1,109 @@
|
||||
{
|
||||
"ticket_summary": {
|
||||
"id": 11062,
|
||||
"code": "T11083",
|
||||
"name": "Site bloqué après MAJ",
|
||||
"project_id": 3,
|
||||
"project_name": "Demandes",
|
||||
"stage_id": 8,
|
||||
"stage_name": "Clôturé",
|
||||
"date_extraction": "2025-04-16T15:12:10.796869"
|
||||
},
|
||||
"metadata": {
|
||||
"message_count": {
|
||||
"total": 3,
|
||||
"processed": 2,
|
||||
"excluded": 1
|
||||
},
|
||||
"cleaning_strategy": "standard",
|
||||
"cleaning_config": {
|
||||
"preserve_links": true,
|
||||
"preserve_images": true,
|
||||
"strategy": "html2text",
|
||||
"preserve_doc_links": true
|
||||
}
|
||||
},
|
||||
"messages": [
|
||||
{
|
||||
"id": 227895,
|
||||
"body": "",
|
||||
"date": "2025-03-19 10:45:17",
|
||||
"author_id": [
|
||||
30810,
|
||||
"Support Robot"
|
||||
],
|
||||
"email_from": "\"Support Robot\" <quentin.faivre30@gmail.com>",
|
||||
"message_type": "notification",
|
||||
"parent_id": false,
|
||||
"subtype_id": [
|
||||
16,
|
||||
"Task Created"
|
||||
],
|
||||
"subject": false,
|
||||
"tracking_value_ids": [
|
||||
177944,
|
||||
177945,
|
||||
177946,
|
||||
177947,
|
||||
177948
|
||||
],
|
||||
"attachment_ids": [],
|
||||
"is_system": true,
|
||||
"is_stage_change": true,
|
||||
"is_forwarded": false,
|
||||
"is_duplicate": false,
|
||||
"author_details": {
|
||||
"name": "Support Robot",
|
||||
"email": "quentin.faivre30@gmail.com",
|
||||
"is_system": true,
|
||||
"id": 30810,
|
||||
"phone": false,
|
||||
"function": false,
|
||||
"company_id": [
|
||||
1,
|
||||
"CBAO S.A.R.L."
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": 227904,
|
||||
"body": "",
|
||||
"date": "2025-03-19 10:47:10",
|
||||
"author_id": [
|
||||
32165,
|
||||
"Romuald GRUSON"
|
||||
],
|
||||
"email_from": "\"Romuald GRUSON\" <romuald@mail.cbao.fr>",
|
||||
"message_type": "notification",
|
||||
"parent_id": [
|
||||
227895,
|
||||
"[T11083] Site bloqué après MAJ"
|
||||
],
|
||||
"subtype_id": [
|
||||
19,
|
||||
"Stage Changed"
|
||||
],
|
||||
"subject": false,
|
||||
"tracking_value_ids": [
|
||||
177963
|
||||
],
|
||||
"attachment_ids": [],
|
||||
"is_system": true,
|
||||
"is_stage_change": true,
|
||||
"is_forwarded": false,
|
||||
"is_duplicate": false,
|
||||
"author_details": {
|
||||
"name": "Romuald GRUSON",
|
||||
"email": "romuald@mail.cbao.fr",
|
||||
"is_system": false,
|
||||
"id": 32165,
|
||||
"phone": false,
|
||||
"function": false,
|
||||
"company_id": [
|
||||
1,
|
||||
"CBAO S.A.R.L."
|
||||
]
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
27
output/ticket_T11083/T11083_20250416_151210/all_messages.txt
Normal file
@ -0,0 +1,27 @@
|
||||
TICKET: T11083 - Site bloqué après MAJ
|
||||
Date d'extraction: 2025-04-16 15:12:10
|
||||
Nombre de messages: 2
|
||||
|
||||
================================================================================
|
||||
|
||||
********************************************************************************
|
||||
*** CHANGEMENT D'ÉTAT ***
|
||||
********************************************************************************
|
||||
|
||||
DATE: 2025-03-19 10:45:17
|
||||
DE: Support Robot
|
||||
|
||||
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
********************************************************************************
|
||||
*** CHANGEMENT D'ÉTAT ***
|
||||
********************************************************************************
|
||||
|
||||
DATE: 2025-03-19 10:47:10
|
||||
DE: Romuald GRUSON
|
||||
|
||||
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
@ -0,0 +1 @@
|
||||
[]
|
||||
23
output/ticket_T11083/T11083_20250416_151210/followers.json
Normal file
@ -0,0 +1,23 @@
|
||||
[
|
||||
{
|
||||
"id": 89669,
|
||||
"partner_id": [
|
||||
30810,
|
||||
"Support Robot"
|
||||
]
|
||||
},
|
||||
{
|
||||
"id": 89670,
|
||||
"partner_id": [
|
||||
28961,
|
||||
"Fabien LAFAY"
|
||||
]
|
||||
},
|
||||
{
|
||||
"id": 89676,
|
||||
"partner_id": [
|
||||
32165,
|
||||
"Romuald GRUSON"
|
||||
]
|
||||
}
|
||||
]
|
||||
@ -0,0 +1,98 @@
|
||||
{
|
||||
"ticket_id": 11062,
|
||||
"ticket_code": "T11083",
|
||||
"message_metadata": {
|
||||
"227895": {
|
||||
"is_system": true,
|
||||
"is_stage_change": true,
|
||||
"is_forwarded": false,
|
||||
"is_duplicate": false
|
||||
},
|
||||
"227903": {
|
||||
"is_system": true,
|
||||
"is_stage_change": false,
|
||||
"is_forwarded": false,
|
||||
"is_duplicate": false,
|
||||
"excluded": "system_message"
|
||||
},
|
||||
"227904": {
|
||||
"is_system": true,
|
||||
"is_stage_change": true,
|
||||
"is_forwarded": false,
|
||||
"is_duplicate": false
|
||||
}
|
||||
},
|
||||
"messages": [
|
||||
{
|
||||
"id": 227895,
|
||||
"body": "",
|
||||
"date": "2025-03-19 10:45:17",
|
||||
"author_id": [
|
||||
30810,
|
||||
"Support Robot"
|
||||
],
|
||||
"email_from": "\"Support Robot\" <quentin.faivre30@gmail.com>",
|
||||
"message_type": "notification",
|
||||
"parent_id": false,
|
||||
"subtype_id": [
|
||||
16,
|
||||
"Task Created"
|
||||
],
|
||||
"subject": false,
|
||||
"tracking_value_ids": [
|
||||
177944,
|
||||
177945,
|
||||
177946,
|
||||
177947,
|
||||
177948
|
||||
],
|
||||
"attachment_ids": []
|
||||
},
|
||||
{
|
||||
"id": 227903,
|
||||
"body": "<p>doublon</p>",
|
||||
"date": "2025-03-19 10:47:06",
|
||||
"author_id": [
|
||||
32165,
|
||||
"Romuald GRUSON"
|
||||
],
|
||||
"email_from": "\"Romuald GRUSON\" <romuald@mail.cbao.fr>",
|
||||
"message_type": "comment",
|
||||
"parent_id": [
|
||||
227895,
|
||||
"[T11083] Site bloqué après MAJ"
|
||||
],
|
||||
"subtype_id": [
|
||||
2,
|
||||
"Note"
|
||||
],
|
||||
"subject": false,
|
||||
"tracking_value_ids": [],
|
||||
"attachment_ids": []
|
||||
},
|
||||
{
|
||||
"id": 227904,
|
||||
"body": "",
|
||||
"date": "2025-03-19 10:47:10",
|
||||
"author_id": [
|
||||
32165,
|
||||
"Romuald GRUSON"
|
||||
],
|
||||
"email_from": "\"Romuald GRUSON\" <romuald@mail.cbao.fr>",
|
||||
"message_type": "notification",
|
||||
"parent_id": [
|
||||
227895,
|
||||
"[T11083] Site bloqué après MAJ"
|
||||
],
|
||||
"subtype_id": [
|
||||
19,
|
||||
"Stage Changed"
|
||||
],
|
||||
"subject": false,
|
||||
"tracking_value_ids": [
|
||||
177963
|
||||
],
|
||||
"attachment_ids": []
|
||||
}
|
||||
]
|
||||
}
|
||||
20
output/ticket_T11083/T11083_20250416_151210/structure.json
Normal file
@ -0,0 +1,20 @@
|
||||
{
|
||||
"date_extraction": "2025-04-16T15:12:10.859087",
|
||||
"ticket_id": 11062,
|
||||
"ticket_code": "T11083",
|
||||
"ticket_name": "Site bloqué après MAJ",
|
||||
"output_dir": "output/ticket_T11083/T11083_20250416_151210",
|
||||
"files": {
|
||||
"ticket_info": "ticket_info.json",
|
||||
"ticket_summary": "ticket_summary.json",
|
||||
"messages": "all_messages.json",
|
||||
"messages_raw": "messages_raw.json",
|
||||
"messages_text": "all_messages.txt",
|
||||
"attachments": "attachments_info.json",
|
||||
"followers": "followers.json"
|
||||
},
|
||||
"stats": {
|
||||
"messages_count": 2,
|
||||
"attachments_count": 0
|
||||
}
|
||||
}
|
||||
47
output/ticket_T11083/T11083_20250416_151210/ticket_info.json
Normal file
@ -0,0 +1,47 @@
|
||||
{
|
||||
"id": 11062,
|
||||
"name": "Site bloqué après MAJ",
|
||||
"description": "<h1>Point particulier :</h1><ul><li><b>Le cas est bloquant</b></li></ul><h1>Description du problème :</h1><p>Bonjour, le site est bloqué sur la mise a jour depuis 8h30 ce matin \"La mise à jour n'est pas possible car d'autres utilisateurs sont en train de travailler sur le site\".\r\n\r\nCordialement.</p>",
|
||||
"stage_id": [
|
||||
8,
|
||||
"Clôturé"
|
||||
],
|
||||
"project_id": [
|
||||
3,
|
||||
"Demandes"
|
||||
],
|
||||
"partner_id": [
|
||||
3886,
|
||||
"ROCHES ET DERIVÉS, Nicolas GOSSELIN"
|
||||
],
|
||||
"user_id": false,
|
||||
"date_start": "2025-03-19 10:45:17",
|
||||
"date_end": false,
|
||||
"date_deadline": false,
|
||||
"create_date": "2025-03-19 10:45:17",
|
||||
"write_date": "2025-03-19 10:47:10",
|
||||
"tag_ids": [
|
||||
15
|
||||
],
|
||||
"priority": "3",
|
||||
"email_from": "n.gosselin@groupemouen.fr",
|
||||
"email_cc": "",
|
||||
"message_ids": [
|
||||
227904,
|
||||
227903,
|
||||
227895
|
||||
],
|
||||
"message_follower_ids": [
|
||||
89669,
|
||||
89670,
|
||||
89676
|
||||
],
|
||||
"timesheet_ids": [],
|
||||
"attachment_ids": [],
|
||||
"stage_id_name": "Clôturé",
|
||||
"project_id_name": "Demandes",
|
||||
"partner_id_name": "ROCHES ET DERIVÉS, Nicolas GOSSELIN",
|
||||
"tag_names": [
|
||||
"BRG-LAB WEB"
|
||||
]
|
||||
}
|
||||
@ -0,0 +1,16 @@
|
||||
{
|
||||
"id": 11062,
|
||||
"code": "T11083",
|
||||
"name": "Site bloqué après MAJ",
|
||||
"description": "<h1>Point particulier :</h1><ul><li><b>Le cas est bloquant</b></li></ul><h1>Description du problème :</h1><p>Bonjour, le site est bloqué sur la mise a jour depuis 8h30 ce matin \"La mise à jour n'est pas possible car d'autres utilisateurs sont en train de travailler sur le site\".\r\n\r\nCordialement.</p>",
|
||||
"stage": "Clôturé",
|
||||
"project": "Demandes",
|
||||
"partner": "ROCHES ET DERIVÉS, Nicolas GOSSELIN",
|
||||
"assigned_to": "",
|
||||
"tags": [
|
||||
"BRG-LAB WEB"
|
||||
],
|
||||
"create_date": "2025-03-19 10:45:17",
|
||||
"write_date": "2025-03-19 10:47:10",
|
||||
"deadline": false
|
||||
}
|
||||
@ -0,0 +1,26 @@
|
||||
{
|
||||
"id": "11063",
|
||||
"code": "T11084",
|
||||
"name": "Site bloqué après MAJ",
|
||||
"description": "Point particulier :\nLe cas est bloquant\nDescription du problème :\nBonjour, le site est bloqué sur la mise a jour depuis 8h30 ce matin \"La mise à jour n'est pas possible car d'autres utilisateurs sont en train de travailler sur le site\".\n\nCordialement.",
|
||||
"project_name": "Demandes",
|
||||
"stage_name": "Clôturé",
|
||||
"user_id": "",
|
||||
"partner_id_email_from": "ROCHES ET DERIVÉS, Nicolas GOSSELIN, n.gosselin@groupemouen.fr",
|
||||
"create_date": "19/03/2025 10:45:19",
|
||||
"write_date_last_modification": "03/04/2025 07:51:20",
|
||||
"date_deadline": "03/04/2025 00:00:00",
|
||||
"messages": [
|
||||
{
|
||||
"author_id": "Romuald GRUSON",
|
||||
"date": "19/03/2025 13:06:13",
|
||||
"message_type": "E-mail",
|
||||
"subject": "Re: [T11084] - Site bloqué après MAJ",
|
||||
"id": "227919",
|
||||
"content": "Bonjour\n,\nNous avons relancé la mise à jour sur votre plateforme BRG-LAB, celle ci est de nouveau disponible et à jour.\nJe reste à votre entière disposition pour toute information complémentaire.\nCordialement,\n---\nSupport technique\n\n---\n"
|
||||
}
|
||||
],
|
||||
"date_d'extraction": "16/04/2025 15:12:11",
|
||||
"répertoire": "output/ticket_T11084/T11084_20250416_151209",
|
||||
"messages_raw_reference": "output/ticket_T11084/T11084_20250416_151209/messages_raw.json"
|
||||
}
|
||||
@ -0,0 +1,46 @@
|
||||
# Ticket T11084: Site bloqué après MAJ
|
||||
|
||||
## Informations du ticket
|
||||
|
||||
- **id**: 11063
|
||||
- **code**: T11084
|
||||
- **name**: Site bloqué après MAJ
|
||||
- **project_name**: Demandes
|
||||
- **stage_name**: Clôturé
|
||||
- **user_id**:
|
||||
- **partner_id/email_from**: ROCHES ET DERIVÉS, Nicolas GOSSELIN, n.gosselin@groupemouen.fr
|
||||
- **create_date**: 19/03/2025 10:45:19
|
||||
- **write_date/last modification**: 03/04/2025 07:51:20
|
||||
- **date_deadline**: 03/04/2025 00:00:00
|
||||
|
||||
- **description**:
|
||||
|
||||
Point particulier :
|
||||
Le cas est bloquant
|
||||
Description du problème :
|
||||
Bonjour, le site est bloqué sur la mise a jour depuis 8h30 ce matin "La mise à jour n'est pas possible car d'autres utilisateurs sont en train de travailler sur le site".
|
||||
|
||||
Cordialement.
|
||||
|
||||
## Messages
|
||||
|
||||
### Message 1
|
||||
**author_id**: Romuald GRUSON
|
||||
**date**: 19/03/2025 13:06:13
|
||||
**message_type**: E-mail
|
||||
**subject**: Re: [T11084] - Site bloqué après MAJ
|
||||
**id**: 227919
|
||||
Bonjour
|
||||
,
|
||||
Nous avons relancé la mise à jour sur votre plateforme BRG-LAB, celle ci est de nouveau disponible et à jour.
|
||||
Je reste à votre entière disposition pour toute information complémentaire.
|
||||
Cordialement,
|
||||
---
|
||||
Support technique
|
||||
|
||||
---
|
||||
|
||||
## Informations sur l'extraction
|
||||
|
||||
- **Date d'extraction**: 16/04/2025 15:12:11
|
||||
- **Répertoire**: output/ticket_T11084/T11084_20250416_151209
|
||||
189
output/ticket_T11084/T11084_20250416_151209/all_messages.json
Normal file
56
output/ticket_T11084/T11084_20250416_151209/all_messages.txt
Normal file
@ -0,0 +1,56 @@
|
||||
TICKET: T11084 - Site bloqué après MAJ
|
||||
Date d'extraction: 2025-04-16 15:12:10
|
||||
Nombre de messages: 4
|
||||
|
||||
================================================================================
|
||||
|
||||
********************************************************************************
|
||||
*** CHANGEMENT D'ÉTAT ***
|
||||
********************************************************************************
|
||||
|
||||
DATE: 2025-03-19 10:45:20
|
||||
DE: Support Robot
|
||||
|
||||
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
********************************************************************************
|
||||
*** MESSAGE TRANSFÉRÉ ***
|
||||
********************************************************************************
|
||||
|
||||
DATE: 2025-03-19 13:06:13
|
||||
DE: Romuald GRUSON
|
||||
OBJET: Re: [T11084] - Site bloqué après MAJ
|
||||
|
||||
Bonjour
|
||||
,
|
||||
Nous avons relancé la mise à jour sur votre plateforme BRG-LAB, celle ci est de nouveau disponible et à jour.
|
||||
Je reste à votre entière disposition pour toute information complémentaire.
|
||||
Cordialement,
|
||||
---
|
||||
Support technique
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
********************************************************************************
|
||||
*** CHANGEMENT D'ÉTAT ***
|
||||
********************************************************************************
|
||||
|
||||
DATE: 2025-03-19 13:06:26
|
||||
DE: Romuald GRUSON
|
||||
|
||||
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
********************************************************************************
|
||||
*** CHANGEMENT D'ÉTAT ***
|
||||
********************************************************************************
|
||||
|
||||
DATE: 2025-04-03 07:51:20
|
||||
DE: Romuald GRUSON
|
||||
|
||||
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
@ -0,0 +1 @@
|
||||
[]
|
||||
30
output/ticket_T11084/T11084_20250416_151209/followers.json
Normal file
@ -0,0 +1,30 @@
|
||||
[
|
||||
{
|
||||
"id": 89671,
|
||||
"partner_id": [
|
||||
30810,
|
||||
"Support Robot"
|
||||
]
|
||||
},
|
||||
{
|
||||
"id": 89672,
|
||||
"partner_id": [
|
||||
28961,
|
||||
"Fabien LAFAY"
|
||||
]
|
||||
},
|
||||
{
|
||||
"id": 89682,
|
||||
"partner_id": [
|
||||
3886,
|
||||
"ROCHES ET DERIVÉS, Nicolas GOSSELIN"
|
||||
]
|
||||
},
|
||||
{
|
||||
"id": 89683,
|
||||
"partner_id": [
|
||||
32165,
|
||||
"Romuald GRUSON"
|
||||
]
|
||||
}
|
||||
]
|
||||
184
output/ticket_T11084/T11084_20250416_151209/messages_raw.json
Normal file
20
output/ticket_T11084/T11084_20250416_151209/structure.json
Normal file
@ -0,0 +1,20 @@
|
||||
{
|
||||
"date_extraction": "2025-04-16T15:12:10.497997",
|
||||
"ticket_id": 11063,
|
||||
"ticket_code": "T11084",
|
||||
"ticket_name": "Site bloqué après MAJ",
|
||||
"output_dir": "output/ticket_T11084/T11084_20250416_151209",
|
||||
"files": {
|
||||
"ticket_info": "ticket_info.json",
|
||||
"ticket_summary": "ticket_summary.json",
|
||||
"messages": "all_messages.json",
|
||||
"messages_raw": "messages_raw.json",
|
||||
"messages_text": "all_messages.txt",
|
||||
"attachments": "attachments_info.json",
|
||||
"followers": "followers.json"
|
||||
},
|
||||
"stats": {
|
||||
"messages_count": 4,
|
||||
"attachments_count": 0
|
||||
}
|
||||
}
|
||||
55
output/ticket_T11084/T11084_20250416_151209/ticket_info.json
Normal file
@ -0,0 +1,55 @@
|
||||
{
|
||||
"id": 11063,
|
||||
"name": "Site bloqué après MAJ",
|
||||
"description": "<h1>Point particulier :</h1><ul><li><b>Le cas est bloquant</b></li></ul><h1>Description du problème :</h1><p>Bonjour, le site est bloqué sur la mise a jour depuis 8h30 ce matin \"La mise à jour n'est pas possible car d'autres utilisateurs sont en train de travailler sur le site\".\r\n\r\nCordialement.</p>",
|
||||
"stage_id": [
|
||||
8,
|
||||
"Clôturé"
|
||||
],
|
||||
"project_id": [
|
||||
3,
|
||||
"Demandes"
|
||||
],
|
||||
"partner_id": [
|
||||
3886,
|
||||
"ROCHES ET DERIVÉS, Nicolas GOSSELIN"
|
||||
],
|
||||
"user_id": [
|
||||
32,
|
||||
"Romuald GRUSON"
|
||||
],
|
||||
"date_start": "2025-03-19 10:45:19",
|
||||
"date_end": false,
|
||||
"date_deadline": "2025-04-03",
|
||||
"create_date": "2025-03-19 10:45:19",
|
||||
"write_date": "2025-04-03 07:51:20",
|
||||
"tag_ids": [
|
||||
15
|
||||
],
|
||||
"priority": "3",
|
||||
"email_from": "n.gosselin@groupemouen.fr",
|
||||
"email_cc": "",
|
||||
"message_ids": [
|
||||
228931,
|
||||
227922,
|
||||
227921,
|
||||
227920,
|
||||
227919,
|
||||
227896
|
||||
],
|
||||
"message_follower_ids": [
|
||||
89671,
|
||||
89672,
|
||||
89682,
|
||||
89683
|
||||
],
|
||||
"timesheet_ids": [],
|
||||
"attachment_ids": [],
|
||||
"stage_id_name": "Clôturé",
|
||||
"project_id_name": "Demandes",
|
||||
"partner_id_name": "ROCHES ET DERIVÉS, Nicolas GOSSELIN",
|
||||
"user_id_name": "Romuald GRUSON",
|
||||
"tag_names": [
|
||||
"BRG-LAB WEB"
|
||||
]
|
||||
}
|
||||
@ -0,0 +1,16 @@
|
||||
{
|
||||
"id": 11063,
|
||||
"code": "T11084",
|
||||
"name": "Site bloqué après MAJ",
|
||||
"description": "<h1>Point particulier :</h1><ul><li><b>Le cas est bloquant</b></li></ul><h1>Description du problème :</h1><p>Bonjour, le site est bloqué sur la mise a jour depuis 8h30 ce matin \"La mise à jour n'est pas possible car d'autres utilisateurs sont en train de travailler sur le site\".\r\n\r\nCordialement.</p>",
|
||||
"stage": "Clôturé",
|
||||
"project": "Demandes",
|
||||
"partner": "ROCHES ET DERIVÉS, Nicolas GOSSELIN",
|
||||
"assigned_to": "Romuald GRUSON",
|
||||
"tags": [
|
||||
"BRG-LAB WEB"
|
||||
],
|
||||
"create_date": "2025-03-19 10:45:19",
|
||||
"write_date": "2025-04-03 07:51:20",
|
||||
"deadline": "2025-04-03"
|
||||
}
|
||||
@ -0,0 +1,26 @@
|
||||
{
|
||||
"id": "11064",
|
||||
"code": "T11085",
|
||||
"name": "cbao_support_technique - Message : ROCHES ET DERIV<49>S Nicolas GOSSELIN",
|
||||
"description": "Romuald : Réponse par mail demande n° T11084",
|
||||
"project_name": "Demandes",
|
||||
"stage_name": "Clôturé",
|
||||
"user_id": "",
|
||||
"partner_id_email_from": "ROCHES ET DERIVÉS, Nicolas GOSSELIN, n.gosselin@groupemouen.fr",
|
||||
"create_date": "19/03/2025 10:46:41",
|
||||
"write_date_last_modification": "03/04/2025 07:51:26",
|
||||
"date_deadline": "03/04/2025 00:00:00",
|
||||
"messages": [
|
||||
{
|
||||
"author_id": "vocalia",
|
||||
"date": "19/03/2025 10:44:29",
|
||||
"message_type": "E-mail",
|
||||
"subject": "cbao_support_technique - Message : ROCHES ET DERIV<49>S Nicolas GOSSELIN",
|
||||
"id": "227902",
|
||||
"content": "Veuillez trouver ci-dessous le suivi de vos appels.\nMessage : le 19/03/2025 à 11:41\nNom\nROCHES ET DERIVÉS\nPrénom\nNicolas GOSSELIN\nAdresse mail\noui\nPanne\nplus aucun droit suite a la mise a jour\nRv\nmessage répondeur\nTicket\npas concerné\nMessage\nMessage pour : LAFAY Fabien / urgence --joindre systématiquement Fabien----\nM.GOSSELIN de l entreprise roches et dérivés cherche à vous joindre, le site est bloqué depuis ce matin suite à une mise à jour. Elsa\nAdresse\n- 14790 MOUEN\nTél\n02-31-26-25-66\nE-mail\nn.gosselin@groupemouen.fr\nGsm\n06-10-56-13-06\nVos appels sur Flux RSS :\nCliquez ici\nCordialement\nAgenda5\n\n---\n"
|
||||
}
|
||||
],
|
||||
"date_d'extraction": "16/04/2025 15:12:11",
|
||||
"répertoire": "output/ticket_T11085/T11085_20250416_151209",
|
||||
"messages_raw_reference": "output/ticket_T11085/T11085_20250416_151209/messages_raw.json"
|
||||
}
|
||||
@ -0,0 +1,63 @@
|
||||
# Ticket T11085: cbao_support_technique - Message : ROCHES ET DERIV<49>S Nicolas GOSSELIN
|
||||
|
||||
## Informations du ticket
|
||||
|
||||
- **id**: 11064
|
||||
- **code**: T11085
|
||||
- **name**: cbao_support_technique - Message : ROCHES ET DERIV<49>S Nicolas GOSSELIN
|
||||
- **project_name**: Demandes
|
||||
- **stage_name**: Clôturé
|
||||
- **user_id**:
|
||||
- **partner_id/email_from**: ROCHES ET DERIVÉS, Nicolas GOSSELIN, n.gosselin@groupemouen.fr
|
||||
- **create_date**: 19/03/2025 10:46:41
|
||||
- **write_date/last modification**: 03/04/2025 07:51:26
|
||||
- **date_deadline**: 03/04/2025 00:00:00
|
||||
|
||||
- **description**:
|
||||
|
||||
Romuald : Réponse par mail demande n° T11084
|
||||
|
||||
## Messages
|
||||
|
||||
### Message 1
|
||||
**author_id**: vocalia
|
||||
**date**: 19/03/2025 10:44:29
|
||||
**message_type**: E-mail
|
||||
**subject**: cbao_support_technique - Message : ROCHES ET DERIV<49>S Nicolas GOSSELIN
|
||||
**id**: 227902
|
||||
Veuillez trouver ci-dessous le suivi de vos appels.
|
||||
Message : le 19/03/2025 à 11:41
|
||||
Nom
|
||||
ROCHES ET DERIVÉS
|
||||
Prénom
|
||||
Nicolas GOSSELIN
|
||||
Adresse mail
|
||||
oui
|
||||
Panne
|
||||
plus aucun droit suite a la mise a jour
|
||||
Rv
|
||||
message répondeur
|
||||
Ticket
|
||||
pas concerné
|
||||
Message
|
||||
Message pour : LAFAY Fabien / urgence --joindre systématiquement Fabien----
|
||||
M.GOSSELIN de l entreprise roches et dérivés cherche à vous joindre, le site est bloqué depuis ce matin suite à une mise à jour. Elsa
|
||||
Adresse
|
||||
- 14790 MOUEN
|
||||
Tél
|
||||
02-31-26-25-66
|
||||
E-mail
|
||||
n.gosselin@groupemouen.fr
|
||||
Gsm
|
||||
06-10-56-13-06
|
||||
Vos appels sur Flux RSS :
|
||||
Cliquez ici
|
||||
Cordialement
|
||||
Agenda5
|
||||
|
||||
---
|
||||
|
||||
## Informations sur l'extraction
|
||||
|
||||
- **Date d'extraction**: 16/04/2025 15:12:11
|
||||
- **Répertoire**: output/ticket_T11085/T11085_20250416_151209
|
||||
189
output/ticket_T11085/T11085_20250416_151209/all_messages.json
Normal file
@ -0,0 +1,189 @@
|
||||
{
|
||||
"ticket_summary": {
|
||||
"id": 11064,
|
||||
"code": "T11085",
|
||||
"name": "cbao_support_technique - Message : ROCHES ET DERIV<49>S Nicolas GOSSELIN",
|
||||
"project_id": 3,
|
||||
"project_name": "Demandes",
|
||||
"stage_id": 8,
|
||||
"stage_name": "Clôturé",
|
||||
"date_extraction": "2025-04-16T15:12:09.546064"
|
||||
},
|
||||
"metadata": {
|
||||
"message_count": {
|
||||
"total": 6,
|
||||
"processed": 4,
|
||||
"excluded": 2
|
||||
},
|
||||
"cleaning_strategy": "standard",
|
||||
"cleaning_config": {
|
||||
"preserve_links": true,
|
||||
"preserve_images": true,
|
||||
"strategy": "html2text",
|
||||
"preserve_doc_links": true
|
||||
}
|
||||
},
|
||||
"messages": [
|
||||
{
|
||||
"id": 227902,
|
||||
"body": "Veuillez trouver ci-dessous le suivi de vos appels.\nMessage : le 19/03/2025 à 11:41\nNom\nROCHES ET DERIVÉS\nPrénom\nNicolas GOSSELIN\nAdresse mail\noui\nPanne\nplus aucun droit suite a la mise a jour\nRv\nmessage répondeur\nTicket\npas concerné\nMessage\nMessage pour : LAFAY Fabien / urgence --joindre systématiquement Fabien----\nM.GOSSELIN de l entreprise roches et dérivés cherche à vous joindre, le site est bloqué depuis ce matin suite à une mise à jour. Elsa\nAdresse\n- 14790 MOUEN\nTél\n02-31-26-25-66\nE-mail\nn.gosselin@groupemouen.fr\nGsm\n06-10-56-13-06\nVos appels sur Flux RSS :\nCliquez ici\nCordialement\nAgenda5",
|
||||
"date": "2025-03-19 10:44:29",
|
||||
"author_id": [
|
||||
31768,
|
||||
"vocalia"
|
||||
],
|
||||
"email_from": "vocalia@a5serv.fr",
|
||||
"message_type": "email",
|
||||
"parent_id": [
|
||||
227901,
|
||||
"[T11085] cbao_support_technique - Message : ROCHES ET DERIV<49>S Nicolas GOSSELIN"
|
||||
],
|
||||
"subtype_id": [
|
||||
1,
|
||||
"Discussions"
|
||||
],
|
||||
"subject": "cbao_support_technique - Message : ROCHES ET DERIV<49>S Nicolas GOSSELIN",
|
||||
"tracking_value_ids": [],
|
||||
"attachment_ids": [],
|
||||
"is_system": false,
|
||||
"is_stage_change": false,
|
||||
"is_forwarded": false,
|
||||
"is_duplicate": false,
|
||||
"body_original": "\r\n\r\n\r\nVeuillez trouver ci-dessous le suivi de vos appels.<br><br>\r\n<img src=\"https://vocalia.a5serv.fr/mepl.png\" border=\"0\" width=\"32\" height=\"32\" style=\"vertical-align:middle\" alt=\"Message\"> <u><b>Message : le 19/03/2025 à 11:41</b></u><br><br>\r\n\r\n\r\n<table border=\"1\" cellpadding=\"3\" cellspacing=\"0\" style=\"border-width:1px; border-style:solid; border-color:#CCCCCC; border-collapse:collapse; font-size:13px; font-family:arial, helvetica, sans-serif\"><tr><td style=\"background-color:#F5F5F5\">Nom</td><td>ROCHES ET DERIVÉS</td></tr><tr><td style=\"background-color:#F5F5F5\">Prénom</td><td>Nicolas GOSSELIN</td></tr><tr><td style=\"vertical-align:top; background-color:#F5F5F5\">Adresse mail</td><td> oui</td></tr><tr><td style=\"vertical-align:top; background-color:#F5F5F5\">Panne</td><td> plus aucun droit suite a la mise a jour </td></tr><tr><td style=\"vertical-align:top; background-color:#F5F5F5\">Rv</td><td> message répondeur</td></tr><tr><td style=\"vertical-align:top; background-color:#F5F5F5\">Ticket</td><td> pas concerné</td></tr><tr><td style=\"vertical-align:top; background-color:#F5F5F5\">Message</td><td>Message pour : LAFAY Fabien / urgence --joindre systématiquement Fabien---- <br>M.GOSSELIN de l entreprise roches et dérivés cherche à vous joindre, le site est bloqué depuis ce matin suite à une mise à jour. Elsa <br><br><br><br></td></tr><tr><td style=\"vertical-align:top; background-color:#F5F5F5\">Adresse</td><td>- 14790 MOUEN</td></tr><tr><td style=\"vertical-align:top; background-color:#F5F5F5\">Tél</td><td>02-31-26-25-66</td></tr><tr><td style=\"vertical-align:top; background-color:#F5F5F5\">E-mail</td> <td>n.gosselin@groupemouen.fr</td></tr><tr><td style=\"vertical-align:top; background-color:#F5F5F5\">Gsm</td> <td>06-10-56-13-06</td></tr></table>\r\n\r\n\r\n\r\n\r\n\r\n<br>Vos appels sur Flux RSS : <a href=\"https://vocalia.a5serv.fr/cgi-bin/synchro/irss.pl?id=22a11548aui72_jjilm7m08dhek_0110.ics\">Cliquez ici</a><br>\r\n\r\n<br>Cordialement<br><br>\r\n\r\n<br><div align=\"center\"><div style=\"text-align:center; color:#777777; font-size:0.8em\"><img src=\"https://agenda5.fr/72.png\" width=\"64\" height=\"64\" alt=\"Agenda5\" border=\"0\" title=\"Agenda5\"><br>Agenda5</div></div>\r\n<br>",
|
||||
"author_details": {
|
||||
"name": "vocalia",
|
||||
"email": "vocalia@a5serv.fr",
|
||||
"is_system": false,
|
||||
"id": 31768,
|
||||
"phone": false,
|
||||
"function": false,
|
||||
"company_id": [
|
||||
1,
|
||||
"CBAO S.A.R.L."
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": 227901,
|
||||
"body": "",
|
||||
"date": "2025-03-19 10:46:43",
|
||||
"author_id": [
|
||||
2,
|
||||
"OdooBot"
|
||||
],
|
||||
"email_from": "\"OdooBot\" <odoobot@example.com>",
|
||||
"message_type": "notification",
|
||||
"parent_id": false,
|
||||
"subtype_id": [
|
||||
16,
|
||||
"Task Created"
|
||||
],
|
||||
"subject": false,
|
||||
"tracking_value_ids": [
|
||||
177958,
|
||||
177959,
|
||||
177960,
|
||||
177961,
|
||||
177962
|
||||
],
|
||||
"attachment_ids": [],
|
||||
"is_system": true,
|
||||
"is_stage_change": true,
|
||||
"is_forwarded": false,
|
||||
"is_duplicate": false,
|
||||
"author_details": {
|
||||
"name": "OdooBot",
|
||||
"email": "odoobot@example.com",
|
||||
"is_system": true,
|
||||
"id": 2,
|
||||
"phone": false,
|
||||
"function": false,
|
||||
"company_id": [
|
||||
1,
|
||||
"CBAO S.A.R.L."
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": 227925,
|
||||
"body": "",
|
||||
"date": "2025-03-19 13:07:53",
|
||||
"author_id": [
|
||||
32165,
|
||||
"Romuald GRUSON"
|
||||
],
|
||||
"email_from": "\"Romuald GRUSON\" <romuald@mail.cbao.fr>",
|
||||
"message_type": "notification",
|
||||
"parent_id": [
|
||||
227901,
|
||||
"[T11085] cbao_support_technique - Message : ROCHES ET DERIV<49>S Nicolas GOSSELIN"
|
||||
],
|
||||
"subtype_id": [
|
||||
19,
|
||||
"Stage Changed"
|
||||
],
|
||||
"subject": false,
|
||||
"tracking_value_ids": [
|
||||
177989,
|
||||
177990
|
||||
],
|
||||
"attachment_ids": [],
|
||||
"is_system": true,
|
||||
"is_stage_change": true,
|
||||
"is_forwarded": false,
|
||||
"is_duplicate": false,
|
||||
"author_details": {
|
||||
"name": "Romuald GRUSON",
|
||||
"email": "romuald@mail.cbao.fr",
|
||||
"is_system": false,
|
||||
"id": 32165,
|
||||
"phone": false,
|
||||
"function": false,
|
||||
"company_id": [
|
||||
1,
|
||||
"CBAO S.A.R.L."
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": 228932,
|
||||
"body": "",
|
||||
"date": "2025-04-03 07:51:26",
|
||||
"author_id": [
|
||||
32165,
|
||||
"Romuald GRUSON"
|
||||
],
|
||||
"email_from": "\"Romuald GRUSON\" <romuald@mail.cbao.fr>",
|
||||
"message_type": "notification",
|
||||
"parent_id": [
|
||||
227901,
|
||||
"[T11085] cbao_support_technique - Message : ROCHES ET DERIV<49>S Nicolas GOSSELIN"
|
||||
],
|
||||
"subtype_id": [
|
||||
19,
|
||||
"Stage Changed"
|
||||
],
|
||||
"subject": false,
|
||||
"tracking_value_ids": [
|
||||
179060
|
||||
],
|
||||
"attachment_ids": [],
|
||||
"is_system": true,
|
||||
"is_stage_change": true,
|
||||
"is_forwarded": false,
|
||||
"is_duplicate": false,
|
||||
"author_details": {
|
||||
"name": "Romuald GRUSON",
|
||||
"email": "romuald@mail.cbao.fr",
|
||||
"is_system": false,
|
||||
"id": 32165,
|
||||
"phone": false,
|
||||
"function": false,
|
||||
"company_id": [
|
||||
1,
|
||||
"CBAO S.A.R.L."
|
||||
]
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
74
output/ticket_T11085/T11085_20250416_151209/all_messages.txt
Normal file
@ -0,0 +1,74 @@
|
||||
TICKET: T11085 - cbao_support_technique - Message : ROCHES ET DERIV<49>S Nicolas GOSSELIN
|
||||
Date d'extraction: 2025-04-16 15:12:09
|
||||
Nombre de messages: 4
|
||||
|
||||
================================================================================
|
||||
|
||||
DATE: 2025-03-19 10:44:29
|
||||
DE: vocalia
|
||||
OBJET: cbao_support_technique - Message : ROCHES ET DERIV<49>S Nicolas GOSSELIN
|
||||
|
||||
Veuillez trouver ci-dessous le suivi de vos appels.
|
||||
Message : le 19/03/2025 à 11:41
|
||||
Nom
|
||||
ROCHES ET DERIVÉS
|
||||
Prénom
|
||||
Nicolas GOSSELIN
|
||||
Adresse mail
|
||||
oui
|
||||
Panne
|
||||
plus aucun droit suite a la mise a jour
|
||||
Rv
|
||||
message répondeur
|
||||
Ticket
|
||||
pas concerné
|
||||
Message
|
||||
Message pour : LAFAY Fabien / urgence --joindre systématiquement Fabien----
|
||||
M.GOSSELIN de l entreprise roches et dérivés cherche à vous joindre, le site est bloqué depuis ce matin suite à une mise à jour. Elsa
|
||||
Adresse
|
||||
- 14790 MOUEN
|
||||
Tél
|
||||
02-31-26-25-66
|
||||
E-mail
|
||||
n.gosselin@groupemouen.fr
|
||||
Gsm
|
||||
06-10-56-13-06
|
||||
Vos appels sur Flux RSS :
|
||||
Cliquez ici
|
||||
Cordialement
|
||||
Agenda5
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
********************************************************************************
|
||||
*** CHANGEMENT D'ÉTAT ***
|
||||
********************************************************************************
|
||||
|
||||
DATE: 2025-03-19 10:46:43
|
||||
DE: OdooBot
|
||||
|
||||
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
********************************************************************************
|
||||
*** CHANGEMENT D'ÉTAT ***
|
||||
********************************************************************************
|
||||
|
||||
DATE: 2025-03-19 13:07:53
|
||||
DE: Romuald GRUSON
|
||||
|
||||
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
********************************************************************************
|
||||
*** CHANGEMENT D'ÉTAT ***
|
||||
********************************************************************************
|
||||
|
||||
DATE: 2025-04-03 07:51:26
|
||||
DE: Romuald GRUSON
|
||||
|
||||
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
BIN
output/ticket_T11085/T11085_20250416_151209/attachments/72.png
Normal file
|
After Width: | Height: | Size: 1.5 KiB |
BIN
output/ticket_T11085/T11085_20250416_151209/attachments/mepl.png
Normal file
|
After Width: | Height: | Size: 574 B |
@ -0,0 +1,36 @@
|
||||
[
|
||||
{
|
||||
"id": "embedded_1",
|
||||
"name": "mepl.png",
|
||||
"mimetype": "image/png",
|
||||
"file_size": "574",
|
||||
"create_date": null,
|
||||
"creator_name": "Extraction automatique",
|
||||
"download_status": "success",
|
||||
"local_path": "output/ticket_T11085/T11085_20250416_151209/attachments/mepl.png",
|
||||
"error": "",
|
||||
"is_embedded_image": true,
|
||||
"source_url": "https://vocalia.a5serv.fr/mepl.png",
|
||||
"source": "message_embedded",
|
||||
"extraction_date": "2025-04-16T15:12:09.744949",
|
||||
"source_message_id": 227902,
|
||||
"message_author": "vocalia"
|
||||
},
|
||||
{
|
||||
"id": "embedded_2",
|
||||
"name": "72.png",
|
||||
"mimetype": "image/png",
|
||||
"file_size": "1547",
|
||||
"create_date": null,
|
||||
"creator_name": "Extraction automatique",
|
||||
"download_status": "success",
|
||||
"local_path": "output/ticket_T11085/T11085_20250416_151209/attachments/72.png",
|
||||
"error": "",
|
||||
"is_embedded_image": true,
|
||||
"source_url": "https://agenda5.fr/72.png",
|
||||
"source": "message_embedded",
|
||||
"extraction_date": "2025-04-16T15:12:09.904984",
|
||||
"source_message_id": 227902,
|
||||
"message_author": "vocalia"
|
||||
}
|
||||
]
|
||||
16
output/ticket_T11085/T11085_20250416_151209/followers.json
Normal file
@ -0,0 +1,16 @@
|
||||
[
|
||||
{
|
||||
"id": 89675,
|
||||
"partner_id": [
|
||||
28961,
|
||||
"Fabien LAFAY"
|
||||
]
|
||||
},
|
||||
{
|
||||
"id": 89684,
|
||||
"partner_id": [
|
||||
32165,
|
||||
"Romuald GRUSON"
|
||||
]
|
||||
}
|
||||
]
|
||||
184
output/ticket_T11085/T11085_20250416_151209/messages_raw.json
Normal file
@ -0,0 +1,184 @@
|
||||
{
|
||||
"ticket_id": 11064,
|
||||
"ticket_code": "T11085",
|
||||
"message_metadata": {
|
||||
"227902": {
|
||||
"is_system": false,
|
||||
"is_stage_change": false,
|
||||
"is_forwarded": false,
|
||||
"is_duplicate": false
|
||||
},
|
||||
"227901": {
|
||||
"is_system": true,
|
||||
"is_stage_change": true,
|
||||
"is_forwarded": false,
|
||||
"is_duplicate": false
|
||||
},
|
||||
"227923": {
|
||||
"is_system": true,
|
||||
"is_stage_change": false,
|
||||
"is_forwarded": false,
|
||||
"is_duplicate": false,
|
||||
"excluded": "system_message"
|
||||
},
|
||||
"227924": {
|
||||
"is_system": true,
|
||||
"is_stage_change": false,
|
||||
"is_forwarded": false,
|
||||
"is_duplicate": false,
|
||||
"excluded": "system_message"
|
||||
},
|
||||
"227925": {
|
||||
"is_system": true,
|
||||
"is_stage_change": true,
|
||||
"is_forwarded": false,
|
||||
"is_duplicate": false
|
||||
},
|
||||
"228932": {
|
||||
"is_system": true,
|
||||
"is_stage_change": true,
|
||||
"is_forwarded": false,
|
||||
"is_duplicate": false
|
||||
}
|
||||
},
|
||||
"messages": [
|
||||
{
|
||||
"id": 227902,
|
||||
"body": "\r\n\r\n\r\nVeuillez trouver ci-dessous le suivi de vos appels.<br><br>\r\n<img src=\"https://vocalia.a5serv.fr/mepl.png\" border=\"0\" width=\"32\" height=\"32\" style=\"vertical-align:middle\" alt=\"Message\"> <u><b>Message : le 19/03/2025 à 11:41</b></u><br><br>\r\n\r\n\r\n<table border=\"1\" cellpadding=\"3\" cellspacing=\"0\" style=\"border-width:1px; border-style:solid; border-color:#CCCCCC; border-collapse:collapse; font-size:13px; font-family:arial, helvetica, sans-serif\"><tr><td style=\"background-color:#F5F5F5\">Nom</td><td>ROCHES ET DERIVÉS</td></tr><tr><td style=\"background-color:#F5F5F5\">Prénom</td><td>Nicolas GOSSELIN</td></tr><tr><td style=\"vertical-align:top; background-color:#F5F5F5\">Adresse mail</td><td> oui</td></tr><tr><td style=\"vertical-align:top; background-color:#F5F5F5\">Panne</td><td> plus aucun droit suite a la mise a jour </td></tr><tr><td style=\"vertical-align:top; background-color:#F5F5F5\">Rv</td><td> message répondeur</td></tr><tr><td style=\"vertical-align:top; background-color:#F5F5F5\">Ticket</td><td> pas concerné</td></tr><tr><td style=\"vertical-align:top; background-color:#F5F5F5\">Message</td><td>Message pour : LAFAY Fabien / urgence --joindre systématiquement Fabien---- <br>M.GOSSELIN de l entreprise roches et dérivés cherche à vous joindre, le site est bloqué depuis ce matin suite à une mise à jour. Elsa <br><br><br><br></td></tr><tr><td style=\"vertical-align:top; background-color:#F5F5F5\">Adresse</td><td>- 14790 MOUEN</td></tr><tr><td style=\"vertical-align:top; background-color:#F5F5F5\">Tél</td><td>02-31-26-25-66</td></tr><tr><td style=\"vertical-align:top; background-color:#F5F5F5\">E-mail</td> <td>n.gosselin@groupemouen.fr</td></tr><tr><td style=\"vertical-align:top; background-color:#F5F5F5\">Gsm</td> <td>06-10-56-13-06</td></tr></table>\r\n\r\n\r\n\r\n\r\n\r\n<br>Vos appels sur Flux RSS : <a href=\"https://vocalia.a5serv.fr/cgi-bin/synchro/irss.pl?id=22a11548aui72_jjilm7m08dhek_0110.ics\">Cliquez ici</a><br>\r\n\r\n<br>Cordialement<br><br>\r\n\r\n<br><div align=\"center\"><div style=\"text-align:center; color:#777777; font-size:0.8em\"><img src=\"https://agenda5.fr/72.png\" width=\"64\" height=\"64\" alt=\"Agenda5\" border=\"0\" title=\"Agenda5\"><br>Agenda5</div></div>\r\n<br>",
|
||||
"date": "2025-03-19 10:44:29",
|
||||
"author_id": [
|
||||
31768,
|
||||
"vocalia"
|
||||
],
|
||||
"email_from": "vocalia@a5serv.fr",
|
||||
"message_type": "email",
|
||||
"parent_id": [
|
||||
227901,
|
||||
"[T11085] cbao_support_technique - Message : ROCHES ET DERIV<49>S Nicolas GOSSELIN"
|
||||
],
|
||||
"subtype_id": [
|
||||
1,
|
||||
"Discussions"
|
||||
],
|
||||
"subject": "cbao_support_technique - Message : ROCHES ET DERIV<49>S Nicolas GOSSELIN",
|
||||
"tracking_value_ids": [],
|
||||
"attachment_ids": []
|
||||
},
|
||||
{
|
||||
"id": 227901,
|
||||
"body": "",
|
||||
"date": "2025-03-19 10:46:43",
|
||||
"author_id": [
|
||||
2,
|
||||
"OdooBot"
|
||||
],
|
||||
"email_from": "\"OdooBot\" <odoobot@example.com>",
|
||||
"message_type": "notification",
|
||||
"parent_id": false,
|
||||
"subtype_id": [
|
||||
16,
|
||||
"Task Created"
|
||||
],
|
||||
"subject": false,
|
||||
"tracking_value_ids": [
|
||||
177958,
|
||||
177959,
|
||||
177960,
|
||||
177961,
|
||||
177962
|
||||
],
|
||||
"attachment_ids": []
|
||||
},
|
||||
{
|
||||
"id": 227923,
|
||||
"body": "",
|
||||
"date": "2025-03-19 13:07:03",
|
||||
"author_id": [
|
||||
32165,
|
||||
"Romuald GRUSON"
|
||||
],
|
||||
"email_from": "\"Romuald GRUSON\" <romuald@mail.cbao.fr>",
|
||||
"message_type": "notification",
|
||||
"parent_id": false,
|
||||
"subtype_id": [
|
||||
2,
|
||||
"Note"
|
||||
],
|
||||
"subject": false,
|
||||
"tracking_value_ids": [
|
||||
177987
|
||||
],
|
||||
"attachment_ids": []
|
||||
},
|
||||
{
|
||||
"id": 227924,
|
||||
"body": "",
|
||||
"date": "2025-03-19 13:07:53",
|
||||
"author_id": [
|
||||
32165,
|
||||
"Romuald GRUSON"
|
||||
],
|
||||
"email_from": "\"Romuald GRUSON\" <romuald@mail.cbao.fr>",
|
||||
"message_type": "notification",
|
||||
"parent_id": false,
|
||||
"subtype_id": [
|
||||
2,
|
||||
"Note"
|
||||
],
|
||||
"subject": false,
|
||||
"tracking_value_ids": [
|
||||
177988
|
||||
],
|
||||
"attachment_ids": []
|
||||
},
|
||||
{
|
||||
"id": 227925,
|
||||
"body": "",
|
||||
"date": "2025-03-19 13:07:53",
|
||||
"author_id": [
|
||||
32165,
|
||||
"Romuald GRUSON"
|
||||
],
|
||||
"email_from": "\"Romuald GRUSON\" <romuald@mail.cbao.fr>",
|
||||
"message_type": "notification",
|
||||
"parent_id": [
|
||||
227901,
|
||||
"[T11085] cbao_support_technique - Message : ROCHES ET DERIV<49>S Nicolas GOSSELIN"
|
||||
],
|
||||
"subtype_id": [
|
||||
19,
|
||||
"Stage Changed"
|
||||
],
|
||||
"subject": false,
|
||||
"tracking_value_ids": [
|
||||
177989,
|
||||
177990
|
||||
],
|
||||
"attachment_ids": []
|
||||
},
|
||||
{
|
||||
"id": 228932,
|
||||
"body": "",
|
||||
"date": "2025-04-03 07:51:26",
|
||||
"author_id": [
|
||||
32165,
|
||||
"Romuald GRUSON"
|
||||
],
|
||||
"email_from": "\"Romuald GRUSON\" <romuald@mail.cbao.fr>",
|
||||
"message_type": "notification",
|
||||
"parent_id": [
|
||||
227901,
|
||||
"[T11085] cbao_support_technique - Message : ROCHES ET DERIV<49>S Nicolas GOSSELIN"
|
||||
],
|
||||
"subtype_id": [
|
||||
19,
|
||||
"Stage Changed"
|
||||
],
|
||||
"subject": false,
|
||||
"tracking_value_ids": [
|
||||
179060
|
||||
],
|
||||
"attachment_ids": []
|
||||
}
|
||||
]
|
||||
}
|
||||
20
output/ticket_T11085/T11085_20250416_151209/structure.json
Normal file
@ -0,0 +1,20 @@
|
||||
{
|
||||
"date_extraction": "2025-04-16T15:12:09.938031",
|
||||
"ticket_id": 11064,
|
||||
"ticket_code": "T11085",
|
||||
"ticket_name": "cbao_support_technique - Message : ROCHES ET DERIV<49>S Nicolas GOSSELIN",
|
||||
"output_dir": "output/ticket_T11085/T11085_20250416_151209",
|
||||
"files": {
|
||||
"ticket_info": "ticket_info.json",
|
||||
"ticket_summary": "ticket_summary.json",
|
||||
"messages": "all_messages.json",
|
||||
"messages_raw": "messages_raw.json",
|
||||
"messages_text": "all_messages.txt",
|
||||
"attachments": "attachments_info.json",
|
||||
"followers": "followers.json"
|
||||
},
|
||||
"stats": {
|
||||
"messages_count": 4,
|
||||
"attachments_count": 2
|
||||
}
|
||||
}
|
||||
53
output/ticket_T11085/T11085_20250416_151209/ticket_info.json
Normal file
@ -0,0 +1,53 @@
|
||||
{
|
||||
"id": 11064,
|
||||
"name": "cbao_support_technique - Message : ROCHES ET DERIV<49>S Nicolas GOSSELIN",
|
||||
"description": "<p>Romuald : Réponse par mail demande n° T11084</p>",
|
||||
"stage_id": [
|
||||
8,
|
||||
"Clôturé"
|
||||
],
|
||||
"project_id": [
|
||||
3,
|
||||
"Demandes"
|
||||
],
|
||||
"partner_id": [
|
||||
3886,
|
||||
"ROCHES ET DERIVÉS, Nicolas GOSSELIN"
|
||||
],
|
||||
"user_id": [
|
||||
32,
|
||||
"Romuald GRUSON"
|
||||
],
|
||||
"date_start": "2025-03-19 10:46:43",
|
||||
"date_end": false,
|
||||
"date_deadline": "2025-04-03",
|
||||
"create_date": "2025-03-19 10:46:41",
|
||||
"write_date": "2025-04-03 07:51:26",
|
||||
"tag_ids": [
|
||||
15
|
||||
],
|
||||
"priority": "0",
|
||||
"email_from": "n.gosselin@groupemouen.fr",
|
||||
"email_cc": "",
|
||||
"message_ids": [
|
||||
228932,
|
||||
227925,
|
||||
227924,
|
||||
227923,
|
||||
227902,
|
||||
227901
|
||||
],
|
||||
"message_follower_ids": [
|
||||
89675,
|
||||
89684
|
||||
],
|
||||
"timesheet_ids": [],
|
||||
"attachment_ids": [],
|
||||
"stage_id_name": "Clôturé",
|
||||
"project_id_name": "Demandes",
|
||||
"partner_id_name": "ROCHES ET DERIVÉS, Nicolas GOSSELIN",
|
||||
"user_id_name": "Romuald GRUSON",
|
||||
"tag_names": [
|
||||
"BRG-LAB WEB"
|
||||
]
|
||||
}
|
||||
@ -0,0 +1,16 @@
|
||||
{
|
||||
"id": 11064,
|
||||
"code": "T11085",
|
||||
"name": "cbao_support_technique - Message : ROCHES ET DERIV<49>S Nicolas GOSSELIN",
|
||||
"description": "<p>Romuald : Réponse par mail demande n° T11084</p>",
|
||||
"stage": "Clôturé",
|
||||
"project": "Demandes",
|
||||
"partner": "ROCHES ET DERIVÉS, Nicolas GOSSELIN",
|
||||
"assigned_to": "Romuald GRUSON",
|
||||
"tags": [
|
||||
"BRG-LAB WEB"
|
||||
],
|
||||
"create_date": "2025-03-19 10:46:41",
|
||||
"write_date": "2025-04-03 07:51:26",
|
||||
"deadline": "2025-04-03"
|
||||
}
|
||||
@ -0,0 +1,34 @@
|
||||
{
|
||||
"id": "11065",
|
||||
"code": "T11086",
|
||||
"name": "Erreur fatale essai VBS",
|
||||
"description": "*Contenu non extractible*",
|
||||
"project_name": "Demandes",
|
||||
"stage_name": "Clôturé",
|
||||
"user_id": "",
|
||||
"partner_id_email_from": "AXYLIS (GROUPE MINIER), Delphine PILON, Delphine PILON <dpilon@axylis.com>",
|
||||
"create_date": "19/03/2025 11:06:53",
|
||||
"write_date_last_modification": "03/04/2025 07:51:32",
|
||||
"date_deadline": "03/04/2025 00:00:00",
|
||||
"messages": [
|
||||
{
|
||||
"author_id": "Delphine PILON",
|
||||
"date": "19/03/2025 11:02:12",
|
||||
"message_type": "E-mail",
|
||||
"subject": "Erreur fatale essai VBS",
|
||||
"id": "227908",
|
||||
"content": "Bonjour,\nSur tous les essais VBS, j’ai le message d’erreur ci-dessous qui s’affiche.\nPouvez-vous, s’il vous plait, résoudre le problème assez rapidement ?\nMes clients attendent leurs résultats\n\n- image002.png (image/png) [ID: 144867]\n- image001.png (image/png) [ID: 144865]\n\n---\n\n"
|
||||
},
|
||||
{
|
||||
"author_id": "Romuald GRUSON",
|
||||
"date": "19/03/2025 13:03:13",
|
||||
"message_type": "E-mail",
|
||||
"subject": "Re: [T11086] - Erreur fatale essai VBS",
|
||||
"id": "227915",
|
||||
"content": "Bonjour\n,\nNous avons déployé en urgence un patch ce midi pour corriger cette anomalie. Nous sommes désolés pour ce désagrément, une erreur de compilation des données s'est glissée dans le déploiement de notre mise à jour de cette nuit.\nJe reste à votre entière disposition pour toute information complémentaire.\nCordialement,\n---\nSupport technique\n\n---\n"
|
||||
}
|
||||
],
|
||||
"date_d'extraction": "16/04/2025 15:12:11",
|
||||
"répertoire": "output/ticket_T11086/T11086_20250416_151208",
|
||||
"messages_raw_reference": "output/ticket_T11086/T11086_20250416_151208/messages_raw.json"
|
||||
}
|
||||
@ -0,0 +1,58 @@
|
||||
# Ticket T11086: Erreur fatale essai VBS
|
||||
|
||||
## Informations du ticket
|
||||
|
||||
- **id**: 11065
|
||||
- **code**: T11086
|
||||
- **name**: Erreur fatale essai VBS
|
||||
- **project_name**: Demandes
|
||||
- **stage_name**: Clôturé
|
||||
- **user_id**:
|
||||
- **partner_id/email_from**: AXYLIS (GROUPE MINIER), Delphine PILON, Delphine PILON <dpilon@axylis.com>
|
||||
- **create_date**: 19/03/2025 11:06:53
|
||||
- **write_date/last modification**: 03/04/2025 07:51:32
|
||||
- **date_deadline**: 03/04/2025 00:00:00
|
||||
|
||||
- **description**:
|
||||
|
||||
*Contenu non extractible*
|
||||
|
||||
## Messages
|
||||
|
||||
### Message 1
|
||||
**author_id**: Delphine PILON
|
||||
**date**: 19/03/2025 11:02:12
|
||||
**message_type**: E-mail
|
||||
**subject**: Erreur fatale essai VBS
|
||||
**id**: 227908
|
||||
Bonjour,
|
||||
Sur tous les essais VBS, j’ai le message d’erreur ci-dessous qui s’affiche.
|
||||
Pouvez-vous, s’il vous plait, résoudre le problème assez rapidement ?
|
||||
Mes clients attendent leurs résultats
|
||||
|
||||
**attachment_ids**:
|
||||
- image002.png (image/png) [ID: 144867]
|
||||
- image001.png (image/png) [ID: 144865]
|
||||
|
||||
---
|
||||
|
||||
### Message 2
|
||||
**author_id**: Romuald GRUSON
|
||||
**date**: 19/03/2025 13:03:13
|
||||
**message_type**: E-mail
|
||||
**subject**: Re: [T11086] - Erreur fatale essai VBS
|
||||
**id**: 227915
|
||||
Bonjour
|
||||
,
|
||||
Nous avons déployé en urgence un patch ce midi pour corriger cette anomalie. Nous sommes désolés pour ce désagrément, une erreur de compilation des données s'est glissée dans le déploiement de notre mise à jour de cette nuit.
|
||||
Je reste à votre entière disposition pour toute information complémentaire.
|
||||
Cordialement,
|
||||
---
|
||||
Support technique
|
||||
|
||||
---
|
||||
|
||||
## Informations sur l'extraction
|
||||
|
||||
- **Date d'extraction**: 16/04/2025 15:12:11
|
||||
- **Répertoire**: output/ticket_T11086/T11086_20250416_151208
|
||||
231
output/ticket_T11086/T11086_20250416_151208/all_messages.json
Normal file
67
output/ticket_T11086/T11086_20250416_151208/all_messages.txt
Normal file
@ -0,0 +1,67 @@
|
||||
TICKET: T11086 - Erreur fatale essai VBS
|
||||
Date d'extraction: 2025-04-16 15:12:08
|
||||
Nombre de messages: 5
|
||||
|
||||
================================================================================
|
||||
|
||||
DATE: 2025-03-19 11:02:12
|
||||
DE: Delphine PILON
|
||||
OBJET: Erreur fatale essai VBS
|
||||
|
||||
Bonjour,
|
||||
Sur tous les essais VBS, j’ai le message d’erreur ci-dessous qui s’affiche.
|
||||
Pouvez-vous, s’il vous plait, résoudre le problème assez rapidement ?
|
||||
Mes clients attendent leurs résultats
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
********************************************************************************
|
||||
*** CHANGEMENT D'ÉTAT ***
|
||||
********************************************************************************
|
||||
|
||||
DATE: 2025-03-19 11:06:56
|
||||
DE: OdooBot
|
||||
|
||||
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
********************************************************************************
|
||||
*** MESSAGE TRANSFÉRÉ ***
|
||||
********************************************************************************
|
||||
|
||||
DATE: 2025-03-19 13:03:13
|
||||
DE: Romuald GRUSON
|
||||
OBJET: Re: [T11086] - Erreur fatale essai VBS
|
||||
|
||||
Bonjour
|
||||
,
|
||||
Nous avons déployé en urgence un patch ce midi pour corriger cette anomalie. Nous sommes désolés pour ce désagrément, une erreur de compilation des données s'est glissée dans le déploiement de notre mise à jour de cette nuit.
|
||||
Je reste à votre entière disposition pour toute information complémentaire.
|
||||
Cordialement,
|
||||
---
|
||||
Support technique
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
********************************************************************************
|
||||
*** CHANGEMENT D'ÉTAT ***
|
||||
********************************************************************************
|
||||
|
||||
DATE: 2025-03-19 13:04:19
|
||||
DE: Romuald GRUSON
|
||||
|
||||
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
********************************************************************************
|
||||
*** CHANGEMENT D'ÉTAT ***
|
||||
********************************************************************************
|
||||
|
||||
DATE: 2025-04-03 07:51:32
|
||||
DE: Romuald GRUSON
|
||||
|
||||
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
After Width: | Height: | Size: 126 KiB |
|
After Width: | Height: | Size: 280 KiB |
|
After Width: | Height: | Size: 126 KiB |
|
After Width: | Height: | Size: 280 KiB |
@ -0,0 +1,72 @@
|
||||
[
|
||||
{
|
||||
"id": 144867,
|
||||
"name": "image002.png",
|
||||
"mimetype": "image/png",
|
||||
"file_size": 286527,
|
||||
"create_date": "2025-03-19 11:06:53",
|
||||
"create_uid": [
|
||||
1,
|
||||
"OdooBot"
|
||||
],
|
||||
"description": "image002.png",
|
||||
"res_name": "[T11086] Erreur fatale essai VBS",
|
||||
"creator_name": "OdooBot",
|
||||
"creator_id": 1,
|
||||
"download_status": "success",
|
||||
"local_path": "output/ticket_T11086/T11086_20250416_151208/attachments/image002.png",
|
||||
"error": ""
|
||||
},
|
||||
{
|
||||
"id": 144865,
|
||||
"name": "image001.png",
|
||||
"mimetype": "image/png",
|
||||
"file_size": 129352,
|
||||
"create_date": "2025-03-19 11:06:53",
|
||||
"create_uid": [
|
||||
1,
|
||||
"OdooBot"
|
||||
],
|
||||
"description": "image001.png",
|
||||
"res_name": "[T11086] Erreur fatale essai VBS",
|
||||
"creator_name": "OdooBot",
|
||||
"creator_id": 1,
|
||||
"download_status": "success",
|
||||
"local_path": "output/ticket_T11086/T11086_20250416_151208/attachments/image001.png",
|
||||
"error": ""
|
||||
},
|
||||
{
|
||||
"id": "embedded_3",
|
||||
"name": "image_144867.png",
|
||||
"mimetype": "image/png",
|
||||
"file_size": "286527",
|
||||
"create_date": null,
|
||||
"creator_name": "Extraction automatique",
|
||||
"download_status": "success",
|
||||
"local_path": "output/ticket_T11086/T11086_20250416_151208/attachments/image_144867.png",
|
||||
"error": "",
|
||||
"is_embedded_image": true,
|
||||
"source_url": "https://odoo.cbao.fr/web/image/144867?access_token=79dd4392-8593-432c-b8ba-6bb833d67851",
|
||||
"source": "message_embedded",
|
||||
"extraction_date": "2025-04-16T15:12:08.858190",
|
||||
"source_message_id": "",
|
||||
"message_author": ""
|
||||
},
|
||||
{
|
||||
"id": "embedded_4",
|
||||
"name": "image_144865.png",
|
||||
"mimetype": "image/png",
|
||||
"file_size": "129352",
|
||||
"create_date": null,
|
||||
"creator_name": "Extraction automatique",
|
||||
"download_status": "success",
|
||||
"local_path": "output/ticket_T11086/T11086_20250416_151208/attachments/image_144865.png",
|
||||
"error": "",
|
||||
"is_embedded_image": true,
|
||||
"source_url": "https://odoo.cbao.fr/web/image/144865?access_token=833e3881-9c0d-41a6-8f95-0ff4edfbabe8",
|
||||
"source": "message_embedded",
|
||||
"extraction_date": "2025-04-16T15:12:09.018414",
|
||||
"source_message_id": "",
|
||||
"message_author": ""
|
||||
}
|
||||
]
|
||||
23
output/ticket_T11086/T11086_20250416_151208/followers.json
Normal file
@ -0,0 +1,23 @@
|
||||
[
|
||||
{
|
||||
"id": 89678,
|
||||
"partner_id": [
|
||||
28961,
|
||||
"Fabien LAFAY"
|
||||
]
|
||||
},
|
||||
{
|
||||
"id": 89680,
|
||||
"partner_id": [
|
||||
26137,
|
||||
"AXYLIS (GROUPE MINIER), Delphine PILON"
|
||||
]
|
||||
},
|
||||
{
|
||||
"id": 89681,
|
||||
"partner_id": [
|
||||
32165,
|
||||
"Romuald GRUSON"
|
||||
]
|
||||
}
|
||||
]
|
||||
243
output/ticket_T11086/T11086_20250416_151208/messages_raw.json
Normal file
20
output/ticket_T11086/T11086_20250416_151208/structure.json
Normal file
@ -0,0 +1,20 @@
|
||||
{
|
||||
"date_extraction": "2025-04-16T15:12:09.052708",
|
||||
"ticket_id": 11065,
|
||||
"ticket_code": "T11086",
|
||||
"ticket_name": "Erreur fatale essai VBS",
|
||||
"output_dir": "output/ticket_T11086/T11086_20250416_151208",
|
||||
"files": {
|
||||
"ticket_info": "ticket_info.json",
|
||||
"ticket_summary": "ticket_summary.json",
|
||||
"messages": "all_messages.json",
|
||||
"messages_raw": "messages_raw.json",
|
||||
"messages_text": "all_messages.txt",
|
||||
"attachments": "attachments_info.json",
|
||||
"followers": "followers.json"
|
||||
},
|
||||
"stats": {
|
||||
"messages_count": 5,
|
||||
"attachments_count": 4
|
||||
}
|
||||
}
|
||||
56
output/ticket_T11086/T11086_20250416_151208/ticket_info.json
Normal file
@ -0,0 +1,56 @@
|
||||
{
|
||||
"id": 11065,
|
||||
"name": "Erreur fatale essai VBS",
|
||||
"description": "<p><br></p>",
|
||||
"stage_id": [
|
||||
8,
|
||||
"Clôturé"
|
||||
],
|
||||
"project_id": [
|
||||
3,
|
||||
"Demandes"
|
||||
],
|
||||
"partner_id": [
|
||||
26137,
|
||||
"AXYLIS (GROUPE MINIER), Delphine PILON"
|
||||
],
|
||||
"user_id": [
|
||||
32,
|
||||
"Romuald GRUSON"
|
||||
],
|
||||
"date_start": "2025-03-19 11:06:56",
|
||||
"date_end": false,
|
||||
"date_deadline": "2025-04-03",
|
||||
"create_date": "2025-03-19 11:06:53",
|
||||
"write_date": "2025-04-03 07:51:32",
|
||||
"tag_ids": [
|
||||
15
|
||||
],
|
||||
"priority": "0",
|
||||
"email_from": "Delphine PILON <dpilon@axylis.com>",
|
||||
"email_cc": "",
|
||||
"message_ids": [
|
||||
228933,
|
||||
227918,
|
||||
227917,
|
||||
227916,
|
||||
227915,
|
||||
227909,
|
||||
227908,
|
||||
227907
|
||||
],
|
||||
"message_follower_ids": [
|
||||
89678,
|
||||
89680,
|
||||
89681
|
||||
],
|
||||
"timesheet_ids": [],
|
||||
"attachment_ids": [],
|
||||
"stage_id_name": "Clôturé",
|
||||
"project_id_name": "Demandes",
|
||||
"partner_id_name": "AXYLIS (GROUPE MINIER), Delphine PILON",
|
||||
"user_id_name": "Romuald GRUSON",
|
||||
"tag_names": [
|
||||
"BRG-LAB WEB"
|
||||
]
|
||||
}
|
||||
@ -0,0 +1,16 @@
|
||||
{
|
||||
"id": 11065,
|
||||
"code": "T11086",
|
||||
"name": "Erreur fatale essai VBS",
|
||||
"description": "<p><br></p>",
|
||||
"stage": "Clôturé",
|
||||
"project": "Demandes",
|
||||
"partner": "AXYLIS (GROUPE MINIER), Delphine PILON",
|
||||
"assigned_to": "Romuald GRUSON",
|
||||
"tags": [
|
||||
"BRG-LAB WEB"
|
||||
],
|
||||
"create_date": "2025-03-19 11:06:53",
|
||||
"write_date": "2025-04-03 07:51:32",
|
||||
"deadline": "2025-04-03"
|
||||
}
|
||||
@ -0,0 +1,34 @@
|
||||
{
|
||||
"id": "11066",
|
||||
"code": "T11087",
|
||||
"name": "erreur fatale essai aplatissement",
|
||||
"description": "*Contenu non extractible*",
|
||||
"project_name": "Demandes",
|
||||
"stage_name": "Clôturé",
|
||||
"user_id": "",
|
||||
"partner_id_email_from": "AXYLIS (GROUPE MINIER), Delphine PILON, Delphine PILON <dpilon@axylis.com>",
|
||||
"create_date": "19/03/2025 11:37:08",
|
||||
"write_date_last_modification": "03/04/2025 07:51:38",
|
||||
"date_deadline": "03/04/2025 00:00:00",
|
||||
"messages": [
|
||||
{
|
||||
"author_id": "Delphine PILON",
|
||||
"date": "19/03/2025 11:33:40",
|
||||
"message_type": "E-mail",
|
||||
"subject": "erreur fatale essai aplatissement",
|
||||
"id": "227911",
|
||||
"content": "Rebonjour,\nJ’ai également une erreur fatale sur l’essai aplatissement.\nPouvez-vous, s’il vous plait, debugger l’ensemble des essais bloqués\nMerci\nBien cordialement\n\n- image001.png (image/png) [ID: 144870]\n\n---\n\n"
|
||||
},
|
||||
{
|
||||
"author_id": "Romuald GRUSON",
|
||||
"date": "19/03/2025 13:10:56",
|
||||
"message_type": "E-mail",
|
||||
"subject": "Re: [T11087] - erreur fatale essai aplatissement",
|
||||
"id": "227926",
|
||||
"content": "Bonjour\n,\nNous avons déployé un patch ce midi pour corriger cette anomalie. Nous sommes désolés pour ce désagrément, une erreur de compilation des données s'est glissée dans le déploiement de notre mise à jour de cette nuit.\nJe reste à votre entière disposition pour toute information complémentaire.\nCordialement,\n---\nSupport technique\n\n---\n"
|
||||
}
|
||||
],
|
||||
"date_d'extraction": "16/04/2025 15:12:11",
|
||||
"répertoire": "output/ticket_T11087/T11087_20250416_151207",
|
||||
"messages_raw_reference": "output/ticket_T11087/T11087_20250416_151207/messages_raw.json"
|
||||
}
|
||||
@ -0,0 +1,58 @@
|
||||
# Ticket T11087: erreur fatale essai aplatissement
|
||||
|
||||
## Informations du ticket
|
||||
|
||||
- **id**: 11066
|
||||
- **code**: T11087
|
||||
- **name**: erreur fatale essai aplatissement
|
||||
- **project_name**: Demandes
|
||||
- **stage_name**: Clôturé
|
||||
- **user_id**:
|
||||
- **partner_id/email_from**: AXYLIS (GROUPE MINIER), Delphine PILON, Delphine PILON <dpilon@axylis.com>
|
||||
- **create_date**: 19/03/2025 11:37:08
|
||||
- **write_date/last modification**: 03/04/2025 07:51:38
|
||||
- **date_deadline**: 03/04/2025 00:00:00
|
||||
|
||||
- **description**:
|
||||
|
||||
*Contenu non extractible*
|
||||
|
||||
## Messages
|
||||
|
||||
### Message 1
|
||||
**author_id**: Delphine PILON
|
||||
**date**: 19/03/2025 11:33:40
|
||||
**message_type**: E-mail
|
||||
**subject**: erreur fatale essai aplatissement
|
||||
**id**: 227911
|
||||
Rebonjour,
|
||||
J’ai également une erreur fatale sur l’essai aplatissement.
|
||||
Pouvez-vous, s’il vous plait, debugger l’ensemble des essais bloqués
|
||||
Merci
|
||||
Bien cordialement
|
||||
|
||||
**attachment_ids**:
|
||||
- image001.png (image/png) [ID: 144870]
|
||||
|
||||
---
|
||||
|
||||
### Message 2
|
||||
**author_id**: Romuald GRUSON
|
||||
**date**: 19/03/2025 13:10:56
|
||||
**message_type**: E-mail
|
||||
**subject**: Re: [T11087] - erreur fatale essai aplatissement
|
||||
**id**: 227926
|
||||
Bonjour
|
||||
,
|
||||
Nous avons déployé un patch ce midi pour corriger cette anomalie. Nous sommes désolés pour ce désagrément, une erreur de compilation des données s'est glissée dans le déploiement de notre mise à jour de cette nuit.
|
||||
Je reste à votre entière disposition pour toute information complémentaire.
|
||||
Cordialement,
|
||||
---
|
||||
Support technique
|
||||
|
||||
---
|
||||
|
||||
## Informations sur l'extraction
|
||||
|
||||
- **Date d'extraction**: 16/04/2025 15:12:11
|
||||
- **Répertoire**: output/ticket_T11087/T11087_20250416_151207
|
||||
230
output/ticket_T11087/T11087_20250416_151207/all_messages.json
Normal file
68
output/ticket_T11087/T11087_20250416_151207/all_messages.txt
Normal file
@ -0,0 +1,68 @@
|
||||
TICKET: T11087 - erreur fatale essai aplatissement
|
||||
Date d'extraction: 2025-04-16 15:12:07
|
||||
Nombre de messages: 5
|
||||
|
||||
================================================================================
|
||||
|
||||
DATE: 2025-03-19 11:33:40
|
||||
DE: Delphine PILON
|
||||
OBJET: erreur fatale essai aplatissement
|
||||
|
||||
Rebonjour,
|
||||
J’ai également une erreur fatale sur l’essai aplatissement.
|
||||
Pouvez-vous, s’il vous plait, debugger l’ensemble des essais bloqués
|
||||
Merci
|
||||
Bien cordialement
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
********************************************************************************
|
||||
*** CHANGEMENT D'ÉTAT ***
|
||||
********************************************************************************
|
||||
|
||||
DATE: 2025-03-19 11:37:10
|
||||
DE: OdooBot
|
||||
|
||||
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
********************************************************************************
|
||||
*** MESSAGE TRANSFÉRÉ ***
|
||||
********************************************************************************
|
||||
|
||||
DATE: 2025-03-19 13:10:56
|
||||
DE: Romuald GRUSON
|
||||
OBJET: Re: [T11087] - erreur fatale essai aplatissement
|
||||
|
||||
Bonjour
|
||||
,
|
||||
Nous avons déployé un patch ce midi pour corriger cette anomalie. Nous sommes désolés pour ce désagrément, une erreur de compilation des données s'est glissée dans le déploiement de notre mise à jour de cette nuit.
|
||||
Je reste à votre entière disposition pour toute information complémentaire.
|
||||
Cordialement,
|
||||
---
|
||||
Support technique
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
********************************************************************************
|
||||
*** CHANGEMENT D'ÉTAT ***
|
||||
********************************************************************************
|
||||
|
||||
DATE: 2025-03-19 13:11:24
|
||||
DE: Romuald GRUSON
|
||||
|
||||
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
********************************************************************************
|
||||
*** CHANGEMENT D'ÉTAT ***
|
||||
********************************************************************************
|
||||
|
||||
DATE: 2025-04-03 07:51:38
|
||||
DE: Romuald GRUSON
|
||||
|
||||
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
After Width: | Height: | Size: 280 KiB |
|
After Width: | Height: | Size: 280 KiB |
@ -0,0 +1,37 @@
|
||||
[
|
||||
{
|
||||
"id": 144870,
|
||||
"name": "image001.png",
|
||||
"mimetype": "image/png",
|
||||
"file_size": 286527,
|
||||
"create_date": "2025-03-19 11:37:08",
|
||||
"create_uid": [
|
||||
1,
|
||||
"OdooBot"
|
||||
],
|
||||
"description": "image001.png",
|
||||
"res_name": "[T11087] erreur fatale essai aplatissement",
|
||||
"creator_name": "OdooBot",
|
||||
"creator_id": 1,
|
||||
"download_status": "success",
|
||||
"local_path": "output/ticket_T11087/T11087_20250416_151207/attachments/image001.png",
|
||||
"error": ""
|
||||
},
|
||||
{
|
||||
"id": "embedded_2",
|
||||
"name": "image_144870.png",
|
||||
"mimetype": "image/png",
|
||||
"file_size": "286527",
|
||||
"create_date": null,
|
||||
"creator_name": "Extraction automatique",
|
||||
"download_status": "success",
|
||||
"local_path": "output/ticket_T11087/T11087_20250416_151207/attachments/image_144870.png",
|
||||
"error": "",
|
||||
"is_embedded_image": true,
|
||||
"source_url": "https://odoo.cbao.fr/web/image/144870?access_token=e93edd3a-9ebe-41ce-b525-c734d0e7864d",
|
||||
"source": "message_embedded",
|
||||
"extraction_date": "2025-04-16T15:12:07.968565",
|
||||
"source_message_id": "",
|
||||
"message_author": ""
|
||||
}
|
||||
]
|
||||
23
output/ticket_T11087/T11087_20250416_151207/followers.json
Normal file
@ -0,0 +1,23 @@
|
||||
[
|
||||
{
|
||||
"id": 89679,
|
||||
"partner_id": [
|
||||
28961,
|
||||
"Fabien LAFAY"
|
||||
]
|
||||
},
|
||||
{
|
||||
"id": 89685,
|
||||
"partner_id": [
|
||||
26137,
|
||||
"AXYLIS (GROUPE MINIER), Delphine PILON"
|
||||
]
|
||||
},
|
||||
{
|
||||
"id": 89686,
|
||||
"partner_id": [
|
||||
32165,
|
||||
"Romuald GRUSON"
|
||||
]
|
||||
}
|
||||
]
|
||||
242
output/ticket_T11087/T11087_20250416_151207/messages_raw.json
Normal file
20
output/ticket_T11087/T11087_20250416_151207/structure.json
Normal file
@ -0,0 +1,20 @@
|
||||
{
|
||||
"date_extraction": "2025-04-16T15:12:08.003333",
|
||||
"ticket_id": 11066,
|
||||
"ticket_code": "T11087",
|
||||
"ticket_name": "erreur fatale essai aplatissement",
|
||||
"output_dir": "output/ticket_T11087/T11087_20250416_151207",
|
||||
"files": {
|
||||
"ticket_info": "ticket_info.json",
|
||||
"ticket_summary": "ticket_summary.json",
|
||||
"messages": "all_messages.json",
|
||||
"messages_raw": "messages_raw.json",
|
||||
"messages_text": "all_messages.txt",
|
||||
"attachments": "attachments_info.json",
|
||||
"followers": "followers.json"
|
||||
},
|
||||
"stats": {
|
||||
"messages_count": 5,
|
||||
"attachments_count": 2
|
||||
}
|
||||
}
|
||||
56
output/ticket_T11087/T11087_20250416_151207/ticket_info.json
Normal file
@ -0,0 +1,56 @@
|
||||
{
|
||||
"id": 11066,
|
||||
"name": "erreur fatale essai aplatissement",
|
||||
"description": "<p><br></p>",
|
||||
"stage_id": [
|
||||
8,
|
||||
"Clôturé"
|
||||
],
|
||||
"project_id": [
|
||||
3,
|
||||
"Demandes"
|
||||
],
|
||||
"partner_id": [
|
||||
26137,
|
||||
"AXYLIS (GROUPE MINIER), Delphine PILON"
|
||||
],
|
||||
"user_id": [
|
||||
32,
|
||||
"Romuald GRUSON"
|
||||
],
|
||||
"date_start": "2025-03-19 11:37:09",
|
||||
"date_end": false,
|
||||
"date_deadline": "2025-04-03",
|
||||
"create_date": "2025-03-19 11:37:08",
|
||||
"write_date": "2025-04-03 07:51:38",
|
||||
"tag_ids": [
|
||||
15
|
||||
],
|
||||
"priority": "0",
|
||||
"email_from": "Delphine PILON <dpilon@axylis.com>",
|
||||
"email_cc": "",
|
||||
"message_ids": [
|
||||
228934,
|
||||
227929,
|
||||
227928,
|
||||
227927,
|
||||
227926,
|
||||
227912,
|
||||
227911,
|
||||
227910
|
||||
],
|
||||
"message_follower_ids": [
|
||||
89679,
|
||||
89685,
|
||||
89686
|
||||
],
|
||||
"timesheet_ids": [],
|
||||
"attachment_ids": [],
|
||||
"stage_id_name": "Clôturé",
|
||||
"project_id_name": "Demandes",
|
||||
"partner_id_name": "AXYLIS (GROUPE MINIER), Delphine PILON",
|
||||
"user_id_name": "Romuald GRUSON",
|
||||
"tag_names": [
|
||||
"BRG-LAB WEB"
|
||||
]
|
||||
}
|
||||
@ -0,0 +1,16 @@
|
||||
{
|
||||
"id": 11066,
|
||||
"code": "T11087",
|
||||
"name": "erreur fatale essai aplatissement",
|
||||
"description": "<p><br></p>",
|
||||
"stage": "Clôturé",
|
||||
"project": "Demandes",
|
||||
"partner": "AXYLIS (GROUPE MINIER), Delphine PILON",
|
||||
"assigned_to": "Romuald GRUSON",
|
||||
"tags": [
|
||||
"BRG-LAB WEB"
|
||||
],
|
||||
"create_date": "2025-03-19 11:37:08",
|
||||
"write_date": "2025-04-03 07:51:38",
|
||||
"deadline": "2025-04-03"
|
||||
}
|
||||
@ -0,0 +1,34 @@
|
||||
{
|
||||
"id": "11067",
|
||||
"code": "T11088",
|
||||
"name": "BUG mise à jour",
|
||||
"description": "*Contenu non extractible*",
|
||||
"project_name": "Demandes",
|
||||
"stage_name": "Clôturé",
|
||||
"user_id": "",
|
||||
"partner_id_email_from": "CONSEIL DEPARTEMENTAL DU MORBIHAN (56), Dominique CARVAL, CARVAL Dominique <dominique.carval@morbihan.fr>",
|
||||
"create_date": "19/03/2025 13:21:47",
|
||||
"write_date_last_modification": "03/04/2025 07:51:44",
|
||||
"date_deadline": "03/04/2025 00:00:00",
|
||||
"messages": [
|
||||
{
|
||||
"author_id": "Dominique CARVAL",
|
||||
"date": "19/03/2025 13:20:33",
|
||||
"message_type": "E-mail",
|
||||
"subject": "BUG mise à jour",
|
||||
"id": "227965",
|
||||
"content": "*Message transféré - contenu non extractible*\n\n- image002.png (image/png) [ID: 144875]\n- image001.png (image/png) [ID: 144873]\n\n---\n\n"
|
||||
},
|
||||
{
|
||||
"author_id": "Romuald GRUSON",
|
||||
"date": "19/03/2025 13:49:59",
|
||||
"message_type": "E-mail",
|
||||
"subject": "Re: [T11088] - BUG mise à jour",
|
||||
"id": "227984",
|
||||
"content": "Bonjour\n,\nNous avons relancé la mise à jour sur votre plateforme BRG-LAB, celle ci sera disponible dans quelques instants.\nJe reste à votre entière disposition pour toute information complémentaire.\nCordialement,\n---\nSupport technique\n\n---\n"
|
||||
}
|
||||
],
|
||||
"date_d'extraction": "16/04/2025 15:12:11",
|
||||
"répertoire": "output/ticket_T11088/T11088_20250416_151205",
|
||||
"messages_raw_reference": "output/ticket_T11088/T11088_20250416_151205/messages_raw.json"
|
||||
}
|
||||
@ -0,0 +1,55 @@
|
||||
# Ticket T11088: BUG mise à jour
|
||||
|
||||
## Informations du ticket
|
||||
|
||||
- **id**: 11067
|
||||
- **code**: T11088
|
||||
- **name**: BUG mise à jour
|
||||
- **project_name**: Demandes
|
||||
- **stage_name**: Clôturé
|
||||
- **user_id**:
|
||||
- **partner_id/email_from**: CONSEIL DEPARTEMENTAL DU MORBIHAN (56), Dominique CARVAL, CARVAL Dominique <dominique.carval@morbihan.fr>
|
||||
- **create_date**: 19/03/2025 13:21:47
|
||||
- **write_date/last modification**: 03/04/2025 07:51:44
|
||||
- **date_deadline**: 03/04/2025 00:00:00
|
||||
|
||||
- **description**:
|
||||
|
||||
*Contenu non extractible*
|
||||
|
||||
## Messages
|
||||
|
||||
### Message 1
|
||||
**author_id**: Dominique CARVAL
|
||||
**date**: 19/03/2025 13:20:33
|
||||
**message_type**: E-mail
|
||||
**subject**: BUG mise à jour
|
||||
**id**: 227965
|
||||
*Message transféré - contenu non extractible*
|
||||
|
||||
**attachment_ids**:
|
||||
- image002.png (image/png) [ID: 144875]
|
||||
- image001.png (image/png) [ID: 144873]
|
||||
|
||||
---
|
||||
|
||||
### Message 2
|
||||
**author_id**: Romuald GRUSON
|
||||
**date**: 19/03/2025 13:49:59
|
||||
**message_type**: E-mail
|
||||
**subject**: Re: [T11088] - BUG mise à jour
|
||||
**id**: 227984
|
||||
Bonjour
|
||||
,
|
||||
Nous avons relancé la mise à jour sur votre plateforme BRG-LAB, celle ci sera disponible dans quelques instants.
|
||||
Je reste à votre entière disposition pour toute information complémentaire.
|
||||
Cordialement,
|
||||
---
|
||||
Support technique
|
||||
|
||||
---
|
||||
|
||||
## Informations sur l'extraction
|
||||
|
||||
- **Date d'extraction**: 16/04/2025 15:12:11
|
||||
- **Répertoire**: output/ticket_T11088/T11088_20250416_151205
|
||||
231
output/ticket_T11088/T11088_20250416_151205/all_messages.json
Normal file
68
output/ticket_T11088/T11088_20250416_151205/all_messages.txt
Normal file
@ -0,0 +1,68 @@
|
||||
TICKET: T11088 - BUG mise à jour
|
||||
Date d'extraction: 2025-04-16 15:12:06
|
||||
Nombre de messages: 5
|
||||
|
||||
================================================================================
|
||||
|
||||
********************************************************************************
|
||||
*** MESSAGE TRANSFÉRÉ ***
|
||||
********************************************************************************
|
||||
|
||||
DATE: 2025-03-19 13:20:33
|
||||
DE: Dominique CARVAL
|
||||
OBJET: BUG mise à jour
|
||||
|
||||
*Message transféré - contenu non extractible*
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
********************************************************************************
|
||||
*** CHANGEMENT D'ÉTAT ***
|
||||
********************************************************************************
|
||||
|
||||
DATE: 2025-03-19 13:21:49
|
||||
DE: OdooBot
|
||||
|
||||
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
********************************************************************************
|
||||
*** MESSAGE TRANSFÉRÉ ***
|
||||
********************************************************************************
|
||||
|
||||
DATE: 2025-03-19 13:49:59
|
||||
DE: Romuald GRUSON
|
||||
OBJET: Re: [T11088] - BUG mise à jour
|
||||
|
||||
Bonjour
|
||||
,
|
||||
Nous avons relancé la mise à jour sur votre plateforme BRG-LAB, celle ci sera disponible dans quelques instants.
|
||||
Je reste à votre entière disposition pour toute information complémentaire.
|
||||
Cordialement,
|
||||
---
|
||||
Support technique
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
********************************************************************************
|
||||
*** CHANGEMENT D'ÉTAT ***
|
||||
********************************************************************************
|
||||
|
||||
DATE: 2025-03-19 13:50:01
|
||||
DE: Romuald GRUSON
|
||||
|
||||
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
********************************************************************************
|
||||
*** CHANGEMENT D'ÉTAT ***
|
||||
********************************************************************************
|
||||
|
||||
DATE: 2025-04-03 07:51:44
|
||||
DE: Romuald GRUSON
|
||||
|
||||
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
After Width: | Height: | Size: 911 KiB |
|
After Width: | Height: | Size: 5.3 KiB |
|
After Width: | Height: | Size: 911 KiB |
|
After Width: | Height: | Size: 5.3 KiB |
@ -0,0 +1,72 @@
|
||||
[
|
||||
{
|
||||
"id": 144875,
|
||||
"name": "image002.png",
|
||||
"mimetype": "image/png",
|
||||
"file_size": 5417,
|
||||
"create_date": "2025-03-19 13:21:47",
|
||||
"create_uid": [
|
||||
1,
|
||||
"OdooBot"
|
||||
],
|
||||
"description": "image002.png",
|
||||
"res_name": "[T11088] BUG mise à jour",
|
||||
"creator_name": "OdooBot",
|
||||
"creator_id": 1,
|
||||
"download_status": "success",
|
||||
"local_path": "output/ticket_T11088/T11088_20250416_151205/attachments/image002.png",
|
||||
"error": ""
|
||||
},
|
||||
{
|
||||
"id": 144873,
|
||||
"name": "image001.png",
|
||||
"mimetype": "image/png",
|
||||
"file_size": 932420,
|
||||
"create_date": "2025-03-19 13:21:47",
|
||||
"create_uid": [
|
||||
1,
|
||||
"OdooBot"
|
||||
],
|
||||
"description": "image001.png",
|
||||
"res_name": "[T11088] BUG mise à jour",
|
||||
"creator_name": "OdooBot",
|
||||
"creator_id": 1,
|
||||
"download_status": "success",
|
||||
"local_path": "output/ticket_T11088/T11088_20250416_151205/attachments/image001.png",
|
||||
"error": ""
|
||||
},
|
||||
{
|
||||
"id": "embedded_3",
|
||||
"name": "image_144875.png",
|
||||
"mimetype": "image/png",
|
||||
"file_size": "5417",
|
||||
"create_date": null,
|
||||
"creator_name": "Extraction automatique",
|
||||
"download_status": "success",
|
||||
"local_path": "output/ticket_T11088/T11088_20250416_151205/attachments/image_144875.png",
|
||||
"error": "",
|
||||
"is_embedded_image": true,
|
||||
"source_url": "https://odoo.cbao.fr/web/image/144875?access_token=5c43b30e-d037-4c34-8389-12293cf95f29",
|
||||
"source": "message_embedded",
|
||||
"extraction_date": "2025-04-16T15:12:06.841605",
|
||||
"source_message_id": "",
|
||||
"message_author": ""
|
||||
},
|
||||
{
|
||||
"id": "embedded_4",
|
||||
"name": "image_144873.png",
|
||||
"mimetype": "image/png",
|
||||
"file_size": "932420",
|
||||
"create_date": null,
|
||||
"creator_name": "Extraction automatique",
|
||||
"download_status": "success",
|
||||
"local_path": "output/ticket_T11088/T11088_20250416_151205/attachments/image_144873.png",
|
||||
"error": "",
|
||||
"is_embedded_image": true,
|
||||
"source_url": "https://odoo.cbao.fr/web/image/144873?access_token=fb4b0cad-765e-4755-af83-b096dd46d172",
|
||||
"source": "message_embedded",
|
||||
"extraction_date": "2025-04-16T15:12:07.078268",
|
||||
"source_message_id": "",
|
||||
"message_author": ""
|
||||
}
|
||||
]
|
||||
23
output/ticket_T11088/T11088_20250416_151205/followers.json
Normal file
@ -0,0 +1,23 @@
|
||||
[
|
||||
{
|
||||
"id": 89691,
|
||||
"partner_id": [
|
||||
28961,
|
||||
"Fabien LAFAY"
|
||||
]
|
||||
},
|
||||
{
|
||||
"id": 89693,
|
||||
"partner_id": [
|
||||
5144,
|
||||
"CONSEIL DEPARTEMENTAL DU MORBIHAN (56), Dominique CARVAL"
|
||||
]
|
||||
},
|
||||
{
|
||||
"id": 89694,
|
||||
"partner_id": [
|
||||
32165,
|
||||
"Romuald GRUSON"
|
||||
]
|
||||
}
|
||||
]
|
||||
243
output/ticket_T11088/T11088_20250416_151205/messages_raw.json
Normal file
20
output/ticket_T11088/T11088_20250416_151205/structure.json
Normal file
@ -0,0 +1,20 @@
|
||||
{
|
||||
"date_extraction": "2025-04-16T15:12:07.110465",
|
||||
"ticket_id": 11067,
|
||||
"ticket_code": "T11088",
|
||||
"ticket_name": "BUG mise à jour",
|
||||
"output_dir": "output/ticket_T11088/T11088_20250416_151205",
|
||||
"files": {
|
||||
"ticket_info": "ticket_info.json",
|
||||
"ticket_summary": "ticket_summary.json",
|
||||
"messages": "all_messages.json",
|
||||
"messages_raw": "messages_raw.json",
|
||||
"messages_text": "all_messages.txt",
|
||||
"attachments": "attachments_info.json",
|
||||
"followers": "followers.json"
|
||||
},
|
||||
"stats": {
|
||||
"messages_count": 5,
|
||||
"attachments_count": 4
|
||||
}
|
||||
}
|
||||
56
output/ticket_T11088/T11088_20250416_151205/ticket_info.json
Normal file
@ -0,0 +1,56 @@
|
||||
{
|
||||
"id": 11067,
|
||||
"name": "BUG mise à jour",
|
||||
"description": "<p><br></p>",
|
||||
"stage_id": [
|
||||
8,
|
||||
"Clôturé"
|
||||
],
|
||||
"project_id": [
|
||||
3,
|
||||
"Demandes"
|
||||
],
|
||||
"partner_id": [
|
||||
5144,
|
||||
"CONSEIL DEPARTEMENTAL DU MORBIHAN (56), Dominique CARVAL"
|
||||
],
|
||||
"user_id": [
|
||||
32,
|
||||
"Romuald GRUSON"
|
||||
],
|
||||
"date_start": "2025-03-19 13:21:49",
|
||||
"date_end": false,
|
||||
"date_deadline": "2025-04-03",
|
||||
"create_date": "2025-03-19 13:21:47",
|
||||
"write_date": "2025-04-03 07:51:44",
|
||||
"tag_ids": [
|
||||
15
|
||||
],
|
||||
"priority": "0",
|
||||
"email_from": "CARVAL Dominique <dominique.carval@morbihan.fr>",
|
||||
"email_cc": "",
|
||||
"message_ids": [
|
||||
228935,
|
||||
227996,
|
||||
227986,
|
||||
227985,
|
||||
227984,
|
||||
227966,
|
||||
227965,
|
||||
227964
|
||||
],
|
||||
"message_follower_ids": [
|
||||
89691,
|
||||
89693,
|
||||
89694
|
||||
],
|
||||
"timesheet_ids": [],
|
||||
"attachment_ids": [],
|
||||
"stage_id_name": "Clôturé",
|
||||
"project_id_name": "Demandes",
|
||||
"partner_id_name": "CONSEIL DEPARTEMENTAL DU MORBIHAN (56), Dominique CARVAL",
|
||||
"user_id_name": "Romuald GRUSON",
|
||||
"tag_names": [
|
||||
"BRG-LAB WEB"
|
||||
]
|
||||
}
|
||||
@ -0,0 +1,16 @@
|
||||
{
|
||||
"id": 11067,
|
||||
"code": "T11088",
|
||||
"name": "BUG mise à jour",
|
||||
"description": "<p><br></p>",
|
||||
"stage": "Clôturé",
|
||||
"project": "Demandes",
|
||||
"partner": "CONSEIL DEPARTEMENTAL DU MORBIHAN (56), Dominique CARVAL",
|
||||
"assigned_to": "Romuald GRUSON",
|
||||
"tags": [
|
||||
"BRG-LAB WEB"
|
||||
],
|
||||
"create_date": "2025-03-19 13:21:47",
|
||||
"write_date": "2025-04-03 07:51:44",
|
||||
"deadline": "2025-04-03"
|
||||
}
|
||||
@ -0,0 +1,57 @@
|
||||
{
|
||||
"id": "11068",
|
||||
"code": "T11089",
|
||||
"name": "Problème création feuille paillasse béton",
|
||||
"description": "*Contenu non extractible*",
|
||||
"project_name": "Demandes",
|
||||
"stage_name": "Clôturé",
|
||||
"user_id": "",
|
||||
"partner_id_email_from": "CONSEIL DEPARTEMENTAL DE LA SARTHE (72), Contact Laboratoire routier, Contact Laboratoire Routier <laboratoire.routier@sarthe.fr>",
|
||||
"create_date": "19/03/2025 15:06:44",
|
||||
"write_date_last_modification": "04/04/2025 08:06:34",
|
||||
"date_deadline": "04/04/2025 00:00:00",
|
||||
"messages": [
|
||||
{
|
||||
"author_id": "Contact Laboratoire routier",
|
||||
"date": "19/03/2025 15:02:29",
|
||||
"message_type": "E-mail",
|
||||
"subject": "Problème création feuille paillasse béton",
|
||||
"id": "228002",
|
||||
"content": "Bonjour,\nJe rencontre un problème pour créer des échantillons d'éprouvettes béton, ci-joint capture d'écran.\nJ'en ai déjà créé 3 depuis ce matin, sans souci et là, une fois de plus, un beug alors que par défaut c'est BRG LAB qui nous impose ses numéros en suite logique.\nje suis donc bloquée et je ne peux plus travailler.\nMerci de faire le nécessaire rapidement.\ncordialement\nPeggy BRIERE\nLaborantin routier\nDépartement de la Sarthe\n\n- création eprouvette béton.PNG (image/png) [ID: 144880]\n\n---\n\n"
|
||||
},
|
||||
{
|
||||
"author_id": "Romuald GRUSON",
|
||||
"date": "19/03/2025 15:36:17",
|
||||
"message_type": "E-mail",
|
||||
"subject": "Re: [T11089] - Problème création feuille paillasse béton",
|
||||
"id": "228005",
|
||||
"content": "Bonjour\n,\nNous constatons bien le dysfonctionnement d'incrémentation sur votre prochain échantillon de béton. Pour y remédier, vous pouvez renseigner manuellement le prélèvement indiqué +1. Après cette action, le dysfonctionnement sera résolu et la numérotation s’incrémente correctement.\nJe reste à votre entière disposition pour toute information complémentaire.\nCordialement,\n---\nSupport technique\n\n---\n\n"
|
||||
},
|
||||
{
|
||||
"author_id": "Contact Laboratoire routier",
|
||||
"date": "20/03/2025 06:55:41",
|
||||
"message_type": "E-mail",
|
||||
"subject": "RE: [T11089] - Problème création feuille paillasse béton",
|
||||
"id": "228011",
|
||||
"content": "Bonjour,\nCela ne fonctionne toujours pas même après votre manip.\nMerci de faire le nécessaire car nous sommes toujours bloqué !!!!!\ncordialement\nPeggy BRIERE\nLaborantin routier\nDépartement de la Sarthe\n\n---\n\n"
|
||||
},
|
||||
{
|
||||
"author_id": "Romuald GRUSON",
|
||||
"date": "20/03/2025 08:10:58",
|
||||
"message_type": "Système",
|
||||
"id": "228032",
|
||||
"content": "20/03/2025 09:10 Plusieurs appels non répondu\n\n---\n\n"
|
||||
},
|
||||
{
|
||||
"author_id": "Romuald GRUSON",
|
||||
"date": "20/03/2025 08:17:59",
|
||||
"message_type": "E-mail",
|
||||
"subject": "Re: [T11089] - Problème création feuille paillasse béton",
|
||||
"id": "228033",
|
||||
"content": "Bonjour\n,\nLe dysfonctionnement survient lorsqu'un échantillon a été réalisé sur l'année précédente au prélèvement.\nLa solution la plus simple est de renseigner la numérotation manuellement à l’étape correspondante. Je vous ai joint une capture d’écran : à la place de\n0032\n, vous pouvez saisir\n0033\n.\nPour tout nouvel échantillon créé cette année, vous ne rencontrerez plus de problème. En revanche, pour les échantillons de l’année précédente, une saisie manuelle restera nécessaire.\nJe reste disponible pour toute discussion téléphonique. N’hésitez pas à me communiquer un numéro et un créneau pour vous joindre.\nJe reste à votre entière disposition pour toute information complémentaire.\nCordialement,\n---\nSupport technique\n\n- image.png (image/png) [ID: 144893]\n\n---\n"
|
||||
}
|
||||
],
|
||||
"date_d'extraction": "16/04/2025 15:12:11",
|
||||
"répertoire": "output/ticket_T11089/T11089_20250416_151202",
|
||||
"messages_raw_reference": "output/ticket_T11089/T11089_20250416_151202/messages_raw.json"
|
||||
}
|
||||
@ -0,0 +1,113 @@
|
||||
# Ticket T11089: Problème création feuille paillasse béton
|
||||
|
||||
## Informations du ticket
|
||||
|
||||
- **id**: 11068
|
||||
- **code**: T11089
|
||||
- **name**: Problème création feuille paillasse béton
|
||||
- **project_name**: Demandes
|
||||
- **stage_name**: Clôturé
|
||||
- **user_id**:
|
||||
- **partner_id/email_from**: CONSEIL DEPARTEMENTAL DE LA SARTHE (72), Contact Laboratoire routier, Contact Laboratoire Routier <laboratoire.routier@sarthe.fr>
|
||||
- **create_date**: 19/03/2025 15:06:44
|
||||
- **write_date/last modification**: 04/04/2025 08:06:34
|
||||
- **date_deadline**: 04/04/2025 00:00:00
|
||||
|
||||
- **description**:
|
||||
|
||||
*Contenu non extractible*
|
||||
|
||||
## Messages
|
||||
|
||||
### Message 1
|
||||
**author_id**: Contact Laboratoire routier
|
||||
**date**: 19/03/2025 15:02:29
|
||||
**message_type**: E-mail
|
||||
**subject**: Problème création feuille paillasse béton
|
||||
**id**: 228002
|
||||
Bonjour,
|
||||
Je rencontre un problème pour créer des échantillons d'éprouvettes béton, ci-joint capture d'écran.
|
||||
J'en ai déjà créé 3 depuis ce matin, sans souci et là, une fois de plus, un beug alors que par défaut c'est BRG LAB qui nous impose ses numéros en suite logique.
|
||||
je suis donc bloquée et je ne peux plus travailler.
|
||||
Merci de faire le nécessaire rapidement.
|
||||
cordialement
|
||||
Peggy BRIERE
|
||||
Laborantin routier
|
||||
Département de la Sarthe
|
||||
|
||||
**attachment_ids**:
|
||||
- création eprouvette béton.PNG (image/png) [ID: 144880]
|
||||
|
||||
---
|
||||
|
||||
### Message 2
|
||||
**author_id**: Romuald GRUSON
|
||||
**date**: 19/03/2025 15:36:17
|
||||
**message_type**: E-mail
|
||||
**subject**: Re: [T11089] - Problème création feuille paillasse béton
|
||||
**id**: 228005
|
||||
Bonjour
|
||||
,
|
||||
Nous constatons bien le dysfonctionnement d'incrémentation sur votre prochain échantillon de béton. Pour y remédier, vous pouvez renseigner manuellement le prélèvement indiqué +1. Après cette action, le dysfonctionnement sera résolu et la numérotation s’incrémente correctement.
|
||||
Je reste à votre entière disposition pour toute information complémentaire.
|
||||
Cordialement,
|
||||
---
|
||||
Support technique
|
||||
|
||||
---
|
||||
|
||||
### Message 3
|
||||
**author_id**: Contact Laboratoire routier
|
||||
**date**: 20/03/2025 06:55:41
|
||||
**message_type**: E-mail
|
||||
**subject**: RE: [T11089] - Problème création feuille paillasse béton
|
||||
**id**: 228011
|
||||
Bonjour,
|
||||
Cela ne fonctionne toujours pas même après votre manip.
|
||||
Merci de faire le nécessaire car nous sommes toujours bloqué !!!!!
|
||||
cordialement
|
||||
Peggy BRIERE
|
||||
Laborantin routier
|
||||
Département de la Sarthe
|
||||
|
||||
---
|
||||
|
||||
### Message 4
|
||||
**author_id**: Romuald GRUSON
|
||||
**date**: 20/03/2025 08:10:58
|
||||
**message_type**: Système
|
||||
**id**: 228032
|
||||
20/03/2025 09:10 Plusieurs appels non répondu
|
||||
|
||||
---
|
||||
|
||||
### Message 5
|
||||
**author_id**: Romuald GRUSON
|
||||
**date**: 20/03/2025 08:17:59
|
||||
**message_type**: E-mail
|
||||
**subject**: Re: [T11089] - Problème création feuille paillasse béton
|
||||
**id**: 228033
|
||||
Bonjour
|
||||
,
|
||||
Le dysfonctionnement survient lorsqu'un échantillon a été réalisé sur l'année précédente au prélèvement.
|
||||
La solution la plus simple est de renseigner la numérotation manuellement à l’étape correspondante. Je vous ai joint une capture d’écran : à la place de
|
||||
0032
|
||||
, vous pouvez saisir
|
||||
0033
|
||||
.
|
||||
Pour tout nouvel échantillon créé cette année, vous ne rencontrerez plus de problème. En revanche, pour les échantillons de l’année précédente, une saisie manuelle restera nécessaire.
|
||||
Je reste disponible pour toute discussion téléphonique. N’hésitez pas à me communiquer un numéro et un créneau pour vous joindre.
|
||||
Je reste à votre entière disposition pour toute information complémentaire.
|
||||
Cordialement,
|
||||
---
|
||||
Support technique
|
||||
|
||||
**attachment_ids**:
|
||||
- image.png (image/png) [ID: 144893]
|
||||
|
||||
---
|
||||
|
||||
## Informations sur l'extraction
|
||||
|
||||
- **Date d'extraction**: 16/04/2025 15:12:11
|
||||
- **Répertoire**: output/ticket_T11089/T11089_20250416_151202
|
||||
430
output/ticket_T11089/T11089_20250416_151202/all_messages.json
Normal file
148
output/ticket_T11089/T11089_20250416_151202/all_messages.txt
Normal file
@ -0,0 +1,148 @@
|
||||
TICKET: T11089 - Problème création feuille paillasse béton
|
||||
Date d'extraction: 2025-04-16 15:12:03
|
||||
Nombre de messages: 10
|
||||
|
||||
================================================================================
|
||||
|
||||
********************************************************************************
|
||||
*** MESSAGE TRANSFÉRÉ ***
|
||||
********************************************************************************
|
||||
|
||||
DATE: 2025-03-19 15:02:29
|
||||
DE: Contact Laboratoire routier
|
||||
OBJET: Problème création feuille paillasse béton
|
||||
|
||||
Bonjour,
|
||||
Je rencontre un problème pour créer des échantillons d'éprouvettes béton, ci-joint capture d'écran.
|
||||
J'en ai déjà créé 3 depuis ce matin, sans souci et là, une fois de plus, un beug alors que par défaut c'est BRG LAB qui nous impose ses numéros en suite logique.
|
||||
je suis donc bloquée et je ne peux plus travailler.
|
||||
Merci de faire le nécessaire rapidement.
|
||||
cordialement
|
||||
Peggy BRIERE
|
||||
Laborantin routier
|
||||
Département de la Sarthe
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
********************************************************************************
|
||||
*** CHANGEMENT D'ÉTAT ***
|
||||
********************************************************************************
|
||||
|
||||
DATE: 2025-03-19 15:06:46
|
||||
DE: OdooBot
|
||||
|
||||
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
********************************************************************************
|
||||
*** MESSAGE TRANSFÉRÉ ***
|
||||
********************************************************************************
|
||||
|
||||
DATE: 2025-03-19 15:36:17
|
||||
DE: Romuald GRUSON
|
||||
OBJET: Re: [T11089] - Problème création feuille paillasse béton
|
||||
|
||||
Bonjour
|
||||
,
|
||||
Nous constatons bien le dysfonctionnement d'incrémentation sur votre prochain échantillon de béton. Pour y remédier, vous pouvez renseigner manuellement le prélèvement indiqué +1. Après cette action, le dysfonctionnement sera résolu et la numérotation s’incrémente correctement.
|
||||
Je reste à votre entière disposition pour toute information complémentaire.
|
||||
Cordialement,
|
||||
---
|
||||
Support technique
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
********************************************************************************
|
||||
*** CHANGEMENT D'ÉTAT ***
|
||||
********************************************************************************
|
||||
|
||||
DATE: 2025-03-19 15:36:26
|
||||
DE: Romuald GRUSON
|
||||
|
||||
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
********************************************************************************
|
||||
*** MESSAGE TRANSFÉRÉ ***
|
||||
********************************************************************************
|
||||
|
||||
DATE: 2025-03-20 06:55:41
|
||||
DE: Contact Laboratoire routier
|
||||
OBJET: RE: [T11089] - Problème création feuille paillasse béton
|
||||
|
||||
Bonjour,
|
||||
Cela ne fonctionne toujours pas même après votre manip.
|
||||
Merci de faire le nécessaire car nous sommes toujours bloqué !!!!!
|
||||
cordialement
|
||||
Peggy BRIERE
|
||||
Laborantin routier
|
||||
Département de la Sarthe
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
********************************************************************************
|
||||
*** CHANGEMENT D'ÉTAT ***
|
||||
********************************************************************************
|
||||
|
||||
DATE: 2025-03-20 07:38:04
|
||||
DE: Romuald GRUSON
|
||||
|
||||
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
DATE: 2025-03-20 08:10:58
|
||||
DE: Romuald GRUSON
|
||||
|
||||
20/03/2025 09:10 Plusieurs appels non répondu
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
********************************************************************************
|
||||
*** MESSAGE TRANSFÉRÉ ***
|
||||
********************************************************************************
|
||||
|
||||
DATE: 2025-03-20 08:17:59
|
||||
DE: Romuald GRUSON
|
||||
OBJET: Re: [T11089] - Problème création feuille paillasse béton
|
||||
|
||||
Bonjour
|
||||
,
|
||||
Le dysfonctionnement survient lorsqu'un échantillon a été réalisé sur l'année précédente au prélèvement.
|
||||
La solution la plus simple est de renseigner la numérotation manuellement à l’étape correspondante. Je vous ai joint une capture d’écran : à la place de
|
||||
0032
|
||||
, vous pouvez saisir
|
||||
0033
|
||||
.
|
||||
Pour tout nouvel échantillon créé cette année, vous ne rencontrerez plus de problème. En revanche, pour les échantillons de l’année précédente, une saisie manuelle restera nécessaire.
|
||||
Je reste disponible pour toute discussion téléphonique. N’hésitez pas à me communiquer un numéro et un créneau pour vous joindre.
|
||||
Je reste à votre entière disposition pour toute information complémentaire.
|
||||
Cordialement,
|
||||
---
|
||||
Support technique
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
********************************************************************************
|
||||
*** CHANGEMENT D'ÉTAT ***
|
||||
********************************************************************************
|
||||
|
||||
DATE: 2025-03-20 08:18:04
|
||||
DE: Romuald GRUSON
|
||||
|
||||
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
********************************************************************************
|
||||
*** CHANGEMENT D'ÉTAT ***
|
||||
********************************************************************************
|
||||
|
||||
DATE: 2025-04-04 08:06:34
|
||||
DE: Romuald GRUSON
|
||||
|
||||
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||