# What Information Does a Capability Catalog Entry Provide for LoopX Registration?

> Discover what a LoopX capability catalog entry provides for registration. Learn about CAPABILITY_ID, PROVIDERS, and CONFIG_SCHEMA metadata.

- Repository: [huangruiteng/loopx](https://github.com/huangruiteng/loopx)
- Tags: api-reference
- Published: 2026-09-02

---

**A LoopX capability catalog entry is a declarative Python module that exposes metadata attributes—such as `CAPABILITY_ID`, `PROVIDERS`, and `CONFIG_SCHEMA`—which the framework's catalog loader consumes to discover, validate, and register capabilities at runtime.**

In the **LoopX** framework (`huangruiteng/loopx`), capabilities are self-contained feature modules that extend core functionality. Each capability declares its registration contract through a dedicated [`catalog_entry.py`](https://github.com/huangruiteng/loopx/blob/main/catalog_entry.py) file located alongside its implementation, enabling the framework to wire components dynamically without hard-coded configuration.

## The Anatomy of a Capability Catalog Entry

A [`catalog_entry.py`](https://github.com/huangruiteng/loopx/blob/main/catalog_entry.py) module acts as a **static metadata manifest** that the catalog loader imports during the bootstrap phase. When placed inside a capability directory—such as `loopx/capabilities/value_connectors/`—this file signals to the registration system that a new capability is available for discovery.

The entry provides eight distinct metadata fields that control how the capability is identified, instantiated, and configured.

## Required Metadata Attributes for Registration

### CAPABILITY_ID and DESCRIPTION

The **`CAPABILITY_ID`** attribute defines the unique snake-case identifier used in the capability registry and for CLI-level referencing (e.g., `value_connectors`). The **`DESCRIPTION`** field supplies a human-readable summary displayed by commands like `loopx capabilities list` and in generated documentation.

### PROVIDERS and ENTRY_POINT

**`PROVIDERS`** is a list of concrete provider class objects that implement the capability's runtime logic (e.g., `ValueConnectorProvider`). The **`ENTRY_POINT`** attribute specifies the callable—typically a factory function like `create_value_connector`—that constructs the capability's main object when instantiated by the runtime.

### CONFIG_SCHEMA and DEFAULTS

**`CONFIG_SCHEMA`** accepts a Pydantic model or JSON schema used to validate user-supplied configuration, while **`DEFAULTS`** provides a dictionary of default values merged with user input before validation. These fields ensure type safety and consistent initialization across different deployment environments.

### REQUIRES and Internal Registration Flags

The **`REQUIRES`** attribute lists other capability IDs that must be loaded first, establishing dependency ordering during bootstrap. The internal **`REGISTERED`** boolean flag is set by the registration process itself to prevent duplicate loading and to track which capabilities have been processed by the engine.

## How the Catalog Loader Processes Entries

The registration flow begins in [`loopx/capabilities/catalog.py`](https://github.com/huangruiteng/loopx/blob/main/loopx/capabilities/catalog.py), where the `load_catalog()` function recursively searches for [`catalog_entry.py`](https://github.com/huangruiteng/loopx/blob/main/catalog_entry.py) files across the capabilities directory tree. For each discovered module, the loader uses `importlib` to import the file and extracts the metadata attributes defined above.

```python

# loopx/capabilities/catalog.py (simplified)

import importlib
from pathlib import Path

registry = {}

def load_catalog():
    for entry_path in Path(__file__).parent.rglob("catalog_entry.py"):
        module = importlib.import_module(entry_path.with_suffix("").as_posix().replace("/", "."))
        cap_id = getattr(module, "CAPABILITY_ID")
        registry[cap_id] = {
            "description": getattr(module, "DESCRIPTION"),
            "providers": getattr(module, "PROVIDERS"),
            "config_schema": getattr(module, "CONFIG_SCHEMA"),
            "default_config": getattr(module, "DEFAULTS"),
            "factory": getattr(module, "create_example", None) or getattr(module, "ENTRY_POINT")
        }

load_catalog()

```

After extraction, the loader populates the central registry dictionary, which the CLI (`loopx/cli/*`) and runtime systems consult to expose commands, wire providers, and handle plugin extensions.

## Real-World Implementation Examples

The LoopX repository contains several production-grade [`catalog_entry.py`](https://github.com/huangruiteng/loopx/blob/main/catalog_entry.py) implementations that demonstrate the full contract:

- **[`loopx/capabilities/value_connectors/catalog_entry.py`](https://github.com/huangruiteng/loopx/blob/main/loopx/capabilities/value_connectors/catalog_entry.py)**: Shows a fully-featured entry for the value connectors capability.
- **[`loopx/capabilities/semantic_preference/catalog_entry.py`](https://github.com/huangruiteng/loopx/blob/main/loopx/capabilities/semantic_preference/catalog_entry.py)**: Demonstrates declaring dependencies on other capabilities using `REQUIRES`.
- **[`loopx/capabilities/reward_memory/catalog_entry.py`](https://github.com/huangruiteng/loopx/blob/main/loopx/capabilities/reward_memory/catalog_entry.py)**: Illustrates complex `CONFIG_SCHEMA` usage with custom Pydantic validation.
- **[`loopx/capabilities/connector_registry/catalog_entry.py`](https://github.com/huangruiteng/loopx/blob/main/loopx/capabilities/connector_registry/catalog_entry.py)**: Example of registering multiple provider classes within a single capability.

### Minimal Catalog Entry Structure

The following example demonstrates the minimum viable implementation required for successful registration:

```python

# loopx/capabilities/example/catalog_entry.py

from .provider import ExampleProvider
from pydantic import BaseModel, Field

CAPABILITY_ID = "example"
DESCRIPTION = "Demo capability that showcases the catalog entry format."
PROVIDERS = [ExampleProvider]

class Config(BaseModel):
    greeting: str = Field("Hello", description="Greeting word")
    repeat: int = Field(1, ge=1, le=10, description="How many times to repeat")

CONFIG_SCHEMA = Config
DEFAULTS = {"greeting": "Hello", "repeat": 1}

def create_example(config: Config) -> ExampleProvider:
    """Factory used by LoopX to build the provider."""
    return ExampleProvider(config=greeting=config.greeting, repeat=config.repeat)

```

### CLI Integration

Once registered, the CLI consumes the metadata to generate commands and validate arguments:

```bash
$ loopx capability enable example --greeting "Hi" --repeat 3

```

The CLI parses arguments against `CONFIG_SCHEMA`, merges them with `DEFAULTS`, and invokes the factory function to instantiate the provider.

## Summary

- A **capability catalog entry** ([`catalog_entry.py`](https://github.com/huangruiteng/loopx/blob/main/catalog_entry.py)) provides eight critical metadata attributes for registration: `CAPABILITY_ID`, `DESCRIPTION`, `PROVIDERS`, `REQUIRES`, `CONFIG_SCHEMA`, `DEFAULTS`, `ENTRY_POINT`, and the internal `REGISTERED` flag.
- The **catalog loader** in [`loopx/capabilities/catalog.py`](https://github.com/huangruiteng/loopx/blob/main/loopx/capabilities/catalog.py) discovers these files via `rglob("catalog_entry.py")` and populates the central registry using `importlib`.
- **Pydantic models** specified in `CONFIG_SCHEMA` enforce type safety, while `DEFAULTS` ensure consistent initialization when users omit explicit values.
- **Factory functions** defined as `ENTRY_POINT` enable the runtime to construct provider instances without hard-coding class constructors.
- Real-world examples in `value_connectors`, `semantic_preference`, and `reward_memory` directories demonstrate production patterns for dependency management and multi-provider registration.

## Frequently Asked Questions

### What happens if CAPABILITY_ID is missing from a catalog entry?

The registration process will fail during the `getattr` extraction phase in [`loopx/capabilities/catalog.py`](https://github.com/huangruiteng/loopx/blob/main/loopx/capabilities/catalog.py). The loader expects this attribute to exist as it serves as the primary key in the capability registry, and its absence will raise an `AttributeError` that prevents the capability from loading.

### Can a single capability register multiple provider implementations?

Yes. The `PROVIDERS` attribute accepts a list of class objects, as demonstrated in [`loopx/capabilities/connector_registry/catalog_entry.py`](https://github.com/huangruiteng/loopx/blob/main/loopx/capabilities/connector_registry/catalog_entry.py). This allows capabilities to expose multiple concrete implementations that share the same configuration schema and entry point semantics.

### How does LoopX validate configuration against CONFIG_SCHEMA?

During instantiation, the runtime passes the merged dictionary of `DEFAULTS` and user-supplied arguments to the Pydantic model specified in `CONFIG_SCHEMA`. The model validates types, constraints, and required fields, raising validation errors before the factory function receives the configuration object.

### Where is the capability registry stored after registration?

The registry is maintained as a global dictionary defined in [`loopx/capabilities/catalog.py`](https://github.com/huangruiteng/loopx/blob/main/loopx/capabilities/catalog.py), populated by the `load_catalog()` function. Both the CLI modules (`loopx/cli/*`) and the core runtime reference this registry to resolve capability IDs to their metadata and factory functions.