1919 class ImageUploadError (Exception ): # type: ignore
2020 pass
2121
22- from .yolo_pipeline import run_yolo_pipeline
22+ PIPELINE_IMPORT_ERROR = None
23+ run_yolo_pipeline = None
24+
25+ try :
26+ from .yolo_pipeline import run_yolo_pipeline # type: ignore
27+ except Exception as e :
28+ PIPELINE_IMPORT_ERROR = f"{ type (e ).__name__ } : { e } "
29+ run_yolo_pipeline = None
30+ #from .yolo_pipeline import run_yolo_pipeline
2331
2432
2533# URL / path helpers
@@ -105,39 +113,40 @@ def _items_to_feedback_html(items):
105113# Main entry
106114def evaluation_function (response : Any , answer : Any , params : Params ) -> Result :
107115 try :
108- # Validate input
116+ # 0) Pipeline import guard (MOST IMPORTANT)
117+ if run_yolo_pipeline is None :
118+ items = [("Error" , f"Pipeline import failed: { PIPELINE_IMPORT_ERROR } " )]
119+ feedback_html = _items_to_feedback_html (items )
120+ try :
121+ return Result (is_correct = False , feedback = feedback_html , feedback_items = items )
122+ except TypeError :
123+ return Result (is_correct = False , feedback_items = items )
124+ # 1) Validate input
125+
109126 if not isinstance (response , list ) or len (response ) == 0 :
110127 items = [("Response" , "Please upload at least one image." )]
111128 feedback_html = _items_to_feedback_html (items )
112129 try :
113130 return Result (is_correct = False , feedback = feedback_html , feedback_items = items )
114131 except TypeError :
115132 return Result (is_correct = False , feedback_items = items )
133+ # 2) Optional controls
116134
117- # Optional controls (safe defaults)
118- # Default: NO image upload (text only), to match your current goal
119135 return_images : bool = bool (_pget (params , "return_images" , False ))
120136 debug : bool = bool (_pget (params , "debug" , False ))
121137
122- # Relative model filenames stored in evaluation_function/
123138 gear_model_rel = str (_pget (params , "gear_model_rel" , "gear_model.pt" ))
124139 shaft_model_rel = str (_pget (params , "shaft_model_rel" , "shaft_model.pt" ))
125-
126-
127- # Process images
140+ # 3) Process images
128141 merged_errors : List [Dict [str , str ]] = []
129142 merged_summaries : List [Dict [str , Any ]] = []
130143 merged_ratios : List [Dict [str , Any ]] = []
131-
132144 feedback_items : List [Tuple [str , str ]] = []
133145
134146 for idx , item in enumerate (response ):
135147 url = item .get ("url" ) if isinstance (item , dict ) else None
136148 if not url :
137- merged_errors .append ({
138- "code" : "NO_URL" ,
139- "message" : f"Image [{ idx } ] has no 'url' field."
140- })
149+ merged_errors .append ({"code" : "NO_URL" , "message" : f"Image [{ idx } ] has no 'url' field." })
141150 continue
142151
143152 img_bgr , err = _load_bgr_image_from_url (url )
@@ -150,13 +159,22 @@ def evaluation_function(response: Any, answer: Any, params: Params) -> Result:
150159 feedback_items .append ((f"Input URL [{ idx } ]" , str (url )))
151160 continue
152161
153- # Run pipeline (your external YOLO pipeline)
154- out = run_yolo_pipeline (
155- img_bgr = img_bgr ,
156- gear_model_rel = gear_model_rel ,
157- shaft_model_rel = shaft_model_rel ,
158- return_images = return_images ,
159- )
162+ # ---- Run YOLO pipeline safely per-image ----
163+ try :
164+ out = run_yolo_pipeline (
165+ img_bgr = img_bgr ,
166+ gear_model_rel = gear_model_rel ,
167+ shaft_model_rel = shaft_model_rel ,
168+ return_images = return_images ,
169+ )
170+ except Exception as e :
171+ merged_errors .append ({
172+ "code" : "PIPELINE_RUNTIME_FAIL" ,
173+ "message" : f"Pipeline failed on image[{ idx } ]: { type (e ).__name__ } : { e } "
174+ })
175+ if debug :
176+ feedback_items .append ((f"Input URL [{ idx } ]" , str (url )))
177+ continue
160178
161179 # Collect outputs safely
162180 summary = out .get ("summary" , {})
@@ -170,7 +188,7 @@ def evaluation_function(response: Any, answer: Any, params: Params) -> Result:
170188 if isinstance (errors , list ):
171189 merged_errors .extend (errors )
172190
173- # Optional annotated images upload (disabled by default)
191+ # Optional annotated images upload (off by default)
174192 if return_images :
175193 imgs = out .get ("images" , None )
176194 if isinstance (imgs , dict ) and upload_image is not None :
@@ -198,12 +216,15 @@ def evaluation_function(response: Any, answer: Any, params: Params) -> Result:
198216 if debug :
199217 feedback_items .append ((f"Input URL [{ idx } ]" , str (url )))
200218
201- # Decide correctness
202- # Your rule: incorrect if any error code starts with "E_"
219+ # ---------------------------
220+ # 4) Decide correctness
221+ # ---------------------------
203222 has_E = any (str (e .get ("code" , "" )).startswith ("E_" ) for e in merged_errors )
204223 is_correct = (not has_E )
205224
206- # Text feedback
225+ # ---------------------------
226+ # 5) Text feedback
227+ # ---------------------------
207228 if merged_summaries :
208229 feedback_items .append (("Summary" , str (merged_summaries [- 1 ])))
209230
@@ -231,4 +252,4 @@ def evaluation_function(response: Any, answer: Any, params: Params) -> Result:
231252 try :
232253 return Result (is_correct = False , feedback = feedback_html , feedback_items = items )
233254 except TypeError :
234- return Result (is_correct = False , feedback_items = items )
255+ return Result (is_correct = False , feedback_items = items )
0 commit comments