From 9524e461616c819e10a032031049454979a649d9 Mon Sep 17 00:00:00 2001 From: agent-a6e6ec231c5f7801 Date: Tue, 21 Apr 2026 11:29:22 +0200 Subject: [PATCH] build(agent): new-agents#a6e6ec iteration --- exoroute/__init__.py | 5 ++++- exoroute/energi_bridge.py | 33 ++++++++++++++++++++++----------- exoroute/primitives.py | 35 +++++++++++++++++++++++++++++++++++ exoroute/toy_schemes.py | 6 +++++- 4 files changed, 66 insertions(+), 13 deletions(-) diff --git a/exoroute/__init__.py b/exoroute/__init__.py index af00e8a..ee4e7c8 100644 --- a/exoroute/__init__.py +++ b/exoroute/__init__.py @@ -1,4 +1,4 @@ -from .primitives import LocalProblem, SharedVariables, PlanDelta, DualVariables, PrivacyBudget, AuditLog, GraphOfContractsRegistry +from .primitives import LocalProblem, SharedVariables, PlanDelta, DualVariables, PrivacyBudget, AuditLog, GraphOfContractsRegistry, TimeRounds, GoCEntry, GoCRegistry from .energi_bridge import EnergiBridge __all__ = [ @@ -9,5 +9,8 @@ __all__ = [ "PrivacyBudget", "AuditLog", "GraphOfContractsRegistry", + "TimeRounds", + "GoCEntry", + "GoCRegistry", "EnergiBridge", ] diff --git a/exoroute/energi_bridge.py b/exoroute/energi_bridge.py index 80a39ab..9316701 100644 --- a/exoroute/energi_bridge.py +++ b/exoroute/energi_bridge.py @@ -1,6 +1,6 @@ -from typing import Dict, Any +from typing import Dict, Any, Optional from datetime import datetime -from .primitives import LocalProblem, SharedVariables, PlanDelta, DualVariables +from .primitives import LocalProblem, SharedVariables, PlanDelta, DualVariables, TimeRounds def _map_to_ir(lp: LocalProblem, sv: SharedVariables, pd: PlanDelta, dv: DualVariables) -> Dict[str, Any]: @@ -21,6 +21,23 @@ def _map_to_ir(lp: LocalProblem, sv: SharedVariables, pd: PlanDelta, dv: DualVar "objective": lp.objective, "constraints": lp.constraints, } + # Base plan_delta payload + pd_payload = { + "delta": pd.delta, + "timestamp": ts_iso, + "author": pd.author, + "contract_id": pd.contract_id, + "signature": pd.signature, + } + # Optional time_rounds handling + tr = getattr(pd, "time_rounds", None) + if tr is not None: + pd_payload["time_rounds"] = { + "round_id": tr.round_id, + "start_ts": tr.start_ts, + "end_ts": tr.end_ts, + } + ir = { "object": {"type": "LocalProblem", "payload": payload}, "morphisms": { @@ -30,13 +47,7 @@ def _map_to_ir(lp: LocalProblem, sv: SharedVariables, pd: PlanDelta, dv: DualVar "lambda_fees": dv.lambda_fees, }, }, - "plan_delta": { - "delta": pd.delta, - "timestamp": ts_iso, - "author": pd.author, - "contract_id": pd.contract_id, - "signature": pd.signature, - }, + "plan_delta": pd_payload, } return ir @@ -58,11 +69,11 @@ class EnergiBridge: # Backwards-compat alias expected by tests @staticmethod - def map_to_ir(lp: LocalProblem, sv: SharedVariables, pd: PlanDelta, dv: DualVariables = None) -> Dict[str, Any]: + def map_to_ir(lp: LocalProblem, sv: SharedVariables, pd: PlanDelta, dv: Optional[DualVariables] = None) -> Dict[str, Any]: return map_to_ir(lp, sv, pd, dv) -def map_to_ir(lp: LocalProblem, sv: SharedVariables, pd: PlanDelta, dv: DualVariables = None) -> Dict[str, Any]: +def map_to_ir(lp: LocalProblem, sv: SharedVariables, pd: PlanDelta, dv: Optional[DualVariables] = None) -> Dict[str, Any]: if dv is None: dv = DualVariables() return _map_to_ir(lp, sv, pd, dv) diff --git a/exoroute/primitives.py b/exoroute/primitives.py index 6486bea..4fdd905 100644 --- a/exoroute/primitives.py +++ b/exoroute/primitives.py @@ -1,6 +1,7 @@ from __future__ import annotations from dataclasses import dataclass, field +from typing import Optional from typing import Dict, List, Any, Optional from datetime import datetime @@ -28,6 +29,8 @@ class PlanDelta: author: str contract_id: str signature: Optional[str] = None + # Optional time-round metadata to support deterministic offline replay + time_rounds: Optional["TimeRounds"] = None @dataclass @@ -62,6 +65,35 @@ class GraphOfContractsRegistry: return self.registry.get(adapter_id) +@dataclass +class TimeRounds: + """Monoid-like container describing discrete offline replay rounds.""" + round_id: str + start_ts: float + end_ts: float + + +@dataclass +class GoCEntry: + adapter_id: str + supported_domains: List[str] + contract_version: str + + +@dataclass +class GoCRegistry: + entries: List[GoCEntry] = field(default_factory=list) + + def register(self, entry: GoCEntry) -> None: + self.entries.append(entry) + + def get_contract_version(self, adapter_id: str) -> Optional[str]: + for e in self.entries: + if e.adapter_id == adapter_id: + return e.contract_version + return None + + __all__ = [ "LocalProblem", "SharedVariables", @@ -70,4 +102,7 @@ __all__ = [ "PrivacyBudget", "AuditLog", "GraphOfContractsRegistry", + "TimeRounds", + "GoCEntry", + "GoCRegistry", ] diff --git a/exoroute/toy_schemes.py b/exoroute/toy_schemes.py index 5385f3b..162eddd 100644 --- a/exoroute/toy_schemes.py +++ b/exoroute/toy_schemes.py @@ -1,6 +1,6 @@ from __future__ import annotations -from .primitives import LocalProblem, SharedVariables, PlanDelta, DualVariables, PrivacyBudget, AuditLog, GraphOfContractsRegistry +from .primitives import LocalProblem, SharedVariables, PlanDelta, DualVariables, PrivacyBudget, AuditLog, GraphOfContractsRegistry, TimeRounds def sample_local_problem() -> LocalProblem: @@ -50,6 +50,10 @@ def sample_registry() -> GraphOfContractsRegistry: return reg +def sample_time_rounds() -> TimeRounds: + return TimeRounds(round_id="tr-1", start_ts=0.0, end_ts=3600.0) + + __all__ = [ "sample_local_problem", "sample_shared_variables",