| // --- DÉBUT DE L'UNIQUE ET CORRECTE MÉTHODE --- | // --- DÉBUT DE L'UNIQUE ET CORRECTE MÉTHODE --- | ||||
| @override | @override | ||||
| @override | |||||
| Future<List<String>> generatePostIdeas({ | Future<List<String>> generatePostIdeas({ | ||||
| required String base64Image, | required String base64Image, | ||||
| required String profession, | required String profession, | ||||
| if (rawResponse.isEmpty) return ["Le modèle n'a retourné aucune réponse."]; | if (rawResponse.isEmpty) return ["Le modèle n'a retourné aucune réponse."]; | ||||
| // La ligne "cleanedResponse" inutile a été supprimée ici. | |||||
| String jsonArrayString; | |||||
| try { | try { | ||||
| final startIndex = rawResponse.indexOf('['); | |||||
| final endIndex = rawResponse.lastIndexOf(']'); | |||||
| // --- NOUVELLE LOGIQUE ROBUSTE AVEC REGEX --- | |||||
| // On cherche un bloc ```json ... ``` | |||||
| final regex = RegExp(r'```json\s*([\s\S]*?)\s*```'); | |||||
| final match = regex.firstMatch(rawResponse); | |||||
| if (startIndex != -1 && endIndex > startIndex) { | |||||
| final jsonArrayString = rawResponse.substring(startIndex, endIndex + 1); | |||||
| if (match != null && match.groupCount > 0) { | |||||
| // On a trouvé un bloc markdown, on extrait le contenu (Groupe 1) | |||||
| jsonArrayString = match.group(1)!.trim(); | |||||
| } else { | |||||
| // Pas de bloc markdown. Peut-être que le modèle a bien répondu ? | |||||
| // On retombe sur l'ancienne logique par sécurité. | |||||
| final startIndex = rawResponse.indexOf('['); | |||||
| final endIndex = rawResponse.lastIndexOf(']'); | |||||
| // On tente le parsing | |||||
| final jsonList = jsonDecode(jsonArrayString) as List; | |||||
| if (startIndex != -1 && endIndex > startIndex) { | |||||
| jsonArrayString = rawResponse.substring(startIndex, endIndex + 1); | |||||
| } else { | |||||
| throw const FormatException("Aucun bloc JSON ```...``` ni tableau '[]' trouvé."); | |||||
| } | |||||
| } | |||||
| // --- FIN DE LA NOUVELLE LOGIQUE --- | |||||
| // Logique de parsing pour une liste d'objets | |||||
| return jsonList.map((item) { | |||||
| if (item is Map<String, dynamic> && item.containsKey('text')) { | |||||
| return item['text'].toString(); | |||||
| } | |||||
| return 'Format de l\'idée inattendu'; | |||||
| }) | |||||
| .where((text) => text != 'Format de l\'idée inattendu') | |||||
| .toList(); | |||||
| // Log de débogage pour voir ce qu'on essaie de parser | |||||
| print('[OllamaPostCreationService] ℹ️ Tentative de parsing sur : "$jsonArrayString"'); | |||||
| final jsonList = jsonDecode(jsonArrayString) as List; | |||||
| // Logique de parsing pour une liste d'objets | |||||
| return jsonList.map((item) { | |||||
| if (item is Map<String, dynamic> && item.containsKey('text')) { | |||||
| return item['text'].toString(); | |||||
| } | |||||
| return 'Format de l\'idée inattendu'; | |||||
| }) | |||||
| .where((text) => text != 'Format de l\'idée inattendu') | |||||
| .toList(); | |||||
| } else { | |||||
| // Le modèle a répondu mais sans tableau JSON | |||||
| throw const FormatException("Aucun tableau JSON '[]' trouvé dans la réponse."); | |||||
| } | |||||
| } catch (e) { | } catch (e) { | ||||
| // C'EST ICI QUE VOTRE ERREUR SE PRODUIT | |||||
| // *** LOGGING AMÉLIORÉ *** | |||||
| // Ceci nous dira l'erreur EXACTE de parsing (ex: "Unterminated string") | |||||
| print('[OllamaPostCreationService] ❌ Erreur de parsing JSON.'); | print('[OllamaPostCreationService] ❌ Erreur de parsing JSON.'); | ||||
| // AJOUT : Logguer l'erreur spécifique pour savoir POURQUOI le JSON est invalide | |||||
| print('[OllamaPostCreationService] ❌ Erreur spécifique : ${e.toString()}'); | print('[OllamaPostCreationService] ❌ Erreur spécifique : ${e.toString()}'); | ||||
| print('[OllamaPostCreationService] ❌ Réponse brute : "$rawResponse"'); | |||||
| print('[OllamaPostCreationService] ❌ Réponse brute (avant regex) : "$rawResponse"'); | |||||
| return ["Le format de la réponse de l'IA est inattendu."]; | return ["Le format de la réponse de l'IA est inattendu."]; | ||||
| } | } | ||||
| rethrow; | rethrow; | ||||
| } | } | ||||
| } | } | ||||
| // --- FIN DE LA MÉTHODE MISE À JOUR --- | |||||
| } | } |