Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions .github/workflows/publish-typescript.yml
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,9 @@ jobs:
node-version: "24"
registry-url: "https://registry.npmjs.org"

- name: Configure npm release age gate
run: echo "NPM_CONFIG_BEFORE=$(date -u -d '7 days ago' +'%Y-%m-%dT%H:%M:%SZ')" >> "$GITHUB_ENV"

- name: Install dependencies
run: npm ci

Expand Down
32 changes: 15 additions & 17 deletions .github/workflows/validate.yml
Original file line number Diff line number Diff line change
Expand Up @@ -16,22 +16,17 @@ jobs:
with:
node-version: "20"

- name: Configure npm release age gate
run: echo "NPM_CONFIG_BEFORE=$(date -u -d '7 days ago' +'%Y-%m-%dT%H:%M:%SZ')" >> "$GITHUB_ENV"

- name: Install validation dependencies
run: npm ci

- name: Validate models YAML against schema
run: |
npm install ajv ajv-cli
npx ajv validate \
-s model-metadata.schema.json \
-d "models/*.yaml" \
--spec=draft2020 \
--all-errors || exit 1
run: npm run validate:models

- name: Validate providers YAML against schema
run: |
npx ajv validate \
-s provider.schema.json \
-d "providers/*.yaml" \
--spec=draft2020 \
--all-errors || exit 1
run: npm run validate:providers

codegen:
runs-on: ubuntu-latest
Expand All @@ -48,7 +43,7 @@ jobs:
- name: Check for changes
run: |
git diff --exit-code packages/typescript/src/generated/
git diff --exit-code packages/python/model_metadata/generated/
git diff --exit-code packages/python/model_metadata_central/generated/

typescript:
runs-on: ubuntu-latest
Expand All @@ -63,6 +58,9 @@ jobs:
node-version: "20"
registry-url: "https://registry.npmjs.org"

- name: Configure npm release age gate
run: echo "NPM_CONFIG_BEFORE=$(date -u -d '7 days ago' +'%Y-%m-%dT%H:%M:%SZ')" >> "$GITHUB_ENV"

- name: Install deps and type-check
run: npm ci && npm run lint

Expand All @@ -81,15 +79,15 @@ jobs:
python-version: "3.10"

- name: Install dependencies
run: uv sync
run: uv sync --locked

- name: Build registry from YAML sources
run: uv run python scripts/build_registry.py

- name: Type-check generated models
run: |
uv run python -c "
from model_metadata.generated.models import ModelMetadata, ProviderMetadata
from model_metadata_central.generated.models import ModelMetadata, ProviderMetadata
m = ModelMetadata.model_validate({
'model_id': 'test',
'model_type': 'chat',
Expand All @@ -103,4 +101,4 @@ jobs:
'routing_priority': 'direct'
})
print('ProviderMetadata valid:', p.provider_id)
"
"
2 changes: 2 additions & 0 deletions .npmrc
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
min-release-age=7
save-exact=true
6 changes: 6 additions & 0 deletions .vscode/settings.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
{
"yaml.schemas": {
"./model-metadata.schema.json": "models/*.yaml",
"./provider.schema.json": "providers/*.yaml"
}
}
37 changes: 23 additions & 14 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# Model Metadata Central

A centralized, language-agnostic, open-source approach to storing and sharing model definitions like context windows, cost per token, etc.
A centralized, language-agnostic, open-source approach to storing and sharing model definitions like context windows, token pricing, providers, and modality support.

**Note**: This project does not strive to be an exhaustive registry of every model, but a registry that I can use in my own projects to provide consistent, sane defaults for model and provider selection for provider and model agnostic projects where the user can configure which models and providers they want to use.

