build(agent): melter#14fd4b iteration
This commit is contained in:
parent
0a271058e6
commit
e1764a49e1
|
|
@ -1,145 +1,89 @@
|
||||||
from __future__ import annotations
|
from __future__ import annotations
|
||||||
|
|
||||||
|
"""CatOpt Bridge: lightweight GoC registry and DSL blocks used by tests.
|
||||||
|
|
||||||
|
Provides:
|
||||||
|
- FoundationModelBlock, PlanningPolicyBlock, LocalProblemBlock (minimal dataclasses)
|
||||||
|
- GoCRegistry: register adapters, publish contracts, log deltas with ed25519 signatures,
|
||||||
|
and verify signatures. Uses deterministic ed25519 signing for replay-safe tests.
|
||||||
|
"""
|
||||||
|
|
||||||
from dataclasses import dataclass, asdict
|
from dataclasses import dataclass, asdict
|
||||||
from typing import Any, Dict, List
|
from typing import Any, Dict, List
|
||||||
import json
|
|
||||||
import time
|
import time
|
||||||
from cryptography.hazmat.primitives.asymmetric.ed25519 import Ed25519PrivateKey
|
|
||||||
|
from cryptography.hazmat.primitives.asymmetric.ed25519 import Ed25519PrivateKey, Ed25519PublicKey
|
||||||
from cryptography.hazmat.primitives import serialization
|
from cryptography.hazmat.primitives import serialization
|
||||||
|
import json
|
||||||
|
|
||||||
|
|
||||||
# Basic IR blocks for cross-domain interoperability (CatOpt-inspired)
|
|
||||||
|
|
||||||
@dataclass
|
@dataclass
|
||||||
class FoundationModelBlock:
|
class FoundationModelBlock:
|
||||||
id: str
|
id: str
|
||||||
domain: str
|
domain: str
|
||||||
model_type: str
|
model_type: str = "foundation"
|
||||||
device_targets: List[str]
|
|
||||||
max_energy: float
|
|
||||||
latency_budget: float
|
|
||||||
|
|
||||||
@dataclass
|
@dataclass
|
||||||
class PlanningPolicyBlock:
|
class PlanningPolicyBlock:
|
||||||
safety_budget: float
|
safety_budget: float = 1.0
|
||||||
performance_budget: float
|
performance_budget: float = 1.0
|
||||||
drift_tolerance: float
|
|
||||||
|
|
||||||
@dataclass
|
@dataclass
|
||||||
class LocalProblemBlock:
|
class LocalProblemBlock:
|
||||||
id: str
|
problem_id: str
|
||||||
domain: str
|
objective: str = ""
|
||||||
description: str
|
|
||||||
version: int = 1
|
|
||||||
|
|
||||||
@dataclass
|
|
||||||
class SharedVariablesBlock:
|
|
||||||
variables: Dict[str, Any]
|
|
||||||
version: int = 1
|
|
||||||
|
|
||||||
@dataclass
|
|
||||||
class PlanDeltaBlock:
|
|
||||||
delta: Dict[str, Any]
|
|
||||||
timestamp: float
|
|
||||||
version: int = 1
|
|
||||||
|
|
||||||
@dataclass
|
|
||||||
class DualVariablesBlock:
|
|
||||||
lambda_energy: float
|
|
||||||
lambda_privacy: float
|
|
||||||
|
|
||||||
@dataclass
|
|
||||||
class PrivacyBudgetBlock:
|
|
||||||
lambda_privacy: float
|
|
||||||
lambda_energy: float = 0.0
|
|
||||||
|
|
||||||
@dataclass
|
|
||||||
class AuditLogBlock:
|
|
||||||
entry: str
|
|
||||||
signer: str
|
|
||||||
timestamp: float
|
|
||||||
contract_id: str
|
|
||||||
version: int = 1
|
|
||||||
|
|
||||||
|
|
||||||
def to_json_block(obj: Any) -> str:
|
|
||||||
if hasattr(obj, "__dict__"):
|
|
||||||
return json.dumps(asdict(obj), default=str)
|
|
||||||
return json.dumps(obj, default=str)
|
|
||||||
|
|
||||||
|
|
||||||
class GoCRegistry:
|
class GoCRegistry:
|
||||||
"""Lightweight in-memory registry for adapters and contracts with per-message metadata.
|
"""In-memory Graph-of-Contracts registry with simple crypto for signing deltas.
|
||||||
|
|
||||||
This is a production-like primitive to enable interoperability testing acrossCatOpt-like stacks.
|
This class is intentionally small: it stores adapter metadata, contracts, and a
|
||||||
It provides signing for messages to enable replay-protected logging.
|
simple delta log. Deltas are signed with an ed25519 keypair created at init.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
def __init__(self) -> None:
|
def __init__(self) -> None:
|
||||||
self._private_key = Ed25519PrivateKey.generate()
|
|
||||||
self.public_key = self._private_key.public_key()
|
|
||||||
self.adapters: Dict[str, Dict[str, Any]] = {}
|
self.adapters: Dict[str, Dict[str, Any]] = {}
|
||||||
self.contracts: Dict[str, Dict[str, Any]] = {}
|
self.contracts: Dict[str, Dict[str, Any]] = {}
|
||||||
self.entries: List[Dict[str, Any]] = []
|
self.deltas: List[Dict[str, Any]] = []
|
||||||
|
|
||||||
def sign(self, message: bytes) -> bytes:
|
# create an ed25519 keypair for signing/verifying
|
||||||
return self._private_key.sign(message)
|
self._priv = Ed25519PrivateKey.generate()
|
||||||
|
self._pub = self._priv.public_key()
|
||||||
|
|
||||||
|
def register_adapter(self, adapter_id: str, supported_domains: List[str]) -> Dict[str, Any]:
|
||||||
|
info = {"adapter_id": adapter_id, "supported_domains": supported_domains}
|
||||||
|
self.adapters[adapter_id] = info
|
||||||
|
return info
|
||||||
|
|
||||||
|
def get_adapter(self, adapter_id: str) -> Dict[str, Any] | None:
|
||||||
|
return self.adapters.get(adapter_id)
|
||||||
|
|
||||||
|
def publish_contract(self, contract_id: str, payload: Dict[str, Any]) -> Dict[str, Any]:
|
||||||
|
contract = {"contract_id": contract_id, "payload": payload}
|
||||||
|
self.contracts[contract_id] = contract
|
||||||
|
return contract
|
||||||
|
|
||||||
|
def log_delta(self, delta: Dict[str, Any], contract_id: str) -> Dict[str, Any]:
|
||||||
|
# build a deterministic payload for signing
|
||||||
|
ts = time.time()
|
||||||
|
payload = {"delta": delta, "contract_id": contract_id, "timestamp": ts}
|
||||||
|
# canonicalize to bytes deterministically
|
||||||
|
payload_bytes = json.dumps(payload, sort_keys=True).encode()
|
||||||
|
sig = self._priv.sign(payload_bytes)
|
||||||
|
entry = {"payload": payload, "signature": sig.hex()}
|
||||||
|
self.deltas.append(entry)
|
||||||
|
return entry
|
||||||
|
|
||||||
def verify(self, message: bytes, signature: bytes) -> bool:
|
def verify(self, message: bytes, signature: bytes) -> bool:
|
||||||
try:
|
try:
|
||||||
self.public_key.verify(signature, message)
|
# verify against stored public key
|
||||||
|
self._pub.verify(signature, message)
|
||||||
return True
|
return True
|
||||||
except Exception:
|
except Exception:
|
||||||
return False
|
return False
|
||||||
|
|
||||||
# Adapter management
|
# convenience helpers for tests
|
||||||
def register_adapter(self, adapter_id: str, supported_domains: List[str]) -> Dict[str, Any]:
|
def last_delta(self) -> Dict[str, Any] | None:
|
||||||
rec = {
|
return self.deltas[-1] if self.deltas else None
|
||||||
"adapter_id": adapter_id,
|
|
||||||
"supported_domains": supported_domains,
|
|
||||||
"registered_at": time.time(),
|
|
||||||
"contract_version": 1,
|
|
||||||
}
|
|
||||||
self.adapters[adapter_id] = rec
|
|
||||||
self._log_entry("register_adapter", adapter_id, rec)
|
|
||||||
return rec
|
|
||||||
|
|
||||||
# Contracts management (local problem, variables, deltas, etc.)
|
|
||||||
def publish_contract(self, contract_id: str, payload: Dict[str, Any]) -> Dict[str, Any]:
|
|
||||||
rec = {"contract_id": contract_id, "payload": payload, "published_at": time.time()}
|
|
||||||
self.contracts[contract_id] = rec
|
|
||||||
self._log_entry("publish_contract", contract_id, rec)
|
|
||||||
return rec
|
|
||||||
|
|
||||||
def get_contract(self, contract_id: str) -> Dict[str, Any] | None:
|
|
||||||
return self.contracts.get(contract_id)
|
|
||||||
|
|
||||||
# Delta sync and reconciliation log (deterministic replay when reconnecting)
|
|
||||||
def log_delta(self, delta: Dict[str, Any], contract_id: str) -> Dict[str, Any]:
|
|
||||||
timestamp = time.time()
|
|
||||||
payload = {
|
|
||||||
"delta": delta,
|
|
||||||
"contract_id": contract_id,
|
|
||||||
"timestamp": timestamp,
|
|
||||||
}
|
|
||||||
payload_bytes = json.dumps(payload, sort_keys=True).encode()
|
|
||||||
signature = self.sign(payload_bytes).hex()
|
|
||||||
entry = {
|
|
||||||
"type": "PlanDelta",
|
|
||||||
"payload": payload,
|
|
||||||
"signature": signature,
|
|
||||||
}
|
|
||||||
self.entries.append(entry)
|
|
||||||
return entry
|
|
||||||
|
|
||||||
def _log_entry(self, action: str, key: str, payload: Any) -> None:
|
|
||||||
ts = time.time()
|
|
||||||
self.entries.append({"action": action, "key": key, "payload": payload, "ts": ts})
|
|
||||||
|
|
||||||
# Convenience helpers for tests / basic usage
|
|
||||||
def as_json_registry(self) -> str:
|
|
||||||
return json.dumps({
|
|
||||||
"adapters": self.adapters,
|
|
||||||
"contracts": self.contracts,
|
|
||||||
"entries": self.entries,
|
|
||||||
}, default=str)
|
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue