build(agent): new-agents#a6e6ec iteration
This commit is contained in:
parent
dd13bf419b
commit
43a7e53845
|
|
@ -2,6 +2,8 @@
|
||||||
|
|
||||||
This repository implements a production-ready skeleton for OpenEnergySphere's federated, contract-driven cross-domain energy planning platform. The MVP focuses on the EnergiBridge interoperability layer, mapping OpenEnergySphere primitives to a canonical IR and enabling plug-and-play adapters across DERs, meters, pumps, and buildings while preserving offline-first operation and governance.
|
This repository implements a production-ready skeleton for OpenEnergySphere's federated, contract-driven cross-domain energy planning platform. The MVP focuses on the EnergiBridge interoperability layer, mapping OpenEnergySphere primitives to a canonical IR and enabling plug-and-play adapters across DERs, meters, pumps, and buildings while preserving offline-first operation and governance.
|
||||||
|
|
||||||
|
Note: Added a minimal EnergiBridge mapper (EnergiBridgeMapper) to illustrate canonical mappings between LocalProblem objects and a vendor-agnostic IR. This enables straightforward extension to more complex cross-domain workflows and adapters.
|
||||||
|
|
||||||
Architecture highlights
|
Architecture highlights
|
||||||
- Core primitives: LocalProblem, SharedVariables, DualVariables, PlanDelta, PrivacyBudget, AuditLog
|
- Core primitives: LocalProblem, SharedVariables, DualVariables, PlanDelta, PrivacyBudget, AuditLog
|
||||||
- Graph-of-Contracts registry for adapters and data schemas with per-message metadata
|
- Graph-of-Contracts registry for adapters and data schemas with per-message metadata
|
||||||
|
|
|
||||||
|
|
@ -1,2 +1,9 @@
|
||||||
""" Energysphere core package minimal init. """
|
""" Energysphere core package minimal init. """
|
||||||
__version__ = "0.1.0"
|
__version__ = "0.1.0"
|
||||||
|
|
||||||
|
# Re-export common bridge utilities for quick access
|
||||||
|
try:
|
||||||
|
from .energi_bridge import EnergiBridgeMapper # type: ignore
|
||||||
|
except Exception:
|
||||||
|
# If optional or during early import stages, fail gracefully.
|
||||||
|
EnergiBridgeMapper = None # type: ignore
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,55 @@
|
||||||
|
"""EnergiBridge: minimal canonical mapping for cross-domain interoperability.
|
||||||
|
|
||||||
|
This is a small MVP shim that translates Energysphere primitives into a
|
||||||
|
vendor-agnostic IR representation (very light-weight). The goal is to provide a
|
||||||
|
stable, testable layer that can be expanded to full CatOpt-like mappings while
|
||||||
|
preserving offline-first semantics and governance hooks in later iterations.
|
||||||
|
"""
|
||||||
|
|
||||||
|
from __future__ import annotations
|
||||||
|
|
||||||
|
from typing import Any, Dict
|
||||||
|
|
||||||
|
from .models import LocalProblem
|
||||||
|
|
||||||
|
|
||||||
|
class EnergiBridgeMapper:
|
||||||
|
"""Lightweight translator between Energysphere primitives and a canonical IR.
|
||||||
|
|
||||||
|
Only a tiny subset is implemented to keep MVP surface small:
|
||||||
|
- LocalProblem becomes a canonical Object with a few core fields.
|
||||||
|
- SharedVariables/PlanDelta could be extended similarly in future iterations.
|
||||||
|
"""
|
||||||
|
|
||||||
|
def __init__(self, namespace: str = "default") -> None:
|
||||||
|
self.namespace = namespace
|
||||||
|
|
||||||
|
def map_local_problem(self, lp: LocalProblem) -> Dict[str, Any]:
|
||||||
|
"""Map a LocalProblem to a canonical Object representation.
|
||||||
|
|
||||||
|
The structure is intentionally simple but stable for downstream adapters
|
||||||
|
to consume. It can be extended with versioning, provenance, and crypto
|
||||||
|
tags in future iterations.
|
||||||
|
"""
|
||||||
|
return {
|
||||||
|
"type": "Object",
|
||||||
|
"namespace": self.namespace,
|
||||||
|
"site_id": lp.site_id,
|
||||||
|
"objective": lp.objective,
|
||||||
|
"parameters": lp.parameters,
|
||||||
|
"version": 1,
|
||||||
|
}
|
||||||
|
|
||||||
|
def map_object_to_local_problem(self, obj: Dict[str, Any]) -> LocalProblem:
|
||||||
|
"""Inverse mapping from canonical Object to LocalProblem when possible."""
|
||||||
|
if obj.get("type") != "Object":
|
||||||
|
raise ValueError("Unsupported canonical type: expected Object")
|
||||||
|
# Basic reconstruction; in MVP we ignore extra fields safely.
|
||||||
|
return LocalProblem(
|
||||||
|
site_id=obj.get("site_id", ""),
|
||||||
|
objective=obj.get("objective", ""),
|
||||||
|
parameters=obj.get("parameters", {}),
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
__all__ = ["EnergiBridgeMapper"]
|
||||||
|
|
@ -0,0 +1,22 @@
|
||||||
|
from energysphere.models import LocalProblem
|
||||||
|
from energysphere.energi_bridge import EnergiBridgeMapper
|
||||||
|
|
||||||
|
|
||||||
|
def test_map_local_problem_to_object():
|
||||||
|
lp = LocalProblem(site_id="site-42", objective="min-cost", parameters={"load": 2.5})
|
||||||
|
mapper = EnergiBridgeMapper(namespace="test-ns")
|
||||||
|
obj = mapper.map_local_problem(lp)
|
||||||
|
assert obj["type"] == "Object"
|
||||||
|
assert obj["site_id"] == "site-42"
|
||||||
|
assert obj["namespace"] == "test-ns"
|
||||||
|
assert obj["version"] == 1
|
||||||
|
|
||||||
|
|
||||||
|
def test_map_object_to_local_problem_roundtrip():
|
||||||
|
lp = LocalProblem(site_id="site-7", objective="min-cost", parameters={"p": 1})
|
||||||
|
mapper = EnergiBridgeMapper()
|
||||||
|
obj = mapper.map_local_problem(lp)
|
||||||
|
lp2 = mapper.map_object_to_local_problem(obj)
|
||||||
|
assert lp2.site_id == lp.site_id
|
||||||
|
assert lp2.objective == lp.objective
|
||||||
|
assert lp2.parameters == lp.parameters
|
||||||
Loading…
Reference in New Issue