How Ouroboros Defines Configuration Models Using Pydantic v2: Tiers, Credentials, and Economics
Ouroboros stores all runtime settings in immutable, frozen Pydantic v2 data models located in src/ouroboros/config/models.py, using a hierarchical structure that separates LLM selection, cost tiers, provider credentials, and economic policies into strictly validated, hashable configuration objects.
The Q00/ouroboros repository leverages Pydantic v2 to create a type-safe, declarative configuration system that governs how the orchestrator selects models, manages API keys, and balances cost against capability. Understanding these Configuration Models defined using Pydantic v2 in Ouroboros is essential for customizing tier-based routing, credential management, and economic thresholds that drive automatic escalation logic.
The Configuration Model Hierarchy
All configuration models inherit from BaseModel with frozen=True, ensuring thread-safe, immutable objects that validate on instantiation. The source code in src/ouroboros/config/models.py (lines 28-124) defines six primary models that compose the complete runtime configuration.
ModelConfig: LLM Selection
The ModelConfig class (lines 28-38) represents a single LLM endpoint:
class ModelConfig(BaseModel, frozen=True):
provider: str # "openai", "anthropic", "google", etc.
model: str # Specific model identifier
This model pairs a provider name with a model identifier, enabling the runtime to look up the correct API credentials and endpoint.
TierConfig: Cost and Capability Tiers
The TierConfig class (lines 40-62) defines a cost tier containing multiple models:
class TierConfig(BaseModel, frozen=True):
cost_factor: float
intelligence_range: tuple[int, int]
models: list[ModelConfig]
use_cases: list[str]
Each tier specifies a cost factor (relative multiplier), an intelligence range (min/max capability score), and a list of ModelConfig objects available within that tier. The model includes @field_validator methods to ensure min ≤ max in the intelligence range.
ProviderCredentials and CredentialsConfig: API Key Management
API keys are encapsulated in ProviderCredentials (lines 65-74):
class ProviderCredentials(BaseModel, frozen=True):
api_key: str
base_url: str | None = None
The CredentialsConfig class (lines 77-85) aggregates these into a provider-indexed mapping:
class CredentialsConfig(BaseModel, frozen=True):
providers: dict[str, ProviderCredentials]
This structure allows Ouroboros to resolve api_key values using the same provider strings referenced in ModelConfig.provider.
EconomicsConfig: Policy and Escalation
The EconomicsConfig class (lines 87-100) ties the system together:
class EconomicsConfig(BaseModel, frozen=True):
default_tier: str # "frugal", "standard", or "frontier"
tiers: dict[str, TierConfig]
escalation_threshold: int
downgrade_success_streak: int
This model stores the default tier for initial requests, a dictionary mapping tier names to TierConfig objects, and thresholds for automatic tier escalation (on failure) and downgrade (on success streaks).
OuroborosConfig: Top-Level Composition
The OuroborosConfig class embeds EconomicsConfig, clarification settings, execution parameters, and orchestrator configuration into a single, validated object that serves as the single source of truth for the entire runtime.
Tier and Credentials Flow
The relationship between tiers, models, and credentials follows a strict lookup chain implemented in the model definitions:
- EconomicsConfig references a
dict[str, TierConfig](tiers). EachTierConfigcontains a list ofModelConfigobjects enumerating the LLMs available within that cost band. - CredentialsConfig maintains a
dict[str, ProviderCredentials]keyed by provider name. The runtime usesModelConfig.providerto index into this dictionary and retrieve the appropriateapi_keyand optionalbase_url. - The default tier (
default_tier) specifies which tier's models to select when no explicit tier is requested by the user or orchestrator. - Escalation (
escalation_threshold) and downgrade (downgrade_success_streak) thresholds drive automatic tier-up and tier-down logic based on task success and failure metrics.
Implementation Details: Validation and Immutability
The Ouroboros Configuration Models defined using Pydantic v2 enforce data integrity through several Pydantic v2-specific mechanisms:
- Immutable models – Every configuration class uses
class ModelConfig(BaseModel, frozen=True), making instances hashable and thread-safe for sharing across async workers. - Typed literals – Tier names use
Literal["frugal", "standard", "frontier"]type hints, providing IDE autocomplete and runtime validation that restricts tier identifiers to supported levels. - Custom validators –
TierConfig.validate_intelligence_rangeguarantees that the minimum intelligence score does not exceed the maximum, whileDriftConfig.validate_critical_thresholdensures critical thresholds are not set lower than warning thresholds. - Helper constructors –
get_default_config()(lines 88-124) builds a fully populatedOuroborosConfigwith a sensible three-tier layout (frugal, standard, frontier) pre-populated with defaultModelConfigentries. Theget_default_credentials()function returns a templateCredentialsConfigwith placeholder API keys for all supported providers.
Working with Configuration Models
Loading Default Configuration
To instantiate the pre-configured tier hierarchy:
from ouroboros.config.models import get_default_config
config = get_default_config()
print(config.economics.default_tier) # → "frugal"
print(config.economics.tiers["standard"].models) # list of ModelConfig objects
Accessing Tier Model Lists
Iterate through available models for a specific tier:
standard_tier = config.economics.tiers["standard"]
for model_cfg in standard_tier.models:
print(f"{model_cfg.provider}:{model_cfg.model}")
# Output:
# openai:gpt-4o
# anthropic:claude-sonnet-4-6
# google:gemini-2.5-pro
Resolving Provider Credentials
Retrieve API keys using the provider index:
from ouroboros.config.models import get_default_credentials
creds = get_default_credentials()
provider = standard_tier.models[0].provider # "openai"
api_key = creds.providers[provider].api_key # → "YOUR_OPENAI_API_KEY"
base_url = creds.providers[provider].base_url # → None or custom endpoint
Creating Custom Tier Configurations
Override specific tiers while maintaining validation:
from ouroboros.config.models import (
OuroborosConfig, TierConfig, ModelConfig, get_default_config
)
custom = get_default_config()
custom.economics.tiers["frontier"] = TierConfig(
cost_factor=50,
intelligence_range=(19, 20),
models=[
ModelConfig(provider="openai", model="gpt-4o-mini"),
ModelConfig(provider="anthropic", model="claude-3-5-haiku")
],
use_cases=["advanced_consensus"]
)
Summary
- Ouroboros Configuration Models defined using Pydantic v2 reside in
src/ouroboros/config/models.pyand enforce strict validation through frozenBaseModelclasses. - The hierarchy consists of
ModelConfig(LLM selection),TierConfig(cost/capability grouping),ProviderCredentials(API keys),CredentialsConfig(provider mapping), andEconomicsConfig(policy orchestration). - All models use
frozen=Truefor immutability and thread safety, with custom@field_validatordecorators ensuring logical constraints like ordered intelligence ranges. - The runtime resolves credentials by matching
ModelConfig.providerstrings against keys inCredentialsConfig.providers. - Default configurations are generated via
get_default_config()(lines 88-124), which populates three standard tiers with pre-selected models.
Frequently Asked Questions
What file contains the Pydantic v2 configuration models in Ouroboros?
The core schema definitions are located in src/ouroboros/config/models.py. This file contains all BaseModel subclasses including ModelConfig, TierConfig, ProviderCredentials, CredentialsConfig, and EconomicsConfig, along with the get_default_config() helper function (lines 88-124).
Why are Ouroboros configuration models frozen?
All configuration classes use frozen=True to ensure immutability after instantiation. This makes the objects hashable (usable as dictionary keys or in sets) and thread-safe, allowing the runtime to share configuration instances across multiple async workers without risk of mutation or race conditions.
How does Ouroboros validate that intelligence ranges are logical?
The TierConfig class (lines 40-62) includes a @field_validator method named validate_intelligence_range that executes during model instantiation. This validator ensures that the minimum intelligence value is less than or equal to the maximum value, raising a ValidationError if the range is inverted.
Can I use custom base URLs for API providers in Ouroboros?
Yes. The ProviderCredentials model (lines 65-74) includes an optional base_url field of type str | None. When provided, this URL overrides the default API endpoint for that provider, enabling compatibility with proxy servers, regional endpoints, or self-hosted model gateways.
Have a question about this repo?
These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →