build(agent): new-agents-3#dd492b iteration

This commit is contained in:
agent-dd492b85242a98c5 2026-04-20 14:16:15 +02:00
parent 7cfae65f0c
commit 3eb87a9f94
3 changed files with 116 additions and 1 deletions

View File

@ -9,6 +9,12 @@ Offline-first cross-domain orchestration for disaster-resilient grids.
- Simulation and hardware-in-the-loop testing with KPI dashboards.
- Governance ledger and event sourcing for auditability.
### EnergiBridge Enhancements
- Introduced EnergiBridge extensions to map GridResilience primitives (LocalProblem/LocalDevicePlans, SharedSignals, PlanDelta) to a vendor-agnostic, cross-domain representation and back.
- Added deterministic delta reconciliation (reconcile_deltas) to merge islanding/load-shedding updates across partitions while preserving cryptographic tags and metadata.
- Added tests validating object/morphism mapping and delta reconciliation to ensure offline-first consistency.
- Kept the surface lightweight and dependency-free for rapid integration with existing adapters.
Project structure and packaging
- Python-based core with adapters under src/gridresilience_studio/adapters.
- Core primitives live in src/gridresilience_studio/core.py.

View File

@ -8,7 +8,7 @@ tests fast and focused on integration surface.
"""
from __future__ import annotations
from dataclasses import dataclass, field
from typing import Any, Dict
from typing import Any, Dict, List
from .core import Object, Morphism, PlanDelta
@ -49,6 +49,74 @@ class EnergiBridge:
"""Identity mapping for PlanDelta (pass-through in this sketch)."""
return delta
# ---------------------------------------------------------------------
# Cross-domain canonical representations (GoC-style)
# ---------------------------------------------------------------------
@staticmethod
def to_goc_object(obj: Object) -> Dict[str, Any]:
"""Translate a GridResilience Object into a simple GoC payload."""
return {
"type": "Object",
"id": obj.id,
"class": obj.type,
"properties": obj.properties,
}
@staticmethod
def to_goc_morphism(morph: Morphism) -> Dict[str, Any]:
"""Translate a GridResilience Morphism into a simple GoC payload."""
return {
"type": "Morphism",
"id": morph.id,
"source": morph.source,
"target": morph.target,
"signals": morph.signals,
"version": morph.version,
}
@staticmethod
def reconcile_deltas(local_deltas: List[PlanDelta], remote_deltas: List[PlanDelta]) -> List[PlanDelta]:
"""Deterministically reconcile two sets of PlanDelta objects.
- Delta IDs are used as the canonical key.
- Actions from both sides are merged (without duplicating identical actions).
- islanded flag is OR'ed; tags are merged shallowly.
- Returns a new list of PlanDelta instances representing the merged view.
"""
merged: dict[str, PlanDelta] = {}
# seed with local deltas
for d in local_deltas:
merged[d.delta_id] = PlanDelta(
delta_id=d.delta_id,
islanded=d.islanded,
actions=list(d.actions),
tags=dict(d.tags),
)
# merge remote deltas
for d in remote_deltas:
if d.delta_id in merged:
base = merged[d.delta_id]
# merge actions without duplicates
existing = list(base.actions)
for act in d.actions:
if act not in existing:
existing.append(act)
base.actions = existing
base.islanded = base.islanded or d.islanded
# shallow merge of tags
base.tags = {**base.tags, **d.tags}
else:
merged[d.delta_id] = PlanDelta(
delta_id=d.delta_id,
islanded=d.islanded,
actions=list(d.actions),
tags=dict(d.tags),
)
return list(merged.values())
__all__ = ["LocalProblem", "SharedSignals", "EnergiBridge"]

View File

@ -0,0 +1,41 @@
import pytest
from gridresilience_studio.energi_bridge import EnergiBridge, LocalProblem, SharedSignals
from gridresilience_studio.core import Object, Morphism, PlanDelta
def test_goC_object_mapping():
lp = LocalProblem(id="LP1", description="Test LocalProblem", resources={"foo": "bar"})
obj = EnergiBridge.map_object(lp)
assert isinstance(obj, Object)
goc = EnergiBridge.to_goc_object(obj)
assert goc["type"] == "Object"
assert goc["id"] == "LP1"
assert goc["class"] == "LocalProblem" or goc["class"] == obj.type
assert isinstance(goc["properties"], dict)
def test_goC_morphism_mapping():
sig = SharedSignals(id="SIG1", source="LP1", target="LP2", signals={"voltage": 1.0})
morph = EnergiBridge.map_signals(sig)
assert isinstance(morph, Morphism)
gocm = EnergiBridge.to_goc_morphism(morph)
assert gocm["type"] == "Morphism"
assert gocm["id"] == "SIG1"
assert gocm["source"] == "LP1"
assert gocm["signals"] == {"voltage": 1.0}
def test_delta_reconciliation():
d_local = PlanDelta(delta_id="D1", islanded=False, actions=[{"type": "noop"}], tags={})
d_remote = PlanDelta(delta_id="D1", islanded=True, actions=[{"type": "toggle"}], tags={"t": "v1"})
merged = EnergiBridge.reconcile_deltas([d_local], [d_remote])
assert len(merged) == 1
merged_delta = merged[0]
assert merged_delta.delta_id == "D1"
# both actions should be merged without duplicates
actions = merged_delta.actions
assert any(a.get("type") == "noop" for a in actions)
assert any(a.get("type") == "toggle" for a in actions)
# islanded should be True due to OR
assert merged_delta.islanded is True