You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Parent epic:#929 Design proposal: PR #1080 §16 Phase 4, Part I §5 Q4 Phase: 4 (final) Depends on:#1141, #1142, #1516, #1465, #1018 — all merged. Deprecation window opened 2026-09-02 (last dependency, #1018/PR #1593); team has decided to proceed now.
Update (2026-09-03) — scope correction: this is not just a deletion
The original scope below assumed callers were "already on new types" and this issue was cleanup. That's false as of 2026-09-03, verified against current main. Neither LocalHFBackend.add_adapter nor OpenAIBackend.add_adapter accepts a composed Adapter (_core.Adapter) directly — both reject it via isinstance gates and raise TypeError. The only working path today for LoRA/embedded intrinsic use is through the three deprecated shim classes (IntrinsicAdapter, EmbeddedIntrinsicAdapter, CustomIntrinsicAdapter), and that's true of production code, not just docs/examples:
AdapterMixin.resolve_adapter() (mellea/backends/adapters/adapter.py:612-724) — the shared lazy-registration path every backend inherits — directly constructs EmbeddedIntrinsicAdapter.from_source(...) (L675) or IntrinsicAdapter(name, adapter_type=AdapterType.LORA, base_model_name=base) (L688).
mellea/backends/openai.py (OpenAIBackend): add_adapter() (L310, isinstance gate L327 — EmbeddedIntrinsicAdapter is the only accepted reality), register_embedded_adapter_model() (L361, L379), _generate_from_intrinsic() (gates at L760, L784, L884/890), self._added_adapters: dict[str, EmbeddedIntrinsicAdapter] type annotation (L278).
Product-facing, easy to miss: cli/alora/README_TEMPLATE.jinja (L44, L52) — every m alora upload --intrinsic invocation generates user scaffolding that subclasses CustomIntrinsicAdapter. This has to change in lockstep with the backend code, not as an afterthought.
Given this, the work splits into two PRs, stacked:
PR1 — build the composed-Adapter-direct path (additive, land first)
Goal: both backends accept a composed Adapter(identity, io_contract, weights_binding) directly, alongside the existing shim path (which keeps working unchanged — no behaviour change for existing callers in this PR).
Code:
LocalHFBackend.add_adapter / OpenAIBackend.add_adapter — extend the isinstance gates to accept a composed Adapter instance and dispatch correctly (LocalFileBinding → PEFT path, EmbeddedBinding → embedded path).
AdapterMixin.resolve_adapter() — construct a composed Adapter instead of the shim classes when registering. (This is the one call site both backends inherit — get this right once.)
register_embedded_adapter_model(), load_peft_adapter() (HF only), _generate_from_intrinsic() in both backends — same treatment, dispatch on binding type rather than the shim's own type.
cli/alora/README_TEMPLATE.jinja — generate composed-Adapter scaffolding instead of a CustomIntrinsicAdapter subclass.
Tests (new — none of this exists today, so none of it is covered today):
Unit tests for the new isinstance/dispatch branches in both backends.
Integration test exercising the composed path end-to-end through call_intrinsic/Intrinsic.
Rewrite the five test files that currently exercise production code through the shim classes to also/instead cover the composed path: test/backends/test_adapters/test_embedded_integration.py, test/backends/test_openai_intrinsics_unit.py, test/backends/test_huggingface_unit.py, test/backends/test_huggingface.py, and the TestOpenAIBackendRegistration class in test/backends/test_adapters/test_embedded_adapter.py.
Docs/examples (8 files):
docs/docs/advanced/intrinsics.md — rewrite the "Composable adapter construction (advanced)" section (currently accurately states neither backend supports this — flip it to the real, working example) and the "Direct adapter function usage" section (currently recommends CustomIntrinsicAdapter directly).
docs/docs/advanced/lora-and-alora-adapters.md — "Use the adapter in Mellea" section already self-flags as pending this issue; update it.
docs/docs/integrations/openai.md — priority: the "load adapters manually" section has no deprecation caveat today (unlike the other two docs) and reads as the unqualified recommended way. Most likely to mislead someone who reads it before this issue lands.
docs/examples/aLora/101_example.py, docs/examples/aLora/README.md, docs/examples/aLora/stembolts_intrinsic.py, docs/examples/granite-switch/manual_adapter_loading.py, docs/examples/granite-switch/README.md, docs/examples/intrinsics/intrinsics.py — all construct a shim class directly as their canonical pattern; update to the composed path.
Tutorials (write here, not deferred to PR2):
"Adding a custom adapter function in 20 lines" — replaces the CustomIntrinsicAdapter monkey-patch story.
"Handling a breaking schema change without breaking users" — requirement-check v1→v2 worked example; HF revision pinning and AdapterSchemaMismatchError.
"Reading adapter function telemetry" — dashboard-building guide referencing mellea.adapter_function.parse_failures, mellea.adapter_function.phase_duration, and the span tree.
PR1 acceptance criteria:
Both backends accept a composed Adapter directly; existing shim path unchanged/still passing
New unit + integration + real-GPU e2e coverage for the composed path (see Tests above)
The five shim-routed test files updated to also cover the composed path
All 8 docs/examples files updated; docs/docs/integrations/openai.md explicitly prioritized
All three tutorials written, validated against current source, linked from docs/docs/advanced/intrinsics.md
markdownlint clean on all touched docs
Full test suite + mypy + ruff clean (existing CI gate — no new exemptions)
PR2 — delete the shims (stacked on PR1)
Goal: remove the now-genuinely-unused deprecated path. This PR's own green CI run against PR1-merged-into-main is the actual proof "we have no use left" — that's the validation, not a comment claiming it.
Code:
Delete IntrinsicAdapter, EmbeddedIntrinsicAdapter, CustomIntrinsicAdapter (mellea/backends/adapters/adapter.py) and their re-exports in mellea/backends/adapters/__init__.py.
Remove the now-dead isinstance branches in both backends that PR1 made redundant.
Tests:
Delete outright (these test the shim's own deprecated behaviour, not anything that survives): test/backends/test_adapters/test_shims.py, test/backends/test_adapters/test_adapter.py, and the from_hub/from_model_directory/construction tests in test/backends/test_adapters/test_embedded_adapter.py (keep any parts of that file that ended up testing the composed path instead, if PR1 added them there).
Final sweep (required, full-repo, not spot-check):
Re-run the same method used to scope this issue — gh api search/code for IntrinsicAdapter, EmbeddedIntrinsicAdapter, CustomIntrinsicAdapter across generative-computing/mellea — confirm zero hits outside historical/changelog text and docs/versioned_docs/ (old version snapshots, out of scope).
Confirm mellea/stdlib/components/intrinsic/intrinsic.py's module docstring (currently references IntrinsicAdapter descriptively) is updated.
IBM adapter-function symbol rename — separate issue if not confirmed by the time this lands.
Any new functionality beyond the composed-path parity described above.
Epic Epic: Fix Adapter Function Lifecycle & Consistency in Mellea #929 items 3a (adapter name vs. intrinsic_name, still an open question per the epic's original text) and 6 (catalog removal/repurpose) — neither is resolved by this issue; flag separately if the epic is to close around this issue's completion.
Not part of this issue (confirmed clean elsewhere)
generative-computing/mellea-contribs — checked 2026-09-03, zero references to any of the three shim classes or old catalog-construction patterns. Nothing there needs updating.
Full shim-usage inventory (this update's line numbers) verified against main on 2026-09-03 via gh api search/code across all three class names, all pages, no truncation.
Parent epic: #929
Design proposal: PR #1080 §16 Phase 4, Part I §5 Q4
Phase: 4 (final)
Depends on: #1141, #1142, #1516, #1465, #1018 — all merged. Deprecation window opened 2026-09-02 (last dependency, #1018/PR #1593); team has decided to proceed now.
Update (2026-09-03) — scope correction: this is not just a deletion
The original scope below assumed callers were "already on new types" and this issue was cleanup. That's false as of 2026-09-03, verified against current
main. NeitherLocalHFBackend.add_adapternorOpenAIBackend.add_adapteraccepts a composedAdapter(_core.Adapter) directly — both reject it viaisinstancegates and raiseTypeError. The only working path today for LoRA/embedded intrinsic use is through the three deprecated shim classes (IntrinsicAdapter,EmbeddedIntrinsicAdapter,CustomIntrinsicAdapter), and that's true of production code, not just docs/examples:AdapterMixin.resolve_adapter()(mellea/backends/adapters/adapter.py:612-724) — the shared lazy-registration path every backend inherits — directly constructsEmbeddedIntrinsicAdapter.from_source(...)(L675) orIntrinsicAdapter(name, adapter_type=AdapterType.LORA, base_model_name=base)(L688).mellea/backends/huggingface.py(LocalHFBackend):add_adapter()(L2375, isinstance gate L2397-2403),register_embedded_adapter_model()(L2442, L2465),load_peft_adapter()(L2493 guard),_generate_from_intrinsic()(isinstance dispatch L891, L932, L1012).mellea/backends/openai.py(OpenAIBackend):add_adapter()(L310, isinstance gate L327 —EmbeddedIntrinsicAdapteris the only accepted reality),register_embedded_adapter_model()(L361, L379),_generate_from_intrinsic()(gates at L760, L784, L884/890),self._added_adapters: dict[str, EmbeddedIntrinsicAdapter]type annotation (L278).cli/alora/README_TEMPLATE.jinja(L44, L52) — everym alora upload --intrinsicinvocation generates user scaffolding that subclassesCustomIntrinsicAdapter. This has to change in lockstep with the backend code, not as an afterthought.Given this, the work splits into two PRs, stacked:
PR1 — build the composed-
Adapter-direct path (additive, land first)Goal: both backends accept a composed
Adapter(identity, io_contract, weights_binding)directly, alongside the existing shim path (which keeps working unchanged — no behaviour change for existing callers in this PR).Code:
LocalHFBackend.add_adapter/OpenAIBackend.add_adapter— extend theisinstancegates to accept a composedAdapterinstance and dispatch correctly (LocalFileBinding→ PEFT path,EmbeddedBinding→ embedded path).AdapterMixin.resolve_adapter()— construct a composedAdapterinstead of the shim classes when registering. (This is the one call site both backends inherit — get this right once.)register_embedded_adapter_model(),load_peft_adapter()(HF only),_generate_from_intrinsic()in both backends — same treatment, dispatch on binding type rather than the shim's own type.cli/alora/README_TEMPLATE.jinja— generate composed-Adapterscaffolding instead of aCustomIntrinsicAdaptersubclass.Tests (new — none of this exists today, so none of it is covered today):
isinstance/dispatch branches in both backends.call_intrinsic/Intrinsic.test/backends/test_adapters/test_embedded_integration.py,test/backends/test_openai_intrinsics_unit.py,test/backends/test_huggingface_unit.py,test/backends/test_huggingface.py, and theTestOpenAIBackendRegistrationclass intest/backends/test_adapters/test_embedded_adapter.py.Docs/examples (8 files):
docs/docs/advanced/intrinsics.md— rewrite the "Composable adapter construction (advanced)" section (currently accurately states neither backend supports this — flip it to the real, working example) and the "Direct adapter function usage" section (currently recommendsCustomIntrinsicAdapterdirectly).docs/docs/advanced/lora-and-alora-adapters.md— "Use the adapter in Mellea" section already self-flags as pending this issue; update it.docs/docs/integrations/openai.md— priority: the "load adapters manually" section has no deprecation caveat today (unlike the other two docs) and reads as the unqualified recommended way. Most likely to mislead someone who reads it before this issue lands.docs/examples/aLora/101_example.py,docs/examples/aLora/README.md,docs/examples/aLora/stembolts_intrinsic.py,docs/examples/granite-switch/manual_adapter_loading.py,docs/examples/granite-switch/README.md,docs/examples/intrinsics/intrinsics.py— all construct a shim class directly as their canonical pattern; update to the composed path.Tutorials (write here, not deferred to PR2):
CustomIntrinsicAdaptermonkey-patch story.requirement-checkv1→v2 worked example; HF revision pinning andAdapterSchemaMismatchError.mellea.adapter_function.parse_failures,mellea.adapter_function.phase_duration, and the span tree.PR1 acceptance criteria:
Adapterdirectly; existing shim path unchanged/still passingAdapterscaffoldingdocs/docs/integrations/openai.mdexplicitly prioritizeddocs/docs/advanced/intrinsics.mdPR2 — delete the shims (stacked on PR1)
Goal: remove the now-genuinely-unused deprecated path. This PR's own green CI run against PR1-merged-into-main is the actual proof "we have no use left" — that's the validation, not a comment claiming it.
Code:
IntrinsicAdapter,EmbeddedIntrinsicAdapter,CustomIntrinsicAdapter(mellea/backends/adapters/adapter.py) and their re-exports inmellea/backends/adapters/__init__.py.isinstancebranches in both backends that PR1 made redundant.Tests:
test/backends/test_adapters/test_shims.py,test/backends/test_adapters/test_adapter.py, and thefrom_hub/from_model_directory/construction tests intest/backends/test_adapters/test_embedded_adapter.py(keep any parts of that file that ended up testing the composed path instead, if PR1 added them there).Final sweep (required, full-repo, not spot-check):
gh api search/codeforIntrinsicAdapter,EmbeddedIntrinsicAdapter,CustomIntrinsicAdapteracrossgenerative-computing/mellea— confirm zero hits outside historical/changelog text anddocs/versioned_docs/(old version snapshots, out of scope).mellea/stdlib/components/intrinsic/intrinsic.py's module docstring (currently referencesIntrinsicAdapterdescriptively) is updated.PR2 acceptance criteria:
Out of scope (either PR)
intrinsic_name, still an open question per the epic's original text) and 6 (catalog removal/repurpose) — neither is resolved by this issue; flag separately if the epic is to close around this issue's completion.Not part of this issue (confirmed clean elsewhere)
generative-computing/mellea-contribs— checked 2026-09-03, zero references to any of the three shim classes or old catalog-construction patterns. Nothing there needs updating.References
mainon 2026-09-03 viagh api search/codeacross all three class names, all pages, no truncation.