How Model Name Mappings in data.py Normalize Provider IDs

Model name mappings are defined in src/data.py as a centralized dictionary called MODEL_TO_NAME_MAPPING that maps raw provider-specific identifiers to human-readable names by lower-casing inputs and stripping vendor prefixes like @cf/ and :free suffixes.

The cheahjs/free-llm-api-resources repository aggregates free LLM APIs from multiple providers, each using incompatible naming conventions. By centralizing these mappings in src/data.py, the project eliminates fragile string manipulation logic throughout the codebase and ensures the generated README displays consistent, readable model names instead of cryptic provider IDs.

Why Model Name Mappings Live in data.py

Every provider—whether Cloudflare CF, Hugging Face, Google Gemini, or OpenRouter—implements its own identifier scheme. Some prepend organizational prefixes like @cf/ or @hf/, while others append qualifiers such as :free. Without normalization, the README generation logic in src/pull_available_models.py would require dozens of provider-specific conditionals to handle these quirks.

The MODEL_TO_NAME_MAPPING dictionary in src/data.py serves as the single source of truth for display names. This centralization allows contributors to add or correct mappings in one location without modifying the data extraction logic scattered across other modules, preventing cryptic IDs like "@cf/google/gemma-2b-it-lora" from appearing in user-facing documentation.

How get_model_name Normalizes Provider IDs

The normalization logic resides in the get_model_name function inside src/pull_available_models.py. When the script processes a raw model identifier, it first lower-cases the string to ensure case-insensitive matching, then consults the global mapping dictionary.


# src/pull_available_models.py

def get_model_name(id):
    id = id.lower()
    if id in MODEL_TO_NAME_MAPPING:
        return MODEL_TO_NAME_MAPPING[id]          # ✅ Friendly name found

    MISSING_MODELS.add(id)                       # ❓ Unmapped ID recorded

    return id                                     # Fallback to raw ID

If the lookup succeeds, the function returns the human-readable label. If the ID is absent from the mapping, the lower-cased raw identifier is added to the global MISSING_MODELS set for debugging purposes and returned as-is.

Handling Case Sensitivity and Provider Noise

The normalization process enforces two critical consistency guarantees that allow the rest of the codebase to ignore provider-specific formatting:

  • Case-insensitive lookups. By converting the input to lowercase before checking the dictionary, the function treats Google/Gemma-2-9B and google/gemma-2-9b as identical keys.
  • Vendor prefix stripping. The mapping entries themselves absorb provider-specific noise. For example, entries map @cf/google/gemma-2b-it-lora to "Gemma 2B Instruct (LoRA)" and google/gemma-2-9b-it:free to "Gemma 2 9B Instruct", removing the @cf/ prefix and :free suffix respectively.

This ensures downstream components receive uniform strings like "Gemma 2 9B Instruct" regardless of whether the original provider used Cloudflare's @cf/google/ prefix or OpenRouter's :free suffix.

Concrete Examples of ID Normalization

The following interactions demonstrate how raw provider IDs transform into clean display names:

>>> from data import MODEL_TO_NAME_MAPPING
>>> from pull_available_models import get_model_name
>>> get_model_name("@cf/google/gemma-2b-it-lora")
'Gemma 2B Instruct (LoRA)'

>>> get_model_name("google/gemma-2-9b-it:free")
'Gemma 2 9B Instruct'

>>> # Unknown ID – will be recorded in MISSING_MODELS and returned unchanged

>>> get_model_name("unknown/provider-model")
'unknown/provider-model'

Extending the Mapping for New Providers

To add support for a new model or provider, append an entry to the dictionary in src/data.py:


# src/data.py

MODEL_TO_NAME_MAPPING = {
    # existing entries …

    "mycompany/custom-model-v1": "MyCompany Custom Model v1",
}

After updating the mapping, any subsequent call to get_model_name("mycompany/custom-model-v1") from src/pull_available_models.py will return the friendly display name rather than the raw technical ID.

Summary

  • The MODEL_TO_NAME_MAPPING dictionary in src/data.py acts as a centralized registry that converts cryptic provider IDs into human-readable model names.
  • The get_model_name function in src/pull_available_models.py normalizes inputs by lower-casing them and falling back to the raw ID (while recording it in MISSING_MODELS) if no mapping exists.
  • This architecture supports case-insensitive lookups and strips vendor-specific prefixes like @cf/ and suffixes like :free.
  • Centralizing mappings prevents brittle string manipulation scattered throughout the codebase and simplifies maintenance when providers change their identifier formats.

Frequently Asked Questions

Why are the mappings stored in a separate data.py file instead of being hardcoded in the pull script?

Isolating the dictionary in src/data.py creates a dedicated location for data maintenance that remains separate from the procedural logic in src/pull_available_models.py. This separation of concerns allows non-technical contributors to update display names without risking changes to the API fetching code.

What happens when a provider introduces a new model ID not yet in the mapping?

The get_model_name function adds any unrecognized ID to the global MISSING_MODELS set after lower-casing it. This enables developers to detect gaps in coverage by checking the set's contents, while users still see the raw ID in the generated README rather than a broken or missing entry.

Does the normalization process modify the original provider ID strings?

No, the normalization is non-destructive. The get_model_name function creates a lower-cased copy of the ID for dictionary lookups but leaves the original argument unchanged. If no mapping exists, the lower-cased version is returned, preserving consistency with the case-insensitive lookup logic.

How does this mapping system handle multiple providers offering the same underlying model?

The mapping uses the full provider-prefixed ID as the dictionary key (e.g., @cf/google/gemma-2b-it vs. google/gemma-2-9b-it:free), allowing distinct entries for different providers even when the underlying model architecture is identical. Each provider's specific identifier maps to an appropriate human-readable name that may include provider context where necessary.

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:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →