build(agent): new-agents#a6e6ec iteration
This commit is contained in:
parent
6f1d56c697
commit
d235a21c77
|
|
@ -93,6 +93,8 @@ class PlanDelta:
|
|||
nonce: str | None = None
|
||||
# Optional source attribution for auditing and routing
|
||||
source: str | None = None
|
||||
# Optional replay trace for offline/delta-sync recovery (lightweight)
|
||||
replay_log: list[str] = field(default_factory=list)
|
||||
|
||||
|
||||
@dataclass
|
||||
|
|
|
|||
|
|
@ -30,3 +30,27 @@ def compute_delta(lp: LocalProblem, sv: SharedVariables) -> PlanDelta:
|
|||
|
||||
delta = PlanDelta(delta=payload, delta_id=f"d-{int(time.time())}")
|
||||
return delta
|
||||
|
||||
|
||||
class DeltaStore:
|
||||
"""Simple, in-process store for PlanDelta objects per site.
|
||||
|
||||
This enables offline-first delta synchronization by persisting deltas
|
||||
locally and replaying them in order when connectivity is restored.
|
||||
"""
|
||||
|
||||
def __init__(self) -> None:
|
||||
# Mapping: site_id -> list of PlanDelta (in order of arrival)
|
||||
self._store: Dict[str, list[PlanDelta]] = {}
|
||||
|
||||
def add_delta(self, site_id: str, delta: PlanDelta) -> None:
|
||||
if site_id not in self._store:
|
||||
self._store[site_id] = []
|
||||
self._store[site_id].append(delta)
|
||||
|
||||
def get_deltas(self, site_id: str) -> list[PlanDelta]:
|
||||
return list(self._store.get(site_id, []))
|
||||
|
||||
def replay(self, site_id: str) -> list[PlanDelta]:
|
||||
"""Return a copy of the deltas for replay in the original order."""
|
||||
return self.get_deltas(site_id)
|
||||
|
|
|
|||
|
|
@ -0,0 +1,28 @@
|
|||
from __future__ import annotations
|
||||
|
||||
import time
|
||||
from energiamesh.core import LocalProblem, SharedVariables, PlanDelta
|
||||
from energiamesh.sync import compute_delta, DeltaStore
|
||||
|
||||
|
||||
def test_delta_store_basic_store_and_replay():
|
||||
# Prepare sample problem/state
|
||||
lp = LocalProblem(site_id="site-1", problem_id="p1", description="test")
|
||||
sv = SharedVariables(signals={"load_forecast": 123.0})
|
||||
|
||||
# Create two deltas to simulate incremental updates
|
||||
d1 = compute_delta(lp, sv)
|
||||
time.sleep(0.001)
|
||||
sv.update("load_forecast", 120.0)
|
||||
d2 = compute_delta(lp, sv)
|
||||
|
||||
store = DeltaStore()
|
||||
store.add_delta(lp.site_id, d1)
|
||||
store.add_delta(lp.site_id, d2)
|
||||
|
||||
# Replay should yield deltas in order
|
||||
deltas = store.replay(lp.site_id)
|
||||
assert len(deltas) == 2
|
||||
assert isinstance(deltas[0], PlanDelta)
|
||||
assert deltas[0].delta == d1.delta
|
||||
assert deltas[1].delta == d2.delta
|
||||
Loading…
Reference in New Issue