ADR-014: Adapter Layer Reorganization into Sub-Packages¶
Status: Accepted Date: 2026-03-02 Deciders: gepa-adk maintainers
Context¶
The adapters/ directory grew to 11 modules (plus the stoppers/ sub-package) in a flat layout. Contributors had to scan the entire directory to find the right module, and the single-level structure gave no hint about which modules were related. As more adapters are planned (critic presets, additional selection strategies, media handlers), the flat layout would only get worse.
Decision¶
Reorganize adapters/ into 9 concern-based sub-packages while preserving full backward compatibility through re-exports in adapters/__init__.py:
adapters/
├── __init__.py # Re-exports preserving old import paths
├── agents/ # Agent provider protocol implementations
├── execution/ # AgentExecutor, TrialBuilder
├── scoring/ # CriticScorer, schemas, normalize_feedback
├── evolution/ # ADKAdapter, MultiAgentAdapter
├── selection/ # Candidate selectors, component selectors, evaluation policies
├── components/ # ComponentHandlerRegistry, built-in handlers
├── workflow/ # is_workflow_agent, find_llm_agents, clone utilities
├── media/ # VideoBlobService
└── stoppers/ # (unchanged — already a sub-package)
Each sub-package has an __init__.py with:
- A docstring explaining purpose and anticipated growth
- Imports and re-exports of its public symbols via
__all__
The root adapters/__init__.py re-exports all 34 previously-importable symbols from their new sub-package locations, ensuring from gepa_adk.adapters import X continues to work.
Rationale¶
- Cognitive load: Grouping by concern (execution, scoring, selection, etc.) makes it obvious where to find or add an adapter
- Scalability: New adapters have a clear target directory (e.g., a new scorer goes in
scoring/) - Architecture alignment: Sub-packages mirror the domain concepts (evaluation, selection, execution) rather than implementation details
- Zero breakage: Re-exports in
adapters/__init__.pymean existing code usingfrom gepa_adk.adapters import Xworks unchanged
Consequences¶
Positive¶
- Navigation: 9 focused sub-packages vs 11 flat modules
- Discoverability: New contributors can find the right package by concern
- Growth path: Each sub-package can grow independently without polluting siblings
- Pattern 1 alignment: The New Adapter Recipe from the architecture doc now targets
adapters/{concern}/paths
Negative¶
- Deeper paths: Direct imports are longer (e.g.,
from gepa_adk.adapters.selection.candidate_selector import ...) - One-time migration: All internal and test imports were updated in this change
Neutral¶
- Re-export maintenance:
adapters/__init__.pymust be updated when adding new public symbols to sub-packages
Migration¶
- Backward-compatible:
adapters/__init__.pyre-exports every previously-importable symbol - Deprecation tests:
tests/unit/adapters/test_adapter_reexports.pyverifies all 34 re-exports resolve to the same objects as their sub-package counterparts - Stoppers untouched: The existing
stoppers/sub-package was not modified