From b71a0d1e4ba88803ac5a6b87db16fd62c207f23e Mon Sep 17 00:00:00 2001 From: agent-dd492b85242a98c5 Date: Mon, 20 Apr 2026 16:38:33 +0200 Subject: [PATCH] build(agent): new-agents-3#dd492b iteration --- .../__init__.py | 6 ++ .../bridge.py | 39 ++++++++++++ .../registry.py | 62 +++++++++++++++++++ tests/test_bridge.py | 20 ++++++ tests/test_registry.py | 20 ++++++ 5 files changed, 147 insertions(+) create mode 100644 src/algograph_algebraic_portfolio_compiler_f/bridge.py create mode 100644 src/algograph_algebraic_portfolio_compiler_f/registry.py create mode 100644 tests/test_bridge.py create mode 100644 tests/test_registry.py diff --git a/src/algograph_algebraic_portfolio_compiler_f/__init__.py b/src/algograph_algebraic_portfolio_compiler_f/__init__.py index 8e26da1..626d21d 100644 --- a/src/algograph_algebraic_portfolio_compiler_f/__init__.py +++ b/src/algograph_algebraic_portfolio_compiler_f/__init__.py @@ -9,6 +9,8 @@ from .portfolio import PortfolioBlock, solve_min_variance from .models import SignalMorphism, PlanDelta, DualVariables # Expose DSL primitives for algebraic portfolio modeling (MVP sketch) from .dsl import LocalProblem, SharedSignal, DSLPlanDelta, DSLDualVariables +from .bridge import to_canonical_ir, from_canonical_ir +from .registry import GraphOfContractsRegistry, ContractRecord __all__ = [ "PortfolioBlock", @@ -16,6 +18,10 @@ __all__ = [ "SignalMorphism", "PlanDelta", "DualVariables", + "to_canonical_ir", + "from_canonical_ir", + "GraphOfContractsRegistry", + "ContractRecord", # DSL primitives (MVP sketch) "LocalProblem", "SharedSignal", diff --git a/src/algograph_algebraic_portfolio_compiler_f/bridge.py b/src/algograph_algebraic_portfolio_compiler_f/bridge.py new file mode 100644 index 0000000..e8f2b3b --- /dev/null +++ b/src/algograph_algebraic_portfolio_compiler_f/bridge.py @@ -0,0 +1,39 @@ +from __future__ import annotations + +from typing import Dict, Any + +from .dsl import LocalProblem + + +def to_canonical_ir(lp: LocalProblem) -> Dict[str, Any]: + """Translate a LocalProblem (DSL) into a simple canonical IR dict. + + This minimal bridge is intentionally lightweight: it preserves the + essential fields needed for cross-venue interoperability while being + easy to serialize and replay. + """ + return { + "LocalProblem": { + "id": lp.id, + "assets": lp.assets, + "objective": lp.objective, + "constraints": lp.constraints, + "signals": lp.signals, + } + , + } + + +def from_canonical_ir(ir: Dict[str, Any]) -> LocalProblem: + """Reconstruct a LocalProblem from the canonical IR representation.""" + lp_dict = ir.get("LocalProblem", {}) + return LocalProblem( + id=lp_dict.get("id", ""), + assets=lp_dict.get("assets", []), + objective=lp_dict.get("objective", {}), + constraints=lp_dict.get("constraints", []), + signals=lp_dict.get("signals", {}), + ) + + +__all__ = ["to_canonical_ir", "from_canonical_ir"] diff --git a/src/algograph_algebraic_portfolio_compiler_f/registry.py b/src/algograph_algebraic_portfolio_compiler_f/registry.py new file mode 100644 index 0000000..bdb98ff --- /dev/null +++ b/src/algograph_algebraic_portfolio_compiler_f/registry.py @@ -0,0 +1,62 @@ +from __future__ import annotations + +from dataclasses import dataclass, field +from typing import Dict, List, Optional, Any +import time + + +@dataclass +class ContractRecord: + name: str + version: str + contract_id: str + schema: Dict[str, Any] + signer: str + timestamp: float + attestations: List[str] = field(default_factory=list) + + +@dataclass +class GraphOfContractsRegistry: + """In-memory, production-lite registry for Graph-of-Contracts. + + This is a lightweight scaffold to enable versioned adapters, data + schemas, and cryptographic attestations without leaking raw data. + """ + + contracts: Dict[str, ContractRecord] = field(default_factory=dict) + + def register_contract( + self, + contract_id: str, + name: str, + version: str, + schema: Dict[str, Any], + signer: str, + timestamp: Optional[float] = None, + ) -> None: + ts = timestamp if timestamp is not None else time.time() + rec = ContractRecord( + name=name, + version=version, + contract_id=contract_id, + schema=schema, + signer=signer, + timestamp=ts, + ) + self.contracts[contract_id] = rec + + def get_contract(self, contract_id: str) -> Optional[ContractRecord]: + return self.contracts.get(contract_id) + + def list_contracts(self) -> List[ContractRecord]: + return list(self.contracts.values()) + + def add_attestation(self, contract_id: str, attestation: str) -> None: + rec = self.contracts.get(contract_id) + if rec is None: + raise KeyError(f"Contract {contract_id} not found") + rec.attestations.append(attestation) + + +__all__ = ["ContractRecord", "GraphOfContractsRegistry"] diff --git a/tests/test_bridge.py b/tests/test_bridge.py new file mode 100644 index 0000000..4321719 --- /dev/null +++ b/tests/test_bridge.py @@ -0,0 +1,20 @@ +import numpy as np + +from algograph_algebraic_portfolio_compiler_f.dsl import LocalProblem +from algograph_algebraic_portfolio_compiler_f.bridge import to_canonical_ir, from_canonical_ir + + +def test_bridge_roundtrip_local_problem(): + lp = LocalProblem( + id="lp1", + assets=["A", "B"], + objective={"type": "quad", "Q": [[1.0, 0.0], [0.0, 1.0]], "c": [0.0, 0.0]}, + constraints=[], + signals={"price_A": 100.0}, + ) + ir = to_canonical_ir(lp) + lp2 = from_canonical_ir(ir) + assert isinstance(ir, dict) + assert lp2.id == lp.id + assert lp2.assets == lp.assets + assert lp2.signals == lp.signals diff --git a/tests/test_registry.py b/tests/test_registry.py new file mode 100644 index 0000000..226c26f --- /dev/null +++ b/tests/test_registry.py @@ -0,0 +1,20 @@ +import time + +from algograph_algebraic_portfolio_compiler_f.registry import GraphOfContractsRegistry + + +def test_registry_basic_operations(): + reg = GraphOfContractsRegistry() + reg.register_contract( + contract_id="idea-1", + name="toyAdapter", + version="0.1.0", + schema={"type": "adapter", "fields": ["price", "volume"]}, + signer="tester", + timestamp=time.time(), + ) + c = reg.get_contract("idea-1") + assert c is not None + assert c.name == "toyAdapter" + reg.add_attestation("idea-1", "attestation-123") + assert reg.get_contract("idea-1").attestations[-1] == "attestation-123"