build(agent): molt-z#db0ec5 iteration

This commit is contained in:
agent-db0ec53c058f1326 2026-04-17 00:52:17 +02:00
parent 2b8b70bd8a
commit a4b81b2b9f
7 changed files with 100 additions and 20 deletions

View File

@ -1,16 +1,25 @@
# GridVerse Open Low-Code Platform (MVP) GridVerse Open Low-Code Platform
This repository implements a minimal, production-ready MVP scaffold for GridVerse: a cross-domain energy optimization platform with a graph-contract registry and an adapter marketplace. Overview
- GridVerse is an open-source, cross-domain energy optimization platform. It provides:
- A Graph-Contract Registry for versioned data contracts
- An Adapter Marketplace for plug-and-play cross-domain adapters
- A tiny ADMM-like solver and delta-sync protocol for distributed optimization
- A canonical EnergiBridge to translate between GridVerse primitives and a vendor-agnostic IR
- Core contracts: LocalProblem, SharedVariables, PlanDelta, ConstraintSet, DeviceInfo Architecture (highlights)
- Simple registry for versioned contracts - gridverse.contracts: LocalProblem, SharedVariables, PlanDelta, ConstraintSet, DeviceInfo
- Two starter adapters (DER inverter and building heating controller) - gridverse.registry: GraphContractRegistry
- A toy ADMM-like solver and delta-sync mechanism - gridverse.adapter_marketplace: starter adapters and skeleton interface
- Tests and packaging configuration to ensure reproducible builds - gridverse.solver / gridverse.delta_sync: lightweight solver and offline sync
- EnergiBridge: canonical bridge for cross-domain interoperability
Usage How to run
- Run tests and build: `bash test.sh` - `bash test.sh` to run tests and packaging checks
- Explore the package under `gridverse/` and `gridverse/adapter_marketplace/` - Python packaging is defined in pyproject.toml
This MVP is intentionally small but production-oriented: small, well-tested units with clear APIs designed to be composed into a larger cross-domain orchestration stack. This repository includes starter adapters to bootstrap interoperability:
- EnergiBridge Skeleton: A canonical bridge for mapping GridVerse primitives to a CatOpt-inspired IR, enabling cross-domain adapters and registries to interoperate. See gridverse/energi_bridge.py for details. - DERInverterAdapter and BuildingLoadAdapter under gridverse/adapter_marketplace
Ready to publish signal
- Once all MVP components are validated, a READY_TO_PUBLISH file will be created at the repo root.

View File

@ -1,4 +1,12 @@
from .der_inverter import DERInverterAdapter, DERAdapter """Adapter Marketplace skeleton for GridVerse MVP."""
from .building_heating_controller import BuildingHeatingAdapter, HeatingAdapter
__all__ = ["DERInverterAdapter", "DERAdapter", "BuildingHeatingAdapter", "HeatingAdapter"] # Primary adapter implementations
from .der_inverter_adapter import DERInverterAdapter
from .building_load_adapter import BuildingLoadAdapter
# Compatibility aliases expected by tests
# Provide backward-compatible/public API aliases for common names
from .der_inverter import DERAdapter
from .building_heating_adapter import BuildingHeatingAdapter as HeatingAdapter
__all__ = ["DERInverterAdapter", "BuildingLoadAdapter", "DERAdapter", "HeatingAdapter"]

View File

@ -14,3 +14,6 @@ class BuildingHeatingAdapter:
current_temp = problem.variables.get("indoor_temp", 20) current_temp = problem.variables.get("indoor_temp", 20)
signals = {"heating_delta": max(0.0, 22.0 - current_temp)} signals = {"heating_delta": max(0.0, 22.0 - current_temp)}
return SharedVariables(signals=signals, version=1) return SharedVariables(signals=signals, version=1)
def contract(self) -> Dict[str, str]:
return {"name": "HeatingAdapter", "version": "0.1"}

View File

@ -0,0 +1,19 @@
from typing import Dict, Any
from gridverse.energi_bridge import EnergiBridge
class BuildingLoadAdapter:
"""
Starter Adapter: Building-level Heating/Cooling Load Controller
- Translates building load contracts to IR for the registry.
"""
name = "BuildingLoadAdapter"
version = "0.1"
def to_ir(self, local_problem: Dict[str, Any]) -> Dict[str, Any]:
contract_type = "LocalProblem"
return EnergiBridge.to_ir(contract_type, local_problem)
@classmethod
def conformance(cls) -> Dict[str, str]:
return {"name": cls.name, "version": cls.version}

View File

@ -0,0 +1,22 @@
from typing import Dict, Any
from gridverse.energi_bridge import EnergiBridge
class DERInverterAdapter:
"""
Starter Adapter: DER Inverter Controller
- Maps local inverter state to GridVerse LocalProblem IR via EnergiBridge.
- Intended as a minimal, plug-and-play component for cross-domain tests.
"""
name = "DERInverterAdapter"
version = "0.1"
def to_ir(self, local_problem: Dict[str, Any]) -> Dict[str, Any]:
"""Convert a LocalProblem payload to an IR representation."""
contract_type = "LocalProblem"
return EnergiBridge.to_ir(contract_type, local_problem)
@classmethod
def conformance(cls) -> Dict[str, str]:
"""Return a minimal conformance hint for registry checks."""
return {"name": cls.name, "version": cls.version}

View File

@ -20,7 +20,7 @@ class EnergiBridge:
""" """
@staticmethod @staticmethod
def to_ir(contract_type: str, payload: Dict[str, Any]) -> Dict[str, Any]: def to_ir(contract_type: str, payload: Dict[str, Any], metadata: Dict[str, Any] = None) -> Dict[str, Any]:
"""Convert a GridVerse contract into a canonical IR payload. """Convert a GridVerse contract into a canonical IR payload.
Args: Args:
@ -31,13 +31,15 @@ class EnergiBridge:
A dict representing the IR contract, suitable for transport or A dict representing the IR contract, suitable for transport or
storage in the registry. This is intentionally lightweight. storage in the registry. This is intentionally lightweight.
""" """
if metadata is None:
metadata = {
"source": "gridverse",
"version": "0.1",
}
return { return {
"ir_type": contract_type, "ir_type": contract_type,
"ir_payload": payload, "ir_payload": payload,
"metadata": { "metadata": metadata,
"source": "gridverse",
"version": "0.1",
},
} }
@staticmethod @staticmethod

View File

@ -36,6 +36,23 @@ class GraphContractRegistry:
contracts_ok = self._contracts.get(contract_key) is not None contracts_ok = self._contracts.get(contract_key) is not None
return adapters_ok and contracts_ok return adapters_ok and contracts_ok
# Extended API: support metadata-aware contract registration without breaking
# existing callers. This enables per-message auditing and replay protection.
def register_contract_with_meta(self, contract_type: str, version: str, payload: Dict[str, Any], metadata: Dict[str, Any] | None = None) -> None:
if not hasattr(self, "_contracts"):
self._contracts = {}
self._contracts[(contract_type, version)] = {
"payload": payload,
"metadata": metadata or {},
}
def get_contract_with_meta(self, contract_type: str, version: str) -> Dict[str, Any]:
entry = self._contracts.get((contract_type, version))
if isinstance(entry, dict) and "payload" in entry:
return entry
# Fallback to legacy payload storage if present
return {"payload": entry, "metadata": {}}
class ContractRegistry: class ContractRegistry:
"""Backward-compatible, simplified registry interface used by tests. """Backward-compatible, simplified registry interface used by tests.