mellea.backends.adapters.io_contracts
Canonical output contracts for adapter functions (Epic #929 Phase 2, issue #1516).
Before this module existed, an adapter function's output contract travelled to
:func:~mellea.stdlib.components.intrinsic._util.call_intrinsic as a caller-supplied
argument, built from a module-level constant in rag.py or guardian.py, while the
adapter actually resolved by :meth:~mellea.backends.adapters.AdapterMixin.resolve_adapter
carried an unrelated placeholder contract. Nothing tied the two together, so passing the
wrong constant was a silent mismatch.
:data:_INTRINSIC_IO_CONTRACTS is the single source of truth instead: it is keyed by the
adapter function's catalog name (:attr:~mellea.backends.adapters.catalog.IntrinsicsCatalogEntry.name,
e.g. "guardian-core" — the same string passed to call_intrinsic and
resolve_adapter). The shim adapters in adapter.py read from it at construction
(via :func:get_io_contract); the high-level helpers reach it indirectly, through
the adapter resolve_adapter returns. Declaring a capability's contract anywhere
else reintroduces the parallel-argument problem this module exists to close.
An adapter a user registers with a backend takes precedence over the registry for its
own contract: call_intrinsic parses with whatever contract the resolved adapter
carries, and only adapters Mellea constructs itself (the lazy shims) get theirs from here.
Functions
FUNC get_io_contract
get_io_contract(name: str) -> IOContract
Return the canonical output contract for an adapter function.
Args:
name: Catalog name of the adapter function (e.g."answerability","guardian-core") — :attr:~mellea.backends.adapters.catalog.IntrinsicsCatalogEntry.name, never :attr:~mellea.backends.adapters.catalog.IntrinsicsCatalogEntry.effective_capability. This is the same string passed to :func:~mellea.stdlib.components.intrinsic._util.call_intrinsicand :meth:~mellea.backends.adapters.AdapterMixin.resolve_adapter.
Returns:
- The contract declared in :data:
_INTRINSIC_IO_CONTRACTSforname. Adapter functions outside the catalog (e.g. one registered through the deprecatedCustomIntrinsicAdapter) fall back to a dict contract with no required keys — permissive about which keys are present, but still requires the parsed JSON to be an object; a top-level array or scalar still raisesValueError, since Mellea has no declared schema for these adapter functions to relax that far.