Repository navigation
refactor(intrinsics): internal migration with shims — old classes inherit from Adapter; call_intrinsic rewritten (Epic #929 Phase 1) #1136
Description
Parent epic: #929
Design proposal: PR #1080
Phase: 1 (Wave 2 — start after 0.1 has a draft PR)
Depends on: 0.1
Blocks: 1.B, 1.C, 1.D, 2.1, 4.1
⚠️ Phase 1 bottleneck. This is the only serialisation point before Wave 3 opens four parallel tracks. Keep the PR narrow (~300–500 LOC) to merge quickly.
Problem
mellea/stdlib/components/intrinsic/_util.py:call_intrinsic and mellea/stdlib/requirements/requirement.py (requirement rerouting) branch on the old IntrinsicAdapter / EmbeddedIntrinsicAdapter subclasses. Until these internal callers operate on the new Adapter type from 0.1, no helper file can migrate. External users may also construct the old classes directly — migrating internals without a backward-compat path breaks them.
Agreed design
Two tightly-coupled changes in one PR (splitting creates ordering pain and conflicting branch state):
(a) Old classes become inheriting shims
IntrinsicAdapter, EmbeddedIntrinsicAdapter, CustomIntrinsicAdapter are restructured to:
- Inherit from
Adapter(new dataclass from 0.1) —isinstance(x, IntrinsicAdapter)andisinstance(x, Adapter)both work - Translate constructor args into
Identity+IOContract+WeightsBindingtriple, then callAdapter.__init__ - Emit a
DeprecationWarningonce per construction site (stacklevel=2) pointing at the new construction pattern - Carry no behavioural state of their own — delegate to inherited
Adaptermachinery
(b) Internal callers operate on Adapter
_util.call_intrinsic and requirement rerouting rewritten to:
adapter = backend.resolve_adapter(name)
with backend.adapter_scope(adapter):
raw = backend.generate(adapter.io_contract.build_prompt(...))
return adapter.io_contract.parse(raw)adapter_scopewrapsactivate()/deactivate()per call; this is the future telemetry parent — Phase 2 wraps it in anintrinsic.callOTel span; the hook point must exist at the right call-site boundary nowprepare()at session start (2.2);release()at session teardown- Capability-based lookup for requirement rerouting uses
Identity.capabilityinstead ofisinstancebranching - Backends grow stub
resolve_adapter/adapter_scopeimplementations delegating to old code paths (real implementations in Phase 2)
Docs update
docs/dev/requirement_aLoRA_rerouting.md— update to describe capability-based lookup (usingIdentity.capability) instead of hardcodedrequirement-checkstring. This resolves thread 7 in the design proposal's thread mapping.
Scope
mellea/backends/adapters/__init__.py— old classes as inheriting shimsmellea/stdlib/components/intrinsic/_util.py—call_intrinsicrewrittenmellea/stdlib/requirements/requirement.py— rerouting rewritten- Abstract backend + concrete backend stubs:
resolve_adapter,adapter_scope(no instrumentation yet) docs/dev/requirement_aLoRA_rerouting.md— capability-based lookup documentation
Out of scope
Helper file migration (1.B–D), backend verb implementations (Phase 2), AdapterMixin rename (2.1), shim removal (4.1).
Acceptance criteria
-
IntrinsicAdapter(...)returns instance satisfying bothisinstance(x, IntrinsicAdapter)andisinstance(x, Adapter) - Same for
EmbeddedIntrinsicAdapterandCustomIntrinsicAdapter - Each old constructor emits exactly one
DeprecationWarningper call (not per import),stacklevel=2 -
_util.call_intrinsicoperates onAdapter; noisinstancebranching on old subclasses - Requirement rerouting uses
Identity.capability -
adapter_scopeexists at the correct call-site boundary; pass-through context manager at this stage -
docs/dev/requirement_aLoRA_rerouting.mdupdated; markdownlint passes - All existing tests pass (behavioural neutrality is the bar)
-
ruff format,ruff check,mypyclean
Test plan
test/backends/adapters/test_old_class_shims.py:
test_old_classes_inherit_from_adaptertest_old_constructor_emits_deprecation_warning— once per call,stacklevel=2test_old_constructor_drop_in_replaceable— construct via old API, assert behaviour matchesAdapter(...)directly
New tests for capability-based lookup with multiple registered capabilities.
Breaking changes
- Subclassing the old classes: anyone overriding internal methods of
IntrinsicAdapteretc. may break. Public constructor signature preserved. isinstancechecks against the oldAdapterABC: depends on the naming-collision resolution chosen in 0.1.
Document both in the PR description with migration examples.
References
- PR docs: design proposal for adapter lifecycle (#929) — review channel, do not merge #1080 §9, §11, §16 Phase 1
- Epic: Fix Adapter Function Lifecycle & Consistency in Mellea #929 thread mapping rows 1, 2, 3
- add support for granite-switch / embedded adapters on our huggingface backend #1018 — uses
resolve_adapter/adapter_scopeintroduced here
Activity
planetf1 commentedon Jun 11, 2026
This issue uses vocabulary that has been superseded by the agreed Epic #929 glossary. Please use the following terms in any new work related to this issue:
The canonical definitions are now in the project glossary and were established as part of #1192. Python symbol names (
IntrinsicAdapter,fetch_intrinsic_metadata, etc.) keep their current names until Phase 1 (#1136) and Phase 4 (#1144).chore(terminology): adopt agreed Granite Switch / Mellea glossary (ge…
chore(terminology): sweep Guardian Intrinsics → Guardian adapter func…
feat(intrinsics): shim old adapters onto Adapter dataclass; rewrite c…
feat(intrinsics): shim old adapters onto Adapter dataclass; rewrite c…
feat(intrinsics): shim old adapters onto Adapter dataclass; rewrite c…
chore(terminology): adopt agreed Granite Switch / Mellea glossary (ge…
chore(terminology): sweep Guardian Intrinsics → Guardian adapter func…
2 remaining items
feat(intrinsics): shim old adapters onto Adapter dataclass; rewrite c…
chore(terminology): adopt agreed Granite Switch / Mellea glossary (ge…
planetf1 commentedon Jun 18, 2026
Testing summary
All 216 unit and integration intrinsic tests pass on both macOS and GPU.
Five GPU-only tests flagged during review turned out to be pre-existing issues on
upstream/main, not regressions. To get solid data we ran them 10× each on the same GPU cluster, comparing main (317d5d9) against this branch (f6fb2e7):context_relevance_alorauncertainty_alorarequirement_check_aloracontext-attributiongroundedness_e2e_string_documentsNo regressions. The two tests that improved (
context-attribution,groundedness) appear to benefit from the_find_adapterordering fix — when aLoRA is available and working, these tests get better results from it.The consistently-failing pair (
context_relevance_alora,uncertainty_alora) are a pre-existing peft bug tracked in #1286. The remaining three are GPU score non-determinism tracked in #1291.feat(intrinsics): shim old adapters onto Adapter dataclass; rewrite c…
feat(intrinsics): shim old adapters onto Adapter dataclass; call_intr…
refactor(telemetry): rename Intrinsic* symbols to AdapterFunction* pe…
refactor(backends)!: narrow AdapterMixin verbs, centralize option res…