nebulaforge-offline-resilie.../nebulaforge/energibridge.py

181 lines
4.3 KiB
Python

from __future__ import annotations
"""EnergiBridge: Canonical Interoperability Layer (CatOpt-inspired).
This module provides a minimal set of DSL-like blocks to express NebulaForge
primitives in a vendor-agnostic Interoperability Registry (GoC).
"""
from dataclasses import dataclass, asdict
from typing import Any, Dict, List
from .contracts import LocalProblem, SharedVariables, PlanDelta, PrivacyBudget, AuditLog
@dataclass
class FoundationModelBlock:
id: str
domain: str
model_type: str
device_targets: List[str]
max_energy: float
latency_budget: float
@dataclass
class PlanningPolicyBlock:
safety_budget: float
performance_budget: float
drift_tolerance: float
@dataclass
class LocalProblemBlock:
problem_id: str
assets: List[str]
objective: str
constraints: str
@dataclass
class SharedVariablesBlock:
forecasts: Dict[str, Any]
priors: Dict[str, Any]
version: int
@dataclass
class PlanDeltaBlock:
delta: Dict[str, Any]
timestamp: float
author: str
contract_id: str
signature: str | None = None
@dataclass
class DualVariablesBlock:
lambda_energy: float
lambda_privacy: float
@dataclass
class PrivacyBudgetBlock:
budget: float
expiry: float | None = None
@dataclass
class AuditLogBlock:
entry: str
signer: str
timestamp: float
contract_id: str
version: int
@dataclass
class GoCEntry:
adapter_id: str
supported_domains: List[str]
contract_version: int
version: int | None = None
class GoCRegistry:
"""Lightweight in-memory Graph of Contracts registry."""
def __init__(self) -> None:
self.adapters: Dict[str, Dict[str, Any]] = {}
def register_adapter(self, adapter_id: str, info: Dict[str, Any]) -> None:
self.adapters[adapter_id] = info
def get_adapter(self, adapter_id: str) -> Dict[str, Any] | None:
return self.adapters.get(adapter_id)
def list_adapters(self) -> List[Dict[str, Any]]:
return list(self.adapters.values())
def to_energi_blocks(
lm: LocalProblem,
sv: SharedVariables,
pd: PlanDelta,
pb: PrivacyBudget,
al: AuditLog,
adapter_id: str = "unknown"
) -> Dict[str, Any]:
"""Convert NebulaForge contracts into EnergiBridge DSL blocks.
This is a minimal, optimistic mapping intended for MVP wiring and testing.
The fields are chosen to be descriptive rather than exhaustive.
"""
fm = FoundationModelBlock(
id=lm.id,
domain=lm.domain,
model_type="foundation",
device_targets=["arm", "riscv"],
max_energy=1.0,
latency_budget=0.1,
)
pp = PlanningPolicyBlock(
safety_budget=1.0,
performance_budget=1.0,
drift_tolerance=0.01,
)
lpb = LocalProblemBlock(
problem_id=lm.id,
assets=[],
objective=lm.description,
constraints="",
)
svb = SharedVariablesBlock(
forecasts=sv.variables if hasattr(sv, "variables") else {},
priors={},
version=sv.version,
)
pdb = PlanDeltaBlock(
delta=pd.delta,
timestamp=pd.timestamp if hasattr(pd, "timestamp") else 0.0,
author="nebula-agent",
contract_id=pd.version and f"contract-{pd.version}" or "contract-0",
signature=None,
)
dvb = DualVariablesBlock(lambda_energy=0.0, lambda_privacy=getattr(pb, "lambda_privacy", 0.0))
pbv = PrivacyBudgetBlock(budget=getattr(pb, "lambda_privacy", 0.0))
alb = AuditLogBlock(
entry=al.entry if hasattr(al, "entry") else "",
signer=al.signer if hasattr(al, "signer") else "",
timestamp=al.timestamp if hasattr(al, "timestamp") else 0.0,
contract_id=al.contract_id if hasattr(al, "contract_id") else "",
version=al.version if hasattr(al, "version") else 1,
)
goc = GoCEntry(
adapter_id=adapter_id,
supported_domains=["space-robotics"],
contract_version=1,
version=1,
)
return {
"FoundationModelBlock": asdict(fm),
"PlanningPolicyBlock": asdict(pp),
"LocalProblemBlock": asdict(lpb),
"SharedVariablesBlock": asdict(svb),
"PlanDeltaBlock": asdict(pdb),
"DualVariablesBlock": asdict(dvb),
"PrivacyBudgetBlock": asdict(pbv),
"AuditLogBlock": asdict(alb),
"GoCEntry": asdict(goc),
}