Expand Down Expand Up @@ -54,12 +54,12 @@ These schema defines properties that are relevant to the model and developers wh
- `model_description`: A human-friendly description of the model
- `model_version`: The version of the model
- **Example** `0613`
- `cost_per_token`: The cost per token in USD
- `cost_per_million_tokens`: The token cost in USD per 1,000,000 tokens
- **Example**: `json {
"input": 0.0000015,
"output": 0.000002
"input": 1.5,
"output": 2
}`
- **Note**: supports either a basic number or an object with `input` and `output` numbers to define different costs between input tokens and output tokens
- **Note**: supports `input`, `cached_input`, `cache_write_input`, and `output`. Each value may be a number or a modality map such as `{ "text": 1.5, "audio": 10 }`.
- `knowledge_cutoff`: The training data cutoff date for the model
- **Note**: This is helpful when dealing with applications where you may need to know if you should supplement the model's training data with more recent information
- `tokenizer`: What type of tokenization the model uses
Expand All @@ -80,10 +80,18 @@ These schema defines properties that are relevant to the model and developers wh
model_id_on_provider: gpt-4o
- provider_id: openrouter
model_id_on_provider: openai/gpt-4o
model_info: https://openrouter.ai/openai/gpt-4o
cost_per_million_tokens:
input: 2.5
output: 10
```
- **Note**: Allows a single model to be accessed via direct provider API or aggregator. Provider definitions live in `/providers`.
- **Note**: Allows a single model to be accessed via direct provider API or aggregator, with provider-specific model IDs, info links, and pricing overrides. Provider definitions live in `/providers`.
- `meta_model`: If the model is a meta model, like [OpenRouter's Auto Router](https://openrouter.ai/openrouter/auto), this field indicates that the model may have special treatment for context, tokenization, and cost

### YAML Editor Hints

This repo includes `.vscode/settings.json` schema associations for `models/*.yaml` and `providers/*.yaml`. In VS Code with a YAML language server, those associations provide key completion, validation, and hover descriptions from the JSON Schemas.

### Provider Schema

Provider definitions in [`providers/`](./providers) describe API endpoints and routing. See [`provider.schema.json`](./provider.schema.json).
Expand Down Expand Up @@ -121,7 +129,7 @@ status: active

### Included Models

66 active models across 12 primary model providers (deprecated models exist in [`/models`](./models) but are excluded from this list). Provider definitions cover 17 direct/local/aggregator routes.
73 model definitions across direct, local, and aggregator providers. Provider definitions cover 18 direct/local/aggregator routes.

**OpenAI**:

Expand All @@ -148,13 +156,11 @@ status: active

**Anthropic**:

- `claude-haiku-4`
- `claude-haiku-4-5`
- `claude-opus-4-6`
- `claude-opus-4-6-fast`
- `claude-opus-4-7`
- `claude-opus-latest`
- `claude-sonnet-4-2`
- `claude-sonnet-4-6`

**Google**:
Expand All @@ -166,19 +172,17 @@ status: active

**DeepSeek**:

- `deepseek-coder-v4`
- `deepseek-v4-flash`
- `deepseek-v4-pro`

**xAI**:

- `grok-4.2`
- `grok-4.2-multi-agent`
- `grok-4.20`
- `grok-4.20-multi-agent`

**Moonshot AI**:

- `kimi-k2.6`
- `kimi-v3`

**Mistral AI**:

Expand All @@ -194,11 +198,11 @@ status: active

- `minimax-m2`
- `minimax-m2.1`
- `minimax-m2.1-highspeed`
- `minimax-m2.5`
- `minimax-m2.5-highspeed`
- `minimax-m2.7`
- `minimax-m2.7-highspeed`
- `minimax-m3`

**Z.AI**:

Expand All @@ -214,6 +218,11 @@ status: active
- `qwen3-32b`
- `qwen3.6-flash`
- `qwen3.6-plus`
- `qwen3.7-plus`

**Claudinio**:

- `claudinio-essential`

**Groq**:

Expand Down
137 changes: 119 additions & 18 deletions model-metadata.schema.json
Original file line number Diff line number Diff line change
Expand Up @@ -45,22 +45,9 @@
"type": "integer",
"minimum": 1
},
"cost_per_token": {
"description": "The cost per token in USD",
"type": ["object", "number"],
"minimum": 0,
"properties": {
"input": {
"description": "The cost per token of input send to the model",
"type": "number",
"minimum": 0
},
"output": {
"description": "The cost per token of output generated by the model",
"type": "number",
"minimum": 0
}
}
"cost_per_million_tokens": {
"description": "The model provider's default token pricing in USD per 1,000,000 tokens. Provider-specific entries may override this on individual providers.",
"$ref": "#/$defs/token_costs"
},
"knowledge_cutoff": {
"description": "The training data cutoff date for the model",
Expand All @@ -76,8 +63,38 @@
"type": "array",
"items": {
"type": "string",
"enum": ["function", "instruction", "code", "multilingual", "multimodal"]
"enum": [
"function",
"instruction",
"code",
"multilingual",
"multimodal",
"structured",
"reasoning"
]
},
"uniqueItems": true,
"minItems": 1
},
"input_type": {
"description": "The type of input the model accepts",
"type": "array",
"items": {
"type": "string",
"enum": ["text", "image", "audio", "video", "other"]
},
"default": ["text"],
"uniqueItems": true,
"minItems": 1
},
"output_type": {
"description": "The type of output the model generates",
"type": "array",
"items": {
"type": "string",
"enum": ["text", "image", "audio", "video", "other"]
},
"default": ["text"],
"uniqueItems": true,
"minItems": 1
},
Expand Down Expand Up @@ -114,18 +131,102 @@
"model_id_on_provider": {
"description": "The model ID as used by this specific provider (may differ from model_id)",
"type": "string"
},
"model_info": {
"description": "Provider-specific link to this model, such as an aggregator listing or provider docs page",
"type": "string",
"format": "uri"
},
"cost_per_million_tokens": {
"description": "Provider-specific token pricing in USD per 1,000,000 tokens. Use this when an aggregator or route prices the model differently from the primary provider.",
"$ref": "#/$defs/token_costs"
}
},
"required": ["provider_id"]
},
"token_costs": {
"type": "object",
"description": "Token pricing in USD per 1,000,000 tokens. Each direction may be a single number or a map of modality-specific prices.",
"properties": {
"input": {
"description": "Input token cost. May be a single blended price or modality-specific prices.",
"$ref": "#/$defs/token_cost_value"
},
"cached_input": {
"description": "Cached input token read cost, when the provider exposes separate cache pricing.",
"$ref": "#/$defs/token_cost_value"
},
"cache_write_input": {
"description": "Cache write input token cost, when the provider exposes separate cache pricing.",
"$ref": "#/$defs/token_cost_value"
},
"output": {
"description": "Output token cost. May be a single blended price or modality-specific prices.",
"$ref": "#/$defs/token_cost_value"
}
},
"additionalProperties": false
},
"token_cost_value": {
"description": "A token price in USD per 1,000,000 tokens, either as one number or split by modality.",
"oneOf": [
{
"type": "number",
"minimum": 0
},
{
"$ref": "#/$defs/modality_costs"
}
]
},
"modality_costs": {
"type": "object",
"description": "Modality-specific token prices in USD per 1,000,000 tokens.",
"properties": {
"text": {
"description": "Text token cost in USD per 1,000,000 tokens.",
"type": "number",
"minimum": 0
},
"image": {
"description": "Image token cost in USD per 1,000,000 tokens.",
"type": "number",
"minimum": 0
},
"audio": {
"description": "Audio token cost in USD per 1,000,000 tokens.",
"type": "number",
"minimum": 0
},
"video": {
"description": "Video token cost in USD per 1,000,000 tokens.",
"type": "number",
"minimum": 0
},
"other": {
"description": "Other or provider-specific token cost in USD per 1,000,000 tokens.",
"type": "number",
"minimum": 0
}
},
"additionalProperties": false,
"minProperties": 1
},
"tokenizer_config": {
"type": "object",
"description": "Tokenizer family and the specific encoding/version identifier within that family",
"properties": {
"family": {
"description": "Tokenizer library or system (example: tiktoken, tekken, sentencepiece)",
"type": "string",
"enum": ["tiktoken", "tekken", "sentencepiece", "huggingface", "other", "unknown"]
"enum": [
"tiktoken",
"tekken",
"sentencepiece",
"huggingface",
"other",
"unknown"
]
},
"name": {
"description": "The encoding or version identifier within the family (example: 'cl100k_base' for tiktoken, 'v3' for tekken)",
Expand Down
9 changes: 6 additions & 3 deletions models/claude-haiku-4-5.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -6,13 +6,16 @@ model_info: https://docs.anthropic.com/en/docs/about-claude/models/overview
model_type: chat
context_window: 200000
max_tokens: 64000
cost_per_token:
input: 0.000001
output: 0.000005
cost_per_million_tokens:
input: 1
output: 5
knowledge_cutoff: "2025-02-28"
tuning: [multimodal, function]
input_type: [text, image]
output_type: [text]
providers:
- provider_id: anthropic
model_id_on_provider: claude-haiku-4-5
- provider_id: openrouter
model_id_on_provider: anthropic/claude-haiku-4.5
model_info: https://openrouter.ai/anthropic/claude-haiku-4.5
Loading
Loading