97 lines
3.8 KiB
Python
97 lines
3.8 KiB
Python
"""Markitect package bridge helpers."""
|
|
|
|
from __future__ import annotations
|
|
|
|
from typing import Any, Protocol
|
|
|
|
from .contracts import ContractIngressResult, graph_from_markitect, profile_from_markitect, selection_from_markitect
|
|
from .models import Diagnostic
|
|
from .utils import stable_digest
|
|
|
|
MARKITECT_PACKAGE_REQUEST_SCHEMA = "phase_memory.markitect.package_request.v1"
|
|
MARKITECT_PACKAGE_RESPONSE_SCHEMA = "phase_memory.markitect.package_response.v1"
|
|
|
|
|
|
class MarkitectValidator(Protocol):
|
|
def validate_profile(self, data: dict[str, Any]) -> ContractIngressResult: ...
|
|
def validate_graph(self, data: dict[str, Any]) -> ContractIngressResult: ...
|
|
def validate_selection(self, data: dict[str, Any]) -> ContractIngressResult: ...
|
|
|
|
|
|
class LocalMarkitectValidator:
|
|
"""Dependency-light validation boundary using local ingress diagnostics."""
|
|
|
|
def validate_profile(self, data: dict[str, Any]) -> ContractIngressResult:
|
|
return profile_from_markitect(data)
|
|
|
|
def validate_graph(self, data: dict[str, Any]) -> ContractIngressResult:
|
|
return graph_from_markitect(data)
|
|
|
|
def validate_selection(self, data: dict[str, Any]) -> ContractIngressResult:
|
|
return selection_from_markitect(data)
|
|
|
|
|
|
class OptionalMarkitectValidator:
|
|
"""Adapter shell for optional Markitect-owned validation."""
|
|
|
|
def __init__(self, delegate: Any | None = None) -> None:
|
|
self.delegate = delegate
|
|
self.local = LocalMarkitectValidator()
|
|
|
|
def validate_profile(self, data: dict[str, Any]) -> ContractIngressResult:
|
|
if self.delegate and hasattr(self.delegate, "validate_memory_profile"):
|
|
return self.delegate.validate_memory_profile(data)
|
|
return self.local.validate_profile(data)
|
|
|
|
def validate_graph(self, data: dict[str, Any]) -> ContractIngressResult:
|
|
if self.delegate and hasattr(self.delegate, "validate_memory_graph"):
|
|
return self.delegate.validate_memory_graph(data)
|
|
return self.local.validate_graph(data)
|
|
|
|
def validate_selection(self, data: dict[str, Any]) -> ContractIngressResult:
|
|
if self.delegate and hasattr(self.delegate, "validate_memory_selection"):
|
|
return self.delegate.validate_memory_selection(data)
|
|
return self.local.validate_selection(data)
|
|
|
|
|
|
def package_request_from_selection(
|
|
selection: dict[str, Any],
|
|
*,
|
|
compiler: str,
|
|
diagnostics: tuple[Diagnostic, ...] = (),
|
|
) -> dict[str, Any]:
|
|
metadata = dict(selection.get("metadata") or {})
|
|
request_id = f"markitect-package-request:{stable_digest([selection, compiler])}"
|
|
return {
|
|
"schema_version": MARKITECT_PACKAGE_REQUEST_SCHEMA,
|
|
"id": request_id,
|
|
"selection_id": selection.get("id"),
|
|
"graph_id": selection.get("graph"),
|
|
"profile_id": selection.get("profile"),
|
|
"selected_nodes": list(selection.get("nodes", ())),
|
|
"selected_events": list(selection.get("events", ())),
|
|
"budget": {
|
|
"max_items": metadata.get("max_items"),
|
|
"max_tokens": metadata.get("max_tokens"),
|
|
"token_estimate": metadata.get("token_estimate"),
|
|
},
|
|
"policy": metadata.get("policy", {}),
|
|
"provenance": {
|
|
"selected_items": metadata.get("selected_items", {}),
|
|
"planned_by": metadata.get("planned_by"),
|
|
},
|
|
"compiler": compiler,
|
|
"compiler_diagnostics": [diagnostic.to_dict() for diagnostic in diagnostics],
|
|
"selection": dict(selection),
|
|
"dry_run": True,
|
|
}
|
|
|
|
|
|
def package_response_envelope(response: dict[str, Any], *, request_id: str) -> dict[str, Any]:
|
|
return {
|
|
"schema_version": MARKITECT_PACKAGE_RESPONSE_SCHEMA,
|
|
"request_id": request_id,
|
|
"package_ref": response.get("package_id") or response.get("package_ref") or "",
|
|
"compiler_diagnostics": list(response.get("diagnostics", ())),
|
|
"response": dict(response),
|
|
}
|