@@ -139,6 +139,38 @@ async def _execute_with_nemotron(self, image_prompt: str, size: str = "1024x1024
139139 "quality" : quality ,
140140 })
141141
142+ @staticmethod
143+ def _extract_tool_error (observation : dict ) -> tuple [bool , str , str ]:
144+ """Normalisiert Fehlererkennung aus Tool-Responses."""
145+ if not isinstance (observation , dict ):
146+ return True , "Unerwartetes Antwortformat vom Tool." , ""
147+
148+ status = str (observation .get ("status" , "" ) or "" ).strip ().lower ()
149+ error_code = str (observation .get ("error_code" , "" ) or "" ).strip ().lower ()
150+
151+ if "error" in observation :
152+ return True , str (observation .get ("error" ) or "Unbekannter Fehler" ), error_code
153+ if status in {"error" , "failed" , "failure" }:
154+ msg = str (
155+ observation .get ("message" )
156+ or observation .get ("error" )
157+ or "Unbekannter Fehler"
158+ )
159+ return True , msg , error_code
160+ return False , "" , error_code
161+
162+ @staticmethod
163+ def _build_safe_retry_prompt (detailed_prompt : str ) -> str :
164+ """Erzeugt einen moderationsfreundlichen Retry-Prompt fuer Bildgenerierung."""
165+ base = str (detailed_prompt or "" ).strip ()
166+ safety_clause = (
167+ "Original fictional character only, no copyrighted or trademarked characters, "
168+ "no logos, no real persons, no violence, no weapons, family-friendly."
169+ )
170+ if base :
171+ return f"{ base } . { safety_clause } "
172+ return safety_clause
173+
142174 async def run (self , task : str ) -> str :
143175 log .info (f"{ self .__class__ .__name__ } - HYBRID MODE (GPT-5.1 + Nemotron)" )
144176
@@ -156,12 +188,35 @@ async def run(self, task: str) -> str:
156188 self ._handle_file_artifacts (observation )
157189
158190 if isinstance (observation , dict ):
159- if "error" in observation :
160- return f"Fehler bei der Bildgenerierung: { observation ['error' ]} "
191+ has_error , error_message , error_code = self ._extract_tool_error (observation )
192+ if has_error and error_code == "moderation_blocked" :
193+ safe_prompt = self ._build_safe_retry_prompt (detailed_prompt )
194+ log .warning ("Bildgenerierung moderiert geblockt. Versuche sicheren Retry." )
195+ observation_retry = await self ._execute_with_nemotron (
196+ safe_prompt , size = "1024x1024" , quality = "high"
197+ )
198+ self ._handle_file_artifacts (observation_retry )
199+ if isinstance (observation_retry , dict ):
200+ retry_error , retry_message , _ = self ._extract_tool_error (observation_retry )
201+ if retry_error :
202+ return f"Fehler bei der Bildgenerierung: { retry_message } "
203+ observation = observation_retry
204+ detailed_prompt = safe_prompt
205+ else :
206+ return "Fehler bei der Bildgenerierung: Unerwartetes Antwortformat beim Retry."
207+
208+ elif has_error :
209+ return f"Fehler bei der Bildgenerierung: { error_message } "
161210
162211 saved_path = observation .get ("saved_as" , "" )
163212 image_url = observation .get ("image_url" , "" )
164213
214+ if not saved_path and not image_url :
215+ return (
216+ "Bildgenerierung abgeschlossen, aber es wurde weder Datei noch URL "
217+ "zurueckgegeben."
218+ )
219+
165220 final_answer = "Ich habe das Bild erfolgreich generiert!"
166221 if saved_path :
167222 final_answer += f"\n \n Gespeichert unter: { saved_path } "
0 commit comments