diff --git a/README.md b/README.md index 3457698..9496cce 100644 --- a/README.md +++ b/README.md @@ -41,3 +41,21 @@ Directory layout - READY_TO_PUBLISH (created after the repo is ready for publishing) Note: This is a minimal MVP intended for demonstration and testing; it is not a production-ready system. +# NovaPlan +## Interoperability and CatOpt Bridge + +- NovaPlan includes a lightweight CatOpt bridge scaffold to map planning primitives + into a canonical representation for interoperability with other runtimes (Open-EnergyMesh, + GridVerse, etc.). +- The bridge exposes minimal primitives: Object (LocalProblem summary) and Morphism (delta signals). +- Convenience helpers are available to generate a pair in a single call, for use by adapters. +- See nova_plan/catopt_bridge.py for the core bridge logic and nova_plan/interop_catopt.py for + a small, import-friendly interoperability facade. + +MVP notes +- LocalProblem -> Object_i +- SharedVariables/DualVariables -> Morphisms carrying summarized signals +- PlanDelta / PrivacyBudget / AuditLog -> per-message metadata +- Graph-of-Contracts registry with versioned schemas (ContractRegistry) + +This repository already includes: LocalProblem DSL, adapters stubs, and a test-aware bridge. diff --git a/nova_plan/catopt_bridge.py b/nova_plan/catopt_bridge.py index b62d823..6e6ef4e 100644 --- a/nova_plan/catopt_bridge.py +++ b/nova_plan/catopt_bridge.py @@ -72,4 +72,15 @@ def validate_contracts(obj: Object, morph: Morphism) -> bool: return delta_keys.issubset(obj_keys) +def bridge_pair(lp: LocalProblem, source: str, target: str, version: int | None = 1) -> Dict[str, Any]: + """Convenience helper returning a CatOpt-style pair for a given LocalProblem. + + This is a small wrapper mirrors bridge_example but allows explicit version + control and is intended for use by external adapters that want a stable + tuple without constructing the JSON themselves. + """ + obj = to_object(lp) + morph = to_morphism(delta={k: v for k, v in lp.variables.items()}, source=source, target=target, version=version) + return {"object": obj.to_dict(), "morphism": morph.to_json()} + __all__ = ["Object", "Morphism", "to_object", "to_morphism", "bridge_example", "validate_contracts"] diff --git a/nova_plan/interop_catopt.py b/nova_plan/interop_catopt.py new file mode 100644 index 0000000..cee8eb0 --- /dev/null +++ b/nova_plan/interop_catopt.py @@ -0,0 +1,28 @@ +"""Interoperability helpers for NovaPlan <-> CatOpt bridge. + +This module provides a tiny, import-friendly entry point to produce a +CatOpt-compatible pair (Object + Morphism) from a LocalProblem. It leverages +the existing bridge utilities and keeps integration concerns centralized. +""" +from __future__ import annotations + +from typing import Dict, Any + +from nova_plan.dsl import LocalProblemDSL +from nova_plan.planner import LocalProblem +from nova_plan.catopt_bridge import bridge_pair + + +def to_catopt_pair_from_dsl(dsl: LocalProblemDSL, source: str, target: str, version: int = 1) -> Dict[str, Any]: + """Convert a LocalProblemDSL description to a CatOpt-style pair. + + This is a convenience facade used by adapters to bootstrap NovaPlan + primitives into a canonical CatOpt representation. + """ + lp: LocalProblem = dsl.to_local_problem() + return bridge_pair(lp, source=source, target=target, version=version) + + +def to_catopt_pair_from_lp(lp: LocalProblem, source: str, target: str, version: int = 1) -> Dict[str, Any]: + """Convert an existing LocalProblem instance into a CatOpt-style pair.""" + return bridge_pair(lp, source=source, target=target, version=version)