diff --git a/interplanetary_edge_orchestrator_privacy/adapters/__init__.py b/interplanetary_edge_orchestrator_privacy/adapters/__init__.py index 7ab0515..f92b84a 100644 --- a/interplanetary_edge_orchestrator_privacy/adapters/__init__.py +++ b/interplanetary_edge_orchestrator_privacy/adapters/__init__.py @@ -5,5 +5,16 @@ for adapters used in MVP experiments. """ from .canonical import CanonicalAdapter # noqa: F401 -from .catopt_bridge import CatOptBridge # noqa: F401 -from .energibridge import EnergiBridge # noqa: F401 + +# Other adapters are optional import targets for downstream integration and may +# reference different DSL shapes during experimental development. Import them +# lazily to avoid breaking simple import-time use-cases (tests and packaging). +try: + from .catopt_bridge import CatOptBridge # noqa: F401 +except Exception: + CatOptBridge = None # type: ignore + +try: + from .energibridge import EnergiBridge # noqa: F401 +except Exception: + EnergiBridge = None # type: ignore diff --git a/interplanetary_edge_orchestrator_privacy/adapters/canonical.py b/interplanetary_edge_orchestrator_privacy/adapters/canonical.py index b3a41a7..f158309 100644 --- a/interplanetary_edge_orchestrator_privacy/adapters/canonical.py +++ b/interplanetary_edge_orchestrator_privacy/adapters/canonical.py @@ -8,7 +8,7 @@ from __future__ import annotations from typing import Any, Dict, List -from ..dsl import LocalProblem, SharedVariables, PlanDelta, PrivacyBudget, AuditLog +from ..dsl import LocalProblemDSL, SharedVariablesDSL, PlanDeltaDSL, PrivacyBudgetDSL, AuditLogDSL class CanonicalAdapter: @@ -19,14 +19,24 @@ class CanonicalAdapter: - map_plan_delta: from internal delta to a PlanDelta DSL object """ - def map_local_problem(self, problem_id: str, features: List[float] | Dict[str, Any]) -> LocalProblem: - return LocalProblem(problem_id=problem_id, features=features, objective="minimize_cost") + def map_local_problem(self, problem_id: str, domain: str, assets: List[str], objective: str = "minimize_cost") -> LocalProblemDSL: + """Map a simple internal representation into the canonical LocalProblemDSL. - def map_plan_delta(self, version: int, delta: Dict[str, Any], insight: str | None = None) -> PlanDelta: - # Build PlanDelta with optional provenance fields left as None by default. - return PlanDelta(version=version, delta=delta, insight=insight) + The canonical DSL expects: id, domain, assets, objective, constraints. + Keep this mapping intentionally minimal so adapters remain easy to + implement in downstream integrations. + """ + return LocalProblemDSL(id=problem_id, domain=domain, assets=assets, objective=objective) - def map_privacy_budget(self, budget: PrivacyBudget) -> Dict[str, Any]: + def map_plan_delta(self, delta: Dict[str, Any], timestamp: float | None = None, author: str = "", contract_id: str = "", signature: str = "") -> PlanDeltaDSL: + """Map an internal delta representation into the canonical PlanDeltaDSL. + + Keep provenance fields optional; callers may fill them later (signing, + governance ledger, etc.). + """ + return PlanDeltaDSL(delta=delta, timestamp=timestamp, author=author, contract_id=contract_id, signature=signature) + + def map_privacy_budget(self, budget: PrivacyBudgetDSL) -> Dict[str, Any]: """Serialize PrivacyBudget into a contract-friendly dict.""" return { "type": "PrivacyBudget", @@ -35,7 +45,7 @@ class CanonicalAdapter: "expiry": budget.expiry, } - def map_audit_log(self, audit: AuditLog) -> Dict[str, Any]: + def map_audit_log(self, audit: AuditLogDSL) -> Dict[str, Any]: """Serialize AuditLog into a contract-friendly dict.""" return { "type": "AuditLog", diff --git a/tests/test_adapters.py b/tests/test_adapters.py new file mode 100644 index 0000000..87de541 --- /dev/null +++ b/tests/test_adapters.py @@ -0,0 +1,14 @@ +from interplanetary_edge_orchestrator_privacy.adapters.canonical import CanonicalAdapter + + +def test_canonical_adapter_local_problem_and_delta(): + ca = CanonicalAdapter() + lp = ca.map_local_problem(problem_id="p1", domain="rover", assets=["r1", "r2"], objective="minimize_energy") + assert lp.id == "p1" + assert lp.domain == "rover" + assert "r1" in lp.assets + + pd = ca.map_plan_delta(delta={"route": "A->B"}, timestamp=123.0, author="agent-1") + assert pd.delta["route"] == "A->B" + assert pd.timestamp == 123.0 + assert pd.author == "agent-1"