@@ -189,11 +189,11 @@ def generate_model_card(context, final_metrics: dict, evaluation_report: Any | N
189189 metadata = model_metadata .get ("metadata" , {})
190190 training_timestamp = metadata .get ("created_at" ) or DEFAULT_NOT_AVAILABLE
191191 experiment_id = metadata .get ("experiment_id" ) or context .experiment_id or DEFAULT_NOT_AVAILABLE
192- builder_version = _resolve_model_builder_version () or metadata .get ("version" ) or DEFAULT_NOT_AVAILABLE
192+ plexe_version = _resolve_plexe_version () or metadata .get ("version" ) or DEFAULT_NOT_AVAILABLE
193193
194194 lines .append (f"- Experiment ID: { experiment_id } " )
195195 lines .append (f"- Training timestamp: { training_timestamp } " )
196- lines .append (f"- Model-builder-v2 version: { builder_version } " )
196+ lines .append (f"- Plexe version: { plexe_version } " )
197197
198198 return "\n " .join (lines ).strip () + "\n "
199199
@@ -208,7 +208,8 @@ def _safe_load_json(path: Path) -> dict | None:
208208 return None
209209 try :
210210 with open (path , encoding = "utf-8" ) as f :
211- return json .load (f )
211+ loaded = json .load (f )
212+ return loaded if isinstance (loaded , dict ) else None
212213 except (json .JSONDecodeError , OSError , UnicodeDecodeError ):
213214 return None
214215
@@ -218,34 +219,62 @@ def _safe_load_yaml(path: Path) -> dict | None:
218219 return None
219220 try :
220221 with open (path , encoding = "utf-8" ) as f :
221- return yaml .safe_load (f )
222+ loaded = yaml .safe_load (f )
223+ return loaded if isinstance (loaded , dict ) else None
222224 except (yaml .YAMLError , OSError , UnicodeDecodeError ):
223225 return None
224226
225227
226228def _normalize_evaluation_report (evaluation_report : Any | None , package_dir : Path ) -> dict | None :
227229 if evaluation_report is None :
228230 fallback = _safe_load_json (package_dir / "evaluation" / "reports" / "evaluation.json" )
229- return fallback
231+ return _to_plain_dict ( fallback )
230232
231233 if isinstance (evaluation_report , dict ):
232- return evaluation_report
234+ return _to_plain_dict ( evaluation_report )
233235
234236 if hasattr (evaluation_report , "to_dict" ):
235237 try :
236- return evaluation_report .to_dict ()
238+ return _to_plain_dict ( evaluation_report .to_dict () )
237239 except Exception :
238240 pass
239241
240242 if hasattr (evaluation_report , "__dict__" ):
241243 try :
242- return dict (evaluation_report .__dict__ )
244+ return _to_plain_dict ( dict (evaluation_report .__dict__ ) )
243245 except Exception :
244246 return None
245247
246248 return None
247249
248250
251+ def _to_plain_structure (value : Any ) -> Any :
252+ if value is None or isinstance (value , str | bytes | bool | numbers .Real ):
253+ return value
254+ if isinstance (value , dict ):
255+ return {k : _to_plain_structure (v ) for k , v in value .items ()}
256+ if isinstance (value , list | tuple ):
257+ return [_to_plain_structure (v ) for v in value ]
258+ if hasattr (value , "to_dict" ):
259+ try :
260+ return _to_plain_structure (value .to_dict ())
261+ except Exception :
262+ pass
263+ if hasattr (value , "__dict__" ):
264+ try :
265+ return _to_plain_structure (dict (value .__dict__ ))
266+ except Exception :
267+ pass
268+ return value
269+
270+
271+ def _to_plain_dict (value : Any ) -> dict | None :
272+ normalized = _to_plain_structure (value )
273+ if isinstance (normalized , dict ):
274+ return normalized
275+ return None
276+
277+
249278def _get_nested (data : dict , keys : list [str ]) -> Any :
250279 current : Any = data
251280 for key in keys :
@@ -549,7 +578,7 @@ def _is_number(value: Any) -> bool:
549578 return isinstance (value , numbers .Real )
550579
551580
552- def _resolve_model_builder_version () -> str | None :
581+ def _resolve_plexe_version () -> str | None :
553582 pyproject_path = _find_pyproject ()
554583 if not pyproject_path :
555584 return None
0 commit comments