Skip to main content

Conscribe

Inheritance is registration. __init__ signature is config schema.

Conscribe is a Python library that provides automatic class registration and config typing stub generation for layered architectures. It eliminates two categories of boilerplate:

  1. Manual registration — Write a class, inherit a base → it's registered. No registry["foo"] = FooClass.
  2. Config guesswork — Your __init__ parameters become the config schema. IDE autocomplete and fail-fast validation come for free.
pip install conscribe

Requires Python >= 3.9. Built on Pydantic v2.


Who Is This For?

Framework developers building config-driven systems with pluggable layers (agents, LLM providers, browser backends, etc.) who need registries, factories, protocol checks, and config schemas — without N layers × boilerplate.

Framework users who write YAML configs and want IDE autocomplete, parameter docs, and fail-fast validation at startup instead of crashing N steps in.


Quick Start

1. Define a Layer

from typing import Protocol, runtime_checkable
from conscribe import create_registrar

@runtime_checkable
class ChatModelProtocol(Protocol):
    def chat(self, messages: list[dict]) -> str: ...

LLMRegistrar = create_registrar(
    "llm",
    ChatModelProtocol,
    discriminator_field="provider",
    strip_prefixes=["Chat"],
)

2. Create a Base Class

class ChatBaseModel(metaclass=LLMRegistrar.Meta):
    __abstract__ = True

3. Write Implementations (auto-registered)

class ChatOpenAI(ChatBaseModel):
    """OpenAI LLM provider.

    Args:
        model_id: Model identifier, e.g. gpt-4o
        temperature: Sampling temperature, 0-2
    """
    def __init__(self, *, model_id: str, temperature: float = 0.0):
        self.model_id = model_id
        self.temperature = temperature

    def chat(self, messages): ...

# Registered as "open_ai". No decorator. No registry call.

4. Discover & Use

from conscribe import discover

discover("my_app.llm.providers")

llm_cls = LLMRegistrar.get("open_ai")   # → ChatOpenAI
llm = llm_cls(model_id="gpt-4o")
print(LLMRegistrar.keys())              # ["open_ai", "anthropic", ...]

Config Typing

Your __init__ signature is the config schema. Conscribe extracts it, builds a Pydantic discriminated union, and generates stubs for IDE autocomplete:

from conscribe import build_layer_config, generate_layer_config_source

result = build_layer_config(LLMRegistrar)
source = generate_layer_config_source(result)

See the Config Typing Guide for full details.

Config Tiers

Tier What You Write What Users Get
1 Plain __init__(self, *, x: int = 5) Names + types + defaults
1.5 + Google/NumPy docstring with Args: + descriptions
2 + Annotated[int, Field(ge=0)] + constraints
3 __config_schema__ = MyModel Full Pydantic model

Nested Config (Hierarchical Keys)

For layers with natural hierarchies (e.g., model_type → provider):

LLM = create_registrar(
    "llm", ChatModelProtocol,
    discriminator_fields=["model_type", "provider"],
    key_separator=".",
)

Produces hybrid YAML configs where level 0 is flat and level 1+ is nested:

llm:
  model_type: openai        # flat (level 0)
  temperature: 0.7          # flat (level 0 param)
  provider:                 # nested (level 1)
    name: azure
    deployment: my-deploy

Cross-Registry Wiring

Declare which values from other registries a class accepts. Conscribe constrains the config field to Literal[...]:

# Given: LoopRegistrar with "react" and "codeact" registered

class BaseAgent(metaclass=AgentRegistrar.Meta):
    __abstract__ = True
    __wiring__ = {"loop": "loop"}  # all keys from "loop" registry

class SWEAgent(BaseAgent):
    __wiring__ = {"loop": ("loop", ["react"])}  # narrows to subset

    def __init__(self, *, max_steps: int = 10): ...

Generated config:

class SweAgentConfig(BaseModel):
    name: Literal["swe_agent"] = "swe_agent"
    max_steps: int = 10
    loop: Literal["react"] = ...  # wired from: loop

Four modes:

  • "loop": "agent_loop" — auto-discover all keys from registry
  • "loop": ("agent_loop", ["react", "codeact"]) — explicit subset
  • "obs": ("observation", ["terminal"], ["filesystem"]) — required + optional keys
  • "browser": ["chromium", "firefox"] — literal list (no registry)

The 3-element tuple distinguishes required and optional keys — both appear in Literal[...], but the distinction is available as metadata for downstream negotiation logic.

Inheritance: child __wiring__ merges with parent (child keys override). Use None to exclude: {"llm": None}.

Composed Config (Multi-Layer Inline Wiring)

Combine multiple layers into a single config schema. Wired fields become full inline config objects instead of key selectors — enabling recursive IDE autocompletion across layers:

from conscribe import build_composed_config, generate_composed_json_schema

result = build_composed_config(
    {"llm": LLMRegistrar, "agent": AgentRegistrar},
    inline_wiring=True,   # wired fields become target layer union types
)
schema = generate_composed_json_schema(result)

YAML config with inline wiring:

agents:
  - name: browser_use
    use_vision: true
    llm:                        # full LLM config inline — IDE autocompletes all fields
      provider: openai
      model: gpt-4o
      temperature: 0.7
  - name: react
    llm:
      provider: anthropic
      model: claude-3

Use inline_wiring=False to keep wired fields as Literal[...] key selectors.

Cross-Registry Diamond Inheritance

Register a class in multiple registries:

CombinedMeta = LLM.Meta | Agent.Meta

class LLMAgent(metaclass=CombinedMeta):
    ...  # in both LLM and Agent registries

API Reference

Registration

API Purpose
create_registrar(name, protocol, ...) Create a layer registrar (recommended entry point)
Registrar.get(key) Look up a registered class
Registrar.keys() List all registered keys
Registrar.children(prefix) Query hierarchical key descendants
Registrar.tree() Get nested dict of key hierarchy
Registrar.bridge(external_cls) Create bridge for external class
Registrar.register(key) Manual registration decorator
discover(*package_paths) Import modules to trigger registration
scan_registrar_definitions(root) Static AST scan for registrar definitions
list_registries(root, ...) Runtime list of all registered content

Config Typing

API Purpose
extract_config_schema(cls, mro_scope, mro_depth) Extract Pydantic model from __init__
build_layer_config(registrar) Build discriminated union (flat or nested mode)
generate_layer_config_source(result) Generate Python stub source code
generate_layer_json_schema(result) Generate JSON Schema
build_composed_config(registrars, inline_wiring) Build multi-layer composed config
generate_composed_json_schema(result) Generate composed JSON Schema
generate_composed_config_source(result) Generate composed Python source
compute_registry_fingerprint(registrar) Compute registry fingerprint hash
get_registry(name) Look up a registry by name (for wiring)

Design Principles

  • Zero registration burden — Inherit a base class = registered
  • __init__ is the single source of truth — No duplicate config definitions
  • Fail-fast — Duplicate keys raise immediately; invalid config rejects at startup
  • Domain-agnostic — Pure infrastructure, knows nothing about agents or LLMs
  • Stubs and runtime are separate — Stale stubs don't affect correctness

Documentation

Full documentation is shipped inside the package (accessible at site-packages/conscribe/) and browsable on GitHub:

Document Description
llms.txt AI entry point — package summary and navigation
docs/overview.md Core concepts and architecture
docs/guide-alice.md Tutorial: building a framework with conscribe
docs/guide-bob.md Tutorial: consuming a conscribe-based framework
docs/api-reference.md Full API signatures and examples
docs/recipes.md Task-oriented "how do I X?"
docs/registration.md Registration subsystem internals
docs/config-typing.md Config typing pipeline internals
docs/mro-and-degradation.md MRO chains and type degradation
docs/cli.md CLI reference (scan, list, inspect, generate-*)

License

MIT

Release files for conscribe 1.2.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for conscribe 1.2.0
File Size Uploaded
conscribe-1.2.0.tar.gz 77.5 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for conscribe 1.2.0
File Interpreter ABI Platform
conscribe-1.2.0-py3-none-any.whl Python 3 none any Details

Total release size: 170.3 kB

Release files / conscribe-1.2.0.tar.gz

Download URL conscribe-1.2.0.tar.gz
Size 77.5 kB
Tags Source
SHA-256 checksum
How to use checksums
52760f65116fb209fb04b568ae8451ade79f340ed21e242f4076d4e800b0af8b
BLAKE2b-256 checksum
How to use checksums
1b597ad38fdc988e43f814c32c583245fe59028bc95dae71b5f1ba47bcccd924
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/6.2.0 CPython/3.12.13

Release files / conscribe-1.2.0-py3-none-any.whl

Download URL conscribe-1.2.0-py3-none-any.whl
Size 92.8 kB
Tags Python 3
SHA-256 checksum
How to use checksums
011195c9767941c8204353aa46bd1f260b3c10c870d502c886bfcdd5bcb98828
BLAKE2b-256 checksum
How to use checksums
afe91190d7b9c8e3afe97fa1497041826a2cd88776e1d21487d8ecf37d9eb878
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/6.2.0 CPython/3.12.13

Release history Release notifications | RSS feed

1.3.0

2 release files

This release

1.2.0 This release

2 release files

1.1.2

2 release files

1.1.1

2 release files

1.1.0

2 release files

1.0.0

2 release files

0.9.0

2 release files

0.8.0

2 release files

0.7.0

2 release files

0.6.1

2 release files

0.6.0

2 release files

0.5.3

2 release files

0.5.2

2 release files

0.5.1

2 release files

0.5.0

2 release files

0.4.1

2 release files

0.4.0

2 release files

0.3.0

2 release files

0.2.0

2 release files

0.1.2

2 release files

0.1.1

2 release files

0.1.0

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page