Migration Guide — Phase 7: Plug & Play
This guide walks you through migrating existing XYBEROS code to use the Phase 7 patterns: entry-point discovery, capability-based provider selection, and graceful degradation.
Table of Contents
- Why Migrate?
- Migration: Provider → Capability-Aware Provider
- Migration: Manager → Graceful Degradation
- Migration: Registry → Entry-Point Discovery
- Migration: Pipeline → Phase-Gated Pipeline
- Checklist
Why Migrate?
| Pattern | Before (Phase 0-6) | After (Phase 7) |
|---|---|---|
| Provider selection | Always uses .default() |
Capability-gated .best() or .fallback() |
| Failure handling | Raises immediately | Graceful degradation across providers |
| Plugin registration | Manual registry.register() |
Auto-discovery via entry points |
| Input gating | No built-in mechanism | can_handle() on each provider |
Migration: Provider → Capability-Aware Provider
Before
from xyberos.common.provider import Provider
class MyProvider(Provider):
@property
def name(self) -> str:
return "my_provider"
def process(self, input: str) -> str:
return input.upper()
After
from xyberos.common import Provider, ProviderCapability
from xyberos.common.capabilities import nlp_capability
class MyProvider(Provider):
@property
def name(self) -> str:
return "my_provider"
@property
def capability(self) -> ProviderCapability:
return nlp_capability(
languages=("en",),
description="NLP-based uppercase transformer",
)
def can_handle(self, input: str) -> bool:
"""Only handle English text under 10KB."""
return (
isinstance(input, str)
and len(input) < 10_000
)
def process(self, input: str) -> str:
return input.upper()
What changed
- Added
capabilityproperty — declares this is an NLP (Phase 2) provider that handles English with ~50ms latency. - Added
can_handle()— prevents the provider from being selected for inputs it cannot process (e.g. non-string or oversized).
Migration: Manager → Graceful Degradation
Before
class MyManager:
def __init__(self, registry):
self._registry = registry
def detect(self, text: str) -> tuple[str, float]:
provider = self._registry.default()
return provider.detect(text)
After
import logging
logger = logging.getLogger(__name__)
class MyManager:
def __init__(self, registry):
self._registry = registry
def detect(self, text: str) -> tuple[str, float]:
"""Detect with graceful degradation."""
return self._registry.fallback(
text,
"detect",
default_result=("unknown", 0.0),
)
def detect_fast(self, text: str) -> tuple[str, float]:
"""Fast path — default provider only, no fallback."""
return self._registry.default().detect(text)
What changed
detect()now usesregistry.fallback()— tries each provider in priority order. On failure, logs and tries the next.- Added
detect_fast()— direct default provider call for when you want the old behavior (fast, no fallback). - No try/except needed —
fallback()handles it.
Migration: Registry → Entry-Point Discovery
Before
After
registry = MyRegistry()
# Option A: Auto-discover from entry points
registry.discover("xyberos.providers")
# Option B: Manual with entry-point helper
from xyberos.common.registry import discover_and_register
discover_and_register(registry, "xyberos.providers", default_name="my_provider")
# Option C: Manual (unchanged)
registry.register("my_provider", MyProvider(), default=True)
Adding entry points to your package
In your pyproject.toml:
See docs/plugins.md for details.
Migration: Pipeline → Phase-Gated Pipeline
Before
from xyberos.common.pipeline import Pipeline
pipeline = Pipeline([stage1, stage2, stage3])
result = pipeline.execute(input)
After (phase-limited execution)
from xyberos.brain.perception.perceiver import CognitivePerceiver
from xyberos.brain.perception.models import PerceptionInput
perceiver = CognitivePerceiver()
# Only run deterministic + NLP processors (phases 1-2)
observation = perceiver.perceive_with_capability(
PerceptionInput(content="Hello"),
max_phase=2,
)
After (graceful degradation)
from xyberos.brain.perception.perceiver import GracefulPerceiver
perceiver = GracefulPerceiver(fallback_phase=2)
# If full pipeline fails, falls back to phase 1-2 only
# On total failure, returns minimal Observation (never crashes)
observation = perceiver.perceive(PerceptionInput(content="Hello"))
Checklist
Use this checklist when migrating a module to Phase 7:
- [ ] Provider: Added
capabilityproperty with appropriate phase - [ ] Provider: Added
can_handle()with input validation - [ ] Manager: Uses
registry.fallback()instead ofregistry.default() - [ ] Manager: Added
_fast()variant for direct default access - [ ] Registry: Calls
registry.discover()during initialization - [ ] Entry Points: Added
pyproject.tomlentry point for each provider - [ ] Pipeline: Considered
GracefulPerceiverfor perception - [ ] Tests: Added tests for fallback behavior
- [ ] Tests: Added tests for
can_handle()gating - [ ] Tests: Added tests for capability-based selection