diff --git a/src/cosmosmesh_privacy_preserving_federated_/catopt_bridge.py b/src/cosmosmesh_privacy_preserving_federated_/catopt_bridge.py index 4a4eb2a..e0e00d2 100644 --- a/src/cosmosmesh_privacy_preserving_federated_/catopt_bridge.py +++ b/src/cosmosmesh_privacy_preserving_federated_/catopt_bridge.py @@ -45,5 +45,32 @@ class CatOptBridge: def translate_plan_delta(self, plan_delta: Dict[str, Any]) -> Dict[str, Any]: return {"type": "PlanDelta", "delta": plan_delta} + def to_catopt(self, lp: Any, sv: Any, dv: Any) -> Dict[str, Any]: + """Convert CosmosMesh MVP primitives into a canonical CatOpt-like object. + + This is a lightweight, MVP-friendly wrapper that serializes dataclass-like + objects into plain dictionaries suitable for transport or storage without + pulling in heavy dependencies. + """ + def _as_dict(obj: Any) -> Dict[str, Any]: + if obj is None: + return {} + # Dataclass-like instances may implement to_dict; fall back to __dict__ + if hasattr(obj, "to_dict") and callable(getattr(obj, "to_dict")): + try: + return obj.to_dict() # type: ignore[attr-defined] + except Exception: + pass + if isinstance(obj, dict): + return obj + # Generic dataclass would expose __dict__ + return getattr(obj, "__dict__", {}) + + return { + "LocalProblem": _as_dict(lp), + "SharedVariables": _as_dict(sv), + "DualVariables": _as_dict(dv), + } + __all__ = ["CatOptBridge"]