from __future__ import annotations from dataclasses import asdict, is_dataclass from enum import Enum from typing import Any def to_jsonable(value: Any) -> Any: """Recursively convert values into JSON-serializable primitives.""" if value is None: return None if isinstance(value, (str, int, float, bool)): return value if isinstance(value, Enum): return value.value if is_dataclass(value): return to_jsonable(asdict(value)) if isinstance(value, dict): return {str(key): to_jsonable(item) for key, item in value.items()} if isinstance(value, (list, tuple)): return [to_jsonable(item) for item in value] if isinstance(value, set): return [to_jsonable(item) for item in sorted(value, key=lambda item: repr(item))] if hasattr(value, "to_dict") and callable(value.to_dict): return to_jsonable(value.to_dict()) return str(value)