diff --git a/.github/workflows/publish-python.yml b/.github/workflows/publish-python.yml new file mode 100644 index 0000000..27668b3 --- /dev/null +++ b/.github/workflows/publish-python.yml @@ -0,0 +1,44 @@ +name: Publish Python Package + +on: + push: + tags: + - "python-v*" + workflow_dispatch: + +concurrency: + group: ${{ github.ref }} + cancel-in-progress: true + +jobs: + deploy: + runs-on: ubuntu-latest + defaults: + run: + working-directory: packages/python + environment: + name: pypi + url: https://pypi.org/p/model-metadata-central + permissions: + id-token: write + contents: read + steps: + - uses: actions/checkout@v4 + + - name: Install uv + uses: astral-sh/setup-uv@v5 + with: + enable-cache: true + python-version: "3.10" + + - name: Sync dependencies + run: uv sync + + - name: Build registry from YAML sources + run: uv run python scripts/build_registry.py + + - name: Build + run: uv build + + - name: Publish + run: uv publish --trusted-publishing always diff --git a/.github/workflows/publish-typescript.yml b/.github/workflows/publish-typescript.yml new file mode 100644 index 0000000..356c63d --- /dev/null +++ b/.github/workflows/publish-typescript.yml @@ -0,0 +1,62 @@ +name: Publish TypeScript Package + +on: + push: + tags: + - "typescript-v*" + +jobs: + build: + runs-on: ubuntu-latest + permissions: + contents: read + outputs: + version: ${{ steps.version.outputs.version }} + + steps: + - uses: actions/checkout@v4 + + - name: Extract version from tag + id: version + run: echo "version=${GITHUB_REF#refs/tags/typescript-v}" >> $GITHUB_OUTPUT + + - uses: actions/setup-node@v4 + with: + node-version: "20" + registry-url: "https://registry.npmjs.org" + + - name: Install dependencies + run: npm ci + + - name: Build + run: npm run build + working-directory: packages/typescript + + - name: Upload build artifact + uses: actions/upload-artifact@v4 + with: + name: dist-typescript-${{ steps.version.outputs.version }} + path: packages/typescript/dist + retention-days: 1 + + publish: + needs: build + runs-on: ubuntu-latest + environment: + name: npm + url: https://www.npmjs.com/package/model-metadata-central + permissions: + id-token: write + contents: read + + steps: + - name: Download build artifact + uses: actions/download-artifact@v4 + with: + name: dist-typescript-${{ needs.build.outputs.version }} + path: dist + + - name: Publish to npm + uses: npmjs/action-publish-oidc@v1 + with: + publish-access: public \ No newline at end of file diff --git a/.github/workflows/validate.yml b/.github/workflows/validate.yml new file mode 100644 index 0000000..5402396 --- /dev/null +++ b/.github/workflows/validate.yml @@ -0,0 +1,106 @@ +name: Validate & Build + +on: + push: + branches: [main] + pull_request: + branches: [main] + +jobs: + validate-models: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + + - uses: actions/setup-node@v4 + with: + node-version: "20" + + - 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 + + - name: Validate providers YAML against schema + run: | + npx ajv validate \ + -s provider.schema.json \ + -d "providers/*.yaml" \ + --spec=draft2020 \ + --all-errors || exit 1 + + codegen: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + + - uses: actions/setup-node@v4 + with: + node-version: "20" + + - name: Run codegen + run: node scripts/codegen.mjs + + - name: Check for changes + run: | + git diff --exit-code packages/typescript/src/generated/ + git diff --exit-code packages/python/model_metadata/generated/ + + typescript: + runs-on: ubuntu-latest + defaults: + run: + working-directory: packages/typescript + steps: + - uses: actions/checkout@v4 + + - uses: actions/setup-node@v4 + with: + node-version: "20" + registry-url: "https://registry.npmjs.org" + + - name: Install deps and type-check + run: npm ci && npm run lint + + python: + runs-on: ubuntu-latest + defaults: + run: + working-directory: packages/python + steps: + - uses: actions/checkout@v4 + + - name: Install uv + uses: astral-sh/setup-uv@v5 + with: + enable-cache: true + python-version: "3.10" + + - name: Install dependencies + run: uv sync + + - 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 + m = ModelMetadata.model_validate({ + 'model_id': 'test', + 'model_type': 'chat', + 'context_window': 1000 + }) + print('ModelMetadata valid:', m.model_id) + p = ProviderMetadata.model_validate({ + 'provider_id': 'openai', + 'name': 'OpenAI', + 'api_type': 'openai_compatible', + 'routing_priority': 'direct' + }) + print('ProviderMetadata valid:', p.provider_id) + " \ No newline at end of file diff --git a/.gitignore b/.gitignore index f071240..5a46e23 100644 --- a/.gitignore +++ b/.gitignore @@ -1,2 +1,5 @@ __pycache__ -.pytest_cache \ No newline at end of file +.pytest_cache + +node_modules +dist \ No newline at end of file diff --git a/README.md b/README.md index 0a55564..0919540 100644 --- a/README.md +++ b/README.md @@ -2,6 +2,12 @@ A centralized, language-agnostic, open-source approach to storing and sharing model definitions like context windows, cost per token, etc. +**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. + +**Want a model added?** [Request a Model](https://github.com/InterwebAlchemy/llm-model-definitions/issues). + +For an exhaustive registry, check out [models.dev](https://models.dev). + ## Problem Nearly every project that wants to incorporate multiple models needs to handle knowledge about the underlying model like context window length. @@ -9,16 +15,12 @@ Nearly every project that wants to incorporate multiple models needs to handle k This leads to the proliferation of essentially the same code repeated across multiple codebases that all need to be updated when new models are released, token costs change, a model is deprecated, etc. ### Examples -- [LangChain `base/base_language/count_tokens.ts`](https://github.com/langchain-ai/langchainjs/blob/main/langchain/src/base_language/count_tokens.ts) -- [LiteLLM `model_prices_and_context_window.json`](https://github.com/BerriAI/litellm/blob/main/model_prices_and_context_window.json) - - **Note**: This was my inspiration for this initiative -- [AutoGen `token_count_utils.py`](https://github.com/microsoft/autogen/blob/main/autogen/token_count_utils.py) -- [tokentrim model_map.py](https://github.com/KillianLucas/tokentrim/blob/main/tokentrim/model_map.py) - - **Note**: [Open Interpreter](https://github.com/KillianLucas/open-interpreter/) relies on this -- [AI Research Assistant `sevices/openai/models`](https://github.com/InterwebAlchemy/obsidian-ai-research-assistant/tree/main/src/services/openai/models) - - **Note**: This is one of my projects -- [Mentat `llm_api.py`](https://github.com/AbanteAI/mentat/blob/main/mentat/llm_api.py) -- [AutoGPT `autogpt/core/resource/model_providers/openai.py`](https://github.com/Significant-Gravitas/AutoGPT/blob/master/autogpts/autogpt/autogpt/core/resource/model_providers/openai.py) + +- [LangChain](<[libs/langchain-core/src/language_models/base.ts](https://github.com/langchain-ai/langchainjs/blob/main/libs/langchain-core/src/language_models/base.ts)>) +- [LiteLLM](https://github.com/BerriAI/litellm/blob/main/model_prices_and_context_window.json) +- [AutoGen](https://github.com/microsoft/autogen/blob/main/python/packages/autogen-core/src/autogen_core/models/_model_client.py#L16) +- [tokentrim](https://github.com/KillianLucas/tokentrim/blob/main/tokentrim/model_map.py) +- [AI Research Assistant Obsidian Plugin](https://github.com/InterwebAlchemy/obsidian-ai-research-assistant/blob/main/src/services/openai/models/index.ts) - [AgentGPT `next/src/types/modelSettings.ts`](https://github.com/reworkd/AgentGPT/blob/main/next/src/types/modelSettings.ts) - [MetaGPT `utils/token_counter.py`](https://github.com/geekan/MetaGPT/blob/main/metagpt/utils/token_counter.py) @@ -26,24 +28,24 @@ Have more examples? [Create a Pull Request](https://github.com/InterwebAlchemy/l ## Proposal -Centralized ownership (by an open source foundation) of a tech stack agnostic utility that defines model information and allows developers to easily import and consume these definitions in their own codebases. +Centralized, language-agnostic utility that defines model information and allows developers to easily import and consume these definitions in their own codebases. ### JSON Schema -A [JSON Schema](https://json-schema.org/) definition can be found in [`model-metadata.schema.json`](./model-metadata.schema.json), and example Model Metadata definitions can be found in the [`/models` directory](./models). +A [JSON Schema](https://json-schema.org/) definition can be found in [`model-metadata.schema.json`](./model-metadata.schema.json), and example Model Metadata definitions can be found in the [`/models` directory](./models). Provider definitions live in [`/providers`](./providers) with their own schema in [`provider.schema.json`](./provider.schema.json). -This schema defines properties that are relevant to the model and developers who wish to leverage it in their own codebases. +These schema defines properties that are relevant to the model and developers who wish to leverage it in their own codebases. #### Required Properties - `model_id`: The identifier of the model that the provider uses - **Example**: `gpt-3.5-turbo` - `model_name`: The human-friendly name of the model - - **Example**: `GPT-3.5 Turbo` + - **Example**: `GPT-3.5 Turbo` - `model_type`: The type of model (`chat`, `completion`, or `embedding`) - - **Example**: `chat` + - **Example**: `chat` - `context_window`: The maximum number of tokens in the model's context window - - **Example**: `4096` + - **Example**: `4096` #### Optional Properties @@ -53,66 +55,182 @@ This schema defines properties that are relevant to the model and developers who - `model_version`: The version of the model - **Example** `0613` - `cost_per_token`: The cost per token in USD - - **Example**: ```json { - "input": 0.0000015, - "output": 0.000002 - }``` + - **Example**: `json { + "input": 0.0000015, + "output": 0.000002 +}` - **Note**: supports either a basic number or an object with `input` and `output` numbers to define different costs between input tokens and output tokens - `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 -- `token_encoding`: What encoding the model uses for tokens - - **Example**: `cl100k_base` - - **Note**: This is helpful when using `tiktoken`, `gpt-tokenizer`, etc. or needing to know if a model requires an [alternate approach to counting tokens](https://github.com/belladoreai/llama-tokenizer-js) +- `tokenizer`: What type of tokenization the model uses + - `family`: The tokenizer family, e.g. `tiktoken` (OpenAI), `tekken` (Mistral), `sentencepiece` (Google), `other`, or `unknown` + - **Note**: This is helpful when determining if/how the consuming application can calculate token usage using a standard open source library like `tiktoken` or `gpt-tokenizer`, etc. or an [alternate approach to counting tokens](https://github.com/belladoreai/llama-tokenizer-js) + - `name`: The specific tokenizer name or protocol used by the model, e.g. `cl100k_base` (tiktoken), `p50k_base` (tiktoken), `v3` (tekken), etc. - `tuning`: The types of tuning that the model has been given in Array format; currently supports `function`, `instruction`, `code`, `multilingual`, and `multimodal` - **Example**: `["function", "instruction"]` - **Note**: This is helpful when deciding which models are suitable for given tasks +- `deprecated`: Whether the model has been deprecated by the provider + - **Example**: `false` + - **Note**: Deprecated models may still work but should be avoided for new integrations +- `providers`: Which providers serve this model and how to reference it on each + - **Example**: + ```yaml + providers: + - provider_id: openai + model_id_on_provider: gpt-4o + - provider_id: openrouter + model_id_on_provider: openai/gpt-4o + ``` + - **Note**: Allows a single model to be accessed via direct provider API or aggregator. Provider definitions live in `/providers`. + +### Provider Schema + +Provider definitions in [`providers/`](./providers) describe API endpoints and routing. See [`provider.schema.json`](./provider.schema.json). -#### Example +#### Required Properties + +- `provider_id`: Unique lowercase identifier matching the `providers/` filename and used in model `provider_reference` +- `name`: Human-readable name +- `api_type`: One of `openai_compatible`, `anthropic`, `openai`, `other` +- `routing_priority`: `direct` (serves models itself) or `aggregator` (routes to other providers) or `both` + +#### Provider Routing + +The `routing_priority` field differentiates direct providers (who serve models themselves) from aggregators (who route to other providers): + +| `routing_priority` | Provider Examples | +| ------------------ | ------------------------------------------------------ | +| `direct` | OpenAI, Anthropic, DeepSeek, Groq, Mistral, Cloudflare | +| `aggregator` | OpenRouter | -Here is an example Model Metadata definition for [OpenAI's GPT-3.5 Turbo model](https://platform.openai.com/docs/models/gpt-3-5): +Ollama, LM Studio, and LocalAI use `direct` but default to localhost with no auth — override `base_url` and `auth_type` in your app config when deploying. + +#### Example ```yaml -model_id: gpt-3.5-turbo -model_name: GPT-3.5 Turbo -model_provider: openai -model_description: Most capable GPT-3.5 model and optimized for chat at 1/10th the cost of text-davinci-003. -model_info: https://platform.openai.com/docs/models/gpt-3-5 -model_version: latest -model_type: chat -context_window: 4097 -max_tokens: 4095 -cost_per_token: - input: 0.0000015 - output: 0.000002 -knowledge_cutoff: 2021-09-01 -token_encoding: cl100k_base -tuning: - - function +provider_id: openai +name: OpenAI +website_url: https://openai.com +api_type: openai_compatible +base_url: https://api.openai.com/v1 +auth_type: api_key +routing_priority: direct +status: active ``` -## Roadmap - -**Note**: This project is open to feedback at every stage of rhis roadmap. - -- [x] Create JSON Schema -- [x] Generate example model definitions -- [x] Discuss schema with [AI Engineer Foundation](https://github.com/AI-Engineer-Foundation/) -- [x] Rename to `model-metadata-central` -- [ ] Integrate a GitHub Action to validate Model Metadata definitions against schema -- [ ] Publish JSON Schema to GitHub Pages -- [ ] Add guidance for including metadata definitions via git submodule -- [ ] Generate language-specific packages for importing these definitions into other codebases - - [ ] TypeScript - - [x] Python - - [ ] Rust - - [ ] Go - - Other languages? Open an [issue](https://github.com/InterwebAlchemy/llm-model-definitions/issues) to request one! -- [ ] Integrate metadata for more models -- [ ] Integrate a GitHub Action to generate these packages -- [ ] Integrate a GitHub Action to publish these packages to NPM, PyPI, etc. -- [ ] Donate project to [AI Engineer Foundation](https://github.com/AI-Engineer-Foundation/) -- [ ] Update publishing actions to publish to the AI Engineer Foundation's NPM, PyPI, etc. -- [ ] Ongoing support, evangelism, and maintenance of the project -- [ ] **Hopeful**: Generate static GitHub Pages site that lists models, displays their metadata, and allows filtering by properties -- [ ] **Hopeful**: Get [projects](https://github.com/InterwebAlchemy/llm-model-definitions#examples) to adopt the language-specific packages and extend them as necessary instead of creating their own model definitions -- [ ] **Aspirational**: Get model providers to adopt the schema definition and update the repo when model metadata changes or new models are released +### 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. + +**OpenAI**: + +- `gpt-4-turbo` +- `gpt-4.1` +- `gpt-4.1-mini` +- `gpt-4.1-nano` +- `gpt-4.5` +- `gpt-4o` +- `gpt-4o-mini` +- `gpt-5` +- `gpt-5-mini` +- `gpt-5-nano` +- `gpt-5.3-codex` +- `gpt-5.4` +- `gpt-5.4-image-2` +- `gpt-5.4-mini` +- `gpt-5.4-nano` +- `gpt-5.4-pro` +- `gpt-5.5` +- `gpt-5.5-pro` +- `o3` +- `o4-mini` + +**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**: + +- `gemini-2.5-flash` +- `gemini-2.5-pro` +- `gemma-4-26b-a4b-it` +- `gemma-4-31b-it` + +**DeepSeek**: + +- `deepseek-coder-v4` +- `deepseek-v4-flash` +- `deepseek-v4-pro` + +**xAI**: + +- `grok-4.2` +- `grok-4.2-multi-agent` + +**Moonshot AI**: + +- `kimi-k2.6` +- `kimi-v3` + +**Mistral AI**: + +- `codestral-latest` +- `mistral-large-2411` +- `mistral-large-2512` +- `mistral-large-latest` +- `mistral-medium-latest` +- `mistral-nemo` +- `mistral-small-latest` + +**MiniMax**: + +- `minimax-m2` +- `minimax-m2.1` +- `minimax-m2.1-highspeed` +- `minimax-m2.5` +- `minimax-m2.5-highspeed` +- `minimax-m2.7` +- `minimax-m2.7-highspeed` + +**Z.AI**: + +- `glm-4.7` +- `glm-4.7-flash` +- `glm-5` +- `glm-5-turbo` +- `glm-5.1` +- `glm-5v-turbo` + +**Qwen**: + +- `qwen3-32b` +- `qwen3.6-flash` +- `qwen3.6-plus` + +**Groq**: + +- `deepseek-r1-distill-llama-70b` +- `llama-3.1-8b-instant` +- `llama-3.3-70b-versatile` + +**NVIDIA**: + +- `nemotron-3-super-120b-a12b` + +Full definitions (including deprecated models) live in [`/models`](./models). + +### Packages + +Language-specific packages wrap the registry with a typed API. See each package for usage examples. + +| Package | Status | +| ------------------------------------ | ------ | +| [TypeScript](./packages/typescript/) | Alpha | +| [Python](./packages/python/) | Alpha | diff --git a/model-metadata.schema.json b/model-metadata.schema.json index 2785fc8..1414512 100644 --- a/model-metadata.schema.json +++ b/model-metadata.schema.json @@ -67,11 +67,9 @@ "type": "string", "format": "date" }, - "token_encoding": { - "description": "What encoding the model uses for tokens (example: cl100k_base)", - "type": "string", - "enum": ["cl100k_base", "p50k_base", "p50k_edit", "r50k_base", "llama", "unknown"], - "default": "unknown" + "tokenizer": { + "description": "Tokenizer family and specific encoding/version used by the model", + "$ref": "#/$defs/tokenizer_config" }, "tuning": { "description": "Tags for things the model was tuned for (example: function, instruction)", @@ -82,7 +80,54 @@ }, "uniqueItems": true, "minItems": 1 + }, + "deprecated": { + "description": "Whether the model has been deprecated by the provider", + "type": "boolean", + "default": false + }, + "providers": { + "description": "The providers that serve this model and their configuration", + "type": "array", + "items": { + "$ref": "#/$defs/provider_reference" + }, + "uniqueItems": true, + "minItems": 1 } }, - "required": ["model_id", "model_provider", "model_type", "context_window"] + "required": ["model_id", "model_type", "context_window"], + "$defs": { + "provider_reference": { + "type": "object", + "description": "A reference to a provider definition", + "properties": { + "provider_id": { + "description": "The identifier matching a provider in providers/", + "type": "string" + }, + "model_id_on_provider": { + "description": "The model ID as used by this specific provider (may differ from model_id)", + "type": "string" + } + }, + "required": ["provider_id"] + }, + "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"] + }, + "name": { + "description": "The encoding or version identifier within the family (example: 'cl100k_base' for tiktoken, 'v3' for tekken)", + "type": "string" + } + }, + "required": ["family"] + } + } } diff --git a/models/claude-haiku-4-5.yaml b/models/claude-haiku-4-5.yaml new file mode 100644 index 0000000..e458fed --- /dev/null +++ b/models/claude-haiku-4-5.yaml @@ -0,0 +1,18 @@ +model_id: claude-haiku-4-5 +model_name: Claude Haiku 4.5 (latest) +model_provider: anthropic +model_description: Anthropic's fast, low-cost Claude 4.5 model with near-frontier intelligence for high-volume work. +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 +knowledge_cutoff: "2025-02-28" +tuning: [multimodal, function] +providers: + - provider_id: anthropic + model_id_on_provider: claude-haiku-4-5 + - provider_id: openrouter + model_id_on_provider: anthropic/claude-haiku-4.5 diff --git a/models/claude-haiku-4.yaml b/models/claude-haiku-4.yaml new file mode 100644 index 0000000..6730a45 --- /dev/null +++ b/models/claude-haiku-4.yaml @@ -0,0 +1,15 @@ +model_id: claude-haiku-4 +model_name: Claude Haiku 4 +model_provider: anthropic +model_description: Fast, affordable Claude. Optimized for high-volume, latency-sensitive tasks where quality-per-token matters more than raw capability. +model_info: https://docs.anthropic.com/en/docs/models/claude-haiku-4 +model_type: chat +context_window: 200000 +cost_per_token: + input: 0.0000008 + output: 0.000004 +providers: + - provider_id: anthropic + model_id_on_provider: haiku-4 + - provider_id: openrouter + model_id_on_provider: anthropic/claude-haiku-4 \ No newline at end of file diff --git a/models/claude-opus-4-6-fast.yaml b/models/claude-opus-4-6-fast.yaml new file mode 100644 index 0000000..b1910ba --- /dev/null +++ b/models/claude-opus-4-6-fast.yaml @@ -0,0 +1,16 @@ +model_id: claude-opus-4-6-fast +model_name: Claude Opus 4.6 (Fast) +model_provider: anthropic +model_description: High-speed variant of Opus 4.6. Optimized for rapid responses while retaining strong reasoning and capabilities. +model_info: https://docs.anthropic.com/en/docs/models/claude-opus-4-6 +model_type: chat +context_window: 1000000 +cost_per_token: + input: 0.000030 + output: 0.000150 +tuning: [function] +providers: + - provider_id: anthropic + model_id_on_provider: claude-opus-4-6-fast + - provider_id: openrouter + model_id_on_provider: anthropic/claude-opus-4-6-fast \ No newline at end of file diff --git a/models/claude-opus-4-6.yaml b/models/claude-opus-4-6.yaml new file mode 100644 index 0000000..e32ac3d --- /dev/null +++ b/models/claude-opus-4-6.yaml @@ -0,0 +1,18 @@ +model_id: claude-opus-4-6 +model_name: Claude Opus 4.6 +model_provider: anthropic +model_description: Anthropic's previous-generation Opus model with 1M context, retained for downstream compatibility. +model_info: https://docs.anthropic.com/en/docs/about-claude/models/overview +model_type: chat +context_window: 1000000 +max_tokens: 128000 +cost_per_token: + input: 0.000005 + output: 0.000025 +knowledge_cutoff: "2025-05-31" +tuning: [multimodal, function] +providers: + - provider_id: anthropic + model_id_on_provider: claude-opus-4-6 + - provider_id: openrouter + model_id_on_provider: anthropic/claude-opus-4.6 diff --git a/models/claude-opus-4-7.yaml b/models/claude-opus-4-7.yaml new file mode 100644 index 0000000..3282bbd --- /dev/null +++ b/models/claude-opus-4-7.yaml @@ -0,0 +1,16 @@ +model_id: claude-opus-4-7 +model_name: Claude Opus 4.7 +model_provider: anthropic +model_description: Anthropic's most capable model. Exceptional at complex reasoning, coding, creative collaboration, and scientific analysis. +model_info: https://docs.anthropic.com/en/docs/models/claude-opus-4-7 +model_type: chat +context_window: 1000000 +cost_per_token: + input: 0.000005 + output: 0.000025 +tuning: [function] +providers: + - provider_id: anthropic + model_id_on_provider: claude-opus-4-7 + - provider_id: openrouter + model_id_on_provider: anthropic/claude-opus-4-7 \ No newline at end of file diff --git a/models/claude-opus-latest.yaml b/models/claude-opus-latest.yaml new file mode 100644 index 0000000..fb3825c --- /dev/null +++ b/models/claude-opus-latest.yaml @@ -0,0 +1,16 @@ +model_id: claude-opus-latest +model_name: Claude Opus Latest +model_provider: anthropic +model_description: Points to the latest stable Opus release. Use when you want the newest Claude without pinning a version. +model_info: https://docs.anthropic.com/en/docs/models +model_type: chat +context_window: 1000000 +cost_per_token: + input: 0.000005 + output: 0.000025 +tuning: [function] +providers: + - provider_id: anthropic + model_id_on_provider: opus + - provider_id: openrouter + model_id_on_provider: anthropic/claude-opus-latest \ No newline at end of file diff --git a/models/claude-sonnet-4-2.yaml b/models/claude-sonnet-4-2.yaml new file mode 100644 index 0000000..b9a5deb --- /dev/null +++ b/models/claude-sonnet-4-2.yaml @@ -0,0 +1,16 @@ +model_id: claude-sonnet-4-2 +model_name: Claude Sonnet 4.2 +model_provider: anthropic +model_description: Balanced Anthropic model. Strong for coding, analysis, and everyday tasks at a mid-range price point. +model_info: https://docs.anthropic.com/en/docs/models/claude-sonnet-4-2 +model_type: chat +context_window: 200000 +cost_per_token: + input: 0.000003 + output: 0.000015 +tuning: [function] +providers: + - provider_id: anthropic + model_id_on_provider: claude-sonnet-4-2 + - provider_id: openrouter + model_id_on_provider: anthropic/claude-sonnet-4-2 \ No newline at end of file diff --git a/models/claude-sonnet-4-6.yaml b/models/claude-sonnet-4-6.yaml new file mode 100644 index 0000000..2b69494 --- /dev/null +++ b/models/claude-sonnet-4-6.yaml @@ -0,0 +1,18 @@ +model_id: claude-sonnet-4-6 +model_name: Claude Sonnet 4.6 +model_provider: anthropic +model_description: Anthropic's balanced Claude model with strong speed/intelligence tradeoffs, extended thinking, and 1M context. +model_info: https://docs.anthropic.com/en/docs/about-claude/models/overview +model_type: chat +context_window: 1000000 +max_tokens: 64000 +cost_per_token: + input: 0.000003 + output: 0.000015 +knowledge_cutoff: "2025-08-31" +tuning: [multimodal, function] +providers: + - provider_id: anthropic + model_id_on_provider: claude-sonnet-4-6 + - provider_id: openrouter + model_id_on_provider: anthropic/claude-sonnet-4.6 diff --git a/models/codestral-latest.yaml b/models/codestral-latest.yaml new file mode 100644 index 0000000..5985728 --- /dev/null +++ b/models/codestral-latest.yaml @@ -0,0 +1,20 @@ +model_id: codestral-latest +model_name: Codestral (latest) +model_provider: mistralai +model_description: Mistral's code-specialized model for software engineering and code completion workflows. +model_info: https://docs.mistral.ai/getting-started/models/models_overview/ +model_type: chat +context_window: 256000 +max_tokens: 4096 +cost_per_token: + input: 3e-7 + output: 9e-7 +knowledge_cutoff: "2024-10-01" +tokenizer: + family: tekken +tuning: [function, instruction] +providers: + - provider_id: mistralai + model_id_on_provider: codestral-latest + - provider_id: openrouter + model_id_on_provider: mistralai/codestral-latest diff --git a/models/deepseek-coder-v4.yaml b/models/deepseek-coder-v4.yaml new file mode 100644 index 0000000..4840d74 --- /dev/null +++ b/models/deepseek-coder-v4.yaml @@ -0,0 +1,16 @@ +model_id: deepseek-coder-v4 +model_name: DeepSeek Coder V4 +model_provider: deepseek +model_description: DeepSeek's dedicated code model. Specialized for code generation, completion, and debugging across many languages. +model_info: https://api.deepseek.com +model_type: chat +context_window: 1048576 +cost_per_token: + input: 0.00000043 + output: 0.00000087 +tuning: [code] +providers: + - provider_id: deepseek + model_id_on_provider: deepseek-coder + - provider_id: openrouter + model_id_on_provider: deepseek/deepseek-coder-v4 \ No newline at end of file diff --git a/models/deepseek-r1-distill-llama-70b.yaml b/models/deepseek-r1-distill-llama-70b.yaml new file mode 100644 index 0000000..013faaf --- /dev/null +++ b/models/deepseek-r1-distill-llama-70b.yaml @@ -0,0 +1,16 @@ +model_id: deepseek-r1-distill-llama-70b +model_name: DeepSeek R1 Distill Llama 70B +model_provider: groq +model_description: Groq-hosted DeepSeek R1 distilled Llama 70B reasoning model. +model_info: https://console.groq.com/docs/models +model_type: chat +context_window: 131072 +max_tokens: 8192 +cost_per_token: + input: 7.5e-7 + output: 9.9e-7 +knowledge_cutoff: "2024-07-01" +tuning: [function, instruction] +providers: + - provider_id: groq + model_id_on_provider: deepseek-r1-distill-llama-70b diff --git a/models/deepseek-v4-flash.yaml b/models/deepseek-v4-flash.yaml new file mode 100644 index 0000000..90dddf0 --- /dev/null +++ b/models/deepseek-v4-flash.yaml @@ -0,0 +1,15 @@ +model_id: deepseek-v4-flash +model_name: DeepSeek V4 Flash +model_provider: deepseek +model_description: Fast, efficient DeepSeek variant. Optimized for high-volume applications where latency and cost are critical. +model_info: https://api.deepseek.com +model_type: chat +context_window: 1048576 +cost_per_token: + input: 0.00000014 + output: 0.00000028 +providers: + - provider_id: deepseek + model_id_on_provider: deepseek-chat + - provider_id: openrouter + model_id_on_provider: deepseek/deepseek-v4-flash \ No newline at end of file diff --git a/models/deepseek-v4-pro.yaml b/models/deepseek-v4-pro.yaml new file mode 100644 index 0000000..4eb782b --- /dev/null +++ b/models/deepseek-v4-pro.yaml @@ -0,0 +1,16 @@ +model_id: deepseek-v4-pro +model_name: DeepSeek V4 Pro +model_provider: deepseek +model_description: DeepSeek's flagship model. Excellent reasoning and code capabilities at a fraction of OpenAI's cost. +model_info: https://api.deepseek.com +model_type: chat +context_window: 1048576 +cost_per_token: + input: 0.00000043 + output: 0.00000087 +tuning: [function] +providers: + - provider_id: deepseek + model_id_on_provider: deepseek-chat + - provider_id: openrouter + model_id_on_provider: deepseek/deepseek-v4-pro \ No newline at end of file diff --git a/models/gemini-2.0-flash.yaml b/models/gemini-2.0-flash.yaml new file mode 100644 index 0000000..9ae0994 --- /dev/null +++ b/models/gemini-2.0-flash.yaml @@ -0,0 +1,16 @@ +model_id: gemini-2.0-flash +model_name: Gemini 2.0 Flash +model_provider: google +model_description: Previous-generation Gemini. Good balance of speed, cost, and capability for standard tasks. +model_info: https://ai.google.dev/gemini-api/models/gemini-2.0-flash +model_type: chat +context_window: 128000 +cost_per_token: + input: 0.00000010 + output: 0.00000040 +deprecated: true +providers: + - provider_id: google + model_id_on_provider: gemini-2.0-flash + - provider_id: openrouter + model_id_on_provider: google/gemini-2.0-flash \ No newline at end of file diff --git a/models/gemini-2.5-flash.yaml b/models/gemini-2.5-flash.yaml new file mode 100644 index 0000000..1887bad --- /dev/null +++ b/models/gemini-2.5-flash.yaml @@ -0,0 +1,16 @@ +model_id: gemini-2.5-flash +model_name: Gemini 2.5 Flash +model_provider: google +model_description: Fast, efficient Gemini model. Optimized for high-volume applications with strong reasoning and code performance. +model_info: https://ai.google.dev/gemini-api/models/gemini-2.5-flash +model_type: chat +context_window: 1000000 +cost_per_token: + input: 0.000000075 + output: 0.00000030 +tuning: [multimodal] +providers: + - provider_id: google + model_id_on_provider: gemini-2.5-flash + - provider_id: openrouter + model_id_on_provider: google/gemini-2.5-flash \ No newline at end of file diff --git a/models/gemini-2.5-pro.yaml b/models/gemini-2.5-pro.yaml new file mode 100644 index 0000000..dd3d778 --- /dev/null +++ b/models/gemini-2.5-pro.yaml @@ -0,0 +1,16 @@ +model_id: gemini-2.5-pro +model_name: Gemini 2.5 Pro +model_provider: google +model_description: Google's flagship model. Exceptional at long-context tasks, multimodal reasoning, and code generation. +model_info: https://ai.google.dev/gemini-api/docs/models/gemini-2.5-pro +model_type: chat +context_window: 1000000 +cost_per_token: + input: 0.00000125 + output: 0.000005 +tuning: [multimodal] +providers: + - provider_id: google + model_id_on_provider: gemini-2.5-pro + - provider_id: openrouter + model_id_on_provider: google/gemini-2.5-pro \ No newline at end of file diff --git a/models/gemma-4-26b-a4b-it.yaml b/models/gemma-4-26b-a4b-it.yaml new file mode 100644 index 0000000..0c37132 --- /dev/null +++ b/models/gemma-4-26b-a4b-it.yaml @@ -0,0 +1,17 @@ +model_id: gemma-4-26b-a4b-it +model_name: Gemma 4 26B +model_provider: google +model_description: Google's smaller open-weight instruction-tuned model. Efficient for constrained deployment environments. +model_info: https://ai.google.dev/gemma +model_type: chat +context_window: 262144 +cost_per_token: + input: 0.00000006 + output: 0.00000033 +providers: + - provider_id: google + model_id_on_provider: gemma-4-26b-a4b-it + - provider_id: cloudflare + model_id_on_provider: "@cf/google/gemma-4-26b-a4b-it" + - provider_id: openrouter + model_id_on_provider: google/gemma-4-26b-a4b-it diff --git a/models/gemma-4-31b-it.yaml b/models/gemma-4-31b-it.yaml new file mode 100644 index 0000000..9e5ef94 --- /dev/null +++ b/models/gemma-4-31b-it.yaml @@ -0,0 +1,15 @@ +model_id: gemma-4-31b-it +model_name: Gemma 4 31B +model_provider: google +model_description: Google's open-weight instruction-tuned model. Strong reasoning in a smaller footprint. Good for fine-tuning and self-hosting. +model_info: https://ai.google.dev/gemma +model_type: chat +context_window: 262144 +cost_per_token: + input: 0.00000013 + output: 0.00000038 +providers: + - provider_id: google + model_id_on_provider: gemma-4-31b-it + - provider_id: openrouter + model_id_on_provider: google/gemma-4-31b-it \ No newline at end of file diff --git a/models/glm-4.7-flash.yaml b/models/glm-4.7-flash.yaml new file mode 100644 index 0000000..53bf54c --- /dev/null +++ b/models/glm-4.7-flash.yaml @@ -0,0 +1,20 @@ +model_id: glm-4.7-flash +model_name: GLM-4.7-Flash +model_provider: zai +model_description: Fast open-weight GLM model optimized for multilingual dialogue, tool calling, and reasoning. +model_info: https://docs.z.ai/guides/overview/pricing +model_type: chat +context_window: 200000 +max_tokens: 131072 +cost_per_token: + input: 0 + output: 0 +knowledge_cutoff: "2025-04-01" +tuning: [function, instruction] +providers: + - provider_id: zai + model_id_on_provider: glm-4.7-flash + - provider_id: cloudflare + model_id_on_provider: "@cf/zai-org/glm-4.7-flash" + - provider_id: openrouter + model_id_on_provider: z-ai/glm-4.7-flash diff --git a/models/glm-4.7.yaml b/models/glm-4.7.yaml new file mode 100644 index 0000000..486bcfb --- /dev/null +++ b/models/glm-4.7.yaml @@ -0,0 +1,18 @@ +model_id: glm-4.7 +model_name: GLM-4.7 +model_provider: zai +model_description: Open-weight Z.AI GLM model with strong multilingual, reasoning, and instruction-following capabilities. +model_info: https://docs.z.ai/guides/overview/pricing +model_type: chat +context_window: 204800 +max_tokens: 131072 +cost_per_token: + input: 6e-7 + output: 0.0000022 +knowledge_cutoff: "2025-04-01" +tuning: [function, instruction] +providers: + - provider_id: zai + model_id_on_provider: glm-4.7 + - provider_id: openrouter + model_id_on_provider: z-ai/glm-4.7 diff --git a/models/glm-5-turbo.yaml b/models/glm-5-turbo.yaml new file mode 100644 index 0000000..6e1710d --- /dev/null +++ b/models/glm-5-turbo.yaml @@ -0,0 +1,17 @@ +model_id: glm-5-turbo +model_name: GLM-5-Turbo +model_provider: zai +model_description: Higher-throughput GLM-5 Turbo model for production Z.AI workloads. +model_info: https://docs.z.ai/guides/overview/pricing +model_type: chat +context_window: 200000 +max_tokens: 131072 +cost_per_token: + input: 0.0000012 + output: 0.000004 +tuning: [function] +providers: + - provider_id: zai + model_id_on_provider: glm-5-turbo + - provider_id: openrouter + model_id_on_provider: z-ai/glm-5-turbo diff --git a/models/glm-5.1.yaml b/models/glm-5.1.yaml new file mode 100644 index 0000000..74499a3 --- /dev/null +++ b/models/glm-5.1.yaml @@ -0,0 +1,17 @@ +model_id: glm-5.1 +model_name: GLM-5.1 +model_provider: zai +model_description: Updated GLM-5.1 model with current Z.AI pricing and long-context support. +model_info: https://docs.z.ai/guides/overview/pricing +model_type: chat +context_window: 200000 +max_tokens: 131072 +cost_per_token: + input: 0.0000014 + output: 0.0000044 +tuning: [function] +providers: + - provider_id: zai + model_id_on_provider: glm-5.1 + - provider_id: openrouter + model_id_on_provider: z-ai/glm-5.1 diff --git a/models/glm-5.yaml b/models/glm-5.yaml new file mode 100644 index 0000000..308aa5a --- /dev/null +++ b/models/glm-5.yaml @@ -0,0 +1,17 @@ +model_id: glm-5 +model_name: GLM-5 +model_provider: zai +model_description: Z.AI GLM-5 model for current-generation reasoning and agentic workloads. +model_info: https://docs.z.ai/guides/overview/pricing +model_type: chat +context_window: 204800 +max_tokens: 131072 +cost_per_token: + input: 0.000001 + output: 0.0000032 +tuning: [function, instruction] +providers: + - provider_id: zai + model_id_on_provider: glm-5 + - provider_id: openrouter + model_id_on_provider: z-ai/glm-5 diff --git a/models/glm-5v-turbo.yaml b/models/glm-5v-turbo.yaml new file mode 100644 index 0000000..8c173bc --- /dev/null +++ b/models/glm-5v-turbo.yaml @@ -0,0 +1,17 @@ +model_id: glm-5v-turbo +model_name: glm-5v-turbo +model_provider: zai +model_description: Vision-capable GLM-5 Turbo variant for multimodal document, image, and video inputs. +model_info: https://docs.z.ai/guides/overview/pricing +model_type: chat +context_window: 200000 +max_tokens: 131072 +cost_per_token: + input: 0.0000012 + output: 0.000004 +tuning: [multimodal, function] +providers: + - provider_id: zai + model_id_on_provider: glm-5v-turbo + - provider_id: openrouter + model_id_on_provider: z-ai/glm-5v-turbo diff --git a/models/gpt-3.5-turbo-16k.yaml b/models/gpt-3.5-turbo-16k.yaml new file mode 100644 index 0000000..857873b --- /dev/null +++ b/models/gpt-3.5-turbo-16k.yaml @@ -0,0 +1,21 @@ +model_id: gpt-3.5-turbo-16k +model_name: GPT-3.5 Turbo 16K +model_provider: openai +model_description: Deprecated 16K GPT-3.5 Turbo snapshot retained for legacy downstream configurations. +model_info: https://platform.openai.com/docs/models/gpt-3.5-turbo-16k-0613 +model_version: "0613" +model_type: chat +context_window: 16385 +max_tokens: 4096 +cost_per_token: + input: 0.000003 + output: 0.000004 +knowledge_cutoff: "2021-09-01" +tokenizer: + family: tiktoken + name: cl100k_base +tuning: [instruction] +deprecated: true +providers: + - provider_id: openai + model_id_on_provider: gpt-3.5-turbo-16k-0613 diff --git a/models/gpt-3.5-turbo-instruct.yaml b/models/gpt-3.5-turbo-instruct.yaml index 321b0ee..a9b4de4 100644 --- a/models/gpt-3.5-turbo-instruct.yaml +++ b/models/gpt-3.5-turbo-instruct.yaml @@ -11,7 +11,10 @@ cost_per_token: input: 0.0000015 output: 0.000002 knowledge_cutoff: "2021-09-01" -token_encoding: cl100k_base +tokenizer: + family: tiktoken + name: cl100k_base tuning: - instruction - function +deprecated: true diff --git a/models/gpt-3.5-turbo.yaml b/models/gpt-3.5-turbo.yaml index a2dc6d0..6ff0e05 100644 --- a/models/gpt-3.5-turbo.yaml +++ b/models/gpt-3.5-turbo.yaml @@ -11,5 +11,11 @@ cost_per_token: input: 0.0000015 output: 0.000002 knowledge_cutoff: "2021-09-01" -token_encoding: cl100k_base +tokenizer: + family: tiktoken + name: cl100k_base tuning: [function] +deprecated: true +providers: + - provider_id: openai + model_id_on_provider: gpt-3.5-turbo diff --git a/models/gpt-4-32k.yaml b/models/gpt-4-32k.yaml index d793214..5832c4c 100644 --- a/models/gpt-4-32k.yaml +++ b/models/gpt-4-32k.yaml @@ -1,4 +1,4 @@ -model_id: gpt-4 +model_id: gpt-4-32k model_name: GPT-4 32K model_provider: openai model_description: Same capabilities as the standard gpt-4 mode but with 4x the context length. @@ -10,6 +10,9 @@ cost_per_token: input: 0.00006 output: 0.00012 knowledge_cutoff: "2021-09-01" -token_encoding: cl100k_base +tokenizer: + family: tiktoken + name: cl100k_base tuning: - - function \ No newline at end of file + - function +deprecated: true diff --git a/models/gpt-4-turbo.yaml b/models/gpt-4-turbo.yaml new file mode 100644 index 0000000..6256aa1 --- /dev/null +++ b/models/gpt-4-turbo.yaml @@ -0,0 +1,21 @@ +model_id: gpt-4-turbo +model_name: GPT-4 Turbo +model_provider: openai +model_description: Legacy GPT-4 Turbo model with a 128K context window. Kept for integrations that still route older GPT-4 workloads. +model_info: https://platform.openai.com/docs/models/gpt-4-turbo +model_type: chat +context_window: 128000 +max_tokens: 4096 +cost_per_token: + input: 0.00001 + output: 0.00003 +knowledge_cutoff: "2023-12-01" +tokenizer: + family: tiktoken + name: o200k_base +tuning: [multimodal, function] +providers: + - provider_id: openai + model_id_on_provider: gpt-4-turbo + - provider_id: openrouter + model_id_on_provider: openai/gpt-4-turbo diff --git a/models/gpt-4.1-mini.yaml b/models/gpt-4.1-mini.yaml new file mode 100644 index 0000000..bfb57b3 --- /dev/null +++ b/models/gpt-4.1-mini.yaml @@ -0,0 +1,21 @@ +model_id: gpt-4.1-mini +model_name: GPT-4.1 mini +model_provider: openai +model_description: Smaller GPT-4.1 variant balancing latency, price, and strong general-purpose capability. +model_info: https://platform.openai.com/docs/models/gpt-4.1-mini +model_type: chat +context_window: 1047576 +max_tokens: 32768 +cost_per_token: + input: 4e-7 + output: 0.0000016 +knowledge_cutoff: "2024-04-01" +tokenizer: + family: tiktoken + name: o200k_base +tuning: [multimodal, function] +providers: + - provider_id: openai + model_id_on_provider: gpt-4.1-mini + - provider_id: openrouter + model_id_on_provider: openai/gpt-4.1-mini diff --git a/models/gpt-4.1-nano.yaml b/models/gpt-4.1-nano.yaml new file mode 100644 index 0000000..96d17d6 --- /dev/null +++ b/models/gpt-4.1-nano.yaml @@ -0,0 +1,21 @@ +model_id: gpt-4.1-nano +model_name: GPT-4.1 nano +model_provider: openai +model_description: Lowest-cost GPT-4.1 variant for classification, extraction, and latency-sensitive tasks. +model_info: https://platform.openai.com/docs/models/gpt-4.1-nano +model_type: chat +context_window: 1047576 +max_tokens: 32768 +cost_per_token: + input: 1e-7 + output: 4e-7 +knowledge_cutoff: "2024-04-01" +tokenizer: + family: tiktoken + name: o200k_base +tuning: [multimodal, function] +providers: + - provider_id: openai + model_id_on_provider: gpt-4.1-nano + - provider_id: openrouter + model_id_on_provider: openai/gpt-4.1-nano diff --git a/models/gpt-4.1.yaml b/models/gpt-4.1.yaml new file mode 100644 index 0000000..78d8251 --- /dev/null +++ b/models/gpt-4.1.yaml @@ -0,0 +1,21 @@ +model_id: gpt-4.1 +model_name: GPT-4.1 +model_provider: openai +model_description: Large-context GPT-4.1 model for coding, instruction following, and multimodal document workflows. +model_info: https://platform.openai.com/docs/models/gpt-4.1 +model_type: chat +context_window: 1047576 +max_tokens: 32768 +cost_per_token: + input: 0.000002 + output: 0.000008 +knowledge_cutoff: "2024-04-01" +tokenizer: + family: tiktoken + name: o200k_base +tuning: [multimodal, function] +providers: + - provider_id: openai + model_id_on_provider: gpt-4.1 + - provider_id: openrouter + model_id_on_provider: openai/gpt-4.1 diff --git a/models/gpt-4.5.yaml b/models/gpt-4.5.yaml new file mode 100644 index 0000000..c47eab4 --- /dev/null +++ b/models/gpt-4.5.yaml @@ -0,0 +1,19 @@ +model_id: gpt-4.5 +model_name: GPT-4.5 +model_provider: openai +model_description: GPT-4 successor with improved reasoning and instruction following. Strong all-around model between GPT-4o and GPT-5 series. +model_info: https://platform.openai.com/docs/models/gpt-4.5 +model_type: chat +context_window: 128000 +cost_per_token: + input: 0.000010 + output: 0.000030 +tuning: [function] +tokenizer: + family: tiktoken + name: o200k_base +providers: + - provider_id: openai + model_id_on_provider: gpt-4.5 + - provider_id: openrouter + model_id_on_provider: openai/gpt-4.5 \ No newline at end of file diff --git a/models/gpt-4.yaml b/models/gpt-4.yaml index 4aeb6c7..60f2ad7 100644 --- a/models/gpt-4.yaml +++ b/models/gpt-4.yaml @@ -11,6 +11,12 @@ cost_per_token: input: 0.00003 output: 0.00006 knowledge_cutoff: "2021-09-01" -token_encoding: cl100k_base +tokenizer: + family: tiktoken + name: cl100k_base tuning: - function +deprecated: true +providers: + - provider_id: openai + model_id_on_provider: gpt-4 diff --git a/models/gpt-4o-mini.yaml b/models/gpt-4o-mini.yaml new file mode 100644 index 0000000..2ff4857 --- /dev/null +++ b/models/gpt-4o-mini.yaml @@ -0,0 +1,20 @@ +model_id: gpt-4o-mini +model_name: GPT-4o Mini +model_provider: openai +model_description: Smaller, faster, cheaper GPT-4o. Optimized for high-volume, cost-sensitive applications. +model_info: https://platform.openai.com/docs/models/gpt-4o-mini +model_type: chat +context_window: 128000 +max_tokens: 16384 +cost_per_token: + input: 0.00000015 + output: 0.00000060 +tuning: [multimodal] +tokenizer: + family: tiktoken + name: o200k_base +providers: + - provider_id: openai + model_id_on_provider: gpt-4o-mini + - provider_id: openrouter + model_id_on_provider: openai/gpt-4o-mini \ No newline at end of file diff --git a/models/gpt-4o.yaml b/models/gpt-4o.yaml new file mode 100644 index 0000000..b148213 --- /dev/null +++ b/models/gpt-4o.yaml @@ -0,0 +1,20 @@ +model_id: gpt-4o +model_name: GPT-4o +model_provider: openai +model_description: GPT-4 Omni — multimodal model with vision, audio, and text. Fast and cost-efficient relative to GPT-4 Turbo. +model_info: https://platform.openai.com/docs/models/gpt-4o +model_type: chat +context_window: 128000 +max_tokens: 32768 +cost_per_token: + input: 0.000005 + output: 0.000015 +tuning: [multimodal] +tokenizer: + family: tiktoken + name: o200k_base +providers: + - provider_id: openai + model_id_on_provider: gpt-4o + - provider_id: openrouter + model_id_on_provider: openai/gpt-4o \ No newline at end of file diff --git a/models/gpt-5-mini.yaml b/models/gpt-5-mini.yaml new file mode 100644 index 0000000..458a325 --- /dev/null +++ b/models/gpt-5-mini.yaml @@ -0,0 +1,21 @@ +model_id: gpt-5-mini +model_name: GPT-5 Mini +model_provider: openai +model_description: Lower-cost GPT-5 variant for high-volume tasks that still benefit from reasoning support. +model_info: https://platform.openai.com/docs/models/gpt-5-mini +model_type: chat +context_window: 400000 +max_tokens: 128000 +cost_per_token: + input: 2.5e-7 + output: 0.000002 +knowledge_cutoff: "2024-05-30" +tokenizer: + family: tiktoken + name: o200k_base +tuning: [multimodal, function] +providers: + - provider_id: openai + model_id_on_provider: gpt-5-mini + - provider_id: openrouter + model_id_on_provider: openai/gpt-5-mini diff --git a/models/gpt-5-nano.yaml b/models/gpt-5-nano.yaml new file mode 100644 index 0000000..a48f51a --- /dev/null +++ b/models/gpt-5-nano.yaml @@ -0,0 +1,21 @@ +model_id: gpt-5-nano +model_name: GPT-5 Nano +model_provider: openai +model_description: Smallest GPT-5 variant for inexpensive, latency-sensitive automation. +model_info: https://platform.openai.com/docs/models/gpt-5-nano +model_type: chat +context_window: 400000 +max_tokens: 128000 +cost_per_token: + input: 5e-8 + output: 4e-7 +knowledge_cutoff: "2024-05-30" +tokenizer: + family: tiktoken + name: o200k_base +tuning: [multimodal, function] +providers: + - provider_id: openai + model_id_on_provider: gpt-5-nano + - provider_id: openrouter + model_id_on_provider: openai/gpt-5-nano diff --git a/models/gpt-5.3-codex.yaml b/models/gpt-5.3-codex.yaml new file mode 100644 index 0000000..53b1f21 --- /dev/null +++ b/models/gpt-5.3-codex.yaml @@ -0,0 +1,21 @@ +model_id: gpt-5.3-codex +model_name: GPT-5.3 Codex +model_provider: openai +model_description: Codex-optimized GPT-5.3 model for coding agents and long-running software engineering tasks. +model_info: https://platform.openai.com/docs/models/gpt-5.3-codex +model_type: chat +context_window: 400000 +max_tokens: 128000 +cost_per_token: + input: 0.00000175 + output: 0.000014 +knowledge_cutoff: "2025-08-31" +tokenizer: + family: tiktoken + name: o200k_base +tuning: [multimodal, function] +providers: + - provider_id: openai + model_id_on_provider: gpt-5.3-codex + - provider_id: openrouter + model_id_on_provider: openai/gpt-5.3-codex diff --git a/models/gpt-5.4-image-2.yaml b/models/gpt-5.4-image-2.yaml new file mode 100644 index 0000000..e3dd0ce --- /dev/null +++ b/models/gpt-5.4-image-2.yaml @@ -0,0 +1,16 @@ +model_id: gpt-5.4-image-2 +model_name: GPT-5.4 Image 2 +model_provider: openai +model_description: GPT-5.4 optimized for image understanding and generation. Multimodal model supporting vision tasks. +model_info: https://platform.openai.com/docs/models/gpt-5.4-image-2 +model_type: chat +context_window: 272000 +cost_per_token: + input: 0.000008 + output: 0.000015 +tuning: [multimodal] +providers: + - provider_id: openai + model_id_on_provider: gpt-5.4-image-2 + - provider_id: openrouter + model_id_on_provider: openai/gpt-5.4-image-2 \ No newline at end of file diff --git a/models/gpt-5.4-mini.yaml b/models/gpt-5.4-mini.yaml new file mode 100644 index 0000000..bc1a977 --- /dev/null +++ b/models/gpt-5.4-mini.yaml @@ -0,0 +1,21 @@ +model_id: gpt-5.4-mini +model_name: GPT-5.4 mini +model_provider: openai +model_description: Fast, cost-efficient GPT-5.4 variant for coding, computer use, and subagent workloads. +model_info: https://platform.openai.com/docs/models/gpt-5.4-mini +model_type: chat +context_window: 400000 +max_tokens: 128000 +cost_per_token: + input: 7.5e-7 + output: 0.0000045 +knowledge_cutoff: "2025-08-31" +tokenizer: + family: tiktoken + name: o200k_base +tuning: [multimodal, function] +providers: + - provider_id: openai + model_id_on_provider: gpt-5.4-mini + - provider_id: openrouter + model_id_on_provider: openai/gpt-5.4-mini diff --git a/models/gpt-5.4-nano.yaml b/models/gpt-5.4-nano.yaml new file mode 100644 index 0000000..9a4669c --- /dev/null +++ b/models/gpt-5.4-nano.yaml @@ -0,0 +1,21 @@ +model_id: gpt-5.4-nano +model_name: GPT-5.4 nano +model_provider: openai +model_description: Lowest-latency GPT-5.4 variant for inexpensive high-volume tasks. +model_info: https://platform.openai.com/docs/models/gpt-5.4-nano +model_type: chat +context_window: 400000 +max_tokens: 128000 +cost_per_token: + input: 2e-7 + output: 0.00000125 +knowledge_cutoff: "2025-08-31" +tokenizer: + family: tiktoken + name: o200k_base +tuning: [multimodal, function] +providers: + - provider_id: openai + model_id_on_provider: gpt-5.4-nano + - provider_id: openrouter + model_id_on_provider: openai/gpt-5.4-nano diff --git a/models/gpt-5.4-pro.yaml b/models/gpt-5.4-pro.yaml new file mode 100644 index 0000000..a454986 --- /dev/null +++ b/models/gpt-5.4-pro.yaml @@ -0,0 +1,21 @@ +model_id: gpt-5.4-pro +model_name: GPT-5.4 Pro +model_provider: openai +model_description: High-capability GPT-5.4 Pro model for the hardest reasoning and professional workloads. +model_info: https://platform.openai.com/docs/models/gpt-5.4-pro +model_type: chat +context_window: 1050000 +max_tokens: 128000 +cost_per_token: + input: 0.00003 + output: 0.00018 +knowledge_cutoff: "2025-08-31" +tokenizer: + family: tiktoken + name: o200k_base +tuning: [multimodal, function] +providers: + - provider_id: openai + model_id_on_provider: gpt-5.4-pro + - provider_id: openrouter + model_id_on_provider: openai/gpt-5.4-pro diff --git a/models/gpt-5.4.yaml b/models/gpt-5.4.yaml new file mode 100644 index 0000000..eb99079 --- /dev/null +++ b/models/gpt-5.4.yaml @@ -0,0 +1,21 @@ +model_id: gpt-5.4 +model_name: GPT-5.4 +model_provider: openai +model_description: Current OpenAI model for coding and professional work with a 1M token context window. +model_info: https://platform.openai.com/docs/models/gpt-5.4 +model_type: chat +context_window: 1050000 +max_tokens: 128000 +cost_per_token: + input: 0.0000025 + output: 0.000015 +knowledge_cutoff: "2025-08-31" +tokenizer: + family: tiktoken + name: o200k_base +tuning: [multimodal, function] +providers: + - provider_id: openai + model_id_on_provider: gpt-5.4 + - provider_id: openrouter + model_id_on_provider: openai/gpt-5.4 diff --git a/models/gpt-5.5-pro.yaml b/models/gpt-5.5-pro.yaml new file mode 100644 index 0000000..8862879 --- /dev/null +++ b/models/gpt-5.5-pro.yaml @@ -0,0 +1,17 @@ +model_id: gpt-5.5-pro +model_name: GPT-5.5 Pro +model_provider: openai +model_description: Most capable OpenAI model with largest context window. Optimized for complex reasoning, advanced coding, and scientific analysis. +model_info: https://platform.openai.com/docs/models/gpt-5.5-pro +model_type: chat +context_window: 1050000 +max_tokens: 1049999 +cost_per_token: + input: 0.000030 + output: 0.000180 +tuning: [function] +providers: + - provider_id: openai + model_id_on_provider: gpt-5.5-pro + - provider_id: openrouter + model_id_on_provider: openai/gpt-5.5-pro \ No newline at end of file diff --git a/models/gpt-5.5.yaml b/models/gpt-5.5.yaml new file mode 100644 index 0000000..bbb2cda --- /dev/null +++ b/models/gpt-5.5.yaml @@ -0,0 +1,17 @@ +model_id: gpt-5.5 +model_name: GPT-5.5 +model_provider: openai +model_description: Capable OpenAI model with large context window. Strong for complex tasks at lower cost than Pro. +model_info: https://platform.openai.com/docs/models/gpt-5.5 +model_type: chat +context_window: 1050000 +max_tokens: 1049999 +cost_per_token: + input: 0.000005 + output: 0.000030 +tuning: [function] +providers: + - provider_id: openai + model_id_on_provider: gpt-5.5 + - provider_id: openrouter + model_id_on_provider: openai/gpt-5.5 \ No newline at end of file diff --git a/models/gpt-5.yaml b/models/gpt-5.yaml new file mode 100644 index 0000000..509de0b --- /dev/null +++ b/models/gpt-5.yaml @@ -0,0 +1,21 @@ +model_id: gpt-5 +model_name: GPT-5 +model_provider: openai +model_description: General GPT-5 model for reasoning, coding, and multimodal text/image workflows. +model_info: https://platform.openai.com/docs/models/gpt-5 +model_type: chat +context_window: 400000 +max_tokens: 128000 +cost_per_token: + input: 0.00000125 + output: 0.00001 +knowledge_cutoff: "2024-09-30" +tokenizer: + family: tiktoken + name: o200k_base +tuning: [multimodal, function] +providers: + - provider_id: openai + model_id_on_provider: gpt-5 + - provider_id: openrouter + model_id_on_provider: openai/gpt-5 diff --git a/models/grok-4.2-multi-agent.yaml b/models/grok-4.2-multi-agent.yaml new file mode 100644 index 0000000..55a467c --- /dev/null +++ b/models/grok-4.2-multi-agent.yaml @@ -0,0 +1,15 @@ +model_id: grok-4.2-multi-agent +model_name: Grok 4.2 Multi-Agent +model_provider: x-ai +model_description: Grok 4.2 optimized for multi-agent workflows. Enhanced tool use and coordination for parallel task execution. +model_info: https://x.ai/api +model_type: chat +context_window: 2000000 +cost_per_token: + input: 0.000002 + output: 0.000006 +providers: + - provider_id: x-ai + model_id_on_provider: grok-4.2 + - provider_id: openrouter + model_id_on_provider: x-ai/grok-4.2-multi-agent \ No newline at end of file diff --git a/models/grok-4.2.yaml b/models/grok-4.2.yaml new file mode 100644 index 0000000..916b5fd --- /dev/null +++ b/models/grok-4.2.yaml @@ -0,0 +1,16 @@ +model_id: grok-4.2 +model_name: Grok 4.2 +model_provider: x-ai +model_description: xAI's flagship model. Strong reasoning with real-time web access. Known for personality and directness. +model_info: https://x.ai/api +model_type: chat +context_window: 2000000 +cost_per_token: + input: 0.000002 + output: 0.000006 +tuning: [function] +providers: + - provider_id: x-ai + model_id_on_provider: grok-4.2 + - provider_id: openrouter + model_id_on_provider: x-ai/grok-4.2 \ No newline at end of file diff --git a/models/kimi-k2.6.yaml b/models/kimi-k2.6.yaml new file mode 100644 index 0000000..f51849f --- /dev/null +++ b/models/kimi-k2.6.yaml @@ -0,0 +1,18 @@ +model_id: kimi-k2.6 +model_name: Kimi K2.6 +model_provider: moonshotai +model_description: Moonshot AI's flagship model. Strong long-context understanding and reasoning at competitive pricing. +model_info: https://platform.moonshot.ai/docs +model_type: chat +context_window: 256000 +cost_per_token: + input: 0.00000074 + output: 0.00000466 +tuning: [function] +providers: + - provider_id: moonshotai + model_id_on_provider: kimi-k2.6 + - provider_id: cloudflare + model_id_on_provider: "@cf/moonshotai/kimi-k2.6" + - provider_id: openrouter + model_id_on_provider: moonshotai/kimi-k2.6 diff --git a/models/kimi-v3.yaml b/models/kimi-v3.yaml new file mode 100644 index 0000000..1ea10a9 --- /dev/null +++ b/models/kimi-v3.yaml @@ -0,0 +1,15 @@ +model_id: kimi-v3 +model_name: Kimi V3 +model_provider: moonshotai +model_description: Mid-range Moonshot model. Good balance of capability and cost for standard tasks. +model_info: https://platform.moonshot.ai/docs +model_type: chat +context_window: 256000 +cost_per_token: + input: 0.00000020 + output: 0.000001 +providers: + - provider_id: moonshotai + model_id_on_provider: kimi-v3 + - provider_id: openrouter + model_id_on_provider: moonshotai/kimi-v3 \ No newline at end of file diff --git a/models/llama-3.1-8b-instant.yaml b/models/llama-3.1-8b-instant.yaml new file mode 100644 index 0000000..79e41c3 --- /dev/null +++ b/models/llama-3.1-8b-instant.yaml @@ -0,0 +1,16 @@ +model_id: llama-3.1-8b-instant +model_name: Llama 3.1 8B Instant +model_provider: groq +model_description: Groq-hosted Llama 3.1 8B model for very low-latency, low-cost chat and automation. +model_info: https://console.groq.com/docs/models +model_type: chat +context_window: 131072 +max_tokens: 131072 +cost_per_token: + input: 5e-8 + output: 8e-8 +knowledge_cutoff: "2023-12-01" +tuning: [function, instruction] +providers: + - provider_id: groq + model_id_on_provider: llama-3.1-8b-instant diff --git a/models/llama-3.3-70b-versatile.yaml b/models/llama-3.3-70b-versatile.yaml new file mode 100644 index 0000000..4ddbea7 --- /dev/null +++ b/models/llama-3.3-70b-versatile.yaml @@ -0,0 +1,16 @@ +model_id: llama-3.3-70b-versatile +model_name: Llama 3.3 70B Versatile +model_provider: groq +model_description: Groq-hosted Llama 3.3 70B model optimized for fast general-purpose chat and tool workloads. +model_info: https://console.groq.com/docs/models +model_type: chat +context_window: 131072 +max_tokens: 32768 +cost_per_token: + input: 5.9e-7 + output: 7.9e-7 +knowledge_cutoff: "2023-12-01" +tuning: [function, instruction] +providers: + - provider_id: groq + model_id_on_provider: llama-3.3-70b-versatile diff --git a/models/minimax-m2.1-highspeed.yaml b/models/minimax-m2.1-highspeed.yaml new file mode 100644 index 0000000..3cde692 --- /dev/null +++ b/models/minimax-m2.1-highspeed.yaml @@ -0,0 +1,15 @@ +model_id: minimax-m2.1-highspeed +model_name: MiniMax M2.1-highspeed +model_provider: minimax +model_description: High-speed MiniMax M2.1 variant for faster multilingual programming and agent workflows. +model_info: "https://platform.minimax.io/docs/guides/text-generation" +model_type: chat +context_window: 204800 +max_tokens: 131072 +cost_per_token: + input: 6e-7 + output: 0.0000024 +tuning: [function, instruction, code, multilingual] +providers: + - provider_id: minimax + model_id_on_provider: MiniMax-M2.1-highspeed diff --git a/models/minimax-m2.1.yaml b/models/minimax-m2.1.yaml new file mode 100644 index 0000000..7c26b32 --- /dev/null +++ b/models/minimax-m2.1.yaml @@ -0,0 +1,17 @@ +model_id: minimax-m2.1 +model_name: MiniMax M2.1 +model_provider: minimax +model_description: MiniMax M2.1 model with strong multilingual programming and enhanced coding experience. +model_info: "https://platform.minimax.io/docs/guides/text-generation" +model_type: chat +context_window: 204800 +max_tokens: 131072 +cost_per_token: + input: 3e-7 + output: 0.0000012 +tuning: [function, instruction, code, multilingual] +providers: + - provider_id: minimax + model_id_on_provider: MiniMax-M2.1 + - provider_id: openrouter + model_id_on_provider: minimax/minimax-m2.1 diff --git a/models/minimax-m2.5-highspeed.yaml b/models/minimax-m2.5-highspeed.yaml new file mode 100644 index 0000000..4d39a34 --- /dev/null +++ b/models/minimax-m2.5-highspeed.yaml @@ -0,0 +1,15 @@ +model_id: minimax-m2.5-highspeed +model_name: MiniMax M2.5-highspeed +model_provider: minimax +model_description: High-speed MiniMax M2.5 variant for lower-latency coding and agent workloads. +model_info: "https://platform.minimax.io/docs/guides/text-generation" +model_type: chat +context_window: 204800 +max_tokens: 131072 +cost_per_token: + input: 6e-7 + output: 0.0000024 +tuning: [function, instruction, code, multilingual] +providers: + - provider_id: minimax + model_id_on_provider: MiniMax-M2.5-highspeed diff --git a/models/minimax-m2.5.yaml b/models/minimax-m2.5.yaml new file mode 100644 index 0000000..9dfc15a --- /dev/null +++ b/models/minimax-m2.5.yaml @@ -0,0 +1,17 @@ +model_id: minimax-m2.5 +model_name: MiniMax M2.5 +model_provider: minimax +model_description: MiniMax M2.5 model for complex programming, agent, and productivity tasks. +model_info: "https://platform.minimax.io/docs/guides/text-generation" +model_type: chat +context_window: 204800 +max_tokens: 131072 +cost_per_token: + input: 3e-7 + output: 0.0000012 +tuning: [function, instruction, code, multilingual] +providers: + - provider_id: minimax + model_id_on_provider: MiniMax-M2.5 + - provider_id: openrouter + model_id_on_provider: minimax/minimax-m2.5 diff --git a/models/minimax-m2.7-highspeed.yaml b/models/minimax-m2.7-highspeed.yaml new file mode 100644 index 0000000..904492c --- /dev/null +++ b/models/minimax-m2.7-highspeed.yaml @@ -0,0 +1,15 @@ +model_id: minimax-m2.7-highspeed +model_name: MiniMax M2.7-highspeed +model_provider: minimax +model_description: High-speed MiniMax M2.7 variant with the same capability profile and faster output for latency-sensitive workloads. +model_info: "https://platform.minimax.io/docs/guides/text-generation" +model_type: chat +context_window: 204800 +max_tokens: 131072 +cost_per_token: + input: 6e-7 + output: 0.0000024 +tuning: [function, instruction, code, multilingual] +providers: + - provider_id: minimax + model_id_on_provider: MiniMax-M2.7-highspeed diff --git a/models/minimax-m2.7.yaml b/models/minimax-m2.7.yaml new file mode 100644 index 0000000..7e96c87 --- /dev/null +++ b/models/minimax-m2.7.yaml @@ -0,0 +1,17 @@ +model_id: minimax-m2.7 +model_name: MiniMax M2.7 +model_provider: minimax +model_description: Beginning the journey of recursive self-improvement. Strong for programming, tool calling, search, office productivity, and complex agent workflows. +model_info: "https://platform.minimax.io/docs/guides/text-generation" +model_type: chat +context_window: 204800 +max_tokens: 131072 +cost_per_token: + input: 3e-7 + output: 0.0000012 +tuning: [function, instruction, code, multilingual] +providers: + - provider_id: minimax + model_id_on_provider: MiniMax-M2.7 + - provider_id: openrouter + model_id_on_provider: minimax/minimax-m2.7 diff --git a/models/minimax-m2.yaml b/models/minimax-m2.yaml new file mode 100644 index 0000000..4232b0f --- /dev/null +++ b/models/minimax-m2.yaml @@ -0,0 +1,17 @@ +model_id: minimax-m2 +model_name: MiniMax M2 +model_provider: minimax +model_description: MiniMax M2 model for agentic workflows, advanced reasoning, function calling, and real-time streaming. +model_info: "https://platform.minimax.io/docs/guides/text-generation" +model_type: chat +context_window: 204800 +max_tokens: 128000 +cost_per_token: + input: 3e-7 + output: 0.0000012 +tuning: [function, instruction, code, multilingual] +providers: + - provider_id: minimax + model_id_on_provider: MiniMax-M2 + - provider_id: openrouter + model_id_on_provider: minimax/minimax-m2 diff --git a/models/mistral-7b-instruct.yaml b/models/mistral-7b-instruct.yaml index 5bc91e0..5cd4a92 100644 --- a/models/mistral-7b-instruct.yaml +++ b/models/mistral-7b-instruct.yaml @@ -1,8 +1,15 @@ model_id: mistral-7b-instruct model_name: Mistral 7B Instruct +model_provider: mistralai model_description: Mistral-7B fine-tuned on instruction datasets publicly available on HuggingFace. model_info: https://huggingface.co/mistralai/Mistral-7B-Instruct-v0.1 model_type: chat context_window: 8192 tuning: - instruction +deprecated: true +providers: + - provider_id: mistralai + model_id_on_provider: mistral-7b-instruct-0.3 + - provider_id: openrouter + model_id_on_provider: mistralai/mistral-7b-instruct diff --git a/models/mistral-7b.yaml b/models/mistral-7b.yaml index 1a2e8c1..813f128 100644 --- a/models/mistral-7b.yaml +++ b/models/mistral-7b.yaml @@ -1,7 +1,14 @@ model_id: mistral-7b model_name: Mistral 7B +model_provider: mistralai model_description: Mistral-7B-v0.1 is a small yet powerful model adaptable to many use-cases. model_info: https://mistral.ai/news/announcing-mistral-7b/ model_type: chat context_window: 8192 cost_per_token: 0 +deprecated: true +providers: + - provider_id: mistralai + model_id_on_provider: open-mistral-7b + - provider_id: openrouter + model_id_on_provider: mistralai/mistral-7b diff --git a/models/mistral-large-2411.yaml b/models/mistral-large-2411.yaml new file mode 100644 index 0000000..fb72d65 --- /dev/null +++ b/models/mistral-large-2411.yaml @@ -0,0 +1,20 @@ +model_id: mistral-large-2411 +model_name: Mistral Large 2.1 +model_provider: mistralai +model_description: Versioned Mistral Large 2.1 model retained for integrations pinned to the 24.11 release. +model_info: https://docs.mistral.ai/getting-started/models/models_overview/ +model_type: chat +context_window: 131072 +max_tokens: 16384 +cost_per_token: + input: 0.000002 + output: 0.000006 +knowledge_cutoff: "2024-11-01" +tokenizer: + family: tekken +tuning: [function, instruction] +providers: + - provider_id: mistralai + model_id_on_provider: mistral-large-2411 + - provider_id: openrouter + model_id_on_provider: mistralai/mistral-large-2411 diff --git a/models/mistral-large-2512.yaml b/models/mistral-large-2512.yaml new file mode 100644 index 0000000..5f59ff4 --- /dev/null +++ b/models/mistral-large-2512.yaml @@ -0,0 +1,20 @@ +model_id: mistral-large-2512 +model_name: Mistral Large 3 +model_provider: mistralai +model_description: Mistral Large 3 versioned model with long context and strong multimodal/coding capabilities. +model_info: https://docs.mistral.ai/getting-started/models/models_overview/ +model_type: chat +context_window: 262144 +max_tokens: 262144 +cost_per_token: + input: 5e-7 + output: 0.0000015 +knowledge_cutoff: "2024-11-01" +tokenizer: + family: tekken +tuning: [multimodal, function, instruction] +providers: + - provider_id: mistralai + model_id_on_provider: mistral-large-2512 + - provider_id: openrouter + model_id_on_provider: mistralai/mistral-large-2512 diff --git a/models/mistral-large-latest.yaml b/models/mistral-large-latest.yaml new file mode 100644 index 0000000..16f8bb2 --- /dev/null +++ b/models/mistral-large-latest.yaml @@ -0,0 +1,20 @@ +model_id: mistral-large-latest +model_name: Mistral Large (latest) +model_provider: mistralai +model_description: Mistral's current flagship alias for high-quality reasoning, coding, and multimodal workloads. +model_info: https://docs.mistral.ai/getting-started/models/models_overview/ +model_type: chat +context_window: 262144 +max_tokens: 262144 +cost_per_token: + input: 5e-7 + output: 0.0000015 +knowledge_cutoff: "2024-11-01" +tokenizer: + family: tekken +tuning: [multimodal, function, instruction] +providers: + - provider_id: mistralai + model_id_on_provider: mistral-large-latest + - provider_id: openrouter + model_id_on_provider: mistralai/mistral-large-latest diff --git a/models/mistral-medium-latest.yaml b/models/mistral-medium-latest.yaml new file mode 100644 index 0000000..b06d35a --- /dev/null +++ b/models/mistral-medium-latest.yaml @@ -0,0 +1,20 @@ +model_id: mistral-medium-latest +model_name: Mistral Medium (latest) +model_provider: mistralai +model_description: Mistral's balanced mid-tier model for reasoning, coding, and multimodal workflows. +model_info: https://docs.mistral.ai/getting-started/models/models_overview/ +model_type: chat +context_window: 128000 +max_tokens: 16384 +cost_per_token: + input: 4e-7 + output: 0.000002 +knowledge_cutoff: "2025-05-01" +tokenizer: + family: tekken +tuning: [multimodal, function, instruction] +providers: + - provider_id: mistralai + model_id_on_provider: mistral-medium-latest + - provider_id: openrouter + model_id_on_provider: mistralai/mistral-medium-latest diff --git a/models/mistral-nemo.yaml b/models/mistral-nemo.yaml new file mode 100644 index 0000000..7372b19 --- /dev/null +++ b/models/mistral-nemo.yaml @@ -0,0 +1,20 @@ +model_id: mistral-nemo +model_name: Mistral Nemo +model_provider: mistralai +model_description: Open-weight Mistral Nemo model, useful for local or low-cost multilingual deployments. +model_info: https://docs.mistral.ai/getting-started/models/models_overview/ +model_type: chat +context_window: 128000 +max_tokens: 128000 +cost_per_token: + input: 1.5e-7 + output: 1.5e-7 +knowledge_cutoff: "2024-07-01" +tokenizer: + family: tekken +tuning: [function, instruction] +providers: + - provider_id: mistralai + model_id_on_provider: mistral-nemo + - provider_id: openrouter + model_id_on_provider: mistralai/mistral-nemo diff --git a/models/mistral-small-latest.yaml b/models/mistral-small-latest.yaml new file mode 100644 index 0000000..8ba7ebe --- /dev/null +++ b/models/mistral-small-latest.yaml @@ -0,0 +1,20 @@ +model_id: mistral-small-latest +model_name: Mistral Small (latest) +model_provider: mistralai +model_description: Mistral's efficient small model alias for low-cost general-purpose and agentic workloads. +model_info: https://docs.mistral.ai/getting-started/models/models_overview/ +model_type: chat +context_window: 256000 +max_tokens: 256000 +cost_per_token: + input: 1.5e-7 + output: 6e-7 +knowledge_cutoff: "2025-06-01" +tokenizer: + family: tekken +tuning: [multimodal, function, instruction] +providers: + - provider_id: mistralai + model_id_on_provider: mistral-small-latest + - provider_id: openrouter + model_id_on_provider: mistralai/mistral-small-latest diff --git a/models/nemotron-3-super-120b-a12b.yaml b/models/nemotron-3-super-120b-a12b.yaml new file mode 100644 index 0000000..01f1786 --- /dev/null +++ b/models/nemotron-3-super-120b-a12b.yaml @@ -0,0 +1,20 @@ +model_id: nemotron-3-super-120b-a12b +model_name: Nemotron 3 Super +model_provider: nvidia +model_description: NVIDIA Nemotron 3 Super, an open-weight hybrid MoE model for agentic reasoning, tool use, and long-context workloads. +model_info: https://docs.api.nvidia.com/nim/reference/nvidia-nemotron-3-super-120b-a12b +model_type: chat +context_window: 262144 +max_tokens: 262144 +cost_per_token: + input: 2e-7 + output: 8e-7 +knowledge_cutoff: "2024-04-01" +tuning: [function, instruction] +providers: + - provider_id: nvidia + model_id_on_provider: nvidia/nemotron-3-super-120b-a12b + - provider_id: openrouter + model_id_on_provider: nvidia/nemotron-3-super-120b-a12b + - provider_id: cloudflare + model_id_on_provider: "@cf/nvidia/nemotron-3-120b-a12b" diff --git a/models/o3.yaml b/models/o3.yaml new file mode 100644 index 0000000..4cad1a4 --- /dev/null +++ b/models/o3.yaml @@ -0,0 +1,18 @@ +model_id: o3 +model_name: o3 +model_provider: openai +model_description: OpenAI reasoning model. Extended thinking model optimized for complex reasoning, science, and coding. Charges for reasoning tokens. +model_info: https://platform.openai.com/docs/models/o3 +model_type: chat +context_window: 200000 +cost_per_token: + input: 0.000004 + output: 0.000016 +tokenizer: + family: tiktoken + name: o200k_base +providers: + - provider_id: openai + model_id_on_provider: o3 + - provider_id: openrouter + model_id_on_provider: openai/o3 \ No newline at end of file diff --git a/models/o4-mini.yaml b/models/o4-mini.yaml new file mode 100644 index 0000000..3e18fa8 --- /dev/null +++ b/models/o4-mini.yaml @@ -0,0 +1,18 @@ +model_id: o4-mini +model_name: o4 Mini +model_provider: openai +model_description: Lightweight OpenAI reasoning model. Fast and cost-efficient reasoning for simpler tasks. +model_info: https://platform.openai.com/docs/models/o4-mini +model_type: chat +context_window: 100000 +cost_per_token: + input: 0.000001 + output: 0.000004 +tokenizer: + family: tiktoken + name: o200k_base +providers: + - provider_id: openai + model_id_on_provider: o4-mini + - provider_id: openrouter + model_id_on_provider: openai/o4-mini \ No newline at end of file diff --git a/models/qwen3-32b.yaml b/models/qwen3-32b.yaml new file mode 100644 index 0000000..0b37de8 --- /dev/null +++ b/models/qwen3-32b.yaml @@ -0,0 +1,20 @@ +model_id: qwen3-32b +model_name: Qwen3 32B +model_provider: qwen +model_description: Groq-hosted Qwen3 32B open-weight model for reasoning, code, and multilingual work. +model_info: https://console.groq.com/docs/models +model_type: chat +context_window: 131072 +max_tokens: 40960 +cost_per_token: + input: 2.9e-7 + output: 5.9e-7 +knowledge_cutoff: "2024-11-08" +tuning: [function, instruction] +providers: + - provider_id: groq + model_id_on_provider: qwen/qwen3-32b + - provider_id: qwen + model_id_on_provider: qwen3-32b + - provider_id: openrouter + model_id_on_provider: qwen/qwen3-32b diff --git a/models/qwen3.6-flash.yaml b/models/qwen3.6-flash.yaml new file mode 100644 index 0000000..0981139 --- /dev/null +++ b/models/qwen3.6-flash.yaml @@ -0,0 +1,15 @@ +model_id: qwen3.6-flash +model_name: Qwen 3.6 Flash +model_provider: qwen +model_description: Fast, efficient Qwen variant. Optimized for high-volume applications. +model_info: https://qwen.io/docs +model_type: chat +context_window: 1000000 +cost_per_token: + input: 0.00000010 + output: 0.00000040 +providers: + - provider_id: qwen + model_id_on_provider: qwen3.6-flash + - provider_id: openrouter + model_id_on_provider: qwen/qwen3.6-flash \ No newline at end of file diff --git a/models/qwen3.6-plus.yaml b/models/qwen3.6-plus.yaml new file mode 100644 index 0000000..e2111bb --- /dev/null +++ b/models/qwen3.6-plus.yaml @@ -0,0 +1,16 @@ +model_id: qwen3.6-plus +model_name: Qwen 3.6 Plus +model_provider: qwen +model_description: Alibaba's flagship model. Strong multilingual and reasoning capabilities with large context support. +model_info: https://qwen.io/docs +model_type: chat +context_window: 1000000 +cost_per_token: + input: 0.00000033 + output: 0.00000195 +tuning: [function] +providers: + - provider_id: qwen + model_id_on_provider: qwen3.6-plus + - provider_id: openrouter + model_id_on_provider: qwen/qwen3.6-plus \ No newline at end of file diff --git a/package.json b/package.json new file mode 100644 index 0000000..2ad36ca --- /dev/null +++ b/package.json @@ -0,0 +1,7 @@ +{ + "name": "model-metadata-central", + "private": true, + "scripts": { + "generate": "node scripts/codegen.mjs" + } +} \ No newline at end of file diff --git a/packages/README.md b/packages/README.md index 0738141..dbe6463 100644 --- a/packages/README.md +++ b/packages/README.md @@ -1,23 +1,45 @@ -## Model Metadata Definition Packages +# Language Packages -This directory contains the underlying source code for the distributed packages that developers can import into their projects to reference the model metadata contained in this repo. +Pre-compiled registries and typed APIs for consuming model metadata in your project. -### Packages +## TypeScript -The packages are separated into different directories for each supported language. +```sh +npm install @interwebalchemy/model-metadata +``` + +[Read the README →](./typescript/README.md) + +## Python + +```sh +pip install model-metadata-central +``` + +[Read the README →](./python/README.md) -#### Python +## Build -The Python package is available on the Python Package Index as [`model-metadata`](https://pypi.org/project/model-metadata/). +Both packages compile YAML sources to JSON registries during `prepare`/`prepublish`: -```shell -pip install model-metadata +```sh +cd packages/typescript && npm install && npm run build +cd packages/python && uv run python -c "from model_metadata_central.utils.load_metadata import load_metadata; print(load_metadata('gpt-4o'))" ``` -**Note**: This hasn't been published yet. +## Aligning APIs -Documentation for specific usage for this package is available in the [Python package's README](./python/README.md). +The TypeScript and Python packages aim to share the same API surface: -#### TypeScript +| TypeScript | Python | +|---|---| +| `getModel(id)` | `get_model(id)` | +| `getAllModels()` | `get_all_models()` | +| `getModelsByProvider(id)` | `get_models_by_provider(id)` | +| `getModelOnProvider(id, providerModelId)` | `get_model_on_provider(id, provider_model_id)` | +| `getProvider(id)` | `get_provider(id)` | +| `getAllProviders()` | `get_all_providers()` | +| `getProviderModelId(modelId, providerId)` | `get_provider_model_id(model_id, provider_id)` | +| Named exports (`gpt4o`, etc.) | Module constants (`GPT_4_O`, etc.) | -_Coming Soon_ \ No newline at end of file +Both packages use the same underlying JSON schema types, pre-compiled from the YAML definitions in the repo root. diff --git a/packages/python/README.md b/packages/python/README.md index 028c752..6b9c3f8 100644 --- a/packages/python/README.md +++ b/packages/python/README.md @@ -1,36 +1,85 @@ -# Model Metadata +# model-metadata-central -A centralized, language-agnostic, open-source approach to storing and sharing model definitions like context windows, cost per token, etc. +Typed registry of LLM model metadata for Python — context windows, pricing, provider routing. -**Note**: You can read more about the motivation behind this initiative in [the Model Metadata Central project's README](https://github.com/InterwebAlchemy/model-metadata-central). +```sh +pip install model-metadata-central +``` + +## Usage + +### Full registry + +```python +from model_metadata_central import get_all_models, get_all_providers + +models = get_all_models() +for model in models: + print(f"{model['model_name']}: {model['context_window']} context") +``` + +### Look up a single model + +```python +from model_metadata_central import get_model -## Example Usage +model = get_model("gpt-4o") +if model: + print(model["context_window"]) # 128000 + print(model["cost_per_token"]) # {"input": 0.000005, "output": 0.000015} +``` -### Get metadata for a specific model +### Filter by provider ```python -from model_metadata.lib import get_model_metadata +from model_metadata_central import get_models_by_provider -turbo_model = get_model_metadata("gpt-3.5-turbo") +anthropic = get_models_by_provider("anthropic") +openrouter = get_models_by_provider("openrouter") ``` -### Working with metadata for all models +### Provider routing ```python -from model_metadata.lib import get_metadata +from model_metadata_central import get_provider_model_id, get_provider -max_tokens = {} +# Get the model ID for a specific provider +openai_id = get_provider_model_id("gpt-4o", "openai") # "gpt-4o" +orouter_id = get_provider_model_id("gpt-4o", "openrouter") # "openai/gpt-4o" -# Get the max_tokens for each model that has one defined -for model, model_metadata in get_metadata.items(): - if "max_tokens" in model_metadata: - max_tokens[model] = model_metadata["max_tokens"] +# Get provider config +provider = get_provider("openai") +print(provider["base_url"]) # "https://api.openai.com/v1" +print(provider["auth_type"]) # "api_key" ``` -### Get a list of available models +### Named model constants ```python -from model_metadata.lib import get_models +from model_metadata_central import GPT_4_O, CLAUDE_OPUS_4_7 + +# Fully typed dict — bundlers exclude the rest +print(GPT_4_O["context_window"]) +``` + +## API + +| Function | Returns | Description | +|---|---|---| +| `get_model(id)` | `dict \| None` | Lookup by model_id | +| `get_all_models()` | `list[dict]` | All models | +| `get_models_by_provider(provider_id)` | `list[dict]` | Filter by provider | +| `get_model_on_provider(provider_id, provider_model_id=None)` | `dict \| None` | Find model on a specific provider | +| `get_provider(id)` | `dict \| None` | Provider config | +| `get_all_providers()` | `list[dict]` | All providers | +| `get_provider_model_id(model_id, provider_id)` | `str \| None` | Provider-specific model ID | + +## Data + +- Registry pre-compiled from `models/*.yaml` at install/build time +- 74 models across 17 providers +- Prices are in USD per token + +## Schema -models = get_models() -``` \ No newline at end of file +Matches the JSON Schema definitions in the repo root. diff --git a/packages/python/model_metadata/.DS_Store b/packages/python/model_metadata/.DS_Store deleted file mode 100644 index 5008ddf..0000000 Binary files a/packages/python/model_metadata/.DS_Store and /dev/null differ diff --git a/packages/python/model_metadata/data b/packages/python/model_metadata/data deleted file mode 120000 index 1660850..0000000 --- a/packages/python/model_metadata/data +++ /dev/null @@ -1 +0,0 @@ -/Users/ericallen/Development/model-metadata-central/models \ No newline at end of file diff --git a/packages/python/model_metadata/lib.py b/packages/python/model_metadata/lib.py deleted file mode 100644 index c6d19f7..0000000 --- a/packages/python/model_metadata/lib.py +++ /dev/null @@ -1,34 +0,0 @@ -from model_metadata.utils.get_metadata_models import get_metadata_models -from model_metadata.utils.load_metadata import load_metadata - - -def get_model_metadata(model_name: str) -> dict: - """ - Get metadata for a specific model from central metadata store. - """ - metadata = load_metadata(model_name) - - return metadata - - -def get_models() -> [str]: - """ - Get all models from central metadata store. - """ - models = get_metadata_models() - - return models - - -def get_metadata() -> dict: - """ - Get metadata for all models from central metadata store. - """ - models = get_models() - - metadata = dict() - - for model in models: - metadata[f"{model}"] = get_model_metadata(model) - - return metadata diff --git a/packages/python/model_metadata/schema.json b/packages/python/model_metadata/schema.json deleted file mode 120000 index 1584de5..0000000 --- a/packages/python/model_metadata/schema.json +++ /dev/null @@ -1 +0,0 @@ -/Users/ericallen/Development/model-metadata-central/model-metadata.schema.json \ No newline at end of file diff --git a/packages/python/model_metadata/tests/schema_test.py b/packages/python/model_metadata/tests/schema_test.py deleted file mode 100644 index 5dbc72f..0000000 --- a/packages/python/model_metadata/tests/schema_test.py +++ /dev/null @@ -1,28 +0,0 @@ -import json - -import pytest -from jsonschema import validate - -from model_metadata.lib import get_model_metadata - -schema = json.load(open("model_metadata/schema.json")) - - -def test_validate_schema(): - metadata = get_model_metadata("gpt-3.5-turbo") - - try: - validate(metadata, schema=schema) - except: - pytest.fail("Validation failed.") - - assert True - - -def test_invalid_schema(): - metadata = { - "model_id": "gpt-3.5-turbo", - } - - with pytest.raises(Exception): - validate(metadata, schema=schema) diff --git a/packages/python/model_metadata/tests/utils_test.py b/packages/python/model_metadata/tests/utils_test.py deleted file mode 100644 index 2dd7eba..0000000 --- a/packages/python/model_metadata/tests/utils_test.py +++ /dev/null @@ -1,34 +0,0 @@ -import os - -from model_metadata.utils.get_metadata_directory import get_metadata_directory -from model_metadata.utils.get_metadata_models import get_metadata_models -from model_metadata.utils.load_metadata import load_metadata - - -def test_get_metadata_directory(): - assert get_metadata_directory() == os.path.join( - os.getcwd(), "model_metadata", "data" - ) - - -def test_get_models(): - models = get_metadata_models() - - assert len(models) == len(os.listdir(get_metadata_directory())) - - -def test_load_metadata(): - metadata = load_metadata("gpt-3.5-turbo") - - assert ( - metadata["model_id"] == "gpt-3.5-turbo" - and metadata["model_provider"] == "openai" - and metadata["model_name"] == "GPT-3.5 Turbo" - and metadata["model_type"] == "chat" - ) - - -def test_undefined_metadata(): - metadata = load_metadata("unknown-model") - - assert metadata is None diff --git a/packages/python/model_metadata/utils/__init__.py b/packages/python/model_metadata/utils/__init__.py deleted file mode 100644 index e69de29..0000000 diff --git a/packages/python/model_metadata/utils/get_metadata_directory.py b/packages/python/model_metadata/utils/get_metadata_directory.py deleted file mode 100644 index c8d23b2..0000000 --- a/packages/python/model_metadata/utils/get_metadata_directory.py +++ /dev/null @@ -1,14 +0,0 @@ -import os - -import model_metadata - -METADATA_DIRECTORY = "data" - - -def get_metadata_directory() -> str: - """ - Get metadata directory. - """ - module_path = os.path.dirname(model_metadata.__file__) - - return os.path.join(module_path, METADATA_DIRECTORY) diff --git a/packages/python/model_metadata/utils/get_metadata_models.py b/packages/python/model_metadata/utils/get_metadata_models.py deleted file mode 100644 index ff5dd35..0000000 --- a/packages/python/model_metadata/utils/get_metadata_models.py +++ /dev/null @@ -1,19 +0,0 @@ -import os -from pathlib import Path - -from model_metadata.utils.get_metadata_directory import get_metadata_directory - - -def get_metadata_models() -> [str]: - """ - Get all models from central metadata store. - """ - metadata_directory = get_metadata_directory() - - model_names = [ - Path(model_name).stem - for model_name in os.listdir(metadata_directory) - if model_name.endswith(".yaml") - ] - - return model_names diff --git a/packages/python/model_metadata/utils/load_metadata.py b/packages/python/model_metadata/utils/load_metadata.py deleted file mode 100644 index c81ce05..0000000 --- a/packages/python/model_metadata/utils/load_metadata.py +++ /dev/null @@ -1,24 +0,0 @@ -import os - -import yaml - -from model_metadata.utils.get_metadata_directory import get_metadata_directory - - -def load_metadata(model_name: str) -> dict: - """ - Load model metadata from yaml file. - """ - path = get_metadata_directory() - - path = os.path.join(get_metadata_directory(), f"{model_name}.yaml") - - metadata = {} - - try: - with open(path, "r") as f: - metadata = yaml.safe_load(f) - - return metadata - except: - return None diff --git a/packages/python/model_metadata_central/__init__.py b/packages/python/model_metadata_central/__init__.py new file mode 100644 index 0000000..7358d5d --- /dev/null +++ b/packages/python/model_metadata_central/__init__.py @@ -0,0 +1,115 @@ +from model_metadata_central.lib import ( + get_all_models, + get_metadata, + get_model, + get_model_on_provider, + get_models, + get_models_by_provider, +) +from model_metadata_central.utils.exceptions import ModelMetadataNotFoundError + +__all__ = [ + "get_model", + "get_all_models", + "get_models", + "get_models_by_provider", + "get_model_on_provider", + "get_metadata", + "get_provider", + "get_all_providers", + "get_provider_model_id", + "ModelMetadataNotFoundError", + # Named model constants — kept in sync with models/*.yaml + "GPT_4_O", + "GPT_4_O_MINI", + "GPT_4_5", + "GPT_5_5", + "GPT_5_5_PRO", + "GPT_5_4_IMAGE_2", + "GPT_3_5_TURBO", + "GPT_3_5_TURBO_INSTRUCT", + "GPT_4", + "GPT_4_32K", + "O3", + "O4_MINI", + "CLAUDE_OPUS_4_7", + "CLAUDE_OPUS_4_6_FAST", + "CLAUDE_SONNET_4_2", + "CLAUDE_OPUS_LATEST", + "CLAUDE_HAIKU_4", + "GEMINI_2_5_PRO", + "GEMINI_2_5_FLASH", + "GEMINI_2_0_FLASH", + "GEMMA_4_31B_IT", + "GEMMA_4_26B_A4B_IT", + "DEEPSEEK_V4_PRO", + "DEEPSEEK_V4_FLASH", + "DEEPSEEK_CODER_V4", + "GROK_4_2", + "GROK_4_2_MULTI_AGENT", + "KIMI_K2_6", + "KIMI_V3", + "QWEN_3_6_PLUS", + "QWEN_3_6_FLASH", + "MISTRAL_7B", + "MISTRAL_7B_INSTRUCT", +] + +# Named model constants — import only what you need +GPT_4_O = get_model("gpt-4o") +GPT_4_O_MINI = get_model("gpt-4o-mini") +GPT_4_5 = get_model("gpt-4.5") +GPT_5_5 = get_model("gpt-5.5") +GPT_5_5_PRO = get_model("gpt-5.5-pro") +GPT_5_4_IMAGE_2 = get_model("gpt-5.4-image-2") +GPT_3_5_TURBO = get_model("gpt-3.5-turbo") +GPT_3_5_TURBO_INSTRUCT = get_model("gpt-3.5-turbo-instruct") +GPT_4 = get_model("gpt-4") +GPT_4_32K = get_model("gpt-4-32k") +O3 = get_model("o3") +O4_MINI = get_model("o4-mini") +CLAUDE_OPUS_4_7 = get_model("claude-opus-4-7") +CLAUDE_OPUS_4_6_FAST = get_model("claude-opus-4-6-fast") +CLAUDE_SONNET_4_2 = get_model("claude-sonnet-4-2") +CLAUDE_OPUS_LATEST = get_model("claude-opus-latest") +CLAUDE_HAIKU_4 = get_model("claude-haiku-4") +GEMINI_2_5_PRO = get_model("gemini-2.5-pro") +GEMINI_2_5_FLASH = get_model("gemini-2.5-flash") +GEMINI_2_0_FLASH = get_model("gemini-2.0-flash") +GEMMA_4_31B_IT = get_model("gemma-4-31b-it") +GEMMA_4_26B_A4B_IT = get_model("gemma-4-26b-a4b-it") +DEEPSEEK_V4_PRO = get_model("deepseek-v4-pro") +DEEPSEEK_V4_FLASH = get_model("deepseek-v4-flash") +DEEPSEEK_CODER_V4 = get_model("deepseek-coder-v4") +GROK_4_2 = get_model("grok-4.2") +GROK_4_2_MULTI_AGENT = get_model("grok-4.2-multi-agent") +KIMI_K2_6 = get_model("kimi-k2.6") +KIMI_V3 = get_model("kimi-v3") +QWEN_3_6_PLUS = get_model("qwen3.6-plus") +QWEN_3_6_FLASH = get_model("qwen3.6-flash") +MISTRAL_7B = get_model("mistral-7b") +MISTRAL_7B_INSTRUCT = get_model("mistral-7b-instruct") + + +# Provider helpers +def get_provider(provider_id: str) -> dict | None: + """Get provider configuration by provider_id, or None if not found.""" + from model_metadata_central.utils.load_provider import load_provider + return load_provider(provider_id) + + +def get_all_providers() -> list[dict]: + """Get all providers.""" + from model_metadata_central._registry import PROVIDERS + return list(PROVIDERS) + + +def get_provider_model_id(model_id: str, provider_id: str) -> str | None: + """Get the model_id as used by a specific provider.""" + model = get_model(model_id) + if model is None: + return None + for p in model.get("providers") or []: + if p.get("provider_id") == provider_id: + return p.get("model_id_on_provider") + return None diff --git a/packages/python/model_metadata_central/_registry.py b/packages/python/model_metadata_central/_registry.py new file mode 100644 index 0000000..90f7769 --- /dev/null +++ b/packages/python/model_metadata_central/_registry.py @@ -0,0 +1,22 @@ +"""Loader for the bundled JSON registries built by scripts/build_registry.py.""" +import json +from pathlib import Path + +_PKG_DIR = Path(__file__).resolve().parent + + +def _load(name: str) -> list[dict]: + path = _PKG_DIR / name + if not path.exists(): + raise RuntimeError( + f"Bundled {name} is missing. Run " + "`uv run python scripts/build_registry.py` to generate it." + ) + return json.loads(path.read_text()) + + +MODELS: list[dict] = _load("registry.json") +PROVIDERS: list[dict] = _load("providers.json") + +MODELS_BY_ID: dict[str, dict] = {m["model_id"]: m for m in MODELS} +PROVIDERS_BY_ID: dict[str, dict] = {p["provider_id"]: p for p in PROVIDERS} diff --git a/packages/python/model_metadata_central/generated/__init__.py b/packages/python/model_metadata_central/generated/__init__.py new file mode 100644 index 0000000..05b1e47 --- /dev/null +++ b/packages/python/model_metadata_central/generated/__init__.py @@ -0,0 +1,4 @@ +# Re-export for convenience +from .models import ModelMetadata, ProviderMetadata + +__all__ = ["ModelMetadata", "ProviderMetadata"] \ No newline at end of file diff --git a/packages/python/model_metadata_central/generated/models.py b/packages/python/model_metadata_central/generated/models.py new file mode 100644 index 0000000..402b4e8 --- /dev/null +++ b/packages/python/model_metadata_central/generated/models.py @@ -0,0 +1,44 @@ +# Generated from JSON Schema — do not edit manually + +from __future__ import annotations + +from typing import Any, Literal +from pydantic import BaseModel, Field + +class Provider_reference(BaseModel): + provider_id: str + model_id_on_provider: str | None = None + +class Tokenizer_config(BaseModel): + family: Literal['tiktoken', 'tekken', 'sentencepiece', 'huggingface', 'other', 'unknown'] + name: str | None = None + +class ModelMetadata(BaseModel): + """Generated from model-metadata.schema.json""" + model_id: str + model_name: str | None = None + model_provider: str | None = None + model_description: str | None = None + model_info: str | None = None + model_version: str | None = None + model_type: Literal['chat', 'completion', 'embedding'] + context_window: float + max_tokens: float | None = None + cost_per_token: Any | None = None + knowledge_cutoff: str | None = None + tokenizer: Tokenizer_config | None = None + tuning: list | None = None + deprecated: bool | None = None + providers: list | None = None + +class ProviderMetadata(BaseModel): + """Generated from provider.schema.json""" + provider_id: str + name: str + website_url: str | None = None + api_type: Literal['openai_compatible', 'anthropic', 'openai', 'other'] + base_url: str | None = None + auth_type: Literal['api_key', 'bearer', 'oauth', 'managed', 'none'] | None = None + routing_priority: Literal['direct', 'aggregator', 'both'] + status: Literal['active', 'deprecated', 'inactive'] | None = None + notes: str | None = None diff --git a/packages/python/model_metadata_central/lib.py b/packages/python/model_metadata_central/lib.py new file mode 100644 index 0000000..b1663e7 --- /dev/null +++ b/packages/python/model_metadata_central/lib.py @@ -0,0 +1,58 @@ +from model_metadata_central.utils.get_metadata_models import get_metadata_models +from model_metadata_central.utils.load_metadata import load_metadata + + +def get_model(model_id: str) -> dict | None: + """Get metadata for a specific model by model_id, or None if not found.""" + return load_metadata(model_id) + + +def get_all_models() -> list[dict]: + """ + Get all models from the registry. + """ + models = get_metadata_models() + return [load_metadata(m) for m in models] + + +def get_models_by_provider(provider_id: str) -> list[dict]: + """ + Get all models available on a given provider. + """ + return [ + m for m in get_all_models() + if m.get("providers") + and any(p.get("provider_id") == provider_id for p in m["providers"]) + ] + + +def get_model_on_provider(provider_id: str, provider_model_id: str | None = None) -> dict | None: + """ + Find a model available on a specific provider. + + If provider_model_id is given, match both provider and the model's ID on that provider. + Otherwise return the first model found on the provider. + """ + for model in get_all_models(): + providers = model.get("providers") or [] + for p in providers: + if p.get("provider_id") == provider_id: + if provider_model_id is None: + return model + if p.get("model_id_on_provider") == provider_model_id: + return model + return None + + +def get_metadata() -> dict[str, dict]: + """ + Get metadata for all models as a dict keyed by model_id. + """ + return {m["model_id"]: m for m in get_all_models()} + + +def get_models() -> list[str]: + """ + Get all model_ids. Deprecated: use get_all_models() for typed data. + """ + return get_metadata_models() \ No newline at end of file diff --git a/packages/python/model_metadata_central/providers.json b/packages/python/model_metadata_central/providers.json new file mode 100644 index 0000000..b90bbd7 --- /dev/null +++ b/packages/python/model_metadata_central/providers.json @@ -0,0 +1,189 @@ +[ + { + "provider_id": "anthropic", + "name": "Anthropic", + "website_url": "https://anthropic.com", + "api_type": "anthropic", + "base_url": "https://api.anthropic.com/v1", + "auth_type": "api_key", + "routing_priority": "direct", + "status": "active", + "notes": "Primary provider for Claude models. Uses Anthropic's own API protocol." + }, + { + "provider_id": "cloudflare", + "name": "Cloudflare Workers AI", + "website_url": "https://developers.cloudflare.com/workers-ai", + "api_type": "openai_compatible", + "base_url": "https://api.cloudflare.com/client/v4", + "auth_type": "api_key", + "routing_priority": "direct", + "status": "active", + "notes": "Edge inference via Cloudflare Workers AI. Account-scoped model routes use /accounts/{account_id}/ai/run/{model}; OpenAI-compatible routes use /accounts/{account_id}/ai/v1." + }, + { + "provider_id": "deepseek", + "name": "DeepSeek", + "website_url": "https://deepseek.com", + "api_type": "openai_compatible", + "base_url": "https://api.deepseek.com/v1", + "auth_type": "api_key", + "routing_priority": "direct", + "status": "active", + "notes": "Primary provider for DeepSeek V4 and Coder models." + }, + { + "provider_id": "google", + "name": "Google AI", + "website_url": "https://ai.google", + "api_type": "openai_compatible", + "base_url": "https://generativelanguage.googleapis.com/v1beta", + "auth_type": "api_key", + "routing_priority": "direct", + "status": "active", + "notes": "Primary provider for Gemini, Gemma, and Lyria models via Vertex AI or AI Studio." + }, + { + "provider_id": "groq", + "name": "Groq", + "website_url": "https://console.groq.com", + "api_type": "openai_compatible", + "base_url": "https://api.groq.com/openai/v1", + "auth_type": "api_key", + "routing_priority": "direct", + "status": "active", + "notes": "High-speed inference provider. Good for latency-sensitive applications. Popular for Llama and Mixtral models." + }, + { + "provider_id": "lmstudio", + "name": "LM Studio", + "website_url": "https://lmstudio.ai", + "api_type": "openai_compatible", + "base_url": "http://localhost:1234/v1", + "auth_type": "none", + "routing_priority": "direct", + "status": "active", + "notes": "Local inference GUI and API server for GGUF/GGML models. Similar API to Ollama. Authentication disabled by default." + }, + { + "provider_id": "localai", + "name": "LocalAI", + "website_url": "https://localai.io", + "api_type": "openai_compatible", + "base_url": "http://localhost:8080/v1", + "auth_type": "api_key", + "routing_priority": "direct", + "status": "active", + "notes": "Self-hosted inference engine. Supports many open models via ggml/gguf. Often used in Kubernetes/ Docker stacks. Authentication may be bearer token or disabled depending on config." + }, + { + "provider_id": "minimax", + "name": "MiniMax", + "website_url": "https://platform.minimax.io", + "api_type": "anthropic", + "base_url": "https://api.minimax.io/anthropic", + "auth_type": "api_key", + "routing_priority": "direct", + "status": "active", + "notes": "Primary provider for MiniMax text models. Anthropic-compatible API is recommended and supports streaming plus interleaved thinking; MiniMax also exposes OpenAI-compatible text APIs." + }, + { + "provider_id": "mistralai", + "name": "Mistral AI", + "website_url": "https://mistral.ai", + "api_type": "openai_compatible", + "base_url": "https://api.mistral.ai/v1", + "auth_type": "api_key", + "routing_priority": "direct", + "status": "active", + "notes": "Primary provider for Mistral's own models including Mistral Small, Medium, Large, and Codestral." + }, + { + "provider_id": "moonshotai", + "name": "Moonshot AI", + "website_url": "https://moonshot.ai", + "api_type": "openai_compatible", + "base_url": "https://api.moonshotai.com/v1", + "auth_type": "api_key", + "routing_priority": "direct", + "status": "active", + "notes": "Primary provider for Kimi models." + }, + { + "provider_id": "nvidia", + "name": "NVIDIA NIM", + "website_url": "https://build.nvidia.com", + "api_type": "openai_compatible", + "base_url": "https://integrate.api.nvidia.com/v1", + "auth_type": "api_key", + "routing_priority": "direct", + "status": "active", + "notes": "NVIDIA NIM API catalog for hosted and deployable NVIDIA/open model inference, including Nemotron." + }, + { + "provider_id": "ollama", + "name": "Ollama", + "website_url": "https://ollama.com", + "api_type": "openai_compatible", + "base_url": "http://localhost:11434/v1", + "auth_type": "none", + "routing_priority": "direct", + "status": "active", + "notes": "Local inference runtime for macOS, Linux, and Windows. Serves quantized GGUF models. Authentication disabled by default; configure .env/ollama for credentials in production." + }, + { + "provider_id": "openai", + "name": "OpenAI", + "website_url": "https://openai.com", + "api_type": "openai_compatible", + "base_url": "https://api.openai.com/v1", + "auth_type": "api_key", + "routing_priority": "direct", + "status": "active", + "notes": "The primary provider for OpenAI models including GPT-4, GPT-5, and o-series." + }, + { + "provider_id": "openrouter", + "name": "OpenRouter", + "website_url": "https://openrouter.ai", + "api_type": "openai_compatible", + "base_url": "https://openrouter.ai/api/v1", + "auth_type": "api_key", + "routing_priority": "aggregator", + "status": "active", + "notes": "Aggregator that routes to multiple providers. Useful for model comparison and failover. Access models from OpenAI, Anthropic, Google, DeepSeek and more via a unified API." + }, + { + "provider_id": "qwen", + "name": "Qwen", + "website_url": "https://qwen.ai", + "api_type": "openai_compatible", + "base_url": "https://dashscope-intl.aliyuncs.com/compatible-mode/v1", + "auth_type": "api_key", + "routing_priority": "direct", + "status": "active", + "notes": "Primary provider for Qwen models via Alibaba Cloud DashScope." + }, + { + "provider_id": "x-ai", + "name": "xAI", + "website_url": "https://x.ai", + "api_type": "openai_compatible", + "base_url": "https://api.x.ai/v1", + "auth_type": "api_key", + "routing_priority": "direct", + "status": "active", + "notes": "Primary provider for Grok models." + }, + { + "provider_id": "zai", + "name": "Z.AI", + "website_url": "https://z.ai", + "api_type": "openai_compatible", + "base_url": "https://api.z.ai/api/paas/v4", + "auth_type": "api_key", + "routing_priority": "direct", + "status": "active", + "notes": "Primary provider for GLM models. OpenAI-compatible API endpoint for Z.AI/Zhipu model access." + } +] diff --git a/packages/python/model_metadata_central/registry.json b/packages/python/model_metadata_central/registry.json new file mode 100644 index 0000000..72b673f --- /dev/null +++ b/packages/python/model_metadata_central/registry.json @@ -0,0 +1,2111 @@ +[ + { + "model_id": "claude-haiku-4-5", + "model_name": "Claude Haiku 4.5 (latest)", + "model_provider": "anthropic", + "model_description": "Anthropic's fast, low-cost Claude 4.5 model with near-frontier intelligence for high-volume work.", + "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": 1e-06, + "output": 5e-06 + }, + "knowledge_cutoff": "2025-02-28", + "tuning": [ + "multimodal", + "function" + ], + "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_id": "claude-haiku-4", + "model_name": "Claude Haiku 4", + "model_provider": "anthropic", + "model_description": "Fast, affordable Claude. Optimized for high-volume, latency-sensitive tasks where quality-per-token matters more than raw capability.", + "model_info": "https://docs.anthropic.com/en/docs/models/claude-haiku-4", + "model_type": "chat", + "context_window": 200000, + "cost_per_token": { + "input": 8e-07, + "output": 4e-06 + }, + "providers": [ + { + "provider_id": "anthropic", + "model_id_on_provider": "haiku-4" + }, + { + "provider_id": "openrouter", + "model_id_on_provider": "anthropic/claude-haiku-4" + } + ] + }, + { + "model_id": "claude-opus-4-6-fast", + "model_name": "Claude Opus 4.6 (Fast)", + "model_provider": "anthropic", + "model_description": "High-speed variant of Opus 4.6. Optimized for rapid responses while retaining strong reasoning and capabilities.", + "model_info": "https://docs.anthropic.com/en/docs/models/claude-opus-4-6", + "model_type": "chat", + "context_window": 1000000, + "cost_per_token": { + "input": 3e-05, + "output": 0.00015 + }, + "tuning": [ + "function" + ], + "providers": [ + { + "provider_id": "anthropic", + "model_id_on_provider": "claude-opus-4-6-fast" + }, + { + "provider_id": "openrouter", + "model_id_on_provider": "anthropic/claude-opus-4-6-fast" + } + ] + }, + { + "model_id": "claude-opus-4-6", + "model_name": "Claude Opus 4.6", + "model_provider": "anthropic", + "model_description": "Anthropic's previous-generation Opus model with 1M context, retained for downstream compatibility.", + "model_info": "https://docs.anthropic.com/en/docs/about-claude/models/overview", + "model_type": "chat", + "context_window": 1000000, + "max_tokens": 128000, + "cost_per_token": { + "input": 5e-06, + "output": 2.5e-05 + }, + "knowledge_cutoff": "2025-05-31", + "tuning": [ + "multimodal", + "function" + ], + "providers": [ + { + "provider_id": "anthropic", + "model_id_on_provider": "claude-opus-4-6" + }, + { + "provider_id": "openrouter", + "model_id_on_provider": "anthropic/claude-opus-4.6" + } + ] + }, + { + "model_id": "claude-opus-4-7", + "model_name": "Claude Opus 4.7", + "model_provider": "anthropic", + "model_description": "Anthropic's most capable model. Exceptional at complex reasoning, coding, creative collaboration, and scientific analysis.", + "model_info": "https://docs.anthropic.com/en/docs/models/claude-opus-4-7", + "model_type": "chat", + "context_window": 1000000, + "cost_per_token": { + "input": 5e-06, + "output": 2.5e-05 + }, + "tuning": [ + "function" + ], + "providers": [ + { + "provider_id": "anthropic", + "model_id_on_provider": "claude-opus-4-7" + }, + { + "provider_id": "openrouter", + "model_id_on_provider": "anthropic/claude-opus-4-7" + } + ] + }, + { + "model_id": "claude-opus-latest", + "model_name": "Claude Opus Latest", + "model_provider": "anthropic", + "model_description": "Points to the latest stable Opus release. Use when you want the newest Claude without pinning a version.", + "model_info": "https://docs.anthropic.com/en/docs/models", + "model_type": "chat", + "context_window": 1000000, + "cost_per_token": { + "input": 5e-06, + "output": 2.5e-05 + }, + "tuning": [ + "function" + ], + "providers": [ + { + "provider_id": "anthropic", + "model_id_on_provider": "opus" + }, + { + "provider_id": "openrouter", + "model_id_on_provider": "anthropic/claude-opus-latest" + } + ] + }, + { + "model_id": "claude-sonnet-4-2", + "model_name": "Claude Sonnet 4.2", + "model_provider": "anthropic", + "model_description": "Balanced Anthropic model. Strong for coding, analysis, and everyday tasks at a mid-range price point.", + "model_info": "https://docs.anthropic.com/en/docs/models/claude-sonnet-4-2", + "model_type": "chat", + "context_window": 200000, + "cost_per_token": { + "input": 3e-06, + "output": 1.5e-05 + }, + "tuning": [ + "function" + ], + "providers": [ + { + "provider_id": "anthropic", + "model_id_on_provider": "claude-sonnet-4-2" + }, + { + "provider_id": "openrouter", + "model_id_on_provider": "anthropic/claude-sonnet-4-2" + } + ] + }, + { + "model_id": "claude-sonnet-4-6", + "model_name": "Claude Sonnet 4.6", + "model_provider": "anthropic", + "model_description": "Anthropic's balanced Claude model with strong speed/intelligence tradeoffs, extended thinking, and 1M context.", + "model_info": "https://docs.anthropic.com/en/docs/about-claude/models/overview", + "model_type": "chat", + "context_window": 1000000, + "max_tokens": 64000, + "cost_per_token": { + "input": 3e-06, + "output": 1.5e-05 + }, + "knowledge_cutoff": "2025-08-31", + "tuning": [ + "multimodal", + "function" + ], + "providers": [ + { + "provider_id": "anthropic", + "model_id_on_provider": "claude-sonnet-4-6" + }, + { + "provider_id": "openrouter", + "model_id_on_provider": "anthropic/claude-sonnet-4.6" + } + ] + }, + { + "model_id": "codestral-latest", + "model_name": "Codestral (latest)", + "model_provider": "mistralai", + "model_description": "Mistral's code-specialized model for software engineering and code completion workflows.", + "model_info": "https://docs.mistral.ai/getting-started/models/models_overview/", + "model_type": "chat", + "context_window": 256000, + "max_tokens": 4096, + "cost_per_token": { + "input": "3e-7", + "output": "9e-7" + }, + "knowledge_cutoff": "2024-10-01", + "tokenizer": { + "family": "tekken" + }, + "tuning": [ + "function", + "instruction" + ], + "providers": [ + { + "provider_id": "mistralai", + "model_id_on_provider": "codestral-latest" + }, + { + "provider_id": "openrouter", + "model_id_on_provider": "mistralai/codestral-latest" + } + ] + }, + { + "model_id": "deepseek-coder-v4", + "model_name": "DeepSeek Coder V4", + "model_provider": "deepseek", + "model_description": "DeepSeek's dedicated code model. Specialized for code generation, completion, and debugging across many languages.", + "model_info": "https://api.deepseek.com", + "model_type": "chat", + "context_window": 1048576, + "cost_per_token": { + "input": 4.3e-07, + "output": 8.7e-07 + }, + "tuning": [ + "code" + ], + "providers": [ + { + "provider_id": "deepseek", + "model_id_on_provider": "deepseek-coder" + }, + { + "provider_id": "openrouter", + "model_id_on_provider": "deepseek/deepseek-coder-v4" + } + ] + }, + { + "model_id": "deepseek-r1-distill-llama-70b", + "model_name": "DeepSeek R1 Distill Llama 70B", + "model_provider": "groq", + "model_description": "Groq-hosted DeepSeek R1 distilled Llama 70B reasoning model.", + "model_info": "https://console.groq.com/docs/models", + "model_type": "chat", + "context_window": 131072, + "max_tokens": 8192, + "cost_per_token": { + "input": 7.5e-07, + "output": 9.9e-07 + }, + "knowledge_cutoff": "2024-07-01", + "tuning": [ + "function", + "instruction" + ], + "providers": [ + { + "provider_id": "groq", + "model_id_on_provider": "deepseek-r1-distill-llama-70b" + } + ] + }, + { + "model_id": "deepseek-v4-flash", + "model_name": "DeepSeek V4 Flash", + "model_provider": "deepseek", + "model_description": "Fast, efficient DeepSeek variant. Optimized for high-volume applications where latency and cost are critical.", + "model_info": "https://api.deepseek.com", + "model_type": "chat", + "context_window": 1048576, + "cost_per_token": { + "input": 1.4e-07, + "output": 2.8e-07 + }, + "providers": [ + { + "provider_id": "deepseek", + "model_id_on_provider": "deepseek-chat" + }, + { + "provider_id": "openrouter", + "model_id_on_provider": "deepseek/deepseek-v4-flash" + } + ] + }, + { + "model_id": "deepseek-v4-pro", + "model_name": "DeepSeek V4 Pro", + "model_provider": "deepseek", + "model_description": "DeepSeek's flagship model. Excellent reasoning and code capabilities at a fraction of OpenAI's cost.", + "model_info": "https://api.deepseek.com", + "model_type": "chat", + "context_window": 1048576, + "cost_per_token": { + "input": 4.3e-07, + "output": 8.7e-07 + }, + "tuning": [ + "function" + ], + "providers": [ + { + "provider_id": "deepseek", + "model_id_on_provider": "deepseek-chat" + }, + { + "provider_id": "openrouter", + "model_id_on_provider": "deepseek/deepseek-v4-pro" + } + ] + }, + { + "model_id": "gemini-2.0-flash", + "model_name": "Gemini 2.0 Flash", + "model_provider": "google", + "model_description": "Previous-generation Gemini. Good balance of speed, cost, and capability for standard tasks.", + "model_info": "https://ai.google.dev/gemini-api/models/gemini-2.0-flash", + "model_type": "chat", + "context_window": 128000, + "cost_per_token": { + "input": 1e-07, + "output": 4e-07 + }, + "deprecated": true, + "providers": [ + { + "provider_id": "google", + "model_id_on_provider": "gemini-2.0-flash" + }, + { + "provider_id": "openrouter", + "model_id_on_provider": "google/gemini-2.0-flash" + } + ] + }, + { + "model_id": "gemini-2.5-flash", + "model_name": "Gemini 2.5 Flash", + "model_provider": "google", + "model_description": "Fast, efficient Gemini model. Optimized for high-volume applications with strong reasoning and code performance.", + "model_info": "https://ai.google.dev/gemini-api/models/gemini-2.5-flash", + "model_type": "chat", + "context_window": 1000000, + "cost_per_token": { + "input": 7.5e-08, + "output": 3e-07 + }, + "tuning": [ + "multimodal" + ], + "providers": [ + { + "provider_id": "google", + "model_id_on_provider": "gemini-2.5-flash" + }, + { + "provider_id": "openrouter", + "model_id_on_provider": "google/gemini-2.5-flash" + } + ] + }, + { + "model_id": "gemini-2.5-pro", + "model_name": "Gemini 2.5 Pro", + "model_provider": "google", + "model_description": "Google's flagship model. Exceptional at long-context tasks, multimodal reasoning, and code generation.", + "model_info": "https://ai.google.dev/gemini-api/docs/models/gemini-2.5-pro", + "model_type": "chat", + "context_window": 1000000, + "cost_per_token": { + "input": 1.25e-06, + "output": 5e-06 + }, + "tuning": [ + "multimodal" + ], + "providers": [ + { + "provider_id": "google", + "model_id_on_provider": "gemini-2.5-pro" + }, + { + "provider_id": "openrouter", + "model_id_on_provider": "google/gemini-2.5-pro" + } + ] + }, + { + "model_id": "gemma-4-26b-a4b-it", + "model_name": "Gemma 4 26B", + "model_provider": "google", + "model_description": "Google's smaller open-weight instruction-tuned model. Efficient for constrained deployment environments.", + "model_info": "https://ai.google.dev/gemma", + "model_type": "chat", + "context_window": 262144, + "cost_per_token": { + "input": 6e-08, + "output": 3.3e-07 + }, + "providers": [ + { + "provider_id": "google", + "model_id_on_provider": "gemma-4-26b-a4b-it" + }, + { + "provider_id": "cloudflare", + "model_id_on_provider": "@cf/google/gemma-4-26b-a4b-it" + }, + { + "provider_id": "openrouter", + "model_id_on_provider": "google/gemma-4-26b-a4b-it" + } + ] + }, + { + "model_id": "gemma-4-31b-it", + "model_name": "Gemma 4 31B", + "model_provider": "google", + "model_description": "Google's open-weight instruction-tuned model. Strong reasoning in a smaller footprint. Good for fine-tuning and self-hosting.", + "model_info": "https://ai.google.dev/gemma", + "model_type": "chat", + "context_window": 262144, + "cost_per_token": { + "input": 1.3e-07, + "output": 3.8e-07 + }, + "providers": [ + { + "provider_id": "google", + "model_id_on_provider": "gemma-4-31b-it" + }, + { + "provider_id": "openrouter", + "model_id_on_provider": "google/gemma-4-31b-it" + } + ] + }, + { + "model_id": "glm-4.7-flash", + "model_name": "GLM-4.7-Flash", + "model_provider": "zai", + "model_description": "Fast open-weight GLM model optimized for multilingual dialogue, tool calling, and reasoning.", + "model_info": "https://docs.z.ai/guides/overview/pricing", + "model_type": "chat", + "context_window": 200000, + "max_tokens": 131072, + "cost_per_token": { + "input": 0, + "output": 0 + }, + "knowledge_cutoff": "2025-04-01", + "tuning": [ + "function", + "instruction" + ], + "providers": [ + { + "provider_id": "zai", + "model_id_on_provider": "glm-4.7-flash" + }, + { + "provider_id": "cloudflare", + "model_id_on_provider": "@cf/zai-org/glm-4.7-flash" + }, + { + "provider_id": "openrouter", + "model_id_on_provider": "z-ai/glm-4.7-flash" + } + ] + }, + { + "model_id": "glm-4.7", + "model_name": "GLM-4.7", + "model_provider": "zai", + "model_description": "Open-weight Z.AI GLM model with strong multilingual, reasoning, and instruction-following capabilities.", + "model_info": "https://docs.z.ai/guides/overview/pricing", + "model_type": "chat", + "context_window": 204800, + "max_tokens": 131072, + "cost_per_token": { + "input": "6e-7", + "output": 2.2e-06 + }, + "knowledge_cutoff": "2025-04-01", + "tuning": [ + "function", + "instruction" + ], + "providers": [ + { + "provider_id": "zai", + "model_id_on_provider": "glm-4.7" + }, + { + "provider_id": "openrouter", + "model_id_on_provider": "z-ai/glm-4.7" + } + ] + }, + { + "model_id": "glm-5-turbo", + "model_name": "GLM-5-Turbo", + "model_provider": "zai", + "model_description": "Higher-throughput GLM-5 Turbo model for production Z.AI workloads.", + "model_info": "https://docs.z.ai/guides/overview/pricing", + "model_type": "chat", + "context_window": 200000, + "max_tokens": 131072, + "cost_per_token": { + "input": 1.2e-06, + "output": 4e-06 + }, + "tuning": [ + "function" + ], + "providers": [ + { + "provider_id": "zai", + "model_id_on_provider": "glm-5-turbo" + }, + { + "provider_id": "openrouter", + "model_id_on_provider": "z-ai/glm-5-turbo" + } + ] + }, + { + "model_id": "glm-5.1", + "model_name": "GLM-5.1", + "model_provider": "zai", + "model_description": "Updated GLM-5.1 model with current Z.AI pricing and long-context support.", + "model_info": "https://docs.z.ai/guides/overview/pricing", + "model_type": "chat", + "context_window": 200000, + "max_tokens": 131072, + "cost_per_token": { + "input": 1.4e-06, + "output": 4.4e-06 + }, + "tuning": [ + "function" + ], + "providers": [ + { + "provider_id": "zai", + "model_id_on_provider": "glm-5.1" + }, + { + "provider_id": "openrouter", + "model_id_on_provider": "z-ai/glm-5.1" + } + ] + }, + { + "model_id": "glm-5", + "model_name": "GLM-5", + "model_provider": "zai", + "model_description": "Z.AI GLM-5 model for current-generation reasoning and agentic workloads.", + "model_info": "https://docs.z.ai/guides/overview/pricing", + "model_type": "chat", + "context_window": 204800, + "max_tokens": 131072, + "cost_per_token": { + "input": 1e-06, + "output": 3.2e-06 + }, + "tuning": [ + "function", + "instruction" + ], + "providers": [ + { + "provider_id": "zai", + "model_id_on_provider": "glm-5" + }, + { + "provider_id": "openrouter", + "model_id_on_provider": "z-ai/glm-5" + } + ] + }, + { + "model_id": "glm-5v-turbo", + "model_name": "glm-5v-turbo", + "model_provider": "zai", + "model_description": "Vision-capable GLM-5 Turbo variant for multimodal document, image, and video inputs.", + "model_info": "https://docs.z.ai/guides/overview/pricing", + "model_type": "chat", + "context_window": 200000, + "max_tokens": 131072, + "cost_per_token": { + "input": 1.2e-06, + "output": 4e-06 + }, + "tuning": [ + "multimodal", + "function" + ], + "providers": [ + { + "provider_id": "zai", + "model_id_on_provider": "glm-5v-turbo" + }, + { + "provider_id": "openrouter", + "model_id_on_provider": "z-ai/glm-5v-turbo" + } + ] + }, + { + "model_id": "gpt-3.5-turbo-16k", + "model_name": "GPT-3.5 Turbo 16K", + "model_provider": "openai", + "model_description": "Deprecated 16K GPT-3.5 Turbo snapshot retained for legacy downstream configurations.", + "model_info": "https://platform.openai.com/docs/models/gpt-3.5-turbo-16k-0613", + "model_version": "0613", + "model_type": "chat", + "context_window": 16385, + "max_tokens": 4096, + "cost_per_token": { + "input": 3e-06, + "output": 4e-06 + }, + "knowledge_cutoff": "2021-09-01", + "tokenizer": { + "family": "tiktoken", + "name": "cl100k_base" + }, + "tuning": [ + "instruction" + ], + "deprecated": true, + "providers": [ + { + "provider_id": "openai", + "model_id_on_provider": "gpt-3.5-turbo-16k-0613" + } + ] + }, + { + "model_id": "gpt-3.5-turbo-instruct", + "model_name": "GPT-3.5 Turbo Instruct", + "model_provider": "openai", + "model_description": "Similar capabilities as text-davinci-003 but compatible with legacy Completions endpoint and not Chat Completions.", + "model_info": "https://platform.openai.com/docs/models/gpt-3-5", + "model_version": "latest", + "model_type": "completion", + "context_window": 4097, + "max_tokens": 4095, + "cost_per_token": { + "input": 1.5e-06, + "output": 2e-06 + }, + "knowledge_cutoff": "2021-09-01", + "tokenizer": { + "family": "tiktoken", + "name": "cl100k_base" + }, + "tuning": [ + "instruction", + "function" + ], + "deprecated": true + }, + { + "model_id": "gpt-3.5-turbo", + "model_name": "GPT-3.5 Turbo", + "model_provider": "openai", + "model_description": "Most capable GPT-3.5 model and optimized for chat at 1/10th the cost of text-davinci-003.", + "model_info": "https://platform.openai.com/docs/models/gpt-3-5", + "model_version": "latest", + "model_type": "chat", + "context_window": 4097, + "max_tokens": 4095, + "cost_per_token": { + "input": 1.5e-06, + "output": 2e-06 + }, + "knowledge_cutoff": "2021-09-01", + "tokenizer": { + "family": "tiktoken", + "name": "cl100k_base" + }, + "tuning": [ + "function" + ], + "deprecated": true, + "providers": [ + { + "provider_id": "openai", + "model_id_on_provider": "gpt-3.5-turbo" + } + ] + }, + { + "model_id": "gpt-4-32k", + "model_name": "GPT-4 32K", + "model_provider": "openai", + "model_description": "Same capabilities as the standard gpt-4 mode but with 4x the context length.", + "model_info": "https://platform.openai.com/docs/models/gpt-4", + "model_version": "latest", + "model_type": "chat", + "context_window": 32768, + "cost_per_token": { + "input": 6e-05, + "output": 0.00012 + }, + "knowledge_cutoff": "2021-09-01", + "tokenizer": { + "family": "tiktoken", + "name": "cl100k_base" + }, + "tuning": [ + "function" + ], + "deprecated": true + }, + { + "model_id": "gpt-4-turbo", + "model_name": "GPT-4 Turbo", + "model_provider": "openai", + "model_description": "Legacy GPT-4 Turbo model with a 128K context window. Kept for integrations that still route older GPT-4 workloads.", + "model_info": "https://platform.openai.com/docs/models/gpt-4-turbo", + "model_type": "chat", + "context_window": 128000, + "max_tokens": 4096, + "cost_per_token": { + "input": 1e-05, + "output": 3e-05 + }, + "knowledge_cutoff": "2023-12-01", + "tokenizer": { + "family": "tiktoken", + "name": "o200k_base" + }, + "tuning": [ + "multimodal", + "function" + ], + "providers": [ + { + "provider_id": "openai", + "model_id_on_provider": "gpt-4-turbo" + }, + { + "provider_id": "openrouter", + "model_id_on_provider": "openai/gpt-4-turbo" + } + ] + }, + { + "model_id": "gpt-4.1-mini", + "model_name": "GPT-4.1 mini", + "model_provider": "openai", + "model_description": "Smaller GPT-4.1 variant balancing latency, price, and strong general-purpose capability.", + "model_info": "https://platform.openai.com/docs/models/gpt-4.1-mini", + "model_type": "chat", + "context_window": 1047576, + "max_tokens": 32768, + "cost_per_token": { + "input": "4e-7", + "output": 1.6e-06 + }, + "knowledge_cutoff": "2024-04-01", + "tokenizer": { + "family": "tiktoken", + "name": "o200k_base" + }, + "tuning": [ + "multimodal", + "function" + ], + "providers": [ + { + "provider_id": "openai", + "model_id_on_provider": "gpt-4.1-mini" + }, + { + "provider_id": "openrouter", + "model_id_on_provider": "openai/gpt-4.1-mini" + } + ] + }, + { + "model_id": "gpt-4.1-nano", + "model_name": "GPT-4.1 nano", + "model_provider": "openai", + "model_description": "Lowest-cost GPT-4.1 variant for classification, extraction, and latency-sensitive tasks.", + "model_info": "https://platform.openai.com/docs/models/gpt-4.1-nano", + "model_type": "chat", + "context_window": 1047576, + "max_tokens": 32768, + "cost_per_token": { + "input": "1e-7", + "output": "4e-7" + }, + "knowledge_cutoff": "2024-04-01", + "tokenizer": { + "family": "tiktoken", + "name": "o200k_base" + }, + "tuning": [ + "multimodal", + "function" + ], + "providers": [ + { + "provider_id": "openai", + "model_id_on_provider": "gpt-4.1-nano" + }, + { + "provider_id": "openrouter", + "model_id_on_provider": "openai/gpt-4.1-nano" + } + ] + }, + { + "model_id": "gpt-4.1", + "model_name": "GPT-4.1", + "model_provider": "openai", + "model_description": "Large-context GPT-4.1 model for coding, instruction following, and multimodal document workflows.", + "model_info": "https://platform.openai.com/docs/models/gpt-4.1", + "model_type": "chat", + "context_window": 1047576, + "max_tokens": 32768, + "cost_per_token": { + "input": 2e-06, + "output": 8e-06 + }, + "knowledge_cutoff": "2024-04-01", + "tokenizer": { + "family": "tiktoken", + "name": "o200k_base" + }, + "tuning": [ + "multimodal", + "function" + ], + "providers": [ + { + "provider_id": "openai", + "model_id_on_provider": "gpt-4.1" + }, + { + "provider_id": "openrouter", + "model_id_on_provider": "openai/gpt-4.1" + } + ] + }, + { + "model_id": "gpt-4.5", + "model_name": "GPT-4.5", + "model_provider": "openai", + "model_description": "GPT-4 successor with improved reasoning and instruction following. Strong all-around model between GPT-4o and GPT-5 series.", + "model_info": "https://platform.openai.com/docs/models/gpt-4.5", + "model_type": "chat", + "context_window": 128000, + "cost_per_token": { + "input": 1e-05, + "output": 3e-05 + }, + "tuning": [ + "function" + ], + "tokenizer": { + "family": "tiktoken", + "name": "o200k_base" + }, + "providers": [ + { + "provider_id": "openai", + "model_id_on_provider": "gpt-4.5" + }, + { + "provider_id": "openrouter", + "model_id_on_provider": "openai/gpt-4.5" + } + ] + }, + { + "model_id": "gpt-4", + "model_name": "GPT-4", + "model_provider": "openai", + "model_description": "More capable than any GPT-3.5 model able to do more complex tasks and optimized for chat.", + "model_info": "https://platform.openai.com/docs/models/gpt-4", + "model_version": "latest", + "model_type": "chat", + "context_window": 8192, + "max_tokens": 8191, + "cost_per_token": { + "input": 3e-05, + "output": 6e-05 + }, + "knowledge_cutoff": "2021-09-01", + "tokenizer": { + "family": "tiktoken", + "name": "cl100k_base" + }, + "tuning": [ + "function" + ], + "deprecated": true, + "providers": [ + { + "provider_id": "openai", + "model_id_on_provider": "gpt-4" + } + ] + }, + { + "model_id": "gpt-4o-mini", + "model_name": "GPT-4o Mini", + "model_provider": "openai", + "model_description": "Smaller, faster, cheaper GPT-4o. Optimized for high-volume, cost-sensitive applications.", + "model_info": "https://platform.openai.com/docs/models/gpt-4o-mini", + "model_type": "chat", + "context_window": 128000, + "max_tokens": 16384, + "cost_per_token": { + "input": 1.5e-07, + "output": 6e-07 + }, + "tuning": [ + "multimodal" + ], + "tokenizer": { + "family": "tiktoken", + "name": "o200k_base" + }, + "providers": [ + { + "provider_id": "openai", + "model_id_on_provider": "gpt-4o-mini" + }, + { + "provider_id": "openrouter", + "model_id_on_provider": "openai/gpt-4o-mini" + } + ] + }, + { + "model_id": "gpt-4o", + "model_name": "GPT-4o", + "model_provider": "openai", + "model_description": "GPT-4 Omni \u2014 multimodal model with vision, audio, and text. Fast and cost-efficient relative to GPT-4 Turbo.", + "model_info": "https://platform.openai.com/docs/models/gpt-4o", + "model_type": "chat", + "context_window": 128000, + "max_tokens": 32768, + "cost_per_token": { + "input": 5e-06, + "output": 1.5e-05 + }, + "tuning": [ + "multimodal" + ], + "tokenizer": { + "family": "tiktoken", + "name": "o200k_base" + }, + "providers": [ + { + "provider_id": "openai", + "model_id_on_provider": "gpt-4o" + }, + { + "provider_id": "openrouter", + "model_id_on_provider": "openai/gpt-4o" + } + ] + }, + { + "model_id": "gpt-5-mini", + "model_name": "GPT-5 Mini", + "model_provider": "openai", + "model_description": "Lower-cost GPT-5 variant for high-volume tasks that still benefit from reasoning support.", + "model_info": "https://platform.openai.com/docs/models/gpt-5-mini", + "model_type": "chat", + "context_window": 400000, + "max_tokens": 128000, + "cost_per_token": { + "input": 2.5e-07, + "output": 2e-06 + }, + "knowledge_cutoff": "2024-05-30", + "tokenizer": { + "family": "tiktoken", + "name": "o200k_base" + }, + "tuning": [ + "multimodal", + "function" + ], + "providers": [ + { + "provider_id": "openai", + "model_id_on_provider": "gpt-5-mini" + }, + { + "provider_id": "openrouter", + "model_id_on_provider": "openai/gpt-5-mini" + } + ] + }, + { + "model_id": "gpt-5-nano", + "model_name": "GPT-5 Nano", + "model_provider": "openai", + "model_description": "Smallest GPT-5 variant for inexpensive, latency-sensitive automation.", + "model_info": "https://platform.openai.com/docs/models/gpt-5-nano", + "model_type": "chat", + "context_window": 400000, + "max_tokens": 128000, + "cost_per_token": { + "input": "5e-8", + "output": "4e-7" + }, + "knowledge_cutoff": "2024-05-30", + "tokenizer": { + "family": "tiktoken", + "name": "o200k_base" + }, + "tuning": [ + "multimodal", + "function" + ], + "providers": [ + { + "provider_id": "openai", + "model_id_on_provider": "gpt-5-nano" + }, + { + "provider_id": "openrouter", + "model_id_on_provider": "openai/gpt-5-nano" + } + ] + }, + { + "model_id": "gpt-5.3-codex", + "model_name": "GPT-5.3 Codex", + "model_provider": "openai", + "model_description": "Codex-optimized GPT-5.3 model for coding agents and long-running software engineering tasks.", + "model_info": "https://platform.openai.com/docs/models/gpt-5.3-codex", + "model_type": "chat", + "context_window": 400000, + "max_tokens": 128000, + "cost_per_token": { + "input": 1.75e-06, + "output": 1.4e-05 + }, + "knowledge_cutoff": "2025-08-31", + "tokenizer": { + "family": "tiktoken", + "name": "o200k_base" + }, + "tuning": [ + "multimodal", + "function" + ], + "providers": [ + { + "provider_id": "openai", + "model_id_on_provider": "gpt-5.3-codex" + }, + { + "provider_id": "openrouter", + "model_id_on_provider": "openai/gpt-5.3-codex" + } + ] + }, + { + "model_id": "gpt-5.4-image-2", + "model_name": "GPT-5.4 Image 2", + "model_provider": "openai", + "model_description": "GPT-5.4 optimized for image understanding and generation. Multimodal model supporting vision tasks.", + "model_info": "https://platform.openai.com/docs/models/gpt-5.4-image-2", + "model_type": "chat", + "context_window": 272000, + "cost_per_token": { + "input": 8e-06, + "output": 1.5e-05 + }, + "tuning": [ + "multimodal" + ], + "providers": [ + { + "provider_id": "openai", + "model_id_on_provider": "gpt-5.4-image-2" + }, + { + "provider_id": "openrouter", + "model_id_on_provider": "openai/gpt-5.4-image-2" + } + ] + }, + { + "model_id": "gpt-5.4-mini", + "model_name": "GPT-5.4 mini", + "model_provider": "openai", + "model_description": "Fast, cost-efficient GPT-5.4 variant for coding, computer use, and subagent workloads.", + "model_info": "https://platform.openai.com/docs/models/gpt-5.4-mini", + "model_type": "chat", + "context_window": 400000, + "max_tokens": 128000, + "cost_per_token": { + "input": 7.5e-07, + "output": 4.5e-06 + }, + "knowledge_cutoff": "2025-08-31", + "tokenizer": { + "family": "tiktoken", + "name": "o200k_base" + }, + "tuning": [ + "multimodal", + "function" + ], + "providers": [ + { + "provider_id": "openai", + "model_id_on_provider": "gpt-5.4-mini" + }, + { + "provider_id": "openrouter", + "model_id_on_provider": "openai/gpt-5.4-mini" + } + ] + }, + { + "model_id": "gpt-5.4-nano", + "model_name": "GPT-5.4 nano", + "model_provider": "openai", + "model_description": "Lowest-latency GPT-5.4 variant for inexpensive high-volume tasks.", + "model_info": "https://platform.openai.com/docs/models/gpt-5.4-nano", + "model_type": "chat", + "context_window": 400000, + "max_tokens": 128000, + "cost_per_token": { + "input": "2e-7", + "output": 1.25e-06 + }, + "knowledge_cutoff": "2025-08-31", + "tokenizer": { + "family": "tiktoken", + "name": "o200k_base" + }, + "tuning": [ + "multimodal", + "function" + ], + "providers": [ + { + "provider_id": "openai", + "model_id_on_provider": "gpt-5.4-nano" + }, + { + "provider_id": "openrouter", + "model_id_on_provider": "openai/gpt-5.4-nano" + } + ] + }, + { + "model_id": "gpt-5.4-pro", + "model_name": "GPT-5.4 Pro", + "model_provider": "openai", + "model_description": "High-capability GPT-5.4 Pro model for the hardest reasoning and professional workloads.", + "model_info": "https://platform.openai.com/docs/models/gpt-5.4-pro", + "model_type": "chat", + "context_window": 1050000, + "max_tokens": 128000, + "cost_per_token": { + "input": 3e-05, + "output": 0.00018 + }, + "knowledge_cutoff": "2025-08-31", + "tokenizer": { + "family": "tiktoken", + "name": "o200k_base" + }, + "tuning": [ + "multimodal", + "function" + ], + "providers": [ + { + "provider_id": "openai", + "model_id_on_provider": "gpt-5.4-pro" + }, + { + "provider_id": "openrouter", + "model_id_on_provider": "openai/gpt-5.4-pro" + } + ] + }, + { + "model_id": "gpt-5.4", + "model_name": "GPT-5.4", + "model_provider": "openai", + "model_description": "Current OpenAI model for coding and professional work with a 1M token context window.", + "model_info": "https://platform.openai.com/docs/models/gpt-5.4", + "model_type": "chat", + "context_window": 1050000, + "max_tokens": 128000, + "cost_per_token": { + "input": 2.5e-06, + "output": 1.5e-05 + }, + "knowledge_cutoff": "2025-08-31", + "tokenizer": { + "family": "tiktoken", + "name": "o200k_base" + }, + "tuning": [ + "multimodal", + "function" + ], + "providers": [ + { + "provider_id": "openai", + "model_id_on_provider": "gpt-5.4" + }, + { + "provider_id": "openrouter", + "model_id_on_provider": "openai/gpt-5.4" + } + ] + }, + { + "model_id": "gpt-5.5-pro", + "model_name": "GPT-5.5 Pro", + "model_provider": "openai", + "model_description": "Most capable OpenAI model with largest context window. Optimized for complex reasoning, advanced coding, and scientific analysis.", + "model_info": "https://platform.openai.com/docs/models/gpt-5.5-pro", + "model_type": "chat", + "context_window": 1050000, + "max_tokens": 1049999, + "cost_per_token": { + "input": 3e-05, + "output": 0.00018 + }, + "tuning": [ + "function" + ], + "providers": [ + { + "provider_id": "openai", + "model_id_on_provider": "gpt-5.5-pro" + }, + { + "provider_id": "openrouter", + "model_id_on_provider": "openai/gpt-5.5-pro" + } + ] + }, + { + "model_id": "gpt-5.5", + "model_name": "GPT-5.5", + "model_provider": "openai", + "model_description": "Capable OpenAI model with large context window. Strong for complex tasks at lower cost than Pro.", + "model_info": "https://platform.openai.com/docs/models/gpt-5.5", + "model_type": "chat", + "context_window": 1050000, + "max_tokens": 1049999, + "cost_per_token": { + "input": 5e-06, + "output": 3e-05 + }, + "tuning": [ + "function" + ], + "providers": [ + { + "provider_id": "openai", + "model_id_on_provider": "gpt-5.5" + }, + { + "provider_id": "openrouter", + "model_id_on_provider": "openai/gpt-5.5" + } + ] + }, + { + "model_id": "gpt-5", + "model_name": "GPT-5", + "model_provider": "openai", + "model_description": "General GPT-5 model for reasoning, coding, and multimodal text/image workflows.", + "model_info": "https://platform.openai.com/docs/models/gpt-5", + "model_type": "chat", + "context_window": 400000, + "max_tokens": 128000, + "cost_per_token": { + "input": 1.25e-06, + "output": 1e-05 + }, + "knowledge_cutoff": "2024-09-30", + "tokenizer": { + "family": "tiktoken", + "name": "o200k_base" + }, + "tuning": [ + "multimodal", + "function" + ], + "providers": [ + { + "provider_id": "openai", + "model_id_on_provider": "gpt-5" + }, + { + "provider_id": "openrouter", + "model_id_on_provider": "openai/gpt-5" + } + ] + }, + { + "model_id": "grok-4.2-multi-agent", + "model_name": "Grok 4.2 Multi-Agent", + "model_provider": "x-ai", + "model_description": "Grok 4.2 optimized for multi-agent workflows. Enhanced tool use and coordination for parallel task execution.", + "model_info": "https://x.ai/api", + "model_type": "chat", + "context_window": 2000000, + "cost_per_token": { + "input": 2e-06, + "output": 6e-06 + }, + "providers": [ + { + "provider_id": "x-ai", + "model_id_on_provider": "grok-4.2" + }, + { + "provider_id": "openrouter", + "model_id_on_provider": "x-ai/grok-4.2-multi-agent" + } + ] + }, + { + "model_id": "grok-4.2", + "model_name": "Grok 4.2", + "model_provider": "x-ai", + "model_description": "xAI's flagship model. Strong reasoning with real-time web access. Known for personality and directness.", + "model_info": "https://x.ai/api", + "model_type": "chat", + "context_window": 2000000, + "cost_per_token": { + "input": 2e-06, + "output": 6e-06 + }, + "tuning": [ + "function" + ], + "providers": [ + { + "provider_id": "x-ai", + "model_id_on_provider": "grok-4.2" + }, + { + "provider_id": "openrouter", + "model_id_on_provider": "x-ai/grok-4.2" + } + ] + }, + { + "model_id": "kimi-k2.6", + "model_name": "Kimi K2.6", + "model_provider": "moonshotai", + "model_description": "Moonshot AI's flagship model. Strong long-context understanding and reasoning at competitive pricing.", + "model_info": "https://platform.moonshot.ai/docs", + "model_type": "chat", + "context_window": 256000, + "cost_per_token": { + "input": 7.4e-07, + "output": 4.66e-06 + }, + "tuning": [ + "function" + ], + "providers": [ + { + "provider_id": "moonshotai", + "model_id_on_provider": "kimi-k2.6" + }, + { + "provider_id": "cloudflare", + "model_id_on_provider": "@cf/moonshotai/kimi-k2.6" + }, + { + "provider_id": "openrouter", + "model_id_on_provider": "moonshotai/kimi-k2.6" + } + ] + }, + { + "model_id": "kimi-v3", + "model_name": "Kimi V3", + "model_provider": "moonshotai", + "model_description": "Mid-range Moonshot model. Good balance of capability and cost for standard tasks.", + "model_info": "https://platform.moonshot.ai/docs", + "model_type": "chat", + "context_window": 256000, + "cost_per_token": { + "input": 2e-07, + "output": 1e-06 + }, + "providers": [ + { + "provider_id": "moonshotai", + "model_id_on_provider": "kimi-v3" + }, + { + "provider_id": "openrouter", + "model_id_on_provider": "moonshotai/kimi-v3" + } + ] + }, + { + "model_id": "llama-3.1-8b-instant", + "model_name": "Llama 3.1 8B Instant", + "model_provider": "groq", + "model_description": "Groq-hosted Llama 3.1 8B model for very low-latency, low-cost chat and automation.", + "model_info": "https://console.groq.com/docs/models", + "model_type": "chat", + "context_window": 131072, + "max_tokens": 131072, + "cost_per_token": { + "input": "5e-8", + "output": "8e-8" + }, + "knowledge_cutoff": "2023-12-01", + "tuning": [ + "function", + "instruction" + ], + "providers": [ + { + "provider_id": "groq", + "model_id_on_provider": "llama-3.1-8b-instant" + } + ] + }, + { + "model_id": "llama-3.3-70b-versatile", + "model_name": "Llama 3.3 70B Versatile", + "model_provider": "groq", + "model_description": "Groq-hosted Llama 3.3 70B model optimized for fast general-purpose chat and tool workloads.", + "model_info": "https://console.groq.com/docs/models", + "model_type": "chat", + "context_window": 131072, + "max_tokens": 32768, + "cost_per_token": { + "input": 5.9e-07, + "output": 7.9e-07 + }, + "knowledge_cutoff": "2023-12-01", + "tuning": [ + "function", + "instruction" + ], + "providers": [ + { + "provider_id": "groq", + "model_id_on_provider": "llama-3.3-70b-versatile" + } + ] + }, + { + "model_id": "minimax-m2.1-highspeed", + "model_name": "MiniMax M2.1-highspeed", + "model_provider": "minimax", + "model_description": "High-speed MiniMax M2.1 variant for faster multilingual programming and agent workflows.", + "model_info": "https://platform.minimax.io/docs/guides/text-generation", + "model_type": "chat", + "context_window": 204800, + "max_tokens": 131072, + "cost_per_token": { + "input": "6e-7", + "output": 2.4e-06 + }, + "tuning": [ + "function", + "instruction", + "code", + "multilingual" + ], + "providers": [ + { + "provider_id": "minimax", + "model_id_on_provider": "MiniMax-M2.1-highspeed" + } + ] + }, + { + "model_id": "minimax-m2.1", + "model_name": "MiniMax M2.1", + "model_provider": "minimax", + "model_description": "MiniMax M2.1 model with strong multilingual programming and enhanced coding experience.", + "model_info": "https://platform.minimax.io/docs/guides/text-generation", + "model_type": "chat", + "context_window": 204800, + "max_tokens": 131072, + "cost_per_token": { + "input": "3e-7", + "output": 1.2e-06 + }, + "tuning": [ + "function", + "instruction", + "code", + "multilingual" + ], + "providers": [ + { + "provider_id": "minimax", + "model_id_on_provider": "MiniMax-M2.1" + }, + { + "provider_id": "openrouter", + "model_id_on_provider": "minimax/minimax-m2.1" + } + ] + }, + { + "model_id": "minimax-m2.5-highspeed", + "model_name": "MiniMax M2.5-highspeed", + "model_provider": "minimax", + "model_description": "High-speed MiniMax M2.5 variant for lower-latency coding and agent workloads.", + "model_info": "https://platform.minimax.io/docs/guides/text-generation", + "model_type": "chat", + "context_window": 204800, + "max_tokens": 131072, + "cost_per_token": { + "input": "6e-7", + "output": 2.4e-06 + }, + "tuning": [ + "function", + "instruction", + "code", + "multilingual" + ], + "providers": [ + { + "provider_id": "minimax", + "model_id_on_provider": "MiniMax-M2.5-highspeed" + } + ] + }, + { + "model_id": "minimax-m2.5", + "model_name": "MiniMax M2.5", + "model_provider": "minimax", + "model_description": "MiniMax M2.5 model for complex programming, agent, and productivity tasks.", + "model_info": "https://platform.minimax.io/docs/guides/text-generation", + "model_type": "chat", + "context_window": 204800, + "max_tokens": 131072, + "cost_per_token": { + "input": "3e-7", + "output": 1.2e-06 + }, + "tuning": [ + "function", + "instruction", + "code", + "multilingual" + ], + "providers": [ + { + "provider_id": "minimax", + "model_id_on_provider": "MiniMax-M2.5" + }, + { + "provider_id": "openrouter", + "model_id_on_provider": "minimax/minimax-m2.5" + } + ] + }, + { + "model_id": "minimax-m2.7-highspeed", + "model_name": "MiniMax M2.7-highspeed", + "model_provider": "minimax", + "model_description": "High-speed MiniMax M2.7 variant with the same capability profile and faster output for latency-sensitive workloads.", + "model_info": "https://platform.minimax.io/docs/guides/text-generation", + "model_type": "chat", + "context_window": 204800, + "max_tokens": 131072, + "cost_per_token": { + "input": "6e-7", + "output": 2.4e-06 + }, + "tuning": [ + "function", + "instruction", + "code", + "multilingual" + ], + "providers": [ + { + "provider_id": "minimax", + "model_id_on_provider": "MiniMax-M2.7-highspeed" + } + ] + }, + { + "model_id": "minimax-m2.7", + "model_name": "MiniMax M2.7", + "model_provider": "minimax", + "model_description": "Beginning the journey of recursive self-improvement. Strong for programming, tool calling, search, office productivity, and complex agent workflows.", + "model_info": "https://platform.minimax.io/docs/guides/text-generation", + "model_type": "chat", + "context_window": 204800, + "max_tokens": 131072, + "cost_per_token": { + "input": "3e-7", + "output": 1.2e-06 + }, + "tuning": [ + "function", + "instruction", + "code", + "multilingual" + ], + "providers": [ + { + "provider_id": "minimax", + "model_id_on_provider": "MiniMax-M2.7" + }, + { + "provider_id": "openrouter", + "model_id_on_provider": "minimax/minimax-m2.7" + } + ] + }, + { + "model_id": "minimax-m2", + "model_name": "MiniMax M2", + "model_provider": "minimax", + "model_description": "MiniMax M2 model for agentic workflows, advanced reasoning, function calling, and real-time streaming.", + "model_info": "https://platform.minimax.io/docs/guides/text-generation", + "model_type": "chat", + "context_window": 204800, + "max_tokens": 128000, + "cost_per_token": { + "input": "3e-7", + "output": 1.2e-06 + }, + "tuning": [ + "function", + "instruction", + "code", + "multilingual" + ], + "providers": [ + { + "provider_id": "minimax", + "model_id_on_provider": "MiniMax-M2" + }, + { + "provider_id": "openrouter", + "model_id_on_provider": "minimax/minimax-m2" + } + ] + }, + { + "model_id": "mistral-7b-instruct", + "model_name": "Mistral 7B Instruct", + "model_provider": "mistralai", + "model_description": "Mistral-7B fine-tuned on instruction datasets publicly available on HuggingFace.", + "model_info": "https://huggingface.co/mistralai/Mistral-7B-Instruct-v0.1", + "model_type": "chat", + "context_window": 8192, + "tuning": [ + "instruction" + ], + "deprecated": true, + "providers": [ + { + "provider_id": "mistralai", + "model_id_on_provider": "mistral-7b-instruct-0.3" + }, + { + "provider_id": "openrouter", + "model_id_on_provider": "mistralai/mistral-7b-instruct" + } + ] + }, + { + "model_id": "mistral-7b", + "model_name": "Mistral 7B", + "model_provider": "mistralai", + "model_description": "Mistral-7B-v0.1 is a small yet powerful model adaptable to many use-cases.", + "model_info": "https://mistral.ai/news/announcing-mistral-7b/", + "model_type": "chat", + "context_window": 8192, + "cost_per_token": 0, + "deprecated": true, + "providers": [ + { + "provider_id": "mistralai", + "model_id_on_provider": "open-mistral-7b" + }, + { + "provider_id": "openrouter", + "model_id_on_provider": "mistralai/mistral-7b" + } + ] + }, + { + "model_id": "mistral-large-2411", + "model_name": "Mistral Large 2.1", + "model_provider": "mistralai", + "model_description": "Versioned Mistral Large 2.1 model retained for integrations pinned to the 24.11 release.", + "model_info": "https://docs.mistral.ai/getting-started/models/models_overview/", + "model_type": "chat", + "context_window": 131072, + "max_tokens": 16384, + "cost_per_token": { + "input": 2e-06, + "output": 6e-06 + }, + "knowledge_cutoff": "2024-11-01", + "tokenizer": { + "family": "tekken" + }, + "tuning": [ + "function", + "instruction" + ], + "providers": [ + { + "provider_id": "mistralai", + "model_id_on_provider": "mistral-large-2411" + }, + { + "provider_id": "openrouter", + "model_id_on_provider": "mistralai/mistral-large-2411" + } + ] + }, + { + "model_id": "mistral-large-2512", + "model_name": "Mistral Large 3", + "model_provider": "mistralai", + "model_description": "Mistral Large 3 versioned model with long context and strong multimodal/coding capabilities.", + "model_info": "https://docs.mistral.ai/getting-started/models/models_overview/", + "model_type": "chat", + "context_window": 262144, + "max_tokens": 262144, + "cost_per_token": { + "input": "5e-7", + "output": 1.5e-06 + }, + "knowledge_cutoff": "2024-11-01", + "tokenizer": { + "family": "tekken" + }, + "tuning": [ + "multimodal", + "function", + "instruction" + ], + "providers": [ + { + "provider_id": "mistralai", + "model_id_on_provider": "mistral-large-2512" + }, + { + "provider_id": "openrouter", + "model_id_on_provider": "mistralai/mistral-large-2512" + } + ] + }, + { + "model_id": "mistral-large-latest", + "model_name": "Mistral Large (latest)", + "model_provider": "mistralai", + "model_description": "Mistral's current flagship alias for high-quality reasoning, coding, and multimodal workloads.", + "model_info": "https://docs.mistral.ai/getting-started/models/models_overview/", + "model_type": "chat", + "context_window": 262144, + "max_tokens": 262144, + "cost_per_token": { + "input": "5e-7", + "output": 1.5e-06 + }, + "knowledge_cutoff": "2024-11-01", + "tokenizer": { + "family": "tekken" + }, + "tuning": [ + "multimodal", + "function", + "instruction" + ], + "providers": [ + { + "provider_id": "mistralai", + "model_id_on_provider": "mistral-large-latest" + }, + { + "provider_id": "openrouter", + "model_id_on_provider": "mistralai/mistral-large-latest" + } + ] + }, + { + "model_id": "mistral-medium-latest", + "model_name": "Mistral Medium (latest)", + "model_provider": "mistralai", + "model_description": "Mistral's balanced mid-tier model for reasoning, coding, and multimodal workflows.", + "model_info": "https://docs.mistral.ai/getting-started/models/models_overview/", + "model_type": "chat", + "context_window": 128000, + "max_tokens": 16384, + "cost_per_token": { + "input": "4e-7", + "output": 2e-06 + }, + "knowledge_cutoff": "2025-05-01", + "tokenizer": { + "family": "tekken" + }, + "tuning": [ + "multimodal", + "function", + "instruction" + ], + "providers": [ + { + "provider_id": "mistralai", + "model_id_on_provider": "mistral-medium-latest" + }, + { + "provider_id": "openrouter", + "model_id_on_provider": "mistralai/mistral-medium-latest" + } + ] + }, + { + "model_id": "mistral-nemo", + "model_name": "Mistral Nemo", + "model_provider": "mistralai", + "model_description": "Open-weight Mistral Nemo model, useful for local or low-cost multilingual deployments.", + "model_info": "https://docs.mistral.ai/getting-started/models/models_overview/", + "model_type": "chat", + "context_window": 128000, + "max_tokens": 128000, + "cost_per_token": { + "input": 1.5e-07, + "output": 1.5e-07 + }, + "knowledge_cutoff": "2024-07-01", + "tokenizer": { + "family": "tekken" + }, + "tuning": [ + "function", + "instruction" + ], + "providers": [ + { + "provider_id": "mistralai", + "model_id_on_provider": "mistral-nemo" + }, + { + "provider_id": "openrouter", + "model_id_on_provider": "mistralai/mistral-nemo" + } + ] + }, + { + "model_id": "mistral-small-latest", + "model_name": "Mistral Small (latest)", + "model_provider": "mistralai", + "model_description": "Mistral's efficient small model alias for low-cost general-purpose and agentic workloads.", + "model_info": "https://docs.mistral.ai/getting-started/models/models_overview/", + "model_type": "chat", + "context_window": 256000, + "max_tokens": 256000, + "cost_per_token": { + "input": 1.5e-07, + "output": "6e-7" + }, + "knowledge_cutoff": "2025-06-01", + "tokenizer": { + "family": "tekken" + }, + "tuning": [ + "multimodal", + "function", + "instruction" + ], + "providers": [ + { + "provider_id": "mistralai", + "model_id_on_provider": "mistral-small-latest" + }, + { + "provider_id": "openrouter", + "model_id_on_provider": "mistralai/mistral-small-latest" + } + ] + }, + { + "model_id": "nemotron-3-super-120b-a12b", + "model_name": "Nemotron 3 Super", + "model_provider": "nvidia", + "model_description": "NVIDIA Nemotron 3 Super, an open-weight hybrid MoE model for agentic reasoning, tool use, and long-context workloads.", + "model_info": "https://docs.api.nvidia.com/nim/reference/nvidia-nemotron-3-super-120b-a12b", + "model_type": "chat", + "context_window": 262144, + "max_tokens": 262144, + "cost_per_token": { + "input": "2e-7", + "output": "8e-7" + }, + "knowledge_cutoff": "2024-04-01", + "tuning": [ + "function", + "instruction" + ], + "providers": [ + { + "provider_id": "nvidia", + "model_id_on_provider": "nvidia/nemotron-3-super-120b-a12b" + }, + { + "provider_id": "openrouter", + "model_id_on_provider": "nvidia/nemotron-3-super-120b-a12b" + }, + { + "provider_id": "cloudflare", + "model_id_on_provider": "@cf/nvidia/nemotron-3-120b-a12b" + } + ] + }, + { + "model_id": "o3", + "model_name": "o3", + "model_provider": "openai", + "model_description": "OpenAI reasoning model. Extended thinking model optimized for complex reasoning, science, and coding. Charges for reasoning tokens.", + "model_info": "https://platform.openai.com/docs/models/o3", + "model_type": "chat", + "context_window": 200000, + "cost_per_token": { + "input": 4e-06, + "output": 1.6e-05 + }, + "tokenizer": { + "family": "tiktoken", + "name": "o200k_base" + }, + "providers": [ + { + "provider_id": "openai", + "model_id_on_provider": "o3" + }, + { + "provider_id": "openrouter", + "model_id_on_provider": "openai/o3" + } + ] + }, + { + "model_id": "o4-mini", + "model_name": "o4 Mini", + "model_provider": "openai", + "model_description": "Lightweight OpenAI reasoning model. Fast and cost-efficient reasoning for simpler tasks.", + "model_info": "https://platform.openai.com/docs/models/o4-mini", + "model_type": "chat", + "context_window": 100000, + "cost_per_token": { + "input": 1e-06, + "output": 4e-06 + }, + "tokenizer": { + "family": "tiktoken", + "name": "o200k_base" + }, + "providers": [ + { + "provider_id": "openai", + "model_id_on_provider": "o4-mini" + }, + { + "provider_id": "openrouter", + "model_id_on_provider": "openai/o4-mini" + } + ] + }, + { + "model_id": "qwen3-32b", + "model_name": "Qwen3 32B", + "model_provider": "qwen", + "model_description": "Groq-hosted Qwen3 32B open-weight model for reasoning, code, and multilingual work.", + "model_info": "https://console.groq.com/docs/models", + "model_type": "chat", + "context_window": 131072, + "max_tokens": 40960, + "cost_per_token": { + "input": 2.9e-07, + "output": 5.9e-07 + }, + "knowledge_cutoff": "2024-11-08", + "tuning": [ + "function", + "instruction" + ], + "providers": [ + { + "provider_id": "groq", + "model_id_on_provider": "qwen/qwen3-32b" + }, + { + "provider_id": "qwen", + "model_id_on_provider": "qwen3-32b" + }, + { + "provider_id": "openrouter", + "model_id_on_provider": "qwen/qwen3-32b" + } + ] + }, + { + "model_id": "qwen3.6-flash", + "model_name": "Qwen 3.6 Flash", + "model_provider": "qwen", + "model_description": "Fast, efficient Qwen variant. Optimized for high-volume applications.", + "model_info": "https://qwen.io/docs", + "model_type": "chat", + "context_window": 1000000, + "cost_per_token": { + "input": 1e-07, + "output": 4e-07 + }, + "providers": [ + { + "provider_id": "qwen", + "model_id_on_provider": "qwen3.6-flash" + }, + { + "provider_id": "openrouter", + "model_id_on_provider": "qwen/qwen3.6-flash" + } + ] + }, + { + "model_id": "qwen3.6-plus", + "model_name": "Qwen 3.6 Plus", + "model_provider": "qwen", + "model_description": "Alibaba's flagship model. Strong multilingual and reasoning capabilities with large context support.", + "model_info": "https://qwen.io/docs", + "model_type": "chat", + "context_window": 1000000, + "cost_per_token": { + "input": 3.3e-07, + "output": 1.95e-06 + }, + "tuning": [ + "function" + ], + "providers": [ + { + "provider_id": "qwen", + "model_id_on_provider": "qwen3.6-plus" + }, + { + "provider_id": "openrouter", + "model_id_on_provider": "qwen/qwen3.6-plus" + } + ] + } +] diff --git a/packages/python/model_metadata/__init__.py b/packages/python/model_metadata_central/tests/__init__.py similarity index 100% rename from packages/python/model_metadata/__init__.py rename to packages/python/model_metadata_central/tests/__init__.py diff --git a/packages/python/model_metadata_central/tests/schema_test.py b/packages/python/model_metadata_central/tests/schema_test.py new file mode 100644 index 0000000..0748cd2 --- /dev/null +++ b/packages/python/model_metadata_central/tests/schema_test.py @@ -0,0 +1,19 @@ +import pytest + +from model_metadata_central import get_all_models, get_all_providers +from model_metadata_central.generated.models import ModelMetadata, ProviderMetadata + + +def test_all_models_validate_against_schema(): + for model in get_all_models(): + ModelMetadata.model_validate(model) + + +def test_all_providers_validate_against_schema(): + for provider in get_all_providers(): + ProviderMetadata.model_validate(provider) + + +def test_invalid_model_rejected(): + with pytest.raises(Exception): + ModelMetadata.model_validate({"model_id": "incomplete"}) diff --git a/packages/python/model_metadata_central/tests/utils_test.py b/packages/python/model_metadata_central/tests/utils_test.py new file mode 100644 index 0000000..b416ab3 --- /dev/null +++ b/packages/python/model_metadata_central/tests/utils_test.py @@ -0,0 +1,68 @@ +from model_metadata_central import ( + get_all_models, + get_all_providers, + get_model, + get_models_by_provider, + get_provider, + get_provider_model_id, +) +from model_metadata_central.utils.get_metadata_models import get_metadata_models +from model_metadata_central.utils.get_provider_ids import get_provider_ids +from model_metadata_central.utils.load_metadata import load_metadata +from model_metadata_central.utils.load_provider import load_provider + + +def test_load_metadata_known(): + m = load_metadata("gpt-3.5-turbo") + assert m is not None + assert m["model_id"] == "gpt-3.5-turbo" + assert m["model_type"] == "chat" + + +def test_load_metadata_unknown_returns_none(): + assert load_metadata("unknown-model") is None + + +def test_get_metadata_models_matches_registry(): + ids = get_metadata_models() + assert len(ids) == len(get_all_models()) + assert "gpt-4o" in ids + + +def test_get_model_round_trips(): + m = get_model("gpt-4o") + assert m is not None + assert m["context_window"] == 128000 + + +def test_get_models_by_provider_anthropic(): + anthropic_models = get_models_by_provider("anthropic") + assert len(anthropic_models) > 0 + assert all( + any(p["provider_id"] == "anthropic" for p in m.get("providers") or []) + for m in anthropic_models + ) + + +def test_load_provider_known(): + p = load_provider("openai") + assert p is not None + assert p["provider_id"] == "openai" + + +def test_load_provider_unknown_returns_none(): + assert load_provider("nonexistent") is None + + +def test_get_provider_ids_matches_registry(): + pids = get_provider_ids() + assert len(pids) == len(get_all_providers()) + assert "openai" in pids + + +def test_get_provider_model_id(): + assert get_provider_model_id("gpt-4o", "openai") == "gpt-4o" + + +def test_get_provider_model_id_unknown_model_returns_none(): + assert get_provider_model_id("does-not-exist", "openai") is None diff --git a/packages/python/model_metadata/tests/__init__.py b/packages/python/model_metadata_central/utils/__init__.py similarity index 100% rename from packages/python/model_metadata/tests/__init__.py rename to packages/python/model_metadata_central/utils/__init__.py diff --git a/packages/python/model_metadata_central/utils/exceptions.py b/packages/python/model_metadata_central/utils/exceptions.py new file mode 100644 index 0000000..a41db4d --- /dev/null +++ b/packages/python/model_metadata_central/utils/exceptions.py @@ -0,0 +1,6 @@ +class ModelMetadataNotFoundError(Exception): + """Raised when a model cannot be found in the registry.""" + + def __init__(self, model_id: str) -> None: + self.model_id = model_id + super().__init__(f"No metadata found for model: {model_id}") \ No newline at end of file diff --git a/packages/python/model_metadata_central/utils/get_metadata_models.py b/packages/python/model_metadata_central/utils/get_metadata_models.py new file mode 100644 index 0000000..1435b7f --- /dev/null +++ b/packages/python/model_metadata_central/utils/get_metadata_models.py @@ -0,0 +1,6 @@ +from model_metadata_central._registry import MODELS_BY_ID + + +def get_metadata_models() -> list[str]: + """Get all model_ids in the registry.""" + return list(MODELS_BY_ID.keys()) diff --git a/packages/python/model_metadata_central/utils/get_provider_ids.py b/packages/python/model_metadata_central/utils/get_provider_ids.py new file mode 100644 index 0000000..ffdcd16 --- /dev/null +++ b/packages/python/model_metadata_central/utils/get_provider_ids.py @@ -0,0 +1,6 @@ +from model_metadata_central._registry import PROVIDERS_BY_ID + + +def get_provider_ids() -> list[str]: + """Get all provider_ids in the registry.""" + return list(PROVIDERS_BY_ID.keys()) diff --git a/packages/python/model_metadata_central/utils/load_metadata.py b/packages/python/model_metadata_central/utils/load_metadata.py new file mode 100644 index 0000000..4ec6acc --- /dev/null +++ b/packages/python/model_metadata_central/utils/load_metadata.py @@ -0,0 +1,6 @@ +from model_metadata_central._registry import MODELS_BY_ID + + +def load_metadata(model_id: str) -> dict | None: + """Load model metadata from the bundled registry, or None if not found.""" + return MODELS_BY_ID.get(model_id) diff --git a/packages/python/model_metadata_central/utils/load_provider.py b/packages/python/model_metadata_central/utils/load_provider.py new file mode 100644 index 0000000..e5a106d --- /dev/null +++ b/packages/python/model_metadata_central/utils/load_provider.py @@ -0,0 +1,6 @@ +from model_metadata_central._registry import PROVIDERS_BY_ID + + +def load_provider(provider_id: str) -> dict | None: + """Load a provider definition by provider_id, or None if not found.""" + return PROVIDERS_BY_ID.get(provider_id) diff --git a/packages/python/poetry.lock b/packages/python/poetry.lock deleted file mode 100644 index d65b372..0000000 --- a/packages/python/poetry.lock +++ /dev/null @@ -1,624 +0,0 @@ -# This file is automatically @generated by Poetry 1.7.0 and should not be changed by hand. - -[[package]] -name = "attrs" -version = "23.1.0" -description = "Classes Without Boilerplate" -optional = false -python-versions = ">=3.7" -files = [ - {file = "attrs-23.1.0-py3-none-any.whl", hash = "sha256:1f28b4522cdc2fb4256ac1a020c78acf9cba2c6b461ccd2c126f3aa8e8335d04"}, - {file = "attrs-23.1.0.tar.gz", hash = "sha256:6279836d581513a26f1bf235f9acd333bc9115683f14f7e8fae46c98fc50e015"}, -] - -[package.extras] -cov = ["attrs[tests]", "coverage[toml] (>=5.3)"] -dev = ["attrs[docs,tests]", "pre-commit"] -docs = ["furo", "myst-parser", "sphinx", "sphinx-notfound-page", "sphinxcontrib-towncrier", "towncrier", "zope-interface"] -tests = ["attrs[tests-no-zope]", "zope-interface"] -tests-no-zope = ["cloudpickle", "hypothesis", "mypy (>=1.1.1)", "pympler", "pytest (>=4.3.0)", "pytest-mypy-plugins", "pytest-xdist[psutil]"] - -[[package]] -name = "black" -version = "23.11.0" -description = "The uncompromising code formatter." -optional = false -python-versions = ">=3.8" -files = [ - {file = "black-23.11.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:dbea0bb8575c6b6303cc65017b46351dc5953eea5c0a59d7b7e3a2d2f433a911"}, - {file = "black-23.11.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:412f56bab20ac85927f3a959230331de5614aecda1ede14b373083f62ec24e6f"}, - {file = "black-23.11.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d136ef5b418c81660ad847efe0e55c58c8208b77a57a28a503a5f345ccf01394"}, - {file = "black-23.11.0-cp310-cp310-win_amd64.whl", hash = "sha256:6c1cac07e64433f646a9a838cdc00c9768b3c362805afc3fce341af0e6a9ae9f"}, - {file = "black-23.11.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:cf57719e581cfd48c4efe28543fea3d139c6b6f1238b3f0102a9c73992cbb479"}, - {file = "black-23.11.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:698c1e0d5c43354ec5d6f4d914d0d553a9ada56c85415700b81dc90125aac244"}, - {file = "black-23.11.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:760415ccc20f9e8747084169110ef75d545f3b0932ee21368f63ac0fee86b221"}, - {file = "black-23.11.0-cp311-cp311-win_amd64.whl", hash = "sha256:58e5f4d08a205b11800332920e285bd25e1a75c54953e05502052738fe16b3b5"}, - {file = "black-23.11.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:45aa1d4675964946e53ab81aeec7a37613c1cb71647b5394779e6efb79d6d187"}, - {file = "black-23.11.0-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:4c44b7211a3a0570cc097e81135faa5f261264f4dfaa22bd5ee2875a4e773bd6"}, - {file = "black-23.11.0-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:2a9acad1451632021ee0d146c8765782a0c3846e0e0ea46659d7c4f89d9b212b"}, - {file = "black-23.11.0-cp38-cp38-win_amd64.whl", hash = "sha256:fc7f6a44d52747e65a02558e1d807c82df1d66ffa80a601862040a43ec2e3142"}, - {file = "black-23.11.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:7f622b6822f02bfaf2a5cd31fdb7cd86fcf33dab6ced5185c35f5db98260b055"}, - {file = "black-23.11.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:250d7e60f323fcfc8ea6c800d5eba12f7967400eb6c2d21ae85ad31c204fb1f4"}, - {file = "black-23.11.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:5133f5507007ba08d8b7b263c7aa0f931af5ba88a29beacc4b2dc23fcefe9c06"}, - {file = "black-23.11.0-cp39-cp39-win_amd64.whl", hash = "sha256:421f3e44aa67138ab1b9bfbc22ee3780b22fa5b291e4db8ab7eee95200726b07"}, - {file = "black-23.11.0-py3-none-any.whl", hash = "sha256:54caaa703227c6e0c87b76326d0862184729a69b73d3b7305b6288e1d830067e"}, - {file = "black-23.11.0.tar.gz", hash = "sha256:4c68855825ff432d197229846f971bc4d6666ce90492e5b02013bcaca4d9ab05"}, -] - -[package.dependencies] -click = ">=8.0.0" -mypy-extensions = ">=0.4.3" -packaging = ">=22.0" -pathspec = ">=0.9.0" -platformdirs = ">=2" -tomli = {version = ">=1.1.0", markers = "python_version < \"3.11\""} -typing-extensions = {version = ">=4.0.1", markers = "python_version < \"3.11\""} - -[package.extras] -colorama = ["colorama (>=0.4.3)"] -d = ["aiohttp (>=3.7.4)"] -jupyter = ["ipython (>=7.8.0)", "tokenize-rt (>=3.2.0)"] -uvloop = ["uvloop (>=0.15.2)"] - -[[package]] -name = "cfgv" -version = "3.4.0" -description = "Validate configuration and produce human readable error messages." -optional = false -python-versions = ">=3.8" -files = [ - {file = "cfgv-3.4.0-py2.py3-none-any.whl", hash = "sha256:b7265b1f29fd3316bfcd2b330d63d024f2bfd8bcb8b0272f8e19a504856c48f9"}, - {file = "cfgv-3.4.0.tar.gz", hash = "sha256:e52591d4c5f5dead8e0f673fb16db7949d2cfb3f7da4582893288f0ded8fe560"}, -] - -[[package]] -name = "click" -version = "8.1.7" -description = "Composable command line interface toolkit" -optional = false -python-versions = ">=3.7" -files = [ - {file = "click-8.1.7-py3-none-any.whl", hash = "sha256:ae74fb96c20a0277a1d615f1e4d73c8414f5a98db8b799a7931d1582f3390c28"}, - {file = "click-8.1.7.tar.gz", hash = "sha256:ca9853ad459e787e2192211578cc907e7594e294c7ccc834310722b41b9ca6de"}, -] - -[package.dependencies] -colorama = {version = "*", markers = "platform_system == \"Windows\""} - -[[package]] -name = "colorama" -version = "0.4.6" -description = "Cross-platform colored terminal text." -optional = false -python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,!=3.4.*,!=3.5.*,!=3.6.*,>=2.7" -files = [ - {file = "colorama-0.4.6-py2.py3-none-any.whl", hash = "sha256:4f1d9991f5acc0ca119f9d443620b77f9d6b33703e51011c16baf57afb285fc6"}, - {file = "colorama-0.4.6.tar.gz", hash = "sha256:08695f5cb7ed6e0531a20572697297273c47b8cae5a63ffc6d6ed5c201be6e44"}, -] - -[[package]] -name = "distlib" -version = "0.3.7" -description = "Distribution utilities" -optional = false -python-versions = "*" -files = [ - {file = "distlib-0.3.7-py2.py3-none-any.whl", hash = "sha256:2e24928bc811348f0feb63014e97aaae3037f2cf48712d51ae61df7fd6075057"}, - {file = "distlib-0.3.7.tar.gz", hash = "sha256:9dafe54b34a028eafd95039d5e5d4851a13734540f1331060d31c9916e7147a8"}, -] - -[[package]] -name = "exceptiongroup" -version = "1.1.3" -description = "Backport of PEP 654 (exception groups)" -optional = false -python-versions = ">=3.7" -files = [ - {file = "exceptiongroup-1.1.3-py3-none-any.whl", hash = "sha256:343280667a4585d195ca1cf9cef84a4e178c4b6cf2274caef9859782b567d5e3"}, - {file = "exceptiongroup-1.1.3.tar.gz", hash = "sha256:097acd85d473d75af5bb98e41b61ff7fe35efe6675e4f9370ec6ec5126d160e9"}, -] - -[package.extras] -test = ["pytest (>=6)"] - -[[package]] -name = "filelock" -version = "3.13.1" -description = "A platform independent file lock." -optional = false -python-versions = ">=3.8" -files = [ - {file = "filelock-3.13.1-py3-none-any.whl", hash = "sha256:57dbda9b35157b05fb3e58ee91448612eb674172fab98ee235ccb0b5bee19a1c"}, - {file = "filelock-3.13.1.tar.gz", hash = "sha256:521f5f56c50f8426f5e03ad3b281b490a87ef15bc6c526f168290f0c7148d44e"}, -] - -[package.extras] -docs = ["furo (>=2023.9.10)", "sphinx (>=7.2.6)", "sphinx-autodoc-typehints (>=1.24)"] -testing = ["covdefaults (>=2.3)", "coverage (>=7.3.2)", "diff-cover (>=8)", "pytest (>=7.4.3)", "pytest-cov (>=4.1)", "pytest-mock (>=3.12)", "pytest-timeout (>=2.2)"] -typing = ["typing-extensions (>=4.8)"] - -[[package]] -name = "identify" -version = "2.5.31" -description = "File identification library for Python" -optional = false -python-versions = ">=3.8" -files = [ - {file = "identify-2.5.31-py2.py3-none-any.whl", hash = "sha256:90199cb9e7bd3c5407a9b7e81b4abec4bb9d249991c79439ec8af740afc6293d"}, - {file = "identify-2.5.31.tar.gz", hash = "sha256:7736b3c7a28233637e3c36550646fc6389bedd74ae84cb788200cc8e2dd60b75"}, -] - -[package.extras] -license = ["ukkonen"] - -[[package]] -name = "importlib-resources" -version = "6.1.1" -description = "Read resources from Python packages" -optional = false -python-versions = ">=3.8" -files = [ - {file = "importlib_resources-6.1.1-py3-none-any.whl", hash = "sha256:e8bf90d8213b486f428c9c39714b920041cb02c184686a3dee24905aaa8105d6"}, - {file = "importlib_resources-6.1.1.tar.gz", hash = "sha256:3893a00122eafde6894c59914446a512f728a0c1a45f9bb9b63721b6bacf0b4a"}, -] - -[package.dependencies] -zipp = {version = ">=3.1.0", markers = "python_version < \"3.10\""} - -[package.extras] -docs = ["furo", "jaraco.packaging (>=9.3)", "jaraco.tidelift (>=1.4)", "rst.linker (>=1.9)", "sphinx (<7.2.5)", "sphinx (>=3.5)", "sphinx-lint"] -testing = ["pytest (>=6)", "pytest-black (>=0.3.7)", "pytest-checkdocs (>=2.4)", "pytest-cov", "pytest-enabler (>=2.2)", "pytest-mypy (>=0.9.1)", "pytest-ruff", "zipp (>=3.17)"] - -[[package]] -name = "iniconfig" -version = "2.0.0" -description = "brain-dead simple config-ini parsing" -optional = false -python-versions = ">=3.7" -files = [ - {file = "iniconfig-2.0.0-py3-none-any.whl", hash = "sha256:b6a85871a79d2e3b22d2d1b94ac2824226a63c6b741c88f7ae975f18b6778374"}, - {file = "iniconfig-2.0.0.tar.gz", hash = "sha256:2d91e135bf72d31a410b17c16da610a82cb55f6b0477d1a902134b24a455b8b3"}, -] - -[[package]] -name = "isort" -version = "5.12.0" -description = "A Python utility / library to sort Python imports." -optional = false -python-versions = ">=3.8.0" -files = [ - {file = "isort-5.12.0-py3-none-any.whl", hash = "sha256:f84c2818376e66cf843d497486ea8fed8700b340f308f076c6fb1229dff318b6"}, - {file = "isort-5.12.0.tar.gz", hash = "sha256:8bef7dde241278824a6d83f44a544709b065191b95b6e50894bdc722fcba0504"}, -] - -[package.extras] -colors = ["colorama (>=0.4.3)"] -pipfile-deprecated-finder = ["pip-shims (>=0.5.2)", "pipreqs", "requirementslib"] -plugins = ["setuptools"] -requirements-deprecated-finder = ["pip-api", "pipreqs"] - -[[package]] -name = "jsonschema" -version = "4.19.2" -description = "An implementation of JSON Schema validation for Python" -optional = false -python-versions = ">=3.8" -files = [ - {file = "jsonschema-4.19.2-py3-none-any.whl", hash = "sha256:eee9e502c788e89cb166d4d37f43084e3b64ab405c795c03d343a4dbc2c810fc"}, - {file = "jsonschema-4.19.2.tar.gz", hash = "sha256:c9ff4d7447eed9592c23a12ccee508baf0dd0d59650615e847feb6cdca74f392"}, -] - -[package.dependencies] -attrs = ">=22.2.0" -importlib-resources = {version = ">=1.4.0", markers = "python_version < \"3.9\""} -jsonschema-specifications = ">=2023.03.6" -pkgutil-resolve-name = {version = ">=1.3.10", markers = "python_version < \"3.9\""} -referencing = ">=0.28.4" -rpds-py = ">=0.7.1" - -[package.extras] -format = ["fqdn", "idna", "isoduration", "jsonpointer (>1.13)", "rfc3339-validator", "rfc3987", "uri-template", "webcolors (>=1.11)"] -format-nongpl = ["fqdn", "idna", "isoduration", "jsonpointer (>1.13)", "rfc3339-validator", "rfc3986-validator (>0.1.0)", "uri-template", "webcolors (>=1.11)"] - -[[package]] -name = "jsonschema-specifications" -version = "2023.7.1" -description = "The JSON Schema meta-schemas and vocabularies, exposed as a Registry" -optional = false -python-versions = ">=3.8" -files = [ - {file = "jsonschema_specifications-2023.7.1-py3-none-any.whl", hash = "sha256:05adf340b659828a004220a9613be00fa3f223f2b82002e273dee62fd50524b1"}, - {file = "jsonschema_specifications-2023.7.1.tar.gz", hash = "sha256:c91a50404e88a1f6ba40636778e2ee08f6e24c5613fe4c53ac24578a5a7f72bb"}, -] - -[package.dependencies] -importlib-resources = {version = ">=1.4.0", markers = "python_version < \"3.9\""} -referencing = ">=0.28.0" - -[[package]] -name = "mypy-extensions" -version = "1.0.0" -description = "Type system extensions for programs checked with the mypy type checker." -optional = false -python-versions = ">=3.5" -files = [ - {file = "mypy_extensions-1.0.0-py3-none-any.whl", hash = "sha256:4392f6c0eb8a5668a69e23d168ffa70f0be9ccfd32b5cc2d26a34ae5b844552d"}, - {file = "mypy_extensions-1.0.0.tar.gz", hash = "sha256:75dbf8955dc00442a438fc4d0666508a9a97b6bd41aa2f0ffe9d2f2725af0782"}, -] - -[[package]] -name = "nodeenv" -version = "1.8.0" -description = "Node.js virtual environment builder" -optional = false -python-versions = ">=2.7,!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,!=3.4.*,!=3.5.*,!=3.6.*" -files = [ - {file = "nodeenv-1.8.0-py2.py3-none-any.whl", hash = "sha256:df865724bb3c3adc86b3876fa209771517b0cfe596beff01a92700e0e8be4cec"}, - {file = "nodeenv-1.8.0.tar.gz", hash = "sha256:d51e0c37e64fbf47d017feac3145cdbb58836d7eee8c6f6d3b6880c5456227d2"}, -] - -[package.dependencies] -setuptools = "*" - -[[package]] -name = "packaging" -version = "23.2" -description = "Core utilities for Python packages" -optional = false -python-versions = ">=3.7" -files = [ - {file = "packaging-23.2-py3-none-any.whl", hash = "sha256:8c491190033a9af7e1d931d0b5dacc2ef47509b34dd0de67ed209b5203fc88c7"}, - {file = "packaging-23.2.tar.gz", hash = "sha256:048fb0e9405036518eaaf48a55953c750c11e1a1b68e0dd1a9d62ed0c092cfc5"}, -] - -[[package]] -name = "pathspec" -version = "0.11.2" -description = "Utility library for gitignore style pattern matching of file paths." -optional = false -python-versions = ">=3.7" -files = [ - {file = "pathspec-0.11.2-py3-none-any.whl", hash = "sha256:1d6ed233af05e679efb96b1851550ea95bbb64b7c490b0f5aa52996c11e92a20"}, - {file = "pathspec-0.11.2.tar.gz", hash = "sha256:e0d8d0ac2f12da61956eb2306b69f9469b42f4deb0f3cb6ed47b9cce9996ced3"}, -] - -[[package]] -name = "pkgutil-resolve-name" -version = "1.3.10" -description = "Resolve a name to an object." -optional = false -python-versions = ">=3.6" -files = [ - {file = "pkgutil_resolve_name-1.3.10-py3-none-any.whl", hash = "sha256:ca27cc078d25c5ad71a9de0a7a330146c4e014c2462d9af19c6b828280649c5e"}, - {file = "pkgutil_resolve_name-1.3.10.tar.gz", hash = "sha256:357d6c9e6a755653cfd78893817c0853af365dd51ec97f3d358a819373bbd174"}, -] - -[[package]] -name = "platformdirs" -version = "3.11.0" -description = "A small Python package for determining appropriate platform-specific dirs, e.g. a \"user data dir\"." -optional = false -python-versions = ">=3.7" -files = [ - {file = "platformdirs-3.11.0-py3-none-any.whl", hash = "sha256:e9d171d00af68be50e9202731309c4e658fd8bc76f55c11c7dd760d023bda68e"}, - {file = "platformdirs-3.11.0.tar.gz", hash = "sha256:cf8ee52a3afdb965072dcc652433e0c7e3e40cf5ea1477cd4b3b1d2eb75495b3"}, -] - -[package.extras] -docs = ["furo (>=2023.7.26)", "proselint (>=0.13)", "sphinx (>=7.1.1)", "sphinx-autodoc-typehints (>=1.24)"] -test = ["appdirs (==1.4.4)", "covdefaults (>=2.3)", "pytest (>=7.4)", "pytest-cov (>=4.1)", "pytest-mock (>=3.11.1)"] - -[[package]] -name = "pluggy" -version = "1.3.0" -description = "plugin and hook calling mechanisms for python" -optional = false -python-versions = ">=3.8" -files = [ - {file = "pluggy-1.3.0-py3-none-any.whl", hash = "sha256:d89c696a773f8bd377d18e5ecda92b7a3793cbe66c87060a6fb58c7b6e1061f7"}, - {file = "pluggy-1.3.0.tar.gz", hash = "sha256:cf61ae8f126ac6f7c451172cf30e3e43d3ca77615509771b3a984a0730651e12"}, -] - -[package.extras] -dev = ["pre-commit", "tox"] -testing = ["pytest", "pytest-benchmark"] - -[[package]] -name = "pre-commit" -version = "3.5.0" -description = "A framework for managing and maintaining multi-language pre-commit hooks." -optional = false -python-versions = ">=3.8" -files = [ - {file = "pre_commit-3.5.0-py2.py3-none-any.whl", hash = "sha256:841dc9aef25daba9a0238cd27984041fa0467b4199fc4852e27950664919f660"}, - {file = "pre_commit-3.5.0.tar.gz", hash = "sha256:5804465c675b659b0862f07907f96295d490822a450c4c40e747d0b1c6ebcb32"}, -] - -[package.dependencies] -cfgv = ">=2.0.0" -identify = ">=1.0.0" -nodeenv = ">=0.11.1" -pyyaml = ">=5.1" -virtualenv = ">=20.10.0" - -[[package]] -name = "pytest" -version = "7.4.3" -description = "pytest: simple powerful testing with Python" -optional = false -python-versions = ">=3.7" -files = [ - {file = "pytest-7.4.3-py3-none-any.whl", hash = "sha256:0d009c083ea859a71b76adf7c1d502e4bc170b80a8ef002da5806527b9591fac"}, - {file = "pytest-7.4.3.tar.gz", hash = "sha256:d989d136982de4e3b29dabcc838ad581c64e8ed52c11fbe86ddebd9da0818cd5"}, -] - -[package.dependencies] -colorama = {version = "*", markers = "sys_platform == \"win32\""} -exceptiongroup = {version = ">=1.0.0rc8", markers = "python_version < \"3.11\""} -iniconfig = "*" -packaging = "*" -pluggy = ">=0.12,<2.0" -tomli = {version = ">=1.0.0", markers = "python_version < \"3.11\""} - -[package.extras] -testing = ["argcomplete", "attrs (>=19.2.0)", "hypothesis (>=3.56)", "mock", "nose", "pygments (>=2.7.2)", "requests", "setuptools", "xmlschema"] - -[[package]] -name = "pyyaml" -version = "6.0.1" -description = "YAML parser and emitter for Python" -optional = false -python-versions = ">=3.6" -files = [ - {file = "PyYAML-6.0.1-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:d858aa552c999bc8a8d57426ed01e40bef403cd8ccdd0fc5f6f04a00414cac2a"}, - {file = "PyYAML-6.0.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:fd66fc5d0da6d9815ba2cebeb4205f95818ff4b79c3ebe268e75d961704af52f"}, - {file = "PyYAML-6.0.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:69b023b2b4daa7548bcfbd4aa3da05b3a74b772db9e23b982788168117739938"}, - {file = "PyYAML-6.0.1-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:81e0b275a9ecc9c0c0c07b4b90ba548307583c125f54d5b6946cfee6360c733d"}, - {file = "PyYAML-6.0.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ba336e390cd8e4d1739f42dfe9bb83a3cc2e80f567d8805e11b46f4a943f5515"}, - {file = "PyYAML-6.0.1-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:326c013efe8048858a6d312ddd31d56e468118ad4cdeda36c719bf5bb6192290"}, - {file = "PyYAML-6.0.1-cp310-cp310-win32.whl", hash = "sha256:bd4af7373a854424dabd882decdc5579653d7868b8fb26dc7d0e99f823aa5924"}, - {file = "PyYAML-6.0.1-cp310-cp310-win_amd64.whl", hash = "sha256:fd1592b3fdf65fff2ad0004b5e363300ef59ced41c2e6b3a99d4089fa8c5435d"}, - {file = "PyYAML-6.0.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:6965a7bc3cf88e5a1c3bd2e0b5c22f8d677dc88a455344035f03399034eb3007"}, - {file = "PyYAML-6.0.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:f003ed9ad21d6a4713f0a9b5a7a0a79e08dd0f221aff4525a2be4c346ee60aab"}, - {file = "PyYAML-6.0.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:42f8152b8dbc4fe7d96729ec2b99c7097d656dc1213a3229ca5383f973a5ed6d"}, - {file = "PyYAML-6.0.1-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:062582fca9fabdd2c8b54a3ef1c978d786e0f6b3a1510e0ac93ef59e0ddae2bc"}, - {file = "PyYAML-6.0.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d2b04aac4d386b172d5b9692e2d2da8de7bfb6c387fa4f801fbf6fb2e6ba4673"}, - {file = "PyYAML-6.0.1-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:e7d73685e87afe9f3b36c799222440d6cf362062f78be1013661b00c5c6f678b"}, - {file = "PyYAML-6.0.1-cp311-cp311-win32.whl", hash = "sha256:1635fd110e8d85d55237ab316b5b011de701ea0f29d07611174a1b42f1444741"}, - {file = "PyYAML-6.0.1-cp311-cp311-win_amd64.whl", hash = "sha256:bf07ee2fef7014951eeb99f56f39c9bb4af143d8aa3c21b1677805985307da34"}, - {file = "PyYAML-6.0.1-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:855fb52b0dc35af121542a76b9a84f8d1cd886ea97c84703eaa6d88e37a2ad28"}, - {file = "PyYAML-6.0.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:40df9b996c2b73138957fe23a16a4f0ba614f4c0efce1e9406a184b6d07fa3a9"}, - {file = "PyYAML-6.0.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6c22bec3fbe2524cde73d7ada88f6566758a8f7227bfbf93a408a9d86bcc12a0"}, - {file = "PyYAML-6.0.1-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:8d4e9c88387b0f5c7d5f281e55304de64cf7f9c0021a3525bd3b1c542da3b0e4"}, - {file = "PyYAML-6.0.1-cp312-cp312-win32.whl", hash = "sha256:d483d2cdf104e7c9fa60c544d92981f12ad66a457afae824d146093b8c294c54"}, - {file = "PyYAML-6.0.1-cp312-cp312-win_amd64.whl", hash = "sha256:0d3304d8c0adc42be59c5f8a4d9e3d7379e6955ad754aa9d6ab7a398b59dd1df"}, - {file = "PyYAML-6.0.1-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:50550eb667afee136e9a77d6dc71ae76a44df8b3e51e41b77f6de2932bfe0f47"}, - {file = "PyYAML-6.0.1-cp36-cp36m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1fe35611261b29bd1de0070f0b2f47cb6ff71fa6595c077e42bd0c419fa27b98"}, - {file = "PyYAML-6.0.1-cp36-cp36m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:704219a11b772aea0d8ecd7058d0082713c3562b4e271b849ad7dc4a5c90c13c"}, - {file = "PyYAML-6.0.1-cp36-cp36m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:afd7e57eddb1a54f0f1a974bc4391af8bcce0b444685d936840f125cf046d5bd"}, - {file = "PyYAML-6.0.1-cp36-cp36m-win32.whl", hash = "sha256:fca0e3a251908a499833aa292323f32437106001d436eca0e6e7833256674585"}, - {file = "PyYAML-6.0.1-cp36-cp36m-win_amd64.whl", hash = "sha256:f22ac1c3cac4dbc50079e965eba2c1058622631e526bd9afd45fedd49ba781fa"}, - {file = "PyYAML-6.0.1-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:b1275ad35a5d18c62a7220633c913e1b42d44b46ee12554e5fd39c70a243d6a3"}, - {file = "PyYAML-6.0.1-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:18aeb1bf9a78867dc38b259769503436b7c72f7a1f1f4c93ff9a17de54319b27"}, - {file = "PyYAML-6.0.1-cp37-cp37m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:596106435fa6ad000c2991a98fa58eeb8656ef2325d7e158344fb33864ed87e3"}, - {file = "PyYAML-6.0.1-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:baa90d3f661d43131ca170712d903e6295d1f7a0f595074f151c0aed377c9b9c"}, - {file = "PyYAML-6.0.1-cp37-cp37m-win32.whl", hash = "sha256:9046c58c4395dff28dd494285c82ba00b546adfc7ef001486fbf0324bc174fba"}, - {file = "PyYAML-6.0.1-cp37-cp37m-win_amd64.whl", hash = "sha256:4fb147e7a67ef577a588a0e2c17b6db51dda102c71de36f8549b6816a96e1867"}, - {file = "PyYAML-6.0.1-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:1d4c7e777c441b20e32f52bd377e0c409713e8bb1386e1099c2415f26e479595"}, - {file = "PyYAML-6.0.1-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a0cd17c15d3bb3fa06978b4e8958dcdc6e0174ccea823003a106c7d4d7899ac5"}, - {file = "PyYAML-6.0.1-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:28c119d996beec18c05208a8bd78cbe4007878c6dd15091efb73a30e90539696"}, - {file = "PyYAML-6.0.1-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7e07cbde391ba96ab58e532ff4803f79c4129397514e1413a7dc761ccd755735"}, - {file = "PyYAML-6.0.1-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:49a183be227561de579b4a36efbb21b3eab9651dd81b1858589f796549873dd6"}, - {file = "PyYAML-6.0.1-cp38-cp38-win32.whl", hash = "sha256:184c5108a2aca3c5b3d3bf9395d50893a7ab82a38004c8f61c258d4428e80206"}, - {file = "PyYAML-6.0.1-cp38-cp38-win_amd64.whl", hash = "sha256:1e2722cc9fbb45d9b87631ac70924c11d3a401b2d7f410cc0e3bbf249f2dca62"}, - {file = "PyYAML-6.0.1-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:9eb6caa9a297fc2c2fb8862bc5370d0303ddba53ba97e71f08023b6cd73d16a8"}, - {file = "PyYAML-6.0.1-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:c8098ddcc2a85b61647b2590f825f3db38891662cfc2fc776415143f599bb859"}, - {file = "PyYAML-6.0.1-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5773183b6446b2c99bb77e77595dd486303b4faab2b086e7b17bc6bef28865f6"}, - {file = "PyYAML-6.0.1-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:b786eecbdf8499b9ca1d697215862083bd6d2a99965554781d0d8d1ad31e13a0"}, - {file = "PyYAML-6.0.1-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bc1bf2925a1ecd43da378f4db9e4f799775d6367bdb94671027b73b393a7c42c"}, - {file = "PyYAML-6.0.1-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:04ac92ad1925b2cff1db0cfebffb6ffc43457495c9b3c39d3fcae417d7125dc5"}, - {file = "PyYAML-6.0.1-cp39-cp39-win32.whl", hash = "sha256:faca3bdcf85b2fc05d06ff3fbc1f83e1391b3e724afa3feba7d13eeab355484c"}, - {file = "PyYAML-6.0.1-cp39-cp39-win_amd64.whl", hash = "sha256:510c9deebc5c0225e8c96813043e62b680ba2f9c50a08d3724c7f28a747d1486"}, - {file = "PyYAML-6.0.1.tar.gz", hash = "sha256:bfdf460b1736c775f2ba9f6a92bca30bc2095067b8a9d77876d1fad6cc3b4a43"}, -] - -[[package]] -name = "referencing" -version = "0.30.2" -description = "JSON Referencing + Python" -optional = false -python-versions = ">=3.8" -files = [ - {file = "referencing-0.30.2-py3-none-any.whl", hash = "sha256:449b6669b6121a9e96a7f9e410b245d471e8d48964c67113ce9afe50c8dd7bdf"}, - {file = "referencing-0.30.2.tar.gz", hash = "sha256:794ad8003c65938edcdbc027f1933215e0d0ccc0291e3ce20a4d87432b59efc0"}, -] - -[package.dependencies] -attrs = ">=22.2.0" -rpds-py = ">=0.7.0" - -[[package]] -name = "rpds-py" -version = "0.12.0" -description = "Python bindings to Rust's persistent data structures (rpds)" -optional = false -python-versions = ">=3.8" -files = [ - {file = "rpds_py-0.12.0-cp310-cp310-macosx_10_7_x86_64.whl", hash = "sha256:c694bee70ece3b232df4678448fdda245fd3b1bb4ba481fb6cd20e13bb784c46"}, - {file = "rpds_py-0.12.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:30e5ce9f501fb1f970e4a59098028cf20676dee64fc496d55c33e04bbbee097d"}, - {file = "rpds_py-0.12.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d72a4315514e5a0b9837a086cb433b004eea630afb0cc129de76d77654a9606f"}, - {file = "rpds_py-0.12.0-cp310-cp310-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:eebaf8c76c39604d52852366249ab807fe6f7a3ffb0dd5484b9944917244cdbe"}, - {file = "rpds_py-0.12.0-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:a239303acb0315091d54c7ff36712dba24554993b9a93941cf301391d8a997ee"}, - {file = "rpds_py-0.12.0-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:ced40cdbb6dd47a032725a038896cceae9ce267d340f59508b23537f05455431"}, - {file = "rpds_py-0.12.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3c8c0226c71bd0ce9892eaf6afa77ae8f43a3d9313124a03df0b389c01f832de"}, - {file = "rpds_py-0.12.0-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:b8e11715178f3608874508f08e990d3771e0b8c66c73eb4e183038d600a9b274"}, - {file = "rpds_py-0.12.0-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:5210a0018c7e09c75fa788648617ebba861ae242944111d3079034e14498223f"}, - {file = "rpds_py-0.12.0-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:171d9a159f1b2f42a42a64a985e4ba46fc7268c78299272ceba970743a67ee50"}, - {file = "rpds_py-0.12.0-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:57ec6baec231bb19bb5fd5fc7bae21231860a1605174b11585660236627e390e"}, - {file = "rpds_py-0.12.0-cp310-none-win32.whl", hash = "sha256:7188ddc1a8887194f984fa4110d5a3d5b9b5cd35f6bafdff1b649049cbc0ce29"}, - {file = "rpds_py-0.12.0-cp310-none-win_amd64.whl", hash = "sha256:1e04581c6117ad9479b6cfae313e212fe0dfa226ac727755f0d539cd54792963"}, - {file = "rpds_py-0.12.0-cp311-cp311-macosx_10_7_x86_64.whl", hash = "sha256:0a38612d07a36138507d69646c470aedbfe2b75b43a4643f7bd8e51e52779624"}, - {file = "rpds_py-0.12.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:f12d69d568f5647ec503b64932874dade5a20255736c89936bf690951a5e79f5"}, - {file = "rpds_py-0.12.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4f8a1d990dc198a6c68ec3d9a637ba1ce489b38cbfb65440a27901afbc5df575"}, - {file = "rpds_py-0.12.0-cp311-cp311-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:8c567c664fc2f44130a20edac73e0a867f8e012bf7370276f15c6adc3586c37c"}, - {file = "rpds_py-0.12.0-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:0e9e976e0dbed4f51c56db10831c9623d0fd67aac02853fe5476262e5a22acb7"}, - {file = "rpds_py-0.12.0-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:efddca2d02254a52078c35cadad34762adbae3ff01c6b0c7787b59d038b63e0d"}, - {file = "rpds_py-0.12.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d9e7f29c00577aff6b318681e730a519b235af292732a149337f6aaa4d1c5e31"}, - {file = "rpds_py-0.12.0-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:389c0e38358fdc4e38e9995e7291269a3aead7acfcf8942010ee7bc5baee091c"}, - {file = "rpds_py-0.12.0-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:33ab498f9ac30598b6406e2be1b45fd231195b83d948ebd4bd77f337cb6a2bff"}, - {file = "rpds_py-0.12.0-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:d56b1cd606ba4cedd64bb43479d56580e147c6ef3f5d1c5e64203a1adab784a2"}, - {file = "rpds_py-0.12.0-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:1fa73ed22c40a1bec98d7c93b5659cd35abcfa5a0a95ce876b91adbda170537c"}, - {file = "rpds_py-0.12.0-cp311-none-win32.whl", hash = "sha256:dbc25baa6abb205766fb8606f8263b02c3503a55957fcb4576a6bb0a59d37d10"}, - {file = "rpds_py-0.12.0-cp311-none-win_amd64.whl", hash = "sha256:c6b52b7028b547866c2413f614ee306c2d4eafdd444b1ff656bf3295bf1484aa"}, - {file = "rpds_py-0.12.0-cp312-cp312-macosx_10_7_x86_64.whl", hash = "sha256:9620650c364c01ed5b497dcae7c3d4b948daeae6e1883ae185fef1c927b6b534"}, - {file = "rpds_py-0.12.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:2124f9e645a94ab7c853bc0a3644e0ca8ffbe5bb2d72db49aef8f9ec1c285733"}, - {file = "rpds_py-0.12.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:281c8b219d4f4b3581b918b816764098d04964915b2f272d1476654143801aa2"}, - {file = "rpds_py-0.12.0-cp312-cp312-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:27ccc93c7457ef890b0dd31564d2a05e1aca330623c942b7e818e9e7c2669ee4"}, - {file = "rpds_py-0.12.0-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:d1c562a9bb72244fa767d1c1ab55ca1d92dd5f7c4d77878fee5483a22ffac808"}, - {file = "rpds_py-0.12.0-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:e57919c32ee295a2fca458bb73e4b20b05c115627f96f95a10f9f5acbd61172d"}, - {file = "rpds_py-0.12.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:fa35ad36440aaf1ac8332b4a4a433d4acd28f1613f0d480995f5cfd3580e90b7"}, - {file = "rpds_py-0.12.0-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:e6aea5c0eb5b0faf52c7b5c4a47c8bb64437173be97227c819ffa31801fa4e34"}, - {file = "rpds_py-0.12.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:81cf9d306c04df1b45971c13167dc3bad625808aa01281d55f3cf852dde0e206"}, - {file = "rpds_py-0.12.0-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:08e6e7ff286254016b945e1ab632ee843e43d45e40683b66dd12b73791366dd1"}, - {file = "rpds_py-0.12.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:4d0a675a7acbbc16179188d8c6d0afb8628604fc1241faf41007255957335a0b"}, - {file = "rpds_py-0.12.0-cp312-none-win32.whl", hash = "sha256:b2287c09482949e0ca0c0eb68b2aca6cf57f8af8c6dfd29dcd3bc45f17b57978"}, - {file = "rpds_py-0.12.0-cp312-none-win_amd64.whl", hash = "sha256:8015835494b21aa7abd3b43fdea0614ee35ef6b03db7ecba9beb58eadf01c24f"}, - {file = "rpds_py-0.12.0-cp38-cp38-macosx_10_7_x86_64.whl", hash = "sha256:6174d6ad6b58a6bcf67afbbf1723420a53d06c4b89f4c50763d6fa0a6ac9afd2"}, - {file = "rpds_py-0.12.0-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:a689e1ded7137552bea36305a7a16ad2b40be511740b80748d3140614993db98"}, - {file = "rpds_py-0.12.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f45321224144c25a62052035ce96cbcf264667bcb0d81823b1bbc22c4addd194"}, - {file = "rpds_py-0.12.0-cp38-cp38-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:aa32205358a76bf578854bf31698a86dc8b2cb591fd1d79a833283f4a403f04b"}, - {file = "rpds_py-0.12.0-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:91bd2b7cf0f4d252eec8b7046fa6a43cee17e8acdfc00eaa8b3dbf2f9a59d061"}, - {file = "rpds_py-0.12.0-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:3acadbab8b59f63b87b518e09c4c64b142e7286b9ca7a208107d6f9f4c393c5c"}, - {file = "rpds_py-0.12.0-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:429349a510da82c85431f0f3e66212d83efe9fd2850f50f339341b6532c62fe4"}, - {file = "rpds_py-0.12.0-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:05942656cb2cb4989cd50ced52df16be94d344eae5097e8583966a1d27da73a5"}, - {file = "rpds_py-0.12.0-cp38-cp38-musllinux_1_2_aarch64.whl", hash = "sha256:0c5441b7626c29dbd54a3f6f3713ec8e956b009f419ffdaaa3c80eaf98ddb523"}, - {file = "rpds_py-0.12.0-cp38-cp38-musllinux_1_2_i686.whl", hash = "sha256:b6b0e17d39d21698185097652c611f9cf30f7c56ccec189789920e3e7f1cee56"}, - {file = "rpds_py-0.12.0-cp38-cp38-musllinux_1_2_x86_64.whl", hash = "sha256:3b7a64d43e2a1fa2dd46b678e00cabd9a49ebb123b339ce799204c44a593ae1c"}, - {file = "rpds_py-0.12.0-cp38-none-win32.whl", hash = "sha256:e5bbe011a2cea9060fef1bb3d668a2fd8432b8888e6d92e74c9c794d3c101595"}, - {file = "rpds_py-0.12.0-cp38-none-win_amd64.whl", hash = "sha256:bec29b801b4adbf388314c0d050e851d53762ab424af22657021ce4b6eb41543"}, - {file = "rpds_py-0.12.0-cp39-cp39-macosx_10_7_x86_64.whl", hash = "sha256:1096ca0bf2d3426cbe79d4ccc91dc5aaa73629b08ea2d8467375fad8447ce11a"}, - {file = "rpds_py-0.12.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:48aa98987d54a46e13e6954880056c204700c65616af4395d1f0639eba11764b"}, - {file = "rpds_py-0.12.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:7979d90ee2190d000129598c2b0c82f13053dba432b94e45e68253b09bb1f0f6"}, - {file = "rpds_py-0.12.0-cp39-cp39-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:88857060b690a57d2ea8569bca58758143c8faa4639fb17d745ce60ff84c867e"}, - {file = "rpds_py-0.12.0-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:4eb74d44776b0fb0782560ea84d986dffec8ddd94947f383eba2284b0f32e35e"}, - {file = "rpds_py-0.12.0-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:f62581d7e884dd01ee1707b7c21148f61f2febb7de092ae2f108743fcbef5985"}, - {file = "rpds_py-0.12.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6f5dcb658d597410bb7c967c1d24eaf9377b0d621358cbe9d2ff804e5dd12e81"}, - {file = "rpds_py-0.12.0-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:9bf9acce44e967a5103fcd820fc7580c7b0ab8583eec4e2051aec560f7b31a63"}, - {file = "rpds_py-0.12.0-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:240687b5be0f91fbde4936a329c9b7589d9259742766f74de575e1b2046575e4"}, - {file = "rpds_py-0.12.0-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:25740fb56e8bd37692ed380e15ec734be44d7c71974d8993f452b4527814601e"}, - {file = "rpds_py-0.12.0-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:a54917b7e9cd3a67e429a630e237a90b096e0ba18897bfb99ee8bd1068a5fea0"}, - {file = "rpds_py-0.12.0-cp39-none-win32.whl", hash = "sha256:b92aafcfab3d41580d54aca35a8057341f1cfc7c9af9e8bdfc652f83a20ced31"}, - {file = "rpds_py-0.12.0-cp39-none-win_amd64.whl", hash = "sha256:cd316dbcc74c76266ba94eb021b0cc090b97cca122f50bd7a845f587ff4bf03f"}, - {file = "rpds_py-0.12.0-pp310-pypy310_pp73-macosx_10_7_x86_64.whl", hash = "sha256:0853da3d5e9bc6a07b2486054a410b7b03f34046c123c6561b535bb48cc509e1"}, - {file = "rpds_py-0.12.0-pp310-pypy310_pp73-macosx_11_0_arm64.whl", hash = "sha256:cb41ad20064e18a900dd427d7cf41cfaec83bcd1184001f3d91a1f76b3fcea4e"}, - {file = "rpds_py-0.12.0-pp310-pypy310_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b710bf7e7ae61957d5c4026b486be593ed3ec3dca3e5be15e0f6d8cf5d0a4990"}, - {file = "rpds_py-0.12.0-pp310-pypy310_pp73-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:a952ae3eb460c6712388ac2ec706d24b0e651b9396d90c9a9e0a69eb27737fdc"}, - {file = "rpds_py-0.12.0-pp310-pypy310_pp73-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:0bedd91ae1dd142a4dc15970ed2c729ff6c73f33a40fa84ed0cdbf55de87c777"}, - {file = "rpds_py-0.12.0-pp310-pypy310_pp73-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:761531076df51309075133a6bc1db02d98ec7f66e22b064b1d513bc909f29743"}, - {file = "rpds_py-0.12.0-pp310-pypy310_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a2baa6be130e8a00b6cbb9f18a33611ec150b4537f8563bddadb54c1b74b8193"}, - {file = "rpds_py-0.12.0-pp310-pypy310_pp73-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:f05450fa1cd7c525c0b9d1a7916e595d3041ac0afbed2ff6926e5afb6a781b7f"}, - {file = "rpds_py-0.12.0-pp310-pypy310_pp73-musllinux_1_2_aarch64.whl", hash = "sha256:81c4d1a3a564775c44732b94135d06e33417e829ff25226c164664f4a1046213"}, - {file = "rpds_py-0.12.0-pp310-pypy310_pp73-musllinux_1_2_i686.whl", hash = "sha256:e888be685fa42d8b8a3d3911d5604d14db87538aa7d0b29b1a7ea80d354c732d"}, - {file = "rpds_py-0.12.0-pp310-pypy310_pp73-musllinux_1_2_x86_64.whl", hash = "sha256:6f8d7fe73d1816eeb5378409adc658f9525ecbfaf9e1ede1e2d67a338b0c7348"}, - {file = "rpds_py-0.12.0-pp38-pypy38_pp73-macosx_10_7_x86_64.whl", hash = "sha256:0831d3ecdea22e4559cc1793f22e77067c9d8c451d55ae6a75bf1d116a8e7f42"}, - {file = "rpds_py-0.12.0-pp38-pypy38_pp73-macosx_11_0_arm64.whl", hash = "sha256:513ccbf7420c30e283c25c82d5a8f439d625a838d3ba69e79a110c260c46813f"}, - {file = "rpds_py-0.12.0-pp38-pypy38_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:301bd744a1adaa2f6a5e06c98f1ac2b6f8dc31a5c23b838f862d65e32fca0d4b"}, - {file = "rpds_py-0.12.0-pp38-pypy38_pp73-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:f8832a4f83d4782a8f5a7b831c47e8ffe164e43c2c148c8160ed9a6d630bc02a"}, - {file = "rpds_py-0.12.0-pp38-pypy38_pp73-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:4b2416ed743ec5debcf61e1242e012652a4348de14ecc7df3512da072b074440"}, - {file = "rpds_py-0.12.0-pp38-pypy38_pp73-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:35585a8cb5917161f42c2104567bb83a1d96194095fc54a543113ed5df9fa436"}, - {file = "rpds_py-0.12.0-pp38-pypy38_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d389ff1e95b6e46ebedccf7fd1fadd10559add595ac6a7c2ea730268325f832c"}, - {file = "rpds_py-0.12.0-pp38-pypy38_pp73-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:9b007c2444705a2dc4a525964fd4dd28c3320b19b3410da6517cab28716f27d3"}, - {file = "rpds_py-0.12.0-pp38-pypy38_pp73-musllinux_1_2_aarch64.whl", hash = "sha256:188912b22b6c8225f4c4ffa020a2baa6ad8fabb3c141a12dbe6edbb34e7f1425"}, - {file = "rpds_py-0.12.0-pp38-pypy38_pp73-musllinux_1_2_i686.whl", hash = "sha256:1b4cf9ab9a0ae0cb122685209806d3f1dcb63b9fccdf1424fb42a129dc8c2faa"}, - {file = "rpds_py-0.12.0-pp38-pypy38_pp73-musllinux_1_2_x86_64.whl", hash = "sha256:2d34a5450a402b00d20aeb7632489ffa2556ca7b26f4a63c35f6fccae1977427"}, - {file = "rpds_py-0.12.0-pp39-pypy39_pp73-macosx_10_7_x86_64.whl", hash = "sha256:466030a42724780794dea71eb32db83cc51214d66ab3fb3156edd88b9c8f0d78"}, - {file = "rpds_py-0.12.0-pp39-pypy39_pp73-macosx_11_0_arm64.whl", hash = "sha256:68172622a5a57deb079a2c78511c40f91193548e8ab342c31e8cb0764d362459"}, - {file = "rpds_py-0.12.0-pp39-pypy39_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:54cdfcda59251b9c2f87a05d038c2ae02121219a04d4a1e6fc345794295bdc07"}, - {file = "rpds_py-0.12.0-pp39-pypy39_pp73-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:6b75b912a0baa033350367a8a07a8b2d44fd5b90c890bfbd063a8a5f945f644b"}, - {file = "rpds_py-0.12.0-pp39-pypy39_pp73-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:47aeceb4363851d17f63069318ba5721ae695d9da55d599b4d6fb31508595278"}, - {file = "rpds_py-0.12.0-pp39-pypy39_pp73-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:0525847f83f506aa1e28eb2057b696fe38217e12931c8b1b02198cfe6975e142"}, - {file = "rpds_py-0.12.0-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:efbe0b5e0fd078ed7b005faa0170da4f72666360f66f0bb2d7f73526ecfd99f9"}, - {file = "rpds_py-0.12.0-pp39-pypy39_pp73-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:0fadfdda275c838cba5102c7f90a20f2abd7727bf8f4a2b654a5b617529c5c18"}, - {file = "rpds_py-0.12.0-pp39-pypy39_pp73-musllinux_1_2_aarch64.whl", hash = "sha256:56dd500411d03c5e9927a1eb55621e906837a83b02350a9dc401247d0353717c"}, - {file = "rpds_py-0.12.0-pp39-pypy39_pp73-musllinux_1_2_i686.whl", hash = "sha256:6915fc9fa6b3ec3569566832e1bb03bd801c12cea030200e68663b9a87974e76"}, - {file = "rpds_py-0.12.0-pp39-pypy39_pp73-musllinux_1_2_x86_64.whl", hash = "sha256:5f1519b080d8ce0a814f17ad9fb49fb3a1d4d7ce5891f5c85fc38631ca3a8dc4"}, - {file = "rpds_py-0.12.0.tar.gz", hash = "sha256:7036316cc26b93e401cedd781a579be606dad174829e6ad9e9c5a0da6e036f80"}, -] - -[[package]] -name = "setuptools" -version = "68.2.2" -description = "Easily download, build, install, upgrade, and uninstall Python packages" -optional = false -python-versions = ">=3.8" -files = [ - {file = "setuptools-68.2.2-py3-none-any.whl", hash = "sha256:b454a35605876da60632df1a60f736524eb73cc47bbc9f3f1ef1b644de74fd2a"}, - {file = "setuptools-68.2.2.tar.gz", hash = "sha256:4ac1475276d2f1c48684874089fefcd83bd7162ddaafb81fac866ba0db282a87"}, -] - -[package.extras] -docs = ["furo", "jaraco.packaging (>=9.3)", "jaraco.tidelift (>=1.4)", "pygments-github-lexers (==0.0.5)", "rst.linker (>=1.9)", "sphinx (>=3.5)", "sphinx-favicon", "sphinx-hoverxref (<2)", "sphinx-inline-tabs", "sphinx-lint", "sphinx-notfound-page (>=1,<2)", "sphinx-reredirects", "sphinxcontrib-towncrier"] -testing = ["build[virtualenv]", "filelock (>=3.4.0)", "flake8-2020", "ini2toml[lite] (>=0.9)", "jaraco.develop (>=7.21)", "jaraco.envs (>=2.2)", "jaraco.path (>=3.2.0)", "pip (>=19.1)", "pytest (>=6)", "pytest-black (>=0.3.7)", "pytest-checkdocs (>=2.4)", "pytest-cov", "pytest-enabler (>=2.2)", "pytest-mypy (>=0.9.1)", "pytest-perf", "pytest-ruff", "pytest-timeout", "pytest-xdist", "tomli-w (>=1.0.0)", "virtualenv (>=13.0.0)", "wheel"] -testing-integration = ["build[virtualenv] (>=1.0.3)", "filelock (>=3.4.0)", "jaraco.envs (>=2.2)", "jaraco.path (>=3.2.0)", "packaging (>=23.1)", "pytest", "pytest-enabler", "pytest-xdist", "tomli", "virtualenv (>=13.0.0)", "wheel"] - -[[package]] -name = "tomli" -version = "2.0.1" -description = "A lil' TOML parser" -optional = false -python-versions = ">=3.7" -files = [ - {file = "tomli-2.0.1-py3-none-any.whl", hash = "sha256:939de3e7a6161af0c887ef91b7d41a53e7c5a1ca976325f429cb46ea9bc30ecc"}, - {file = "tomli-2.0.1.tar.gz", hash = "sha256:de526c12914f0c550d15924c62d72abc48d6fe7364aa87328337a31007fe8a4f"}, -] - -[[package]] -name = "typing-extensions" -version = "4.8.0" -description = "Backported and Experimental Type Hints for Python 3.8+" -optional = false -python-versions = ">=3.8" -files = [ - {file = "typing_extensions-4.8.0-py3-none-any.whl", hash = "sha256:8f92fc8806f9a6b641eaa5318da32b44d401efaac0f6678c9bc448ba3605faa0"}, - {file = "typing_extensions-4.8.0.tar.gz", hash = "sha256:df8e4339e9cb77357558cbdbceca33c303714cf861d1eef15e1070055ae8b7ef"}, -] - -[[package]] -name = "virtualenv" -version = "20.24.6" -description = "Virtual Python Environment builder" -optional = false -python-versions = ">=3.7" -files = [ - {file = "virtualenv-20.24.6-py3-none-any.whl", hash = "sha256:520d056652454c5098a00c0f073611ccbea4c79089331f60bf9d7ba247bb7381"}, - {file = "virtualenv-20.24.6.tar.gz", hash = "sha256:02ece4f56fbf939dbbc33c0715159951d6bf14aaf5457b092e4548e1382455af"}, -] - -[package.dependencies] -distlib = ">=0.3.7,<1" -filelock = ">=3.12.2,<4" -platformdirs = ">=3.9.1,<4" - -[package.extras] -docs = ["furo (>=2023.7.26)", "proselint (>=0.13)", "sphinx (>=7.1.2)", "sphinx-argparse (>=0.4)", "sphinxcontrib-towncrier (>=0.2.1a0)", "towncrier (>=23.6)"] -test = ["covdefaults (>=2.3)", "coverage (>=7.2.7)", "coverage-enable-subprocess (>=1)", "flaky (>=3.7)", "packaging (>=23.1)", "pytest (>=7.4)", "pytest-env (>=0.8.2)", "pytest-freezer (>=0.4.8)", "pytest-mock (>=3.11.1)", "pytest-randomly (>=3.12)", "pytest-timeout (>=2.1)", "setuptools (>=68)", "time-machine (>=2.10)"] - -[[package]] -name = "zipp" -version = "3.17.0" -description = "Backport of pathlib-compatible object wrapper for zip files" -optional = false -python-versions = ">=3.8" -files = [ - {file = "zipp-3.17.0-py3-none-any.whl", hash = "sha256:0e923e726174922dce09c53c59ad483ff7bbb8e572e00c7f7c46b88556409f31"}, - {file = "zipp-3.17.0.tar.gz", hash = "sha256:84e64a1c28cf7e91ed2078bb8cc8c259cb19b76942096c8d7b84947690cabaf0"}, -] - -[package.extras] -docs = ["furo", "jaraco.packaging (>=9.3)", "jaraco.tidelift (>=1.4)", "rst.linker (>=1.9)", "sphinx (<7.2.5)", "sphinx (>=3.5)", "sphinx-lint"] -testing = ["big-O", "jaraco.functools", "jaraco.itertools", "more-itertools", "pytest (>=6)", "pytest-black (>=0.3.7)", "pytest-checkdocs (>=2.4)", "pytest-cov", "pytest-enabler (>=2.2)", "pytest-ignore-flaky", "pytest-mypy (>=0.9.1)", "pytest-ruff"] - -[metadata] -lock-version = "2.0" -python-versions = ">=3.8" -content-hash = "78eba4272528cd5b23c0721cdc2470cb3a8d3589338e257697c21f4ec757e768" diff --git a/packages/python/pyproject.toml b/packages/python/pyproject.toml index 94bfbca..86b8a18 100644 --- a/packages/python/pyproject.toml +++ b/packages/python/pyproject.toml @@ -1,40 +1,55 @@ -[tool.poetry] -name = "model_metadata" +[project] +name = "model-metadata-central" version = "0.1.0" -description = "Model Metadata Central" +description = "Typed registry of LLM model metadata for Python — context windows, pricing, provider routing." +readme = "README.md" +license = "MIT" authors = [ - "Eric Allen " + { name = "Eric Allen", email = "era@lakera.ai" } ] -license = "MIT" -readme = "README.md" -homepage = "https://github.com/InterwebAlchemy/model-metadata-central" -repository = "https://github.com/InterwebAlchemy/model-metadata-central" -keywords = ["llm", "language model", "metadata", "openai"] -packages = [ - { include = "model_metadata" } +requires-python = ">=3.10" +dependencies = [ + "pydantic>=2.0,<3", + "pyyaml>=6.0,<7", +] +keywords = ["llm", "language model", "metadata", "openai", "anthropic", "pricing", "context-window"] +classifiers = [ + "Development Status :: 4 - Beta", + "Intended Audience :: Developers", + "License :: OSI Approved :: MIT License", + "Programming Language :: Python :: 3", + "Programming Language :: Python :: 3.10", + "Programming Language :: Python :: 3.11", + "Programming Language :: Python :: 3.12", + "Programming Language :: Python :: 3.13", + "Topic :: Software Development :: Libraries", ] -[tool.poetry.dependencies] -python = ">=3.8" -pyyaml = "^6.0.1" +[project.urls] +Homepage = "https://github.com/InterwebAlchemy/model-metadata-central" +Repository = "https://github.com/InterwebAlchemy/model-metadata-central" +Issues = "https://github.com/InterwebAlchemy/model-metadata-central/issues" -[tool.poetry.group.test.dependencies] -pytest = "^7.4.3" +[build-system] +requires = ["hatchling"] +build-backend = "hatchling.build" -[tool.poetry.group.dev.dependencies] -black = "^23.11.0" -isort = "^5.12.0" -pre-commit = "^3.5.0" -jsonschema = "^4.19.2" +[tool.hatch.build.targets.wheel] +packages = ["model_metadata_central"] -[build-system] -requires = ["poetry-core>=1.0.0"] -build-backend = "poetry.core.masonry.api" +[dependency-groups] +dev = [ + "black>=23.11.0", + "isort>=5.12.0", + "jsonschema>=4.19.2", + "pre-commit>=3.5.0", + "pytest>=7.4.3", +] [tool.black] -target-version = ['py311'] +target-version = ["py311"] [tool.isort] profile = "black" multi_line_output = 3 -include_trailing_comma = true \ No newline at end of file +include_trailing_comma = true diff --git a/packages/python/scripts/build_registry.py b/packages/python/scripts/build_registry.py new file mode 100644 index 0000000..8cc6ed6 --- /dev/null +++ b/packages/python/scripts/build_registry.py @@ -0,0 +1,37 @@ +"""Bundle models/*.yaml + providers/*.yaml into registry.json + providers.json +inside the package, mirroring the TypeScript build-registry step. + +Run via `uv run python scripts/build_registry.py`. +""" +import json +from pathlib import Path + +import yaml + +HERE = Path(__file__).resolve().parent +PKG_DIR = HERE.parent / "model_metadata_central" +REPO_ROOT = HERE.parent.parent.parent + +MODELS_DIR = REPO_ROOT / "models" +PROVIDERS_DIR = REPO_ROOT / "providers" + + +def load_yaml_dir(directory: Path) -> list[dict]: + return [ + yaml.safe_load(p.read_text()) + for p in sorted(directory.glob("*.yaml")) + ] + + +def main() -> None: + models = load_yaml_dir(MODELS_DIR) + providers = load_yaml_dir(PROVIDERS_DIR) + + (PKG_DIR / "registry.json").write_text(json.dumps(models, indent=2) + "\n") + (PKG_DIR / "providers.json").write_text(json.dumps(providers, indent=2) + "\n") + + print(f"Wrote {len(models)} models, {len(providers)} providers") + + +if __name__ == "__main__": + main() diff --git a/packages/python/uv.lock b/packages/python/uv.lock new file mode 100644 index 0000000..8c04c4c --- /dev/null +++ b/packages/python/uv.lock @@ -0,0 +1,783 @@ +version = 1 +revision = 3 +requires-python = ">=3.10" + +[[package]] +name = "annotated-types" +version = "0.7.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/ee/67/531ea369ba64dcff5ec9c3402f9f51bf748cec26dde048a2f973a4eea7f5/annotated_types-0.7.0.tar.gz", hash = "sha256:aff07c09a53a08bc8cfccb9c85b05f1aa9a2a6f23728d790723543408344ce89", size = 16081, upload-time = "2024-05-20T21:33:25.928Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/78/b6/6307fbef88d9b5ee7421e68d78a9f162e0da4900bc5f5793f6d3d0e34fb8/annotated_types-0.7.0-py3-none-any.whl", hash = "sha256:1f02e8b43a8fbbc3f3e0d4f0f4bfc8131bcb4eebe8849b8e5c773f3a1c582a53", size = 13643, upload-time = "2024-05-20T21:33:24.1Z" }, +] + +[[package]] +name = "attrs" +version = "26.1.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/9a/8e/82a0fe20a541c03148528be8cac2408564a6c9a0cc7e9171802bc1d26985/attrs-26.1.0.tar.gz", hash = "sha256:d03ceb89cb322a8fd706d4fb91940737b6642aa36998fe130a9bc96c985eff32", size = 952055, upload-time = "2026-03-19T14:22:25.026Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/64/b4/17d4b0b2a2dc85a6df63d1157e028ed19f90d4cd97c36717afef2bc2f395/attrs-26.1.0-py3-none-any.whl", hash = "sha256:c647aa4a12dfbad9333ca4e71fe62ddc36f4e63b2d260a37a8b83d2f043ac309", size = 67548, upload-time = "2026-03-19T14:22:23.645Z" }, +] + +[[package]] +name = "black" +version = "26.3.1" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "click" }, + { name = "mypy-extensions" }, + { name = "packaging" }, + { name = "pathspec" }, + { name = "platformdirs" }, + { name = "pytokens" }, + { name = "tomli", marker = "python_full_version < '3.11'" }, + { name = "typing-extensions", marker = "python_full_version < '3.11'" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/e1/c5/61175d618685d42b005847464b8fb4743a67b1b8fdb75e50e5a96c31a27a/black-26.3.1.tar.gz", hash = "sha256:2c50f5063a9641c7eed7795014ba37b0f5fa227f3d408b968936e24bc0566b07", size = 666155, upload-time = "2026-03-12T03:36:03.593Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/32/a8/11170031095655d36ebc6664fe0897866f6023892396900eec0e8fdc4299/black-26.3.1-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:86a8b5035fce64f5dcd1b794cf8ec4d31fe458cf6ce3986a30deb434df82a1d2", size = 1866562, upload-time = "2026-03-12T03:39:58.639Z" }, + { url = "https://files.pythonhosted.org/packages/69/ce/9e7548d719c3248c6c2abfd555d11169457cbd584d98d179111338423790/black-26.3.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:5602bdb96d52d2d0672f24f6ffe5218795736dd34807fd0fd55ccd6bf206168b", size = 1703623, upload-time = "2026-03-12T03:40:00.347Z" }, + { url = "https://files.pythonhosted.org/packages/7f/0a/8d17d1a9c06f88d3d030d0b1d4373c1551146e252afe4547ed601c0e697f/black-26.3.1-cp310-cp310-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:6c54a4a82e291a1fee5137371ab488866b7c86a3305af4026bdd4dc78642e1ac", size = 1768388, upload-time = "2026-03-12T03:40:01.765Z" }, + { url = "https://files.pythonhosted.org/packages/52/79/c1ee726e221c863cde5164f925bacf183dfdf0397d4e3f94889439b947b4/black-26.3.1-cp310-cp310-win_amd64.whl", hash = "sha256:6e131579c243c98f35bce64a7e08e87fb2d610544754675d4a0e73a070a5aa3a", size = 1412969, upload-time = "2026-03-12T03:40:03.252Z" }, + { url = "https://files.pythonhosted.org/packages/73/a5/15c01d613f5756f68ed8f6d4ec0a1e24b82b18889fa71affd3d1f7fad058/black-26.3.1-cp310-cp310-win_arm64.whl", hash = "sha256:5ed0ca58586c8d9a487352a96b15272b7fa55d139fc8496b519e78023a8dab0a", size = 1220345, upload-time = "2026-03-12T03:40:04.892Z" }, + { url = "https://files.pythonhosted.org/packages/17/57/5f11c92861f9c92eb9dddf515530bc2d06db843e44bdcf1c83c1427824bc/black-26.3.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:28ef38aee69e4b12fda8dba75e21f9b4f979b490c8ac0baa7cb505369ac9e1ff", size = 1851987, upload-time = "2026-03-12T03:40:06.248Z" }, + { url = "https://files.pythonhosted.org/packages/54/aa/340a1463660bf6831f9e39646bf774086dbd8ca7fc3cded9d59bbdf4ad0a/black-26.3.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:bf9bf162ed91a26f1adba8efda0b573bc6924ec1408a52cc6f82cb73ec2b142c", size = 1689499, upload-time = "2026-03-12T03:40:07.642Z" }, + { url = "https://files.pythonhosted.org/packages/f3/01/b726c93d717d72733da031d2de10b92c9fa4c8d0c67e8a8a372076579279/black-26.3.1-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:474c27574d6d7037c1bc875a81d9be0a9a4f9ee95e62800dab3cfaadbf75acd5", size = 1754369, upload-time = "2026-03-12T03:40:09.279Z" }, + { url = "https://files.pythonhosted.org/packages/e3/09/61e91881ca291f150cfc9eb7ba19473c2e59df28859a11a88248b5cbbc4d/black-26.3.1-cp311-cp311-win_amd64.whl", hash = "sha256:5e9d0d86df21f2e1677cc4bd090cd0e446278bcbbe49bf3659c308c3e402843e", size = 1413613, upload-time = "2026-03-12T03:40:10.943Z" }, + { url = "https://files.pythonhosted.org/packages/16/73/544f23891b22e7efe4d8f812371ab85b57f6a01b2fc45e3ba2e52ba985b8/black-26.3.1-cp311-cp311-win_arm64.whl", hash = "sha256:9a5e9f45e5d5e1c5b5c29b3bd4265dcc90e8b92cf4534520896ed77f791f4da5", size = 1219719, upload-time = "2026-03-12T03:40:12.597Z" }, + { url = "https://files.pythonhosted.org/packages/dc/f8/da5eae4fc75e78e6dceb60624e1b9662ab00d6b452996046dfa9b8a6025b/black-26.3.1-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:b5e6f89631eb88a7302d416594a32faeee9fb8fb848290da9d0a5f2903519fc1", size = 1895920, upload-time = "2026-03-12T03:40:13.921Z" }, + { url = "https://files.pythonhosted.org/packages/2c/9f/04e6f26534da2e1629b2b48255c264cabf5eedc5141d04516d9d68a24111/black-26.3.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:41cd2012d35b47d589cb8a16faf8a32ef7a336f56356babd9fcf70939ad1897f", size = 1718499, upload-time = "2026-03-12T03:40:15.239Z" }, + { url = "https://files.pythonhosted.org/packages/04/91/a5935b2a63e31b331060c4a9fdb5a6c725840858c599032a6f3aac94055f/black-26.3.1-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:0f76ff19ec5297dd8e66eb64deda23631e642c9393ab592826fd4bdc97a4bce7", size = 1794994, upload-time = "2026-03-12T03:40:17.124Z" }, + { url = "https://files.pythonhosted.org/packages/e7/0a/86e462cdd311a3c2a8ece708d22aba17d0b2a0d5348ca34b40cdcbea512e/black-26.3.1-cp312-cp312-win_amd64.whl", hash = "sha256:ddb113db38838eb9f043623ba274cfaf7d51d5b0c22ecb30afe58b1bb8322983", size = 1420867, upload-time = "2026-03-12T03:40:18.83Z" }, + { url = "https://files.pythonhosted.org/packages/5b/e5/22515a19cb7eaee3440325a6b0d95d2c0e88dd180cb011b12ae488e031d1/black-26.3.1-cp312-cp312-win_arm64.whl", hash = "sha256:dfdd51fc3e64ea4f35873d1b3fb25326773d55d2329ff8449139ebaad7357efb", size = 1230124, upload-time = "2026-03-12T03:40:20.425Z" }, + { url = "https://files.pythonhosted.org/packages/f5/77/5728052a3c0450c53d9bb3945c4c46b91baa62b2cafab6801411b6271e45/black-26.3.1-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:855822d90f884905362f602880ed8b5df1b7e3ee7d0db2502d4388a954cc8c54", size = 1895034, upload-time = "2026-03-12T03:40:21.813Z" }, + { url = "https://files.pythonhosted.org/packages/52/73/7cae55fdfdfbe9d19e9a8d25d145018965fe2079fa908101c3733b0c55a0/black-26.3.1-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:8a33d657f3276328ce00e4d37fe70361e1ec7614da5d7b6e78de5426cb56332f", size = 1718503, upload-time = "2026-03-12T03:40:23.666Z" }, + { url = "https://files.pythonhosted.org/packages/e1/87/af89ad449e8254fdbc74654e6467e3c9381b61472cc532ee350d28cfdafb/black-26.3.1-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:f1cd08e99d2f9317292a311dfe578fd2a24b15dbce97792f9c4d752275c1fa56", size = 1793557, upload-time = "2026-03-12T03:40:25.497Z" }, + { url = "https://files.pythonhosted.org/packages/43/10/d6c06a791d8124b843bf325ab4ac7d2f5b98731dff84d6064eafd687ded1/black-26.3.1-cp313-cp313-win_amd64.whl", hash = "sha256:c7e72339f841b5a237ff14f7d3880ddd0fc7f98a1199e8c4327f9a4f478c1839", size = 1422766, upload-time = "2026-03-12T03:40:27.14Z" }, + { url = "https://files.pythonhosted.org/packages/59/4f/40a582c015f2d841ac24fed6390bd68f0fc896069ff3a886317959c9daf8/black-26.3.1-cp313-cp313-win_arm64.whl", hash = "sha256:afc622538b430aa4c8c853f7f63bc582b3b8030fd8c80b70fb5fa5b834e575c2", size = 1232140, upload-time = "2026-03-12T03:40:28.882Z" }, + { url = "https://files.pythonhosted.org/packages/d5/da/e36e27c9cebc1311b7579210df6f1c86e50f2d7143ae4fcf8a5017dc8809/black-26.3.1-cp314-cp314-macosx_10_15_x86_64.whl", hash = "sha256:2d6bfaf7fd0993b420bed691f20f9492d53ce9a2bcccea4b797d34e947318a78", size = 1889234, upload-time = "2026-03-12T03:40:30.964Z" }, + { url = "https://files.pythonhosted.org/packages/0e/7b/9871acf393f64a5fa33668c19350ca87177b181f44bb3d0c33b2d534f22c/black-26.3.1-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:f89f2ab047c76a9c03f78d0d66ca519e389519902fa27e7a91117ef7611c0568", size = 1720522, upload-time = "2026-03-12T03:40:32.346Z" }, + { url = "https://files.pythonhosted.org/packages/03/87/e766c7f2e90c07fb7586cc787c9ae6462b1eedab390191f2b7fc7f6170a9/black-26.3.1-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:b07fc0dab849d24a80a29cfab8d8a19187d1c4685d8a5e6385a5ce323c1f015f", size = 1787824, upload-time = "2026-03-12T03:40:33.636Z" }, + { url = "https://files.pythonhosted.org/packages/ac/94/2424338fb2d1875e9e83eed4c8e9c67f6905ec25afd826a911aea2b02535/black-26.3.1-cp314-cp314-win_amd64.whl", hash = "sha256:0126ae5b7c09957da2bdbd91a9ba1207453feada9e9fe51992848658c6c8e01c", size = 1445855, upload-time = "2026-03-12T03:40:35.442Z" }, + { url = "https://files.pythonhosted.org/packages/86/43/0c3338bd928afb8ee7471f1a4eec3bdbe2245ccb4a646092a222e8669840/black-26.3.1-cp314-cp314-win_arm64.whl", hash = "sha256:92c0ec1f2cc149551a2b7b47efc32c866406b6891b0ee4625e95967c8f4acfb1", size = 1258109, upload-time = "2026-03-12T03:40:36.832Z" }, + { url = "https://files.pythonhosted.org/packages/8e/0d/52d98722666d6fc6c3dd4c76df339501d6efd40e0ff95e6186a7b7f0befd/black-26.3.1-py3-none-any.whl", hash = "sha256:2bd5aa94fc267d38bb21a70d7410a89f1a1d318841855f698746f8e7f51acd1b", size = 207542, upload-time = "2026-03-12T03:36:01.668Z" }, +] + +[[package]] +name = "cfgv" +version = "3.5.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/4e/b5/721b8799b04bf9afe054a3899c6cf4e880fcf8563cc71c15610242490a0c/cfgv-3.5.0.tar.gz", hash = "sha256:d5b1034354820651caa73ede66a6294d6e95c1b00acc5e9b098e917404669132", size = 7334, upload-time = "2025-11-19T20:55:51.612Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/db/3c/33bac158f8ab7f89b2e59426d5fe2e4f63f7ed25df84c036890172b412b5/cfgv-3.5.0-py2.py3-none-any.whl", hash = "sha256:a8dc6b26ad22ff227d2634a65cb388215ce6cc96bbcc5cfde7641ae87e8dacc0", size = 7445, upload-time = "2025-11-19T20:55:50.744Z" }, +] + +[[package]] +name = "click" +version = "8.3.3" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "colorama", marker = "sys_platform == 'win32'" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/bb/63/f9e1ea081ce35720d8b92acde70daaedace594dc93b693c869e0d5910718/click-8.3.3.tar.gz", hash = "sha256:398329ad4837b2ff7cbe1dd166a4c0f8900c3ca3a218de04466f38f6497f18a2", size = 328061, upload-time = "2026-04-22T15:11:27.506Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/ae/44/c1221527f6a71a01ec6fbad7fa78f1d50dfa02217385cf0fa3eec7087d59/click-8.3.3-py3-none-any.whl", hash = "sha256:a2bf429bb3033c89fa4936ffb35d5cb471e3719e1f3c8a7c3fff0b8314305613", size = 110502, upload-time = "2026-04-22T15:11:25.044Z" }, +] + +[[package]] +name = "colorama" +version = "0.4.6" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/d8/53/6f443c9a4a8358a93a6792e2acffb9d9d5cb0a5cfd8802644b7b1c9a02e4/colorama-0.4.6.tar.gz", hash = "sha256:08695f5cb7ed6e0531a20572697297273c47b8cae5a63ffc6d6ed5c201be6e44", size = 27697, upload-time = "2022-10-25T02:36:22.414Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/d1/d6/3965ed04c63042e047cb6a3e6ed1a63a35087b6a609aa3a15ed8ac56c221/colorama-0.4.6-py2.py3-none-any.whl", hash = "sha256:4f1d9991f5acc0ca119f9d443620b77f9d6b33703e51011c16baf57afb285fc6", size = 25335, upload-time = "2022-10-25T02:36:20.889Z" }, +] + +[[package]] +name = "distlib" +version = "0.4.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/96/8e/709914eb2b5749865801041647dc7f4e6d00b549cfe88b65ca192995f07c/distlib-0.4.0.tar.gz", hash = "sha256:feec40075be03a04501a973d81f633735b4b69f98b05450592310c0f401a4e0d", size = 614605, upload-time = "2025-07-17T16:52:00.465Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/33/6b/e0547afaf41bf2c42e52430072fa5658766e3d65bd4b03a563d1b6336f57/distlib-0.4.0-py2.py3-none-any.whl", hash = "sha256:9659f7d87e46584a30b5780e43ac7a2143098441670ff0a49d5f9034c54a6c16", size = 469047, upload-time = "2025-07-17T16:51:58.613Z" }, +] + +[[package]] +name = "exceptiongroup" +version = "1.3.1" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "typing-extensions", marker = "python_full_version < '3.13'" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/50/79/66800aadf48771f6b62f7eb014e352e5d06856655206165d775e675a02c9/exceptiongroup-1.3.1.tar.gz", hash = "sha256:8b412432c6055b0b7d14c310000ae93352ed6754f70fa8f7c34141f91c4e3219", size = 30371, upload-time = "2025-11-21T23:01:54.787Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/8a/0e/97c33bf5009bdbac74fd2beace167cab3f978feb69cc36f1ef79360d6c4e/exceptiongroup-1.3.1-py3-none-any.whl", hash = "sha256:a7a39a3bd276781e98394987d3a5701d0c4edffb633bb7a5144577f82c773598", size = 16740, upload-time = "2025-11-21T23:01:53.443Z" }, +] + +[[package]] +name = "filelock" +version = "3.29.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/b5/fe/997687a931ab51049acce6fa1f23e8f01216374ea81374ddee763c493db5/filelock-3.29.0.tar.gz", hash = "sha256:69974355e960702e789734cb4871f884ea6fe50bd8404051a3530bc07809cf90", size = 57571, upload-time = "2026-04-19T15:39:10.068Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/81/47/dd9a212ef6e343a6857485ffe25bba537304f1913bdbed446a23f7f592e1/filelock-3.29.0-py3-none-any.whl", hash = "sha256:96f5f6344709aa1572bbf631c640e4ebeeb519e08da902c39a001882f30ac258", size = 39812, upload-time = "2026-04-19T15:39:08.752Z" }, +] + +[[package]] +name = "identify" +version = "2.6.19" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/52/63/51723b5f116cc04b061cb6f5a561790abf249d25931d515cd375e063e0f4/identify-2.6.19.tar.gz", hash = "sha256:6be5020c38fcb07da56c53733538a3081ea5aa70d36a156f83044bfbf9173842", size = 99567, upload-time = "2026-04-17T18:39:50.265Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/94/84/d9273cd09688070a6523c4aee4663a8538721b2b755c4962aafae0011e72/identify-2.6.19-py2.py3-none-any.whl", hash = "sha256:20e6a87f786f768c092a721ad107fc9df0eb89347be9396cadf3f4abbd1fb78a", size = 99397, upload-time = "2026-04-17T18:39:49.221Z" }, +] + +[[package]] +name = "iniconfig" +version = "2.3.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/72/34/14ca021ce8e5dfedc35312d08ba8bf51fdd999c576889fc2c24cb97f4f10/iniconfig-2.3.0.tar.gz", hash = "sha256:c76315c77db068650d49c5b56314774a7804df16fee4402c1f19d6d15d8c4730", size = 20503, upload-time = "2025-10-18T21:55:43.219Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/cb/b1/3846dd7f199d53cb17f49cba7e651e9ce294d8497c8c150530ed11865bb8/iniconfig-2.3.0-py3-none-any.whl", hash = "sha256:f631c04d2c48c52b84d0d0549c99ff3859c98df65b3101406327ecc7d53fbf12", size = 7484, upload-time = "2025-10-18T21:55:41.639Z" }, +] + +[[package]] +name = "isort" +version = "8.0.1" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/ef/7c/ec4ab396d31b3b395e2e999c8f46dec78c5e29209fac49d1f4dace04041d/isort-8.0.1.tar.gz", hash = "sha256:171ac4ff559cdc060bcfff550bc8404a486fee0caab245679c2abe7cb253c78d", size = 769592, upload-time = "2026-02-28T10:08:20.685Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/3e/95/c7c34aa53c16353c56d0b802fba48d5f5caa2cdee7958acbcb795c830416/isort-8.0.1-py3-none-any.whl", hash = "sha256:28b89bc70f751b559aeca209e6120393d43fbe2490de0559662be7a9787e3d75", size = 89733, upload-time = "2026-02-28T10:08:19.466Z" }, +] + +[[package]] +name = "jsonschema" +version = "4.26.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "attrs" }, + { name = "jsonschema-specifications" }, + { name = "referencing" }, + { name = "rpds-py" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/b3/fc/e067678238fa451312d4c62bf6e6cf5ec56375422aee02f9cb5f909b3047/jsonschema-4.26.0.tar.gz", hash = "sha256:0c26707e2efad8aa1bfc5b7ce170f3fccc2e4918ff85989ba9ffa9facb2be326", size = 366583, upload-time = "2026-01-07T13:41:07.246Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/69/90/f63fb5873511e014207a475e2bb4e8b2e570d655b00ac19a9a0ca0a385ee/jsonschema-4.26.0-py3-none-any.whl", hash = "sha256:d489f15263b8d200f8387e64b4c3a75f06629559fb73deb8fdfb525f2dab50ce", size = 90630, upload-time = "2026-01-07T13:41:05.306Z" }, +] + +[[package]] +name = "jsonschema-specifications" +version = "2025.9.1" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "referencing" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/19/74/a633ee74eb36c44aa6d1095e7cc5569bebf04342ee146178e2d36600708b/jsonschema_specifications-2025.9.1.tar.gz", hash = "sha256:b540987f239e745613c7a9176f3edb72b832a4ac465cf02712288397832b5e8d", size = 32855, upload-time = "2025-09-08T01:34:59.186Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/41/45/1a4ed80516f02155c51f51e8cedb3c1902296743db0bbc66608a0db2814f/jsonschema_specifications-2025.9.1-py3-none-any.whl", hash = "sha256:98802fee3a11ee76ecaca44429fda8a41bff98b00a0f2838151b113f210cc6fe", size = 18437, upload-time = "2025-09-08T01:34:57.871Z" }, +] + +[[package]] +name = "model-metadata-central" +version = "0.1.0" +source = { editable = "." } +dependencies = [ + { name = "pydantic" }, + { name = "pyyaml" }, +] + +[package.dev-dependencies] +dev = [ + { name = "black" }, + { name = "isort" }, + { name = "jsonschema" }, + { name = "pre-commit" }, + { name = "pytest" }, +] + +[package.metadata] +requires-dist = [ + { name = "pydantic", specifier = ">=2.0,<3" }, + { name = "pyyaml", specifier = ">=6.0,<7" }, +] + +[package.metadata.requires-dev] +dev = [ + { name = "black", specifier = ">=23.11.0" }, + { name = "isort", specifier = ">=5.12.0" }, + { name = "jsonschema", specifier = ">=4.19.2" }, + { name = "pre-commit", specifier = ">=3.5.0" }, + { name = "pytest", specifier = ">=7.4.3" }, +] + +[[package]] +name = "mypy-extensions" +version = "1.1.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/a2/6e/371856a3fb9d31ca8dac321cda606860fa4548858c0cc45d9d1d4ca2628b/mypy_extensions-1.1.0.tar.gz", hash = "sha256:52e68efc3284861e772bbcd66823fde5ae21fd2fdb51c62a211403730b916558", size = 6343, upload-time = "2025-04-22T14:54:24.164Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/79/7b/2c79738432f5c924bef5071f933bcc9efd0473bac3b4aa584a6f7c1c8df8/mypy_extensions-1.1.0-py3-none-any.whl", hash = "sha256:1be4cccdb0f2482337c4743e60421de3a356cd97508abadd57d47403e94f5505", size = 4963, upload-time = "2025-04-22T14:54:22.983Z" }, +] + +[[package]] +name = "nodeenv" +version = "1.10.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/24/bf/d1bda4f6168e0b2e9e5958945e01910052158313224ada5ce1fb2e1113b8/nodeenv-1.10.0.tar.gz", hash = "sha256:996c191ad80897d076bdfba80a41994c2b47c68e224c542b48feba42ba00f8bb", size = 55611, upload-time = "2025-12-20T14:08:54.006Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/88/b2/d0896bdcdc8d28a7fc5717c305f1a861c26e18c05047949fb371034d98bd/nodeenv-1.10.0-py2.py3-none-any.whl", hash = "sha256:5bb13e3eed2923615535339b3c620e76779af4cb4c6a90deccc9e36b274d3827", size = 23438, upload-time = "2025-12-20T14:08:52.782Z" }, +] + +[[package]] +name = "packaging" +version = "26.2" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/d7/f1/e7a6dd94a8d4a5626c03e4e99c87f241ba9e350cd9e6d75123f992427270/packaging-26.2.tar.gz", hash = "sha256:ff452ff5a3e828ce110190feff1178bb1f2ea2281fa2075aadb987c2fb221661", size = 228134, upload-time = "2026-04-24T20:15:23.917Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/df/b2/87e62e8c3e2f4b32e5fe99e0b86d576da1312593b39f47d8ceef365e95ed/packaging-26.2-py3-none-any.whl", hash = "sha256:5fc45236b9446107ff2415ce77c807cee2862cb6fac22b8a73826d0693b0980e", size = 100195, upload-time = "2026-04-24T20:15:22.081Z" }, +] + +[[package]] +name = "pathspec" +version = "1.1.1" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/5a/82/42f767fc1c1143d6fd36efb827202a2d997a375e160a71eb2888a925aac1/pathspec-1.1.1.tar.gz", hash = "sha256:17db5ecd524104a120e173814c90367a96a98d07c45b2e10c2f3919fff91bf5a", size = 135180, upload-time = "2026-04-27T01:46:08.907Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/f1/d9/7fb5aa316bc299258e68c73ba3bddbc499654a07f151cba08f6153988714/pathspec-1.1.1-py3-none-any.whl", hash = "sha256:a00ce642f577bf7f473932318056212bc4f8bfdf53128c78bbd5af0b9b20b189", size = 57328, upload-time = "2026-04-27T01:46:07.06Z" }, +] + +[[package]] +name = "platformdirs" +version = "4.9.6" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/9f/4a/0883b8e3802965322523f0b200ecf33d31f10991d0401162f4b23c698b42/platformdirs-4.9.6.tar.gz", hash = "sha256:3bfa75b0ad0db84096ae777218481852c0ebc6c727b3168c1b9e0118e458cf0a", size = 29400, upload-time = "2026-04-09T00:04:10.812Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/75/a6/a0a304dc33b49145b21f4808d763822111e67d1c3a32b524a1baf947b6e1/platformdirs-4.9.6-py3-none-any.whl", hash = "sha256:e61adb1d5e5cb3441b4b7710bea7e4c12250ca49439228cc1021c00dcfac0917", size = 21348, upload-time = "2026-04-09T00:04:09.463Z" }, +] + +[[package]] +name = "pluggy" +version = "1.6.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/f9/e2/3e91f31a7d2b083fe6ef3fa267035b518369d9511ffab804f839851d2779/pluggy-1.6.0.tar.gz", hash = "sha256:7dcc130b76258d33b90f61b658791dede3486c3e6bfb003ee5c9bfb396dd22f3", size = 69412, upload-time = "2025-05-15T12:30:07.975Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/54/20/4d324d65cc6d9205fabedc306948156824eb9f0ee1633355a8f7ec5c66bf/pluggy-1.6.0-py3-none-any.whl", hash = "sha256:e920276dd6813095e9377c0bc5566d94c932c33b27a3e3945d8389c374dd4746", size = 20538, upload-time = "2025-05-15T12:30:06.134Z" }, +] + +[[package]] +name = "pre-commit" +version = "4.6.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "cfgv" }, + { name = "identify" }, + { name = "nodeenv" }, + { name = "pyyaml" }, + { name = "virtualenv" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/8e/22/2de9408ac81acbb8a7d05d4cc064a152ccf33b3d480ebe0cd292153db239/pre_commit-4.6.0.tar.gz", hash = "sha256:718d2208cef53fdc38206e40524a6d4d9576d103eb16f0fec11c875e7716e9d9", size = 198525, upload-time = "2026-04-21T20:31:41.613Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/80/6e/4b28b62ecb6aae56769c34a8ff1d661473ec1e9519e2d5f8b2c150086b26/pre_commit-4.6.0-py2.py3-none-any.whl", hash = "sha256:e2cf246f7299edcabcf15f9b0571fdce06058527f0a06535068a86d38089f29b", size = 226472, upload-time = "2026-04-21T20:31:40.092Z" }, +] + +[[package]] +name = "pydantic" +version = "2.13.3" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "annotated-types" }, + { name = "pydantic-core" }, + { name = "typing-extensions" }, + { name = "typing-inspection" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/d9/e4/40d09941a2cebcb20609b86a559817d5b9291c49dd6f8c87e5feffbe703a/pydantic-2.13.3.tar.gz", hash = "sha256:af09e9d1d09f4e7fe37145c1f577e1d61ceb9a41924bf0094a36506285d0a84d", size = 844068, upload-time = "2026-04-20T14:46:43.632Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/f3/0a/fd7d723f8f8153418fb40cf9c940e82004fce7e987026b08a68a36dd3fe7/pydantic-2.13.3-py3-none-any.whl", hash = "sha256:6db14ac8dfc9a1e57f87ea2c0de670c251240f43cb0c30a5130e9720dc612927", size = 471981, upload-time = "2026-04-20T14:46:41.402Z" }, +] + +[[package]] +name = "pydantic-core" +version = "2.46.3" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "typing-extensions" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/2a/ef/f7abb56c49382a246fd2ce9c799691e3c3e7175ec74b14d99e798bcddb1a/pydantic_core-2.46.3.tar.gz", hash = "sha256:41c178f65b8c29807239d47e6050262eb6bf84eb695e41101e62e38df4a5bc2c", size = 471412, upload-time = "2026-04-20T14:40:56.672Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/22/98/b50eb9a411e87483b5c65dba4fa430a06bac4234d3403a40e5a9905ebcd0/pydantic_core-2.46.3-cp310-cp310-macosx_10_12_x86_64.whl", hash = "sha256:1da3786b8018e60349680720158cc19161cc3b4bdd815beb0a321cd5ce1ad5b1", size = 2108971, upload-time = "2026-04-20T14:43:51.945Z" }, + { url = "https://files.pythonhosted.org/packages/08/4b/f364b9d161718ff2217160a4b5d41ce38de60aed91c3689ebffa1c939d23/pydantic_core-2.46.3-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:cc0988cb29d21bf4a9d5cf2ef970b5c0e38d8d8e107a493278c05dc6c1dda69f", size = 1949588, upload-time = "2026-04-20T14:44:10.386Z" }, + { url = "https://files.pythonhosted.org/packages/8f/8b/30bd03ee83b2f5e29f5ba8e647ab3c456bf56f2ec72fdbcc0215484a0854/pydantic_core-2.46.3-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:27f9067c3bfadd04c55484b89c0d267981b2f3512850f6f66e1e74204a4e4ce3", size = 1975986, upload-time = "2026-04-20T14:43:57.106Z" }, + { url = "https://files.pythonhosted.org/packages/3c/54/13ccf954d84ec275d5d023d5786e4aa48840bc9f161f2838dc98e1153518/pydantic_core-2.46.3-cp310-cp310-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:a642ac886ecf6402d9882d10c405dcf4b902abeb2972cd5fb4a48c83cd59279a", size = 2055830, upload-time = "2026-04-20T14:44:15.499Z" }, + { url = "https://files.pythonhosted.org/packages/be/0e/65f38125e660fdbd72aa858e7dfae893645cfa0e7b13d333e174a367cd23/pydantic_core-2.46.3-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:79f561438481f28681584b89e2effb22855e2179880314bcddbf5968e935e807", size = 2222340, upload-time = "2026-04-20T14:41:51.353Z" }, + { url = "https://files.pythonhosted.org/packages/d1/88/f3ab7739efe0e7e80777dbb84c59eb98518e3f57ea433206194c2e425272/pydantic_core-2.46.3-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:57a973eae4665352a47cf1a99b4ee864620f2fe663a217d7a8da68a1f3a5bfda", size = 2280727, upload-time = "2026-04-20T14:41:30.461Z" }, + { url = "https://files.pythonhosted.org/packages/2a/6d/c228219080817bec4982f9531cadb18da6aaa770fdeb114f49c237ac2c9f/pydantic_core-2.46.3-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:83d002b97072a53ea150d63e0a3adfae5670cef5aa8a6e490240e482d3b22e57", size = 2092158, upload-time = "2026-04-20T14:44:07.305Z" }, + { url = "https://files.pythonhosted.org/packages/0f/b1/525a16711e7c6d61635fac3b0bd54600b5c5d9f60c6fc5aaab26b64a2297/pydantic_core-2.46.3-cp310-cp310-manylinux_2_31_riscv64.whl", hash = "sha256:b40ddd51e7c44b28cfaef746c9d3c506d658885e0a46f9eeef2ee815cbf8e045", size = 2116626, upload-time = "2026-04-20T14:42:34.118Z" }, + { url = "https://files.pythonhosted.org/packages/ef/7c/17d30673351439a6951bf54f564cf2443ab00ae264ec9df00e2efd710eb5/pydantic_core-2.46.3-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:ac5ec7fb9b87f04ee839af2d53bcadea57ded7d229719f56c0ed895bff987943", size = 2160691, upload-time = "2026-04-20T14:41:14.023Z" }, + { url = "https://files.pythonhosted.org/packages/86/66/af8adbcbc0886ead7f1a116606a534d75a307e71e6e08226000d51b880d2/pydantic_core-2.46.3-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:a3b11c812f61b3129c4905781a2601dfdfdea5fe1e6c1cfb696b55d14e9c054f", size = 2182543, upload-time = "2026-04-20T14:40:48.886Z" }, + { url = "https://files.pythonhosted.org/packages/b0/37/6de71e0f54c54a4190010f57deb749e1ddf75c568ada3b1320b70067f121/pydantic_core-2.46.3-cp310-cp310-musllinux_1_1_armv7l.whl", hash = "sha256:1108da631e602e5b3c38d6d04fe5bb3bfa54349e6918e3ca6cf570b2e2b2f9d4", size = 2324513, upload-time = "2026-04-20T14:42:36.121Z" }, + { url = "https://files.pythonhosted.org/packages/51/b1/9fc74ce94f603d5ef59ff258ca9c2c8fb902fb548d340a96f77f4d1c3b7f/pydantic_core-2.46.3-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:de885175515bcfa98ae618c1df7a072f13d179f81376c8007112af20567fd08a", size = 2361853, upload-time = "2026-04-20T14:43:24.886Z" }, + { url = "https://files.pythonhosted.org/packages/40/d0/4c652fc592db35f100279ee751d5a145aca1b9a7984b9684ba7c1b5b0535/pydantic_core-2.46.3-cp310-cp310-win32.whl", hash = "sha256:d11058e3201527d41bc6b545c79187c9e4bf85e15a236a6007f0e991518882b7", size = 1980465, upload-time = "2026-04-20T14:44:46.239Z" }, + { url = "https://files.pythonhosted.org/packages/27/b8/a920453c38afbe1f355e1ea0b0d94a0a3e0b0879d32d793108755fa171d5/pydantic_core-2.46.3-cp310-cp310-win_amd64.whl", hash = "sha256:3612edf65c8ea67ac13616c4d23af12faef1ae435a8a93e5934c2a0cbbdd1fd6", size = 2073884, upload-time = "2026-04-20T14:43:01.201Z" }, + { url = "https://files.pythonhosted.org/packages/22/a2/1ba90a83e85a3f94c796b184f3efde9c72f2830dcda493eea8d59ba78e6d/pydantic_core-2.46.3-cp311-cp311-macosx_10_12_x86_64.whl", hash = "sha256:ab124d49d0459b2373ecf54118a45c28a1e6d4192a533fbc915e70f556feb8e5", size = 2106740, upload-time = "2026-04-20T14:41:20.932Z" }, + { url = "https://files.pythonhosted.org/packages/b6/f6/99ae893c89a0b9d3daec9f95487aa676709aa83f67643b3f0abaf4ab628a/pydantic_core-2.46.3-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:cca67d52a5c7a16aed2b3999e719c4bcf644074eac304a5d3d62dd70ae7d4b2c", size = 1948293, upload-time = "2026-04-20T14:43:42.115Z" }, + { url = "https://files.pythonhosted.org/packages/3e/b8/2e8e636dc9e3f16c2e16bf0849e24be82c5ee82c603c65fc0326666328fc/pydantic_core-2.46.3-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5c024e08c0ba23e6fd68c771a521e9d6a792f2ebb0fa734296b36394dc30390e", size = 1973222, upload-time = "2026-04-20T14:41:57.841Z" }, + { url = "https://files.pythonhosted.org/packages/34/36/0e730beec4d83c5306f417afbd82ff237d9a21e83c5edf675f31ed84c1fe/pydantic_core-2.46.3-cp311-cp311-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:6645ce7eec4928e29a1e3b3d5c946621d105d3e79f0c9cddf07c2a9770949287", size = 2053852, upload-time = "2026-04-20T14:40:43.077Z" }, + { url = "https://files.pythonhosted.org/packages/4b/f0/3071131f47e39136a17814576e0fada9168569f7f8c0e6ac4d1ede6a4958/pydantic_core-2.46.3-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:a712c7118e6c5ea96562f7b488435172abb94a3c53c22c9efc1412264a45cbbe", size = 2221134, upload-time = "2026-04-20T14:43:03.349Z" }, + { url = "https://files.pythonhosted.org/packages/2f/a9/a2dc023eec5aa4b02a467874bad32e2446957d2adcab14e107eab502e978/pydantic_core-2.46.3-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:69a868ef3ff206343579021c40faf3b1edc64b1cc508ff243a28b0a514ccb050", size = 2279785, upload-time = "2026-04-20T14:41:19.285Z" }, + { url = "https://files.pythonhosted.org/packages/0a/44/93f489d16fb63fbd41c670441536541f6e8cfa1e5a69f40bc9c5d30d8c90/pydantic_core-2.46.3-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:cc7e8c32db809aa0f6ea1d6869ebc8518a65d5150fdfad8bcae6a49ae32a22e2", size = 2089404, upload-time = "2026-04-20T14:43:10.108Z" }, + { url = "https://files.pythonhosted.org/packages/2a/78/8692e3aa72b2d004f7a5d937f1dfdc8552ba26caf0bec75f342c40f00dec/pydantic_core-2.46.3-cp311-cp311-manylinux_2_31_riscv64.whl", hash = "sha256:3481bd1341dc85779ee506bc8e1196a277ace359d89d28588a9468c3ecbe63fa", size = 2114898, upload-time = "2026-04-20T14:44:51.475Z" }, + { url = "https://files.pythonhosted.org/packages/6a/62/e83133f2e7832532060175cebf1f13748f4c7e7e7165cdd1f611f174494b/pydantic_core-2.46.3-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:8690eba565c6d68ffd3a8655525cbdd5246510b44a637ee2c6c03a7ebfe64d3c", size = 2157856, upload-time = "2026-04-20T14:43:46.64Z" }, + { url = "https://files.pythonhosted.org/packages/6d/ec/6a500e3ad7718ee50583fae79c8651f5d37e3abce1fa9ae177ae65842c53/pydantic_core-2.46.3-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:4de88889d7e88d50d40ee5b39d5dac0bcaef9ba91f7e536ac064e6b2834ecccf", size = 2180168, upload-time = "2026-04-20T14:42:00.302Z" }, + { url = "https://files.pythonhosted.org/packages/d8/53/8267811054b1aa7fc1dc7ded93812372ef79a839f5e23558136a6afbfde1/pydantic_core-2.46.3-cp311-cp311-musllinux_1_1_armv7l.whl", hash = "sha256:e480080975c1ef7f780b8f99ed72337e7cc5efea2e518a20a692e8e7b278eb8b", size = 2322885, upload-time = "2026-04-20T14:41:05.253Z" }, + { url = "https://files.pythonhosted.org/packages/c8/c1/1c0acdb3aa0856ddc4ecc55214578f896f2de16f400cf51627eb3c26c1c4/pydantic_core-2.46.3-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:de3a5c376f8cd94da9a1b8fd3dd1c16c7a7b216ed31dc8ce9fd7a22bf13b836e", size = 2360328, upload-time = "2026-04-20T14:41:43.991Z" }, + { url = "https://files.pythonhosted.org/packages/f0/d0/ef39cd0f4a926814f360e71c1adeab48ad214d9727e4deb48eedfb5bce1a/pydantic_core-2.46.3-cp311-cp311-win32.whl", hash = "sha256:fc331a5314ffddd5385b9ee9d0d2fee0b13c27e0e02dad71b1ae5d6561f51eeb", size = 1979464, upload-time = "2026-04-20T14:43:12.215Z" }, + { url = "https://files.pythonhosted.org/packages/18/9c/f41951b0d858e343f1cf09398b2a7b3014013799744f2c4a8ad6a3eec4f2/pydantic_core-2.46.3-cp311-cp311-win_amd64.whl", hash = "sha256:b5b9c6cf08a8a5e502698f5e153056d12c34b8fb30317e0c5fd06f45162a6346", size = 2070837, upload-time = "2026-04-20T14:41:47.707Z" }, + { url = "https://files.pythonhosted.org/packages/9f/1e/264a17cd582f6ed50950d4d03dd5fefd84e570e238afe1cb3e25cf238769/pydantic_core-2.46.3-cp311-cp311-win_arm64.whl", hash = "sha256:5dfd51cf457482f04ec49491811a2b8fd5b843b64b11eecd2d7a1ee596ea78a6", size = 2053647, upload-time = "2026-04-20T14:42:27.535Z" }, + { url = "https://files.pythonhosted.org/packages/4b/cb/5b47425556ecc1f3fe18ed2a0083188aa46e1dd812b06e406475b3a5d536/pydantic_core-2.46.3-cp312-cp312-macosx_10_12_x86_64.whl", hash = "sha256:b11b59b3eee90a80a36701ddb4576d9ae31f93f05cb9e277ceaa09e6bf074a67", size = 2101946, upload-time = "2026-04-20T14:40:52.581Z" }, + { url = "https://files.pythonhosted.org/packages/a1/4f/2fb62c2267cae99b815bbf4a7b9283812c88ca3153ef29f7707200f1d4e5/pydantic_core-2.46.3-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:af8653713055ea18a3abc1537fe2ebc42f5b0bbb768d1eb79fd74eb47c0ac089", size = 1951612, upload-time = "2026-04-20T14:42:42.996Z" }, + { url = "https://files.pythonhosted.org/packages/50/6e/b7348fd30d6556d132cddd5bd79f37f96f2601fe0608afac4f5fb01ec0b3/pydantic_core-2.46.3-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:75a519dab6d63c514f3a81053e5266c549679e4aa88f6ec57f2b7b854aceb1b0", size = 1977027, upload-time = "2026-04-20T14:42:02.001Z" }, + { url = "https://files.pythonhosted.org/packages/82/11/31d60ee2b45540d3fb0b29302a393dbc01cd771c473f5b5147bcd353e593/pydantic_core-2.46.3-cp312-cp312-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:a6cd87cb1575b1ad05ba98894c5b5c96411ef678fa2f6ed2576607095b8d9789", size = 2063008, upload-time = "2026-04-20T14:44:17.952Z" }, + { url = "https://files.pythonhosted.org/packages/8a/db/3a9d1957181b59258f44a2300ab0f0be9d1e12d662a4f57bb31250455c52/pydantic_core-2.46.3-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:f80a55484b8d843c8ada81ebf70a682f3f00a3d40e378c06cf17ecb44d280d7d", size = 2233082, upload-time = "2026-04-20T14:40:57.934Z" }, + { url = "https://files.pythonhosted.org/packages/9c/e1/3277c38792aeb5cfb18c2f0c5785a221d9ff4e149abbe1184d53d5f72273/pydantic_core-2.46.3-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:3861f1731b90c50a3266316b9044f5c9b405eecb8e299b0a7120596334e4fe9c", size = 2304615, upload-time = "2026-04-20T14:42:12.584Z" }, + { url = "https://files.pythonhosted.org/packages/5e/d5/e3d9717c9eba10855325650afd2a9cba8e607321697f18953af9d562da2f/pydantic_core-2.46.3-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:fb528e295ed31570ac3dcc9bfdd6e0150bc11ce6168ac87a8082055cf1a67395", size = 2094380, upload-time = "2026-04-20T14:43:05.522Z" }, + { url = "https://files.pythonhosted.org/packages/a1/20/abac35dedcbfd66c6f0b03e4e3564511771d6c9b7ede10a362d03e110d9b/pydantic_core-2.46.3-cp312-cp312-manylinux_2_31_riscv64.whl", hash = "sha256:367508faa4973b992b271ba1494acaab36eb7e8739d1e47be5035fb1ea225396", size = 2135429, upload-time = "2026-04-20T14:41:55.549Z" }, + { url = "https://files.pythonhosted.org/packages/6c/a5/41bfd1df69afad71b5cf0535055bccc73022715ad362edbc124bc1e021d7/pydantic_core-2.46.3-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:5ad3c826fe523e4becf4fe39baa44286cff85ef137c729a2c5e269afbfd0905d", size = 2174582, upload-time = "2026-04-20T14:41:45.96Z" }, + { url = "https://files.pythonhosted.org/packages/79/65/38d86ea056b29b2b10734eb23329b7a7672ca604df4f2b6e9c02d4ee22fe/pydantic_core-2.46.3-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:ec638c5d194ef8af27db69f16c954a09797c0dc25015ad6123eb2c73a4d271ca", size = 2187533, upload-time = "2026-04-20T14:40:55.367Z" }, + { url = "https://files.pythonhosted.org/packages/b6/55/a1129141678a2026badc539ad1dee0a71d06f54c2f06a4bd68c030ac781b/pydantic_core-2.46.3-cp312-cp312-musllinux_1_1_armv7l.whl", hash = "sha256:28ed528c45446062ee66edb1d33df5d88828ae167de76e773a3c7f64bd14e976", size = 2332985, upload-time = "2026-04-20T14:44:13.05Z" }, + { url = "https://files.pythonhosted.org/packages/d7/60/cb26f4077719f709e54819f4e8e1d43f4091f94e285eb6bd21e1190a7b7c/pydantic_core-2.46.3-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:aed19d0c783886d5bd86d80ae5030006b45e28464218747dcf83dabfdd092c7b", size = 2373670, upload-time = "2026-04-20T14:41:53.421Z" }, + { url = "https://files.pythonhosted.org/packages/6b/7e/c3f21882bdf1d8d086876f81b5e296206c69c6082551d776895de7801fa0/pydantic_core-2.46.3-cp312-cp312-win32.whl", hash = "sha256:06d5d8820cbbdb4147578c1fe7ffcd5b83f34508cb9f9ab76e807be7db6ff0a4", size = 1966722, upload-time = "2026-04-20T14:44:30.588Z" }, + { url = "https://files.pythonhosted.org/packages/57/be/6b5e757b859013ebfbd7adba02f23b428f37c86dcbf78b5bb0b4ffd36e99/pydantic_core-2.46.3-cp312-cp312-win_amd64.whl", hash = "sha256:c3212fda0ee959c1dd04c60b601ec31097aaa893573a3a1abd0a47bcac2968c1", size = 2072970, upload-time = "2026-04-20T14:42:54.248Z" }, + { url = "https://files.pythonhosted.org/packages/bf/f8/a989b21cc75e9a32d24192ef700eea606521221a89faa40c919ce884f2b1/pydantic_core-2.46.3-cp312-cp312-win_arm64.whl", hash = "sha256:f1f8338dd7a7f31761f1f1a3c47503a9a3b34eea3c8b01fa6ee96408affb5e72", size = 2035963, upload-time = "2026-04-20T14:44:20.4Z" }, + { url = "https://files.pythonhosted.org/packages/9b/3c/9b5e8eb9821936d065439c3b0fb1490ffa64163bfe7e1595985a47896073/pydantic_core-2.46.3-cp313-cp313-macosx_10_12_x86_64.whl", hash = "sha256:12bc98de041458b80c86c56b24df1d23832f3e166cbaff011f25d187f5c62c37", size = 2102109, upload-time = "2026-04-20T14:41:24.219Z" }, + { url = "https://files.pythonhosted.org/packages/91/97/1c41d1f5a19f241d8069f1e249853bcce378cdb76eec8ab636d7bc426280/pydantic_core-2.46.3-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:85348b8f89d2c3508b65b16c3c33a4da22b8215138d8b996912bb1532868885f", size = 1951820, upload-time = "2026-04-20T14:42:14.236Z" }, + { url = "https://files.pythonhosted.org/packages/30/b4/d03a7ae14571bc2b6b3c7b122441154720619afe9a336fa3a95434df5e2f/pydantic_core-2.46.3-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1105677a6df914b1fb71a81b96c8cce7726857e1717d86001f29be06a25ee6f8", size = 1977785, upload-time = "2026-04-20T14:42:31.648Z" }, + { url = "https://files.pythonhosted.org/packages/ae/0c/4086f808834b59e3c8f1aa26df8f4b6d998cdcf354a143d18ef41529d1fe/pydantic_core-2.46.3-cp313-cp313-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:87082cd65669a33adeba5470769e9704c7cf026cc30afb9cc77fd865578ebaad", size = 2062761, upload-time = "2026-04-20T14:40:37.093Z" }, + { url = "https://files.pythonhosted.org/packages/fa/71/a649be5a5064c2df0db06e0a512c2281134ed2fcc981f52a657936a7527c/pydantic_core-2.46.3-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:60e5f66e12c4f5212d08522963380eaaeac5ebd795826cfd19b2dfb0c7a52b9c", size = 2232989, upload-time = "2026-04-20T14:42:59.254Z" }, + { url = "https://files.pythonhosted.org/packages/a2/84/7756e75763e810b3a710f4724441d1ecc5883b94aacb07ca71c5fb5cfb69/pydantic_core-2.46.3-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:b6cdf19bf84128d5e7c37e8a73a0c5c10d51103a650ac585d42dd6ae233f2b7f", size = 2303975, upload-time = "2026-04-20T14:41:32.287Z" }, + { url = "https://files.pythonhosted.org/packages/6c/35/68a762e0c1e31f35fa0dac733cbd9f5b118042853698de9509c8e5bf128b/pydantic_core-2.46.3-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:031bb17f4885a43773c8c763089499f242aee2ea85cf17154168775dccdecf35", size = 2095325, upload-time = "2026-04-20T14:42:47.685Z" }, + { url = "https://files.pythonhosted.org/packages/77/bf/1bf8c9a8e91836c926eae5e3e51dce009bf495a60ca56060689d3df3f340/pydantic_core-2.46.3-cp313-cp313-manylinux_2_31_riscv64.whl", hash = "sha256:bcf2a8b2982a6673693eae7348ef3d8cf3979c1d63b54fca7c397a635cc68687", size = 2133368, upload-time = "2026-04-20T14:41:22.766Z" }, + { url = "https://files.pythonhosted.org/packages/e5/50/87d818d6bab915984995157ceb2380f5aac4e563dddbed6b56f0ed057aba/pydantic_core-2.46.3-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:28e8cf2f52d72ced402a137145923a762cbb5081e48b34312f7a0c8f55928ec3", size = 2173908, upload-time = "2026-04-20T14:42:52.044Z" }, + { url = "https://files.pythonhosted.org/packages/91/88/a311fb306d0bd6185db41fa14ae888fb81d0baf648a761ae760d30819d33/pydantic_core-2.46.3-cp313-cp313-musllinux_1_1_aarch64.whl", hash = "sha256:17eaface65d9fc5abb940003020309c1bf7a211f5f608d7870297c367e6f9022", size = 2186422, upload-time = "2026-04-20T14:43:29.55Z" }, + { url = "https://files.pythonhosted.org/packages/8f/79/28fd0d81508525ab2054fef7c77a638c8b5b0afcbbaeee493cf7c3fef7e1/pydantic_core-2.46.3-cp313-cp313-musllinux_1_1_armv7l.whl", hash = "sha256:93fd339f23408a07e98950a89644f92c54d8729719a40b30c0a30bb9ebc55d23", size = 2332709, upload-time = "2026-04-20T14:42:16.134Z" }, + { url = "https://files.pythonhosted.org/packages/b3/21/795bf5fe5c0f379308b8ef19c50dedab2e7711dbc8d0c2acf08f1c7daa05/pydantic_core-2.46.3-cp313-cp313-musllinux_1_1_x86_64.whl", hash = "sha256:23cbdb3aaa74dfe0837975dbf69b469753bbde8eacace524519ffdb6b6e89eb7", size = 2372428, upload-time = "2026-04-20T14:41:10.974Z" }, + { url = "https://files.pythonhosted.org/packages/45/b3/ed14c659cbe7605e3ef063077680a64680aec81eb1a04763a05190d49b7f/pydantic_core-2.46.3-cp313-cp313-win32.whl", hash = "sha256:610eda2e3838f401105e6326ca304f5da1e15393ae25dacae5c5c63f2c275b13", size = 1965601, upload-time = "2026-04-20T14:41:42.128Z" }, + { url = "https://files.pythonhosted.org/packages/ef/bb/adb70d9a762ddd002d723fbf1bd492244d37da41e3af7b74ad212609027e/pydantic_core-2.46.3-cp313-cp313-win_amd64.whl", hash = "sha256:68cc7866ed863db34351294187f9b729964c371ba33e31c26f478471c52e1ed0", size = 2071517, upload-time = "2026-04-20T14:43:36.096Z" }, + { url = "https://files.pythonhosted.org/packages/52/eb/66faefabebfe68bd7788339c9c9127231e680b11906368c67ce112fdb47f/pydantic_core-2.46.3-cp313-cp313-win_arm64.whl", hash = "sha256:f64b5537ac62b231572879cd08ec05600308636a5d63bcbdb15063a466977bec", size = 2035802, upload-time = "2026-04-20T14:43:38.507Z" }, + { url = "https://files.pythonhosted.org/packages/7f/db/a7bcb4940183fda36022cd18ba8dd12f2dff40740ec7b58ce7457befa416/pydantic_core-2.46.3-cp314-cp314-macosx_10_12_x86_64.whl", hash = "sha256:afa3aa644f74e290cdede48a7b0bee37d1c35e71b05105f6b340d484af536d9b", size = 2097614, upload-time = "2026-04-20T14:44:38.374Z" }, + { url = "https://files.pythonhosted.org/packages/24/35/e4066358a22e3e99519db370494c7528f5a2aa1367370e80e27e20283543/pydantic_core-2.46.3-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:ced3310e51aa425f7f77da8bbbb5212616655bedbe82c70944320bc1dbe5e018", size = 1951896, upload-time = "2026-04-20T14:40:53.996Z" }, + { url = "https://files.pythonhosted.org/packages/87/92/37cf4049d1636996e4b888c05a501f40a43ff218983a551d57f9d5e14f0d/pydantic_core-2.46.3-cp314-cp314-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e29908922ce9da1a30b4da490bd1d3d82c01dcfdf864d2a74aacee674d0bfa34", size = 1979314, upload-time = "2026-04-20T14:41:49.446Z" }, + { url = "https://files.pythonhosted.org/packages/d8/36/9ff4d676dfbdfb2d591cf43f3d90ded01e15b1404fd101180ed2d62a2fd3/pydantic_core-2.46.3-cp314-cp314-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:0c9ff69140423eea8ed2d5477df3ba037f671f5e897d206d921bc9fdc39613e7", size = 2056133, upload-time = "2026-04-20T14:42:23.574Z" }, + { url = "https://files.pythonhosted.org/packages/bc/f0/405b442a4d7ba855b06eec8b2bf9c617d43b8432d099dfdc7bf999293495/pydantic_core-2.46.3-cp314-cp314-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:b675ab0a0d5b1c8fdb81195dc5bcefea3f3c240871cdd7ff9a2de8aa50772eb2", size = 2228726, upload-time = "2026-04-20T14:44:22.816Z" }, + { url = "https://files.pythonhosted.org/packages/e7/f8/65cd92dd5a0bd89ba277a98ecbfaf6fc36bbd3300973c7a4b826d6ab1391/pydantic_core-2.46.3-cp314-cp314-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:0087084960f209a9a4af50ecd1fb063d9ad3658c07bb81a7a53f452dacbfb2ba", size = 2301214, upload-time = "2026-04-20T14:44:48.792Z" }, + { url = "https://files.pythonhosted.org/packages/fd/86/ef96a4c6e79e7a2d0410826a68fbc0eccc0fd44aa733be199d5fcac3bb87/pydantic_core-2.46.3-cp314-cp314-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ed42e6cc8e1b0e2b9b96e2276bad70ae625d10d6d524aed0c93de974ae029f9f", size = 2099927, upload-time = "2026-04-20T14:41:40.196Z" }, + { url = "https://files.pythonhosted.org/packages/6d/53/269caf30e0096e0a8a8f929d1982a27b3879872cca2d917d17c2f9fdf4fe/pydantic_core-2.46.3-cp314-cp314-manylinux_2_31_riscv64.whl", hash = "sha256:f1771ce258afb3e4201e67d154edbbae712a76a6081079fe247c2f53c6322c22", size = 2128789, upload-time = "2026-04-20T14:41:15.868Z" }, + { url = "https://files.pythonhosted.org/packages/00/b0/1a6d9b6a587e118482910c244a1c5acf4d192604174132efd12bf0ac486f/pydantic_core-2.46.3-cp314-cp314-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:a7610b6a5242a6c736d8ad47fd5fff87fcfe8f833b281b1c409c3d6835d9227f", size = 2173815, upload-time = "2026-04-20T14:44:25.152Z" }, + { url = "https://files.pythonhosted.org/packages/87/56/e7e00d4041a7e62b5a40815590114db3b535bf3ca0bf4dca9f16cef25246/pydantic_core-2.46.3-cp314-cp314-musllinux_1_1_aarch64.whl", hash = "sha256:ff5e7783bcc5476e1db448bf268f11cb257b1c276d3e89f00b5727be86dd0127", size = 2181608, upload-time = "2026-04-20T14:41:28.933Z" }, + { url = "https://files.pythonhosted.org/packages/e8/22/4bd23c3d41f7c185d60808a1de83c76cf5aeabf792f6c636a55c3b1ec7f9/pydantic_core-2.46.3-cp314-cp314-musllinux_1_1_armv7l.whl", hash = "sha256:9d2e32edcc143bc01e95300671915d9ca052d4f745aa0a49c48d4803f8a85f2c", size = 2326968, upload-time = "2026-04-20T14:42:03.962Z" }, + { url = "https://files.pythonhosted.org/packages/24/ac/66cd45129e3915e5ade3b292cb3bc7fd537f58f8f8dbdaba6170f7cabb74/pydantic_core-2.46.3-cp314-cp314-musllinux_1_1_x86_64.whl", hash = "sha256:6e42d83d1c6b87fa56b521479cff237e626a292f3b31b6345c15a99121b454c1", size = 2369842, upload-time = "2026-04-20T14:41:35.52Z" }, + { url = "https://files.pythonhosted.org/packages/a2/51/dd4248abb84113615473aa20d5545b7c4cd73c8644003b5259686f93996c/pydantic_core-2.46.3-cp314-cp314-win32.whl", hash = "sha256:07bc6d2a28c3adb4f7c6ae46aa4f2d2929af127f587ed44057af50bf1ce0f505", size = 1959661, upload-time = "2026-04-20T14:41:00.042Z" }, + { url = "https://files.pythonhosted.org/packages/20/eb/59980e5f1ae54a3b86372bd9f0fa373ea2d402e8cdcd3459334430f91e91/pydantic_core-2.46.3-cp314-cp314-win_amd64.whl", hash = "sha256:8940562319bc621da30714617e6a7eaa6b98c84e8c685bcdc02d7ed5e7c7c44e", size = 2071686, upload-time = "2026-04-20T14:43:16.471Z" }, + { url = "https://files.pythonhosted.org/packages/8c/db/1cf77e5247047dfee34bc01fa9bca134854f528c8eb053e144298893d370/pydantic_core-2.46.3-cp314-cp314-win_arm64.whl", hash = "sha256:5dcbbcf4d22210ced8f837c96db941bdb078f419543472aca5d9a0bb7cddc7df", size = 2026907, upload-time = "2026-04-20T14:43:31.732Z" }, + { url = "https://files.pythonhosted.org/packages/57/c0/b3df9f6a543276eadba0a48487b082ca1f201745329d97dbfa287034a230/pydantic_core-2.46.3-cp314-cp314t-macosx_10_12_x86_64.whl", hash = "sha256:d0fe3dce1e836e418f912c1ad91c73357d03e556a4d286f441bf34fed2dbeecf", size = 2095047, upload-time = "2026-04-20T14:42:37.982Z" }, + { url = "https://files.pythonhosted.org/packages/66/57/886a938073b97556c168fd99e1a7305bb363cd30a6d2c76086bf0587b32a/pydantic_core-2.46.3-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:9ce92e58abc722dac1bf835a6798a60b294e48eb0e625ec9fd994b932ac5feee", size = 1934329, upload-time = "2026-04-20T14:43:49.655Z" }, + { url = "https://files.pythonhosted.org/packages/0b/7c/b42eaa5c34b13b07ecb51da21761297a9b8eb43044c864a035999998f328/pydantic_core-2.46.3-cp314-cp314t-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a03e6467f0f5ab796a486146d1b887b2dc5e5f9b3288898c1b1c3ad974e53e4a", size = 1974847, upload-time = "2026-04-20T14:42:10.737Z" }, + { url = "https://files.pythonhosted.org/packages/e6/9b/92b42db6543e7de4f99ae977101a2967b63122d4b6cf7773812da2d7d5b5/pydantic_core-2.46.3-cp314-cp314t-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:2798b6ba041b9d70acfb9071a2ea13c8456dd1e6a5555798e41ba7b0790e329c", size = 2041742, upload-time = "2026-04-20T14:40:44.262Z" }, + { url = "https://files.pythonhosted.org/packages/0f/19/46fbe1efabb5aa2834b43b9454e70f9a83ad9c338c1291e48bdc4fecf167/pydantic_core-2.46.3-cp314-cp314t-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:9be3e221bdc6d69abf294dcf7aff6af19c31a5cdcc8f0aa3b14be29df4bd03b1", size = 2236235, upload-time = "2026-04-20T14:41:27.307Z" }, + { url = "https://files.pythonhosted.org/packages/77/da/b3f95bc009ad60ec53120f5d16c6faa8cabdbe8a20d83849a1f2b8728148/pydantic_core-2.46.3-cp314-cp314t-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:f13936129ce841f2a5ddf6f126fea3c43cd128807b5a59588c37cf10178c2e64", size = 2282633, upload-time = "2026-04-20T14:44:33.271Z" }, + { url = "https://files.pythonhosted.org/packages/cc/6e/401336117722e28f32fb8220df676769d28ebdf08f2f4469646d404c43a3/pydantic_core-2.46.3-cp314-cp314t-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:28b5f2ef03416facccb1c6ef744c69793175fd27e44ef15669201601cf423acb", size = 2109679, upload-time = "2026-04-20T14:44:41.065Z" }, + { url = "https://files.pythonhosted.org/packages/fc/53/b289f9bc8756a32fe718c46f55afaeaf8d489ee18d1a1e7be1db73f42cc4/pydantic_core-2.46.3-cp314-cp314t-manylinux_2_31_riscv64.whl", hash = "sha256:830d1247d77ad23852314f069e9d7ddafeec5f684baf9d7e7065ed46a049c4e6", size = 2108342, upload-time = "2026-04-20T14:42:50.144Z" }, + { url = "https://files.pythonhosted.org/packages/10/5b/8292fc7c1f9111f1b2b7c1b0dcf1179edcd014fc3ea4517499f50b829d71/pydantic_core-2.46.3-cp314-cp314t-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:d0793c90c1a3c74966e7975eaef3ed30ebdff3260a0f815a62a22adc17e4c01c", size = 2157208, upload-time = "2026-04-20T14:42:08.133Z" }, + { url = "https://files.pythonhosted.org/packages/2b/9e/f80044e9ec07580f057a89fc131f78dda7a58751ddf52bbe05eaf31db50f/pydantic_core-2.46.3-cp314-cp314t-musllinux_1_1_aarch64.whl", hash = "sha256:d2d0aead851b66f5245ec0c4fb2612ef457f8bbafefdf65a2bf9d6bac6140f47", size = 2167237, upload-time = "2026-04-20T14:42:25.412Z" }, + { url = "https://files.pythonhosted.org/packages/f8/84/6781a1b037f3b96be9227edbd1101f6d3946746056231bf4ac48cdff1a8d/pydantic_core-2.46.3-cp314-cp314t-musllinux_1_1_armv7l.whl", hash = "sha256:2f40e4246676beb31c5ce77c38a55ca4e465c6b38d11ea1bd935420568e0b1ab", size = 2312540, upload-time = "2026-04-20T14:40:40.313Z" }, + { url = "https://files.pythonhosted.org/packages/3e/db/19c0839feeb728e7df03255581f198dfdf1c2aeb1e174a8420b63c5252e5/pydantic_core-2.46.3-cp314-cp314t-musllinux_1_1_x86_64.whl", hash = "sha256:cf489cf8986c543939aeee17a09c04d6ffb43bfef8ca16fcbcc5cfdcbed24dba", size = 2369556, upload-time = "2026-04-20T14:41:09.427Z" }, + { url = "https://files.pythonhosted.org/packages/e0/15/3228774cb7cd45f5f721ddf1b2242747f4eb834d0c491f0c02d606f09fed/pydantic_core-2.46.3-cp314-cp314t-win32.whl", hash = "sha256:ffe0883b56cfc05798bf994164d2b2ff03efe2d22022a2bb080f3b626176dd56", size = 1949756, upload-time = "2026-04-20T14:41:25.717Z" }, + { url = "https://files.pythonhosted.org/packages/b8/2a/c79cf53fd91e5a87e30d481809f52f9a60dd221e39de66455cf04deaad37/pydantic_core-2.46.3-cp314-cp314t-win_amd64.whl", hash = "sha256:706d9d0ce9cf4593d07270d8e9f53b161f90c57d315aeec4fb4fd7a8b10240d8", size = 2051305, upload-time = "2026-04-20T14:43:18.627Z" }, + { url = "https://files.pythonhosted.org/packages/0b/db/d8182a7f1d9343a032265aae186eb063fe26ca4c40f256b21e8da4498e89/pydantic_core-2.46.3-cp314-cp314t-win_arm64.whl", hash = "sha256:77706aeb41df6a76568434701e0917da10692da28cb69d5fb6919ce5fdb07374", size = 2026310, upload-time = "2026-04-20T14:41:01.778Z" }, + { url = "https://files.pythonhosted.org/packages/66/7f/03dbad45cd3aa9083fbc93c210ae8b005af67e4136a14186950a747c6874/pydantic_core-2.46.3-graalpy311-graalpy242_311_native-macosx_10_12_x86_64.whl", hash = "sha256:9715525891ed524a0a1eb6d053c74d4d4ad5017677fb00af0b7c2644a31bae46", size = 2105683, upload-time = "2026-04-20T14:42:19.779Z" }, + { url = "https://files.pythonhosted.org/packages/26/22/4dc186ac8ea6b257e9855031f51b62a9637beac4d68ac06bee02f046f836/pydantic_core-2.46.3-graalpy311-graalpy242_311_native-macosx_11_0_arm64.whl", hash = "sha256:9d2f400712a99a013aff420ef1eb9be077f8189a36c1e3ef87660b4e1088a874", size = 1940052, upload-time = "2026-04-20T14:43:59.274Z" }, + { url = "https://files.pythonhosted.org/packages/0d/ca/d376391a5aff1f2e8188960d7873543608130a870961c2b6b5236627c116/pydantic_core-2.46.3-graalpy311-graalpy242_311_native-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:bd2aab0e2e9dc2daf36bd2686c982535d5e7b1d930a1344a7bb6e82baab42a76", size = 1988172, upload-time = "2026-04-20T14:41:17.469Z" }, + { url = "https://files.pythonhosted.org/packages/0e/6b/523b9f85c23788755d6ab949329de692a2e3a584bc6beb67fef5e035aa9d/pydantic_core-2.46.3-graalpy311-graalpy242_311_native-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4e9d76736da5f362fabfeea6a69b13b7f2be405c6d6966f06b2f6bfff7e64531", size = 2128596, upload-time = "2026-04-20T14:40:41.707Z" }, + { url = "https://files.pythonhosted.org/packages/34/42/f426db557e8ab2791bc7562052299944a118655496fbff99914e564c0a94/pydantic_core-2.46.3-graalpy312-graalpy250_312_native-macosx_10_12_x86_64.whl", hash = "sha256:b12dd51f1187c2eb489af8e20f880362db98e954b54ab792fa5d92e8bcc6b803", size = 2091877, upload-time = "2026-04-20T14:43:27.091Z" }, + { url = "https://files.pythonhosted.org/packages/5c/4f/86a832a9d14df58e663bfdf4627dc00d3317c2bd583c4fb23390b0f04b8e/pydantic_core-2.46.3-graalpy312-graalpy250_312_native-macosx_11_0_arm64.whl", hash = "sha256:f00a0961b125f1a47af7bcc17f00782e12f4cd056f83416006b30111d941dfa3", size = 1932428, upload-time = "2026-04-20T14:40:45.781Z" }, + { url = "https://files.pythonhosted.org/packages/11/1a/fe857968954d93fb78e0d4b6df5c988c74c4aaa67181c60be7cfe327c0ca/pydantic_core-2.46.3-graalpy312-graalpy250_312_native-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:57697d7c056aca4bbb680200f96563e841a6386ac1129370a0102592f4dddff5", size = 1997550, upload-time = "2026-04-20T14:44:02.425Z" }, + { url = "https://files.pythonhosted.org/packages/17/eb/9d89ad2d9b0ba8cd65393d434471621b98912abb10fbe1df08e480ba57b5/pydantic_core-2.46.3-graalpy312-graalpy250_312_native-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:fd35aa21299def8db7ef4fe5c4ff862941a9a158ca7b63d61e66fe67d30416b4", size = 2137657, upload-time = "2026-04-20T14:42:45.149Z" }, + { url = "https://files.pythonhosted.org/packages/1f/da/99d40830684f81dec901cac521b5b91c095394cc1084b9433393cde1c2df/pydantic_core-2.46.3-pp311-pypy311_pp73-macosx_10_12_x86_64.whl", hash = "sha256:13afdd885f3d71280cf286b13b310ee0f7ccfefd1dbbb661514a474b726e2f25", size = 2107973, upload-time = "2026-04-20T14:42:06.175Z" }, + { url = "https://files.pythonhosted.org/packages/99/a5/87024121818d75bbb2a98ddbaf638e40e7a18b5e0f5492c9ca4b1b316107/pydantic_core-2.46.3-pp311-pypy311_pp73-macosx_11_0_arm64.whl", hash = "sha256:f91c0aff3e3ee0928edd1232c57f643a7a003e6edf1860bc3afcdc749cb513f3", size = 1947191, upload-time = "2026-04-20T14:43:14.319Z" }, + { url = "https://files.pythonhosted.org/packages/60/62/0c1acfe10945b83a6a59d19fbaa92f48825381509e5701b855c08f13db76/pydantic_core-2.46.3-pp311-pypy311_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6529d1d128321a58d30afcc97b49e98836542f68dd41b33c2e972bb9e5290536", size = 2123791, upload-time = "2026-04-20T14:43:22.766Z" }, + { url = "https://files.pythonhosted.org/packages/75/3e/3b2393b4c8f44285561dc30b00cf307a56a2eff7c483a824db3b8221ca51/pydantic_core-2.46.3-pp311-pypy311_pp73-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:975c267cff4f7e7272eacbe50f6cc03ca9a3da4c4fbd66fffd89c94c1e311aa1", size = 2153197, upload-time = "2026-04-20T14:44:27.932Z" }, + { url = "https://files.pythonhosted.org/packages/ba/75/5af02fb35505051eee727c061f2881c555ab4f8ddb2d42da715a42c9731b/pydantic_core-2.46.3-pp311-pypy311_pp73-musllinux_1_1_aarch64.whl", hash = "sha256:2b8e4f2bbdf71415c544b4b1138b8060db7b6611bc927e8064c769f64bed651c", size = 2181073, upload-time = "2026-04-20T14:43:20.729Z" }, + { url = "https://files.pythonhosted.org/packages/10/92/7e0e1bd9ca3c68305db037560ca2876f89b2647deb2f8b6319005de37505/pydantic_core-2.46.3-pp311-pypy311_pp73-musllinux_1_1_armv7l.whl", hash = "sha256:e61ea8e9fff9606d09178f577ff8ccdd7206ff73d6552bcec18e1033c4254b85", size = 2315886, upload-time = "2026-04-20T14:44:04.826Z" }, + { url = "https://files.pythonhosted.org/packages/b8/d8/101655f27eaf3e44558ead736b2795d12500598beed4683f279396fa186e/pydantic_core-2.46.3-pp311-pypy311_pp73-musllinux_1_1_x86_64.whl", hash = "sha256:b504bda01bafc69b6d3c7a0c7f039dcf60f47fab70e06fe23f57b5c75bdc82b8", size = 2360528, upload-time = "2026-04-20T14:40:47.431Z" }, + { url = "https://files.pythonhosted.org/packages/07/0f/1c34a74c8d07136f0d729ffe5e1fdab04fbdaa7684f61a92f92511a84a15/pydantic_core-2.46.3-pp311-pypy311_pp73-win_amd64.whl", hash = "sha256:b00b76f7142fc60c762ce579bd29c8fa44aaa56592dd3c54fab3928d0d4ca6ff", size = 2184144, upload-time = "2026-04-20T14:42:57Z" }, +] + +[[package]] +name = "pygments" +version = "2.20.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/c3/b2/bc9c9196916376152d655522fdcebac55e66de6603a76a02bca1b6414f6c/pygments-2.20.0.tar.gz", hash = "sha256:6757cd03768053ff99f3039c1a36d6c0aa0b263438fcab17520b30a303a82b5f", size = 4955991, upload-time = "2026-03-29T13:29:33.898Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/f4/7e/a72dd26f3b0f4f2bf1dd8923c85f7ceb43172af56d63c7383eb62b332364/pygments-2.20.0-py3-none-any.whl", hash = "sha256:81a9e26dd42fd28a23a2d169d86d7ac03b46e2f8b59ed4698fb4785f946d0176", size = 1231151, upload-time = "2026-03-29T13:29:30.038Z" }, +] + +[[package]] +name = "pytest" +version = "9.0.3" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "colorama", marker = "sys_platform == 'win32'" }, + { name = "exceptiongroup", marker = "python_full_version < '3.11'" }, + { name = "iniconfig" }, + { name = "packaging" }, + { name = "pluggy" }, + { name = "pygments" }, + { name = "tomli", marker = "python_full_version < '3.11'" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/7d/0d/549bd94f1a0a402dc8cf64563a117c0f3765662e2e668477624baeec44d5/pytest-9.0.3.tar.gz", hash = "sha256:b86ada508af81d19edeb213c681b1d48246c1a91d304c6c81a427674c17eb91c", size = 1572165, upload-time = "2026-04-07T17:16:18.027Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/d4/24/a372aaf5c9b7208e7112038812994107bc65a84cd00e0354a88c2c77a617/pytest-9.0.3-py3-none-any.whl", hash = "sha256:2c5efc453d45394fdd706ade797c0a81091eccd1d6e4bccfcd476e2b8e0ab5d9", size = 375249, upload-time = "2026-04-07T17:16:16.13Z" }, +] + +[[package]] +name = "python-discovery" +version = "1.2.2" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "filelock" }, + { name = "platformdirs" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/de/ef/3bae0e537cfe91e8431efcba4434463d2c5a65f5a89edd47c6cf2f03c55f/python_discovery-1.2.2.tar.gz", hash = "sha256:876e9c57139eb757cb5878cbdd9ae5379e5d96266c99ef731119e04fffe533bb", size = 58872, upload-time = "2026-04-07T17:28:49.249Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/d8/db/795879cc3ddfe338599bddea6388cc5100b088db0a4caf6e6c1af1c27e04/python_discovery-1.2.2-py3-none-any.whl", hash = "sha256:e1ae95d9af875e78f15e19aed0c6137ab1bb49c200f21f5061786490c9585c7a", size = 31894, upload-time = "2026-04-07T17:28:48.09Z" }, +] + +[[package]] +name = "pytokens" +version = "0.4.1" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/b6/34/b4e015b99031667a7b960f888889c5bd34ef585c85e1cb56a594b92836ac/pytokens-0.4.1.tar.gz", hash = "sha256:292052fe80923aae2260c073f822ceba21f3872ced9a68bb7953b348e561179a", size = 23015, upload-time = "2026-01-30T01:03:45.924Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/42/24/f206113e05cb8ef51b3850e7ef88f20da6f4bf932190ceb48bd3da103e10/pytokens-0.4.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:2a44ed93ea23415c54f3face3b65ef2b844d96aeb3455b8a69b3df6beab6acc5", size = 161522, upload-time = "2026-01-30T01:02:50.393Z" }, + { url = "https://files.pythonhosted.org/packages/d4/e9/06a6bf1b90c2ed81a9c7d2544232fe5d2891d1cd480e8a1809ca354a8eb2/pytokens-0.4.1-cp310-cp310-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:add8bf86b71a5d9fb5b89f023a80b791e04fba57960aa790cc6125f7f1d39dfe", size = 246945, upload-time = "2026-01-30T01:02:52.399Z" }, + { url = "https://files.pythonhosted.org/packages/69/66/f6fb1007a4c3d8b682d5d65b7c1fb33257587a5f782647091e3408abe0b8/pytokens-0.4.1-cp310-cp310-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:670d286910b531c7b7e3c0b453fd8156f250adb140146d234a82219459b9640c", size = 259525, upload-time = "2026-01-30T01:02:53.737Z" }, + { url = "https://files.pythonhosted.org/packages/04/92/086f89b4d622a18418bac74ab5db7f68cf0c21cf7cc92de6c7b919d76c88/pytokens-0.4.1-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:4e691d7f5186bd2842c14813f79f8884bb03f5995f0575272009982c5ac6c0f7", size = 262693, upload-time = "2026-01-30T01:02:54.871Z" }, + { url = "https://files.pythonhosted.org/packages/b4/7b/8b31c347cf94a3f900bdde750b2e9131575a61fdb620d3d3c75832262137/pytokens-0.4.1-cp310-cp310-win_amd64.whl", hash = "sha256:27b83ad28825978742beef057bfe406ad6ed524b2d28c252c5de7b4a6dd48fa2", size = 103567, upload-time = "2026-01-30T01:02:56.414Z" }, + { url = "https://files.pythonhosted.org/packages/3d/92/790ebe03f07b57e53b10884c329b9a1a308648fc083a6d4a39a10a28c8fc/pytokens-0.4.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:d70e77c55ae8380c91c0c18dea05951482e263982911fc7410b1ffd1dadd3440", size = 160864, upload-time = "2026-01-30T01:02:57.882Z" }, + { url = "https://files.pythonhosted.org/packages/13/25/a4f555281d975bfdd1eba731450e2fe3a95870274da73fb12c40aeae7625/pytokens-0.4.1-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:4a58d057208cb9075c144950d789511220b07636dd2e4708d5645d24de666bdc", size = 248565, upload-time = "2026-01-30T01:02:59.912Z" }, + { url = "https://files.pythonhosted.org/packages/17/50/bc0394b4ad5b1601be22fa43652173d47e4c9efbf0044c62e9a59b747c56/pytokens-0.4.1-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:b49750419d300e2b5a3813cf229d4e5a4c728dae470bcc89867a9ad6f25a722d", size = 260824, upload-time = "2026-01-30T01:03:01.471Z" }, + { url = "https://files.pythonhosted.org/packages/4e/54/3e04f9d92a4be4fc6c80016bc396b923d2a6933ae94b5f557c939c460ee0/pytokens-0.4.1-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:d9907d61f15bf7261d7e775bd5d7ee4d2930e04424bab1972591918497623a16", size = 264075, upload-time = "2026-01-30T01:03:04.143Z" }, + { url = "https://files.pythonhosted.org/packages/d1/1b/44b0326cb5470a4375f37988aea5d61b5cc52407143303015ebee94abfd6/pytokens-0.4.1-cp311-cp311-win_amd64.whl", hash = "sha256:ee44d0f85b803321710f9239f335aafe16553b39106384cef8e6de40cb4ef2f6", size = 103323, upload-time = "2026-01-30T01:03:05.412Z" }, + { url = "https://files.pythonhosted.org/packages/41/5d/e44573011401fb82e9d51e97f1290ceb377800fb4eed650b96f4753b499c/pytokens-0.4.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:140709331e846b728475786df8aeb27d24f48cbcf7bcd449f8de75cae7a45083", size = 160663, upload-time = "2026-01-30T01:03:06.473Z" }, + { url = "https://files.pythonhosted.org/packages/f0/e6/5bbc3019f8e6f21d09c41f8b8654536117e5e211a85d89212d59cbdab381/pytokens-0.4.1-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:6d6c4268598f762bc8e91f5dbf2ab2f61f7b95bdc07953b602db879b3c8c18e1", size = 255626, upload-time = "2026-01-30T01:03:08.177Z" }, + { url = "https://files.pythonhosted.org/packages/bf/3c/2d5297d82286f6f3d92770289fd439956b201c0a4fc7e72efb9b2293758e/pytokens-0.4.1-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:24afde1f53d95348b5a0eb19488661147285ca4dd7ed752bbc3e1c6242a304d1", size = 269779, upload-time = "2026-01-30T01:03:09.756Z" }, + { url = "https://files.pythonhosted.org/packages/20/01/7436e9ad693cebda0551203e0bf28f7669976c60ad07d6402098208476de/pytokens-0.4.1-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:5ad948d085ed6c16413eb5fec6b3e02fa00dc29a2534f088d3302c47eb59adf9", size = 268076, upload-time = "2026-01-30T01:03:10.957Z" }, + { url = "https://files.pythonhosted.org/packages/2e/df/533c82a3c752ba13ae7ef238b7f8cdd272cf1475f03c63ac6cf3fcfb00b6/pytokens-0.4.1-cp312-cp312-win_amd64.whl", hash = "sha256:3f901fe783e06e48e8cbdc82d631fca8f118333798193e026a50ce1b3757ea68", size = 103552, upload-time = "2026-01-30T01:03:12.066Z" }, + { url = "https://files.pythonhosted.org/packages/cb/dc/08b1a080372afda3cceb4f3c0a7ba2bde9d6a5241f1edb02a22a019ee147/pytokens-0.4.1-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:8bdb9d0ce90cbf99c525e75a2fa415144fd570a1ba987380190e8b786bc6ef9b", size = 160720, upload-time = "2026-01-30T01:03:13.843Z" }, + { url = "https://files.pythonhosted.org/packages/64/0c/41ea22205da480837a700e395507e6a24425151dfb7ead73343d6e2d7ffe/pytokens-0.4.1-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:5502408cab1cb18e128570f8d598981c68a50d0cbd7c61312a90507cd3a1276f", size = 254204, upload-time = "2026-01-30T01:03:14.886Z" }, + { url = "https://files.pythonhosted.org/packages/e0/d2/afe5c7f8607018beb99971489dbb846508f1b8f351fcefc225fcf4b2adc0/pytokens-0.4.1-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:29d1d8fb1030af4d231789959f21821ab6325e463f0503a61d204343c9b355d1", size = 268423, upload-time = "2026-01-30T01:03:15.936Z" }, + { url = "https://files.pythonhosted.org/packages/68/d4/00ffdbd370410c04e9591da9220a68dc1693ef7499173eb3e30d06e05ed1/pytokens-0.4.1-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:970b08dd6b86058b6dc07efe9e98414f5102974716232d10f32ff39701e841c4", size = 266859, upload-time = "2026-01-30T01:03:17.458Z" }, + { url = "https://files.pythonhosted.org/packages/a7/c9/c3161313b4ca0c601eeefabd3d3b576edaa9afdefd32da97210700e47652/pytokens-0.4.1-cp313-cp313-win_amd64.whl", hash = "sha256:9bd7d7f544d362576be74f9d5901a22f317efc20046efe2034dced238cbbfe78", size = 103520, upload-time = "2026-01-30T01:03:18.652Z" }, + { url = "https://files.pythonhosted.org/packages/8f/a7/b470f672e6fc5fee0a01d9e75005a0e617e162381974213a945fcd274843/pytokens-0.4.1-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:4a14d5f5fc78ce85e426aa159489e2d5961acf0e47575e08f35584009178e321", size = 160821, upload-time = "2026-01-30T01:03:19.684Z" }, + { url = "https://files.pythonhosted.org/packages/80/98/e83a36fe8d170c911f864bfded690d2542bfcfacb9c649d11a9e6eb9dc41/pytokens-0.4.1-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:97f50fd18543be72da51dd505e2ed20d2228c74e0464e4262e4899797803d7fa", size = 254263, upload-time = "2026-01-30T01:03:20.834Z" }, + { url = "https://files.pythonhosted.org/packages/0f/95/70d7041273890f9f97a24234c00b746e8da86df462620194cef1d411ddeb/pytokens-0.4.1-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:dc74c035f9bfca0255c1af77ddd2d6ae8419012805453e4b0e7513e17904545d", size = 268071, upload-time = "2026-01-30T01:03:21.888Z" }, + { url = "https://files.pythonhosted.org/packages/da/79/76e6d09ae19c99404656d7db9c35dfd20f2086f3eb6ecb496b5b31163bad/pytokens-0.4.1-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:f66a6bbe741bd431f6d741e617e0f39ec7257ca1f89089593479347cc4d13324", size = 271716, upload-time = "2026-01-30T01:03:23.633Z" }, + { url = "https://files.pythonhosted.org/packages/79/37/482e55fa1602e0a7ff012661d8c946bafdc05e480ea5a32f4f7e336d4aa9/pytokens-0.4.1-cp314-cp314-win_amd64.whl", hash = "sha256:b35d7e5ad269804f6697727702da3c517bb8a5228afa450ab0fa787732055fc9", size = 104539, upload-time = "2026-01-30T01:03:24.788Z" }, + { url = "https://files.pythonhosted.org/packages/30/e8/20e7db907c23f3d63b0be3b8a4fd1927f6da2395f5bcc7f72242bb963dfe/pytokens-0.4.1-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:8fcb9ba3709ff77e77f1c7022ff11d13553f3c30299a9fe246a166903e9091eb", size = 168474, upload-time = "2026-01-30T01:03:26.428Z" }, + { url = "https://files.pythonhosted.org/packages/d6/81/88a95ee9fafdd8f5f3452107748fd04c24930d500b9aba9738f3ade642cc/pytokens-0.4.1-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:79fc6b8699564e1f9b521582c35435f1bd32dd06822322ec44afdeba666d8cb3", size = 290473, upload-time = "2026-01-30T01:03:27.415Z" }, + { url = "https://files.pythonhosted.org/packages/cf/35/3aa899645e29b6375b4aed9f8d21df219e7c958c4c186b465e42ee0a06bf/pytokens-0.4.1-cp314-cp314t-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:d31b97b3de0f61571a124a00ffe9a81fb9939146c122c11060725bd5aea79975", size = 303485, upload-time = "2026-01-30T01:03:28.558Z" }, + { url = "https://files.pythonhosted.org/packages/52/a0/07907b6ff512674d9b201859f7d212298c44933633c946703a20c25e9d81/pytokens-0.4.1-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:967cf6e3fd4adf7de8fc73cd3043754ae79c36475c1c11d514fc72cf5490094a", size = 306698, upload-time = "2026-01-30T01:03:29.653Z" }, + { url = "https://files.pythonhosted.org/packages/39/2a/cbbf9250020a4a8dd53ba83a46c097b69e5eb49dd14e708f496f548c6612/pytokens-0.4.1-cp314-cp314t-win_amd64.whl", hash = "sha256:584c80c24b078eec1e227079d56dc22ff755e0ba8654d8383b2c549107528918", size = 116287, upload-time = "2026-01-30T01:03:30.912Z" }, + { url = "https://files.pythonhosted.org/packages/c6/78/397db326746f0a342855b81216ae1f0a32965deccfd7c830a2dbc66d2483/pytokens-0.4.1-py3-none-any.whl", hash = "sha256:26cef14744a8385f35d0e095dc8b3a7583f6c953c2e3d269c7f82484bf5ad2de", size = 13729, upload-time = "2026-01-30T01:03:45.029Z" }, +] + +[[package]] +name = "pyyaml" +version = "6.0.3" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/05/8e/961c0007c59b8dd7729d542c61a4d537767a59645b82a0b521206e1e25c2/pyyaml-6.0.3.tar.gz", hash = "sha256:d76623373421df22fb4cf8817020cbb7ef15c725b9d5e45f17e189bfc384190f", size = 130960, upload-time = "2025-09-25T21:33:16.546Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/f4/a0/39350dd17dd6d6c6507025c0e53aef67a9293a6d37d3511f23ea510d5800/pyyaml-6.0.3-cp310-cp310-macosx_10_13_x86_64.whl", hash = "sha256:214ed4befebe12df36bcc8bc2b64b396ca31be9304b8f59e25c11cf94a4c033b", size = 184227, upload-time = "2025-09-25T21:31:46.04Z" }, + { url = "https://files.pythonhosted.org/packages/05/14/52d505b5c59ce73244f59c7a50ecf47093ce4765f116cdb98286a71eeca2/pyyaml-6.0.3-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:02ea2dfa234451bbb8772601d7b8e426c2bfa197136796224e50e35a78777956", size = 174019, upload-time = "2025-09-25T21:31:47.706Z" }, + { url = "https://files.pythonhosted.org/packages/43/f7/0e6a5ae5599c838c696adb4e6330a59f463265bfa1e116cfd1fbb0abaaae/pyyaml-6.0.3-cp310-cp310-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:b30236e45cf30d2b8e7b3e85881719e98507abed1011bf463a8fa23e9c3e98a8", size = 740646, upload-time = "2025-09-25T21:31:49.21Z" }, + { url = "https://files.pythonhosted.org/packages/2f/3a/61b9db1d28f00f8fd0ae760459a5c4bf1b941baf714e207b6eb0657d2578/pyyaml-6.0.3-cp310-cp310-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:66291b10affd76d76f54fad28e22e51719ef9ba22b29e1d7d03d6777a9174198", size = 840793, upload-time = "2025-09-25T21:31:50.735Z" }, + { url = "https://files.pythonhosted.org/packages/7a/1e/7acc4f0e74c4b3d9531e24739e0ab832a5edf40e64fbae1a9c01941cabd7/pyyaml-6.0.3-cp310-cp310-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:9c7708761fccb9397fe64bbc0395abcae8c4bf7b0eac081e12b809bf47700d0b", size = 770293, upload-time = "2025-09-25T21:31:51.828Z" }, + { url = "https://files.pythonhosted.org/packages/8b/ef/abd085f06853af0cd59fa5f913d61a8eab65d7639ff2a658d18a25d6a89d/pyyaml-6.0.3-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:418cf3f2111bc80e0933b2cd8cd04f286338bb88bdc7bc8e6dd775ebde60b5e0", size = 732872, upload-time = "2025-09-25T21:31:53.282Z" }, + { url = "https://files.pythonhosted.org/packages/1f/15/2bc9c8faf6450a8b3c9fc5448ed869c599c0a74ba2669772b1f3a0040180/pyyaml-6.0.3-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:5e0b74767e5f8c593e8c9b5912019159ed0533c70051e9cce3e8b6aa699fcd69", size = 758828, upload-time = "2025-09-25T21:31:54.807Z" }, + { url = "https://files.pythonhosted.org/packages/a3/00/531e92e88c00f4333ce359e50c19b8d1de9fe8d581b1534e35ccfbc5f393/pyyaml-6.0.3-cp310-cp310-win32.whl", hash = "sha256:28c8d926f98f432f88adc23edf2e6d4921ac26fb084b028c733d01868d19007e", size = 142415, upload-time = "2025-09-25T21:31:55.885Z" }, + { url = "https://files.pythonhosted.org/packages/2a/fa/926c003379b19fca39dd4634818b00dec6c62d87faf628d1394e137354d4/pyyaml-6.0.3-cp310-cp310-win_amd64.whl", hash = "sha256:bdb2c67c6c1390b63c6ff89f210c8fd09d9a1217a465701eac7316313c915e4c", size = 158561, upload-time = "2025-09-25T21:31:57.406Z" }, + { url = "https://files.pythonhosted.org/packages/6d/16/a95b6757765b7b031c9374925bb718d55e0a9ba8a1b6a12d25962ea44347/pyyaml-6.0.3-cp311-cp311-macosx_10_13_x86_64.whl", hash = "sha256:44edc647873928551a01e7a563d7452ccdebee747728c1080d881d68af7b997e", size = 185826, upload-time = "2025-09-25T21:31:58.655Z" }, + { url = "https://files.pythonhosted.org/packages/16/19/13de8e4377ed53079ee996e1ab0a9c33ec2faf808a4647b7b4c0d46dd239/pyyaml-6.0.3-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:652cb6edd41e718550aad172851962662ff2681490a8a711af6a4d288dd96824", size = 175577, upload-time = "2025-09-25T21:32:00.088Z" }, + { url = "https://files.pythonhosted.org/packages/0c/62/d2eb46264d4b157dae1275b573017abec435397aa59cbcdab6fc978a8af4/pyyaml-6.0.3-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:10892704fc220243f5305762e276552a0395f7beb4dbf9b14ec8fd43b57f126c", size = 775556, upload-time = "2025-09-25T21:32:01.31Z" }, + { url = "https://files.pythonhosted.org/packages/10/cb/16c3f2cf3266edd25aaa00d6c4350381c8b012ed6f5276675b9eba8d9ff4/pyyaml-6.0.3-cp311-cp311-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:850774a7879607d3a6f50d36d04f00ee69e7fc816450e5f7e58d7f17f1ae5c00", size = 882114, upload-time = "2025-09-25T21:32:03.376Z" }, + { url = "https://files.pythonhosted.org/packages/71/60/917329f640924b18ff085ab889a11c763e0b573da888e8404ff486657602/pyyaml-6.0.3-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:b8bb0864c5a28024fac8a632c443c87c5aa6f215c0b126c449ae1a150412f31d", size = 806638, upload-time = "2025-09-25T21:32:04.553Z" }, + { url = "https://files.pythonhosted.org/packages/dd/6f/529b0f316a9fd167281a6c3826b5583e6192dba792dd55e3203d3f8e655a/pyyaml-6.0.3-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:1d37d57ad971609cf3c53ba6a7e365e40660e3be0e5175fa9f2365a379d6095a", size = 767463, upload-time = "2025-09-25T21:32:06.152Z" }, + { url = "https://files.pythonhosted.org/packages/f2/6a/b627b4e0c1dd03718543519ffb2f1deea4a1e6d42fbab8021936a4d22589/pyyaml-6.0.3-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:37503bfbfc9d2c40b344d06b2199cf0e96e97957ab1c1b546fd4f87e53e5d3e4", size = 794986, upload-time = "2025-09-25T21:32:07.367Z" }, + { url = "https://files.pythonhosted.org/packages/45/91/47a6e1c42d9ee337c4839208f30d9f09caa9f720ec7582917b264defc875/pyyaml-6.0.3-cp311-cp311-win32.whl", hash = "sha256:8098f252adfa6c80ab48096053f512f2321f0b998f98150cea9bd23d83e1467b", size = 142543, upload-time = "2025-09-25T21:32:08.95Z" }, + { url = "https://files.pythonhosted.org/packages/da/e3/ea007450a105ae919a72393cb06f122f288ef60bba2dc64b26e2646fa315/pyyaml-6.0.3-cp311-cp311-win_amd64.whl", hash = "sha256:9f3bfb4965eb874431221a3ff3fdcddc7e74e3b07799e0e84ca4a0f867d449bf", size = 158763, upload-time = "2025-09-25T21:32:09.96Z" }, + { url = "https://files.pythonhosted.org/packages/d1/33/422b98d2195232ca1826284a76852ad5a86fe23e31b009c9886b2d0fb8b2/pyyaml-6.0.3-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:7f047e29dcae44602496db43be01ad42fc6f1cc0d8cd6c83d342306c32270196", size = 182063, upload-time = "2025-09-25T21:32:11.445Z" }, + { url = "https://files.pythonhosted.org/packages/89/a0/6cf41a19a1f2f3feab0e9c0b74134aa2ce6849093d5517a0c550fe37a648/pyyaml-6.0.3-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:fc09d0aa354569bc501d4e787133afc08552722d3ab34836a80547331bb5d4a0", size = 173973, upload-time = "2025-09-25T21:32:12.492Z" }, + { url = "https://files.pythonhosted.org/packages/ed/23/7a778b6bd0b9a8039df8b1b1d80e2e2ad78aa04171592c8a5c43a56a6af4/pyyaml-6.0.3-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:9149cad251584d5fb4981be1ecde53a1ca46c891a79788c0df828d2f166bda28", size = 775116, upload-time = "2025-09-25T21:32:13.652Z" }, + { url = "https://files.pythonhosted.org/packages/65/30/d7353c338e12baef4ecc1b09e877c1970bd3382789c159b4f89d6a70dc09/pyyaml-6.0.3-cp312-cp312-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:5fdec68f91a0c6739b380c83b951e2c72ac0197ace422360e6d5a959d8d97b2c", size = 844011, upload-time = "2025-09-25T21:32:15.21Z" }, + { url = "https://files.pythonhosted.org/packages/8b/9d/b3589d3877982d4f2329302ef98a8026e7f4443c765c46cfecc8858c6b4b/pyyaml-6.0.3-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:ba1cc08a7ccde2d2ec775841541641e4548226580ab850948cbfda66a1befcdc", size = 807870, upload-time = "2025-09-25T21:32:16.431Z" }, + { url = "https://files.pythonhosted.org/packages/05/c0/b3be26a015601b822b97d9149ff8cb5ead58c66f981e04fedf4e762f4bd4/pyyaml-6.0.3-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:8dc52c23056b9ddd46818a57b78404882310fb473d63f17b07d5c40421e47f8e", size = 761089, upload-time = "2025-09-25T21:32:17.56Z" }, + { url = "https://files.pythonhosted.org/packages/be/8e/98435a21d1d4b46590d5459a22d88128103f8da4c2d4cb8f14f2a96504e1/pyyaml-6.0.3-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:41715c910c881bc081f1e8872880d3c650acf13dfa8214bad49ed4cede7c34ea", size = 790181, upload-time = "2025-09-25T21:32:18.834Z" }, + { url = "https://files.pythonhosted.org/packages/74/93/7baea19427dcfbe1e5a372d81473250b379f04b1bd3c4c5ff825e2327202/pyyaml-6.0.3-cp312-cp312-win32.whl", hash = "sha256:96b533f0e99f6579b3d4d4995707cf36df9100d67e0c8303a0c55b27b5f99bc5", size = 137658, upload-time = "2025-09-25T21:32:20.209Z" }, + { url = "https://files.pythonhosted.org/packages/86/bf/899e81e4cce32febab4fb42bb97dcdf66bc135272882d1987881a4b519e9/pyyaml-6.0.3-cp312-cp312-win_amd64.whl", hash = "sha256:5fcd34e47f6e0b794d17de1b4ff496c00986e1c83f7ab2fb8fcfe9616ff7477b", size = 154003, upload-time = "2025-09-25T21:32:21.167Z" }, + { url = "https://files.pythonhosted.org/packages/1a/08/67bd04656199bbb51dbed1439b7f27601dfb576fb864099c7ef0c3e55531/pyyaml-6.0.3-cp312-cp312-win_arm64.whl", hash = "sha256:64386e5e707d03a7e172c0701abfb7e10f0fb753ee1d773128192742712a98fd", size = 140344, upload-time = "2025-09-25T21:32:22.617Z" }, + { url = "https://files.pythonhosted.org/packages/d1/11/0fd08f8192109f7169db964b5707a2f1e8b745d4e239b784a5a1dd80d1db/pyyaml-6.0.3-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:8da9669d359f02c0b91ccc01cac4a67f16afec0dac22c2ad09f46bee0697eba8", size = 181669, upload-time = "2025-09-25T21:32:23.673Z" }, + { url = "https://files.pythonhosted.org/packages/b1/16/95309993f1d3748cd644e02e38b75d50cbc0d9561d21f390a76242ce073f/pyyaml-6.0.3-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:2283a07e2c21a2aa78d9c4442724ec1eb15f5e42a723b99cb3d822d48f5f7ad1", size = 173252, upload-time = "2025-09-25T21:32:25.149Z" }, + { url = "https://files.pythonhosted.org/packages/50/31/b20f376d3f810b9b2371e72ef5adb33879b25edb7a6d072cb7ca0c486398/pyyaml-6.0.3-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:ee2922902c45ae8ccada2c5b501ab86c36525b883eff4255313a253a3160861c", size = 767081, upload-time = "2025-09-25T21:32:26.575Z" }, + { url = "https://files.pythonhosted.org/packages/49/1e/a55ca81e949270d5d4432fbbd19dfea5321eda7c41a849d443dc92fd1ff7/pyyaml-6.0.3-cp313-cp313-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:a33284e20b78bd4a18c8c2282d549d10bc8408a2a7ff57653c0cf0b9be0afce5", size = 841159, upload-time = "2025-09-25T21:32:27.727Z" }, + { url = "https://files.pythonhosted.org/packages/74/27/e5b8f34d02d9995b80abcef563ea1f8b56d20134d8f4e5e81733b1feceb2/pyyaml-6.0.3-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:0f29edc409a6392443abf94b9cf89ce99889a1dd5376d94316ae5145dfedd5d6", size = 801626, upload-time = "2025-09-25T21:32:28.878Z" }, + { url = "https://files.pythonhosted.org/packages/f9/11/ba845c23988798f40e52ba45f34849aa8a1f2d4af4b798588010792ebad6/pyyaml-6.0.3-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:f7057c9a337546edc7973c0d3ba84ddcdf0daa14533c2065749c9075001090e6", size = 753613, upload-time = "2025-09-25T21:32:30.178Z" }, + { url = "https://files.pythonhosted.org/packages/3d/e0/7966e1a7bfc0a45bf0a7fb6b98ea03fc9b8d84fa7f2229e9659680b69ee3/pyyaml-6.0.3-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:eda16858a3cab07b80edaf74336ece1f986ba330fdb8ee0d6c0d68fe82bc96be", size = 794115, upload-time = "2025-09-25T21:32:31.353Z" }, + { url = "https://files.pythonhosted.org/packages/de/94/980b50a6531b3019e45ddeada0626d45fa85cbe22300844a7983285bed3b/pyyaml-6.0.3-cp313-cp313-win32.whl", hash = "sha256:d0eae10f8159e8fdad514efdc92d74fd8d682c933a6dd088030f3834bc8e6b26", size = 137427, upload-time = "2025-09-25T21:32:32.58Z" }, + { url = "https://files.pythonhosted.org/packages/97/c9/39d5b874e8b28845e4ec2202b5da735d0199dbe5b8fb85f91398814a9a46/pyyaml-6.0.3-cp313-cp313-win_amd64.whl", hash = "sha256:79005a0d97d5ddabfeeea4cf676af11e647e41d81c9a7722a193022accdb6b7c", size = 154090, upload-time = "2025-09-25T21:32:33.659Z" }, + { url = "https://files.pythonhosted.org/packages/73/e8/2bdf3ca2090f68bb3d75b44da7bbc71843b19c9f2b9cb9b0f4ab7a5a4329/pyyaml-6.0.3-cp313-cp313-win_arm64.whl", hash = "sha256:5498cd1645aa724a7c71c8f378eb29ebe23da2fc0d7a08071d89469bf1d2defb", size = 140246, upload-time = "2025-09-25T21:32:34.663Z" }, + { url = "https://files.pythonhosted.org/packages/9d/8c/f4bd7f6465179953d3ac9bc44ac1a8a3e6122cf8ada906b4f96c60172d43/pyyaml-6.0.3-cp314-cp314-macosx_10_13_x86_64.whl", hash = "sha256:8d1fab6bb153a416f9aeb4b8763bc0f22a5586065f86f7664fc23339fc1c1fac", size = 181814, upload-time = "2025-09-25T21:32:35.712Z" }, + { url = "https://files.pythonhosted.org/packages/bd/9c/4d95bb87eb2063d20db7b60faa3840c1b18025517ae857371c4dd55a6b3a/pyyaml-6.0.3-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:34d5fcd24b8445fadc33f9cf348c1047101756fd760b4dacb5c3e99755703310", size = 173809, upload-time = "2025-09-25T21:32:36.789Z" }, + { url = "https://files.pythonhosted.org/packages/92/b5/47e807c2623074914e29dabd16cbbdd4bf5e9b2db9f8090fa64411fc5382/pyyaml-6.0.3-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:501a031947e3a9025ed4405a168e6ef5ae3126c59f90ce0cd6f2bfc477be31b7", size = 766454, upload-time = "2025-09-25T21:32:37.966Z" }, + { url = "https://files.pythonhosted.org/packages/02/9e/e5e9b168be58564121efb3de6859c452fccde0ab093d8438905899a3a483/pyyaml-6.0.3-cp314-cp314-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:b3bc83488de33889877a0f2543ade9f70c67d66d9ebb4ac959502e12de895788", size = 836355, upload-time = "2025-09-25T21:32:39.178Z" }, + { url = "https://files.pythonhosted.org/packages/88/f9/16491d7ed2a919954993e48aa941b200f38040928474c9e85ea9e64222c3/pyyaml-6.0.3-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:c458b6d084f9b935061bc36216e8a69a7e293a2f1e68bf956dcd9e6cbcd143f5", size = 794175, upload-time = "2025-09-25T21:32:40.865Z" }, + { url = "https://files.pythonhosted.org/packages/dd/3f/5989debef34dc6397317802b527dbbafb2b4760878a53d4166579111411e/pyyaml-6.0.3-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:7c6610def4f163542a622a73fb39f534f8c101d690126992300bf3207eab9764", size = 755228, upload-time = "2025-09-25T21:32:42.084Z" }, + { url = "https://files.pythonhosted.org/packages/d7/ce/af88a49043cd2e265be63d083fc75b27b6ed062f5f9fd6cdc223ad62f03e/pyyaml-6.0.3-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:5190d403f121660ce8d1d2c1bb2ef1bd05b5f68533fc5c2ea899bd15f4399b35", size = 789194, upload-time = "2025-09-25T21:32:43.362Z" }, + { url = "https://files.pythonhosted.org/packages/23/20/bb6982b26a40bb43951265ba29d4c246ef0ff59c9fdcdf0ed04e0687de4d/pyyaml-6.0.3-cp314-cp314-win_amd64.whl", hash = "sha256:4a2e8cebe2ff6ab7d1050ecd59c25d4c8bd7e6f400f5f82b96557ac0abafd0ac", size = 156429, upload-time = "2025-09-25T21:32:57.844Z" }, + { url = "https://files.pythonhosted.org/packages/f4/f4/a4541072bb9422c8a883ab55255f918fa378ecf083f5b85e87fc2b4eda1b/pyyaml-6.0.3-cp314-cp314-win_arm64.whl", hash = "sha256:93dda82c9c22deb0a405ea4dc5f2d0cda384168e466364dec6255b293923b2f3", size = 143912, upload-time = "2025-09-25T21:32:59.247Z" }, + { url = "https://files.pythonhosted.org/packages/7c/f9/07dd09ae774e4616edf6cda684ee78f97777bdd15847253637a6f052a62f/pyyaml-6.0.3-cp314-cp314t-macosx_10_13_x86_64.whl", hash = "sha256:02893d100e99e03eda1c8fd5c441d8c60103fd175728e23e431db1b589cf5ab3", size = 189108, upload-time = "2025-09-25T21:32:44.377Z" }, + { url = "https://files.pythonhosted.org/packages/4e/78/8d08c9fb7ce09ad8c38ad533c1191cf27f7ae1effe5bb9400a46d9437fcf/pyyaml-6.0.3-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:c1ff362665ae507275af2853520967820d9124984e0f7466736aea23d8611fba", size = 183641, upload-time = "2025-09-25T21:32:45.407Z" }, + { url = "https://files.pythonhosted.org/packages/7b/5b/3babb19104a46945cf816d047db2788bcaf8c94527a805610b0289a01c6b/pyyaml-6.0.3-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:6adc77889b628398debc7b65c073bcb99c4a0237b248cacaf3fe8a557563ef6c", size = 831901, upload-time = "2025-09-25T21:32:48.83Z" }, + { url = "https://files.pythonhosted.org/packages/8b/cc/dff0684d8dc44da4d22a13f35f073d558c268780ce3c6ba1b87055bb0b87/pyyaml-6.0.3-cp314-cp314t-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:a80cb027f6b349846a3bf6d73b5e95e782175e52f22108cfa17876aaeff93702", size = 861132, upload-time = "2025-09-25T21:32:50.149Z" }, + { url = "https://files.pythonhosted.org/packages/b1/5e/f77dc6b9036943e285ba76b49e118d9ea929885becb0a29ba8a7c75e29fe/pyyaml-6.0.3-cp314-cp314t-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:00c4bdeba853cc34e7dd471f16b4114f4162dc03e6b7afcc2128711f0eca823c", size = 839261, upload-time = "2025-09-25T21:32:51.808Z" }, + { url = "https://files.pythonhosted.org/packages/ce/88/a9db1376aa2a228197c58b37302f284b5617f56a5d959fd1763fb1675ce6/pyyaml-6.0.3-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:66e1674c3ef6f541c35191caae2d429b967b99e02040f5ba928632d9a7f0f065", size = 805272, upload-time = "2025-09-25T21:32:52.941Z" }, + { url = "https://files.pythonhosted.org/packages/da/92/1446574745d74df0c92e6aa4a7b0b3130706a4142b2d1a5869f2eaa423c6/pyyaml-6.0.3-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:16249ee61e95f858e83976573de0f5b2893b3677ba71c9dd36b9cf8be9ac6d65", size = 829923, upload-time = "2025-09-25T21:32:54.537Z" }, + { url = "https://files.pythonhosted.org/packages/f0/7a/1c7270340330e575b92f397352af856a8c06f230aa3e76f86b39d01b416a/pyyaml-6.0.3-cp314-cp314t-win_amd64.whl", hash = "sha256:4ad1906908f2f5ae4e5a8ddfce73c320c2a1429ec52eafd27138b7f1cbe341c9", size = 174062, upload-time = "2025-09-25T21:32:55.767Z" }, + { url = "https://files.pythonhosted.org/packages/f1/12/de94a39c2ef588c7e6455cfbe7343d3b2dc9d6b6b2f40c4c6565744c873d/pyyaml-6.0.3-cp314-cp314t-win_arm64.whl", hash = "sha256:ebc55a14a21cb14062aa4162f906cd962b28e2e9ea38f9b4391244cd8de4ae0b", size = 149341, upload-time = "2025-09-25T21:32:56.828Z" }, +] + +[[package]] +name = "referencing" +version = "0.37.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "attrs" }, + { name = "rpds-py" }, + { name = "typing-extensions", marker = "python_full_version < '3.13'" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/22/f5/df4e9027acead3ecc63e50fe1e36aca1523e1719559c499951bb4b53188f/referencing-0.37.0.tar.gz", hash = "sha256:44aefc3142c5b842538163acb373e24cce6632bd54bdb01b21ad5863489f50d8", size = 78036, upload-time = "2025-10-13T15:30:48.871Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/2c/58/ca301544e1fa93ed4f80d724bf5b194f6e4b945841c5bfd555878eea9fcb/referencing-0.37.0-py3-none-any.whl", hash = "sha256:381329a9f99628c9069361716891d34ad94af76e461dcb0335825aecc7692231", size = 26766, upload-time = "2025-10-13T15:30:47.625Z" }, +] + +[[package]] +name = "rpds-py" +version = "0.30.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/20/af/3f2f423103f1113b36230496629986e0ef7e199d2aa8392452b484b38ced/rpds_py-0.30.0.tar.gz", hash = "sha256:dd8ff7cf90014af0c0f787eea34794ebf6415242ee1d6fa91eaba725cc441e84", size = 69469, upload-time = "2025-11-30T20:24:38.837Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/06/0c/0c411a0ec64ccb6d104dcabe0e713e05e153a9a2c3c2bd2b32ce412166fe/rpds_py-0.30.0-cp310-cp310-macosx_10_12_x86_64.whl", hash = "sha256:679ae98e00c0e8d68a7fda324e16b90fd5260945b45d3b824c892cec9eea3288", size = 370490, upload-time = "2025-11-30T20:21:33.256Z" }, + { url = "https://files.pythonhosted.org/packages/19/6a/4ba3d0fb7297ebae71171822554abe48d7cab29c28b8f9f2c04b79988c05/rpds_py-0.30.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:4cc2206b76b4f576934f0ed374b10d7ca5f457858b157ca52064bdfc26b9fc00", size = 359751, upload-time = "2025-11-30T20:21:34.591Z" }, + { url = "https://files.pythonhosted.org/packages/cd/7c/e4933565ef7f7a0818985d87c15d9d273f1a649afa6a52ea35ad011195ea/rpds_py-0.30.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:389a2d49eded1896c3d48b0136ead37c48e221b391c052fba3f4055c367f60a6", size = 389696, upload-time = "2025-11-30T20:21:36.122Z" }, + { url = "https://files.pythonhosted.org/packages/5e/01/6271a2511ad0815f00f7ed4390cf2567bec1d4b1da39e2c27a41e6e3b4de/rpds_py-0.30.0-cp310-cp310-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:32c8528634e1bf7121f3de08fa85b138f4e0dc47657866630611b03967f041d7", size = 403136, upload-time = "2025-11-30T20:21:37.728Z" }, + { url = "https://files.pythonhosted.org/packages/55/64/c857eb7cd7541e9b4eee9d49c196e833128a55b89a9850a9c9ac33ccf897/rpds_py-0.30.0-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:f207f69853edd6f6700b86efb84999651baf3789e78a466431df1331608e5324", size = 524699, upload-time = "2025-11-30T20:21:38.92Z" }, + { url = "https://files.pythonhosted.org/packages/9c/ed/94816543404078af9ab26159c44f9e98e20fe47e2126d5d32c9d9948d10a/rpds_py-0.30.0-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:67b02ec25ba7a9e8fa74c63b6ca44cf5707f2fbfadae3ee8e7494297d56aa9df", size = 412022, upload-time = "2025-11-30T20:21:40.407Z" }, + { url = "https://files.pythonhosted.org/packages/61/b5/707f6cf0066a6412aacc11d17920ea2e19e5b2f04081c64526eb35b5c6e7/rpds_py-0.30.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0c0e95f6819a19965ff420f65578bacb0b00f251fefe2c8b23347c37174271f3", size = 390522, upload-time = "2025-11-30T20:21:42.17Z" }, + { url = "https://files.pythonhosted.org/packages/13/4e/57a85fda37a229ff4226f8cbcf09f2a455d1ed20e802ce5b2b4a7f5ed053/rpds_py-0.30.0-cp310-cp310-manylinux_2_31_riscv64.whl", hash = "sha256:a452763cc5198f2f98898eb98f7569649fe5da666c2dc6b5ddb10fde5a574221", size = 404579, upload-time = "2025-11-30T20:21:43.769Z" }, + { url = "https://files.pythonhosted.org/packages/f9/da/c9339293513ec680a721e0e16bf2bac3db6e5d7e922488de471308349bba/rpds_py-0.30.0-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:e0b65193a413ccc930671c55153a03ee57cecb49e6227204b04fae512eb657a7", size = 421305, upload-time = "2025-11-30T20:21:44.994Z" }, + { url = "https://files.pythonhosted.org/packages/f9/be/522cb84751114f4ad9d822ff5a1aa3c98006341895d5f084779b99596e5c/rpds_py-0.30.0-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:858738e9c32147f78b3ac24dc0edb6610000e56dc0f700fd5f651d0a0f0eb9ff", size = 572503, upload-time = "2025-11-30T20:21:46.91Z" }, + { url = "https://files.pythonhosted.org/packages/a2/9b/de879f7e7ceddc973ea6e4629e9b380213a6938a249e94b0cdbcc325bb66/rpds_py-0.30.0-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:da279aa314f00acbb803da1e76fa18666778e8a8f83484fba94526da5de2cba7", size = 598322, upload-time = "2025-11-30T20:21:48.709Z" }, + { url = "https://files.pythonhosted.org/packages/48/ac/f01fc22efec3f37d8a914fc1b2fb9bcafd56a299edbe96406f3053edea5a/rpds_py-0.30.0-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:7c64d38fb49b6cdeda16ab49e35fe0da2e1e9b34bc38bd78386530f218b37139", size = 560792, upload-time = "2025-11-30T20:21:50.024Z" }, + { url = "https://files.pythonhosted.org/packages/e2/da/4e2b19d0f131f35b6146425f846563d0ce036763e38913d917187307a671/rpds_py-0.30.0-cp310-cp310-win32.whl", hash = "sha256:6de2a32a1665b93233cde140ff8b3467bdb9e2af2b91079f0333a0974d12d464", size = 221901, upload-time = "2025-11-30T20:21:51.32Z" }, + { url = "https://files.pythonhosted.org/packages/96/cb/156d7a5cf4f78a7cc571465d8aec7a3c447c94f6749c5123f08438bcf7bc/rpds_py-0.30.0-cp310-cp310-win_amd64.whl", hash = "sha256:1726859cd0de969f88dc8673bdd954185b9104e05806be64bcd87badbe313169", size = 235823, upload-time = "2025-11-30T20:21:52.505Z" }, + { url = "https://files.pythonhosted.org/packages/4d/6e/f964e88b3d2abee2a82c1ac8366da848fce1c6d834dc2132c3fda3970290/rpds_py-0.30.0-cp311-cp311-macosx_10_12_x86_64.whl", hash = "sha256:a2bffea6a4ca9f01b3f8e548302470306689684e61602aa3d141e34da06cf425", size = 370157, upload-time = "2025-11-30T20:21:53.789Z" }, + { url = "https://files.pythonhosted.org/packages/94/ba/24e5ebb7c1c82e74c4e4f33b2112a5573ddc703915b13a073737b59b86e0/rpds_py-0.30.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:dc4f992dfe1e2bc3ebc7444f6c7051b4bc13cd8e33e43511e8ffd13bf407010d", size = 359676, upload-time = "2025-11-30T20:21:55.475Z" }, + { url = "https://files.pythonhosted.org/packages/84/86/04dbba1b087227747d64d80c3b74df946b986c57af0a9f0c98726d4d7a3b/rpds_py-0.30.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:422c3cb9856d80b09d30d2eb255d0754b23e090034e1deb4083f8004bd0761e4", size = 389938, upload-time = "2025-11-30T20:21:57.079Z" }, + { url = "https://files.pythonhosted.org/packages/42/bb/1463f0b1722b7f45431bdd468301991d1328b16cffe0b1c2918eba2c4eee/rpds_py-0.30.0-cp311-cp311-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:07ae8a593e1c3c6b82ca3292efbe73c30b61332fd612e05abee07c79359f292f", size = 402932, upload-time = "2025-11-30T20:21:58.47Z" }, + { url = "https://files.pythonhosted.org/packages/99/ee/2520700a5c1f2d76631f948b0736cdf9b0acb25abd0ca8e889b5c62ac2e3/rpds_py-0.30.0-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:12f90dd7557b6bd57f40abe7747e81e0c0b119bef015ea7726e69fe550e394a4", size = 525830, upload-time = "2025-11-30T20:21:59.699Z" }, + { url = "https://files.pythonhosted.org/packages/e0/ad/bd0331f740f5705cc555a5e17fdf334671262160270962e69a2bdef3bf76/rpds_py-0.30.0-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:99b47d6ad9a6da00bec6aabe5a6279ecd3c06a329d4aa4771034a21e335c3a97", size = 412033, upload-time = "2025-11-30T20:22:00.991Z" }, + { url = "https://files.pythonhosted.org/packages/f8/1e/372195d326549bb51f0ba0f2ecb9874579906b97e08880e7a65c3bef1a99/rpds_py-0.30.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:33f559f3104504506a44bb666b93a33f5d33133765b0c216a5bf2f1e1503af89", size = 390828, upload-time = "2025-11-30T20:22:02.723Z" }, + { url = "https://files.pythonhosted.org/packages/ab/2b/d88bb33294e3e0c76bc8f351a3721212713629ffca1700fa94979cb3eae8/rpds_py-0.30.0-cp311-cp311-manylinux_2_31_riscv64.whl", hash = "sha256:946fe926af6e44f3697abbc305ea168c2c31d3e3ef1058cf68f379bf0335a78d", size = 404683, upload-time = "2025-11-30T20:22:04.367Z" }, + { url = "https://files.pythonhosted.org/packages/50/32/c759a8d42bcb5289c1fac697cd92f6fe01a018dd937e62ae77e0e7f15702/rpds_py-0.30.0-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:495aeca4b93d465efde585977365187149e75383ad2684f81519f504f5c13038", size = 421583, upload-time = "2025-11-30T20:22:05.814Z" }, + { url = "https://files.pythonhosted.org/packages/2b/81/e729761dbd55ddf5d84ec4ff1f47857f4374b0f19bdabfcf929164da3e24/rpds_py-0.30.0-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:d9a0ca5da0386dee0655b4ccdf46119df60e0f10da268d04fe7cc87886872ba7", size = 572496, upload-time = "2025-11-30T20:22:07.713Z" }, + { url = "https://files.pythonhosted.org/packages/14/f6/69066a924c3557c9c30baa6ec3a0aa07526305684c6f86c696b08860726c/rpds_py-0.30.0-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:8d6d1cc13664ec13c1b84241204ff3b12f9bb82464b8ad6e7a5d3486975c2eed", size = 598669, upload-time = "2025-11-30T20:22:09.312Z" }, + { url = "https://files.pythonhosted.org/packages/5f/48/905896b1eb8a05630d20333d1d8ffd162394127b74ce0b0784ae04498d32/rpds_py-0.30.0-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:3896fa1be39912cf0757753826bc8bdc8ca331a28a7c4ae46b7a21280b06bb85", size = 561011, upload-time = "2025-11-30T20:22:11.309Z" }, + { url = "https://files.pythonhosted.org/packages/22/16/cd3027c7e279d22e5eb431dd3c0fbc677bed58797fe7581e148f3f68818b/rpds_py-0.30.0-cp311-cp311-win32.whl", hash = "sha256:55f66022632205940f1827effeff17c4fa7ae1953d2b74a8581baaefb7d16f8c", size = 221406, upload-time = "2025-11-30T20:22:13.101Z" }, + { url = "https://files.pythonhosted.org/packages/fa/5b/e7b7aa136f28462b344e652ee010d4de26ee9fd16f1bfd5811f5153ccf89/rpds_py-0.30.0-cp311-cp311-win_amd64.whl", hash = "sha256:a51033ff701fca756439d641c0ad09a41d9242fa69121c7d8769604a0a629825", size = 236024, upload-time = "2025-11-30T20:22:14.853Z" }, + { url = "https://files.pythonhosted.org/packages/14/a6/364bba985e4c13658edb156640608f2c9e1d3ea3c81b27aa9d889fff0e31/rpds_py-0.30.0-cp311-cp311-win_arm64.whl", hash = "sha256:47b0ef6231c58f506ef0b74d44e330405caa8428e770fec25329ed2cb971a229", size = 229069, upload-time = "2025-11-30T20:22:16.577Z" }, + { url = "https://files.pythonhosted.org/packages/03/e7/98a2f4ac921d82f33e03f3835f5bf3a4a40aa1bfdc57975e74a97b2b4bdd/rpds_py-0.30.0-cp312-cp312-macosx_10_12_x86_64.whl", hash = "sha256:a161f20d9a43006833cd7068375a94d035714d73a172b681d8881820600abfad", size = 375086, upload-time = "2025-11-30T20:22:17.93Z" }, + { url = "https://files.pythonhosted.org/packages/4d/a1/bca7fd3d452b272e13335db8d6b0b3ecde0f90ad6f16f3328c6fb150c889/rpds_py-0.30.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:6abc8880d9d036ecaafe709079969f56e876fcf107f7a8e9920ba6d5a3878d05", size = 359053, upload-time = "2025-11-30T20:22:19.297Z" }, + { url = "https://files.pythonhosted.org/packages/65/1c/ae157e83a6357eceff62ba7e52113e3ec4834a84cfe07fa4b0757a7d105f/rpds_py-0.30.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ca28829ae5f5d569bb62a79512c842a03a12576375d5ece7d2cadf8abe96ec28", size = 390763, upload-time = "2025-11-30T20:22:21.661Z" }, + { url = "https://files.pythonhosted.org/packages/d4/36/eb2eb8515e2ad24c0bd43c3ee9cd74c33f7ca6430755ccdb240fd3144c44/rpds_py-0.30.0-cp312-cp312-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:a1010ed9524c73b94d15919ca4d41d8780980e1765babf85f9a2f90d247153dd", size = 408951, upload-time = "2025-11-30T20:22:23.408Z" }, + { url = "https://files.pythonhosted.org/packages/d6/65/ad8dc1784a331fabbd740ef6f71ce2198c7ed0890dab595adb9ea2d775a1/rpds_py-0.30.0-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:f8d1736cfb49381ba528cd5baa46f82fdc65c06e843dab24dd70b63d09121b3f", size = 514622, upload-time = "2025-11-30T20:22:25.16Z" }, + { url = "https://files.pythonhosted.org/packages/63/8e/0cfa7ae158e15e143fe03993b5bcd743a59f541f5952e1546b1ac1b5fd45/rpds_py-0.30.0-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:d948b135c4693daff7bc2dcfc4ec57237a29bd37e60c2fabf5aff2bbacf3e2f1", size = 414492, upload-time = "2025-11-30T20:22:26.505Z" }, + { url = "https://files.pythonhosted.org/packages/60/1b/6f8f29f3f995c7ffdde46a626ddccd7c63aefc0efae881dc13b6e5d5bb16/rpds_py-0.30.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:47f236970bccb2233267d89173d3ad2703cd36a0e2a6e92d0560d333871a3d23", size = 394080, upload-time = "2025-11-30T20:22:27.934Z" }, + { url = "https://files.pythonhosted.org/packages/6d/d5/a266341051a7a3ca2f4b750a3aa4abc986378431fc2da508c5034d081b70/rpds_py-0.30.0-cp312-cp312-manylinux_2_31_riscv64.whl", hash = "sha256:2e6ecb5a5bcacf59c3f912155044479af1d0b6681280048b338b28e364aca1f6", size = 408680, upload-time = "2025-11-30T20:22:29.341Z" }, + { url = "https://files.pythonhosted.org/packages/10/3b/71b725851df9ab7a7a4e33cf36d241933da66040d195a84781f49c50490c/rpds_py-0.30.0-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:a8fa71a2e078c527c3e9dc9fc5a98c9db40bcc8a92b4e8858e36d329f8684b51", size = 423589, upload-time = "2025-11-30T20:22:31.469Z" }, + { url = "https://files.pythonhosted.org/packages/00/2b/e59e58c544dc9bd8bd8384ecdb8ea91f6727f0e37a7131baeff8d6f51661/rpds_py-0.30.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:73c67f2db7bc334e518d097c6d1e6fed021bbc9b7d678d6cc433478365d1d5f5", size = 573289, upload-time = "2025-11-30T20:22:32.997Z" }, + { url = "https://files.pythonhosted.org/packages/da/3e/a18e6f5b460893172a7d6a680e86d3b6bc87a54c1f0b03446a3c8c7b588f/rpds_py-0.30.0-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:5ba103fb455be00f3b1c2076c9d4264bfcb037c976167a6047ed82f23153f02e", size = 599737, upload-time = "2025-11-30T20:22:34.419Z" }, + { url = "https://files.pythonhosted.org/packages/5c/e2/714694e4b87b85a18e2c243614974413c60aa107fd815b8cbc42b873d1d7/rpds_py-0.30.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:7cee9c752c0364588353e627da8a7e808a66873672bcb5f52890c33fd965b394", size = 563120, upload-time = "2025-11-30T20:22:35.903Z" }, + { url = "https://files.pythonhosted.org/packages/6f/ab/d5d5e3bcedb0a77f4f613706b750e50a5a3ba1c15ccd3665ecc636c968fd/rpds_py-0.30.0-cp312-cp312-win32.whl", hash = "sha256:1ab5b83dbcf55acc8b08fc62b796ef672c457b17dbd7820a11d6c52c06839bdf", size = 223782, upload-time = "2025-11-30T20:22:37.271Z" }, + { url = "https://files.pythonhosted.org/packages/39/3b/f786af9957306fdc38a74cef405b7b93180f481fb48453a114bb6465744a/rpds_py-0.30.0-cp312-cp312-win_amd64.whl", hash = "sha256:a090322ca841abd453d43456ac34db46e8b05fd9b3b4ac0c78bcde8b089f959b", size = 240463, upload-time = "2025-11-30T20:22:39.021Z" }, + { url = "https://files.pythonhosted.org/packages/f3/d2/b91dc748126c1559042cfe41990deb92c4ee3e2b415f6b5234969ffaf0cc/rpds_py-0.30.0-cp312-cp312-win_arm64.whl", hash = "sha256:669b1805bd639dd2989b281be2cfd951c6121b65e729d9b843e9639ef1fd555e", size = 230868, upload-time = "2025-11-30T20:22:40.493Z" }, + { url = "https://files.pythonhosted.org/packages/ed/dc/d61221eb88ff410de3c49143407f6f3147acf2538c86f2ab7ce65ae7d5f9/rpds_py-0.30.0-cp313-cp313-macosx_10_12_x86_64.whl", hash = "sha256:f83424d738204d9770830d35290ff3273fbb02b41f919870479fab14b9d303b2", size = 374887, upload-time = "2025-11-30T20:22:41.812Z" }, + { url = "https://files.pythonhosted.org/packages/fd/32/55fb50ae104061dbc564ef15cc43c013dc4a9f4527a1f4d99baddf56fe5f/rpds_py-0.30.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:e7536cd91353c5273434b4e003cbda89034d67e7710eab8761fd918ec6c69cf8", size = 358904, upload-time = "2025-11-30T20:22:43.479Z" }, + { url = "https://files.pythonhosted.org/packages/58/70/faed8186300e3b9bdd138d0273109784eea2396c68458ed580f885dfe7ad/rpds_py-0.30.0-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:2771c6c15973347f50fece41fc447c054b7ac2ae0502388ce3b6738cd366e3d4", size = 389945, upload-time = "2025-11-30T20:22:44.819Z" }, + { url = "https://files.pythonhosted.org/packages/bd/a8/073cac3ed2c6387df38f71296d002ab43496a96b92c823e76f46b8af0543/rpds_py-0.30.0-cp313-cp313-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:0a59119fc6e3f460315fe9d08149f8102aa322299deaa5cab5b40092345c2136", size = 407783, upload-time = "2025-11-30T20:22:46.103Z" }, + { url = "https://files.pythonhosted.org/packages/77/57/5999eb8c58671f1c11eba084115e77a8899d6e694d2a18f69f0ba471ec8b/rpds_py-0.30.0-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:76fec018282b4ead0364022e3c54b60bf368b9d926877957a8624b58419169b7", size = 515021, upload-time = "2025-11-30T20:22:47.458Z" }, + { url = "https://files.pythonhosted.org/packages/e0/af/5ab4833eadc36c0a8ed2bc5c0de0493c04f6c06de223170bd0798ff98ced/rpds_py-0.30.0-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:692bef75a5525db97318e8cd061542b5a79812d711ea03dbc1f6f8dbb0c5f0d2", size = 414589, upload-time = "2025-11-30T20:22:48.872Z" }, + { url = "https://files.pythonhosted.org/packages/b7/de/f7192e12b21b9e9a68a6d0f249b4af3fdcdff8418be0767a627564afa1f1/rpds_py-0.30.0-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9027da1ce107104c50c81383cae773ef5c24d296dd11c99e2629dbd7967a20c6", size = 394025, upload-time = "2025-11-30T20:22:50.196Z" }, + { url = "https://files.pythonhosted.org/packages/91/c4/fc70cd0249496493500e7cc2de87504f5aa6509de1e88623431fec76d4b6/rpds_py-0.30.0-cp313-cp313-manylinux_2_31_riscv64.whl", hash = "sha256:9cf69cdda1f5968a30a359aba2f7f9aa648a9ce4b580d6826437f2b291cfc86e", size = 408895, upload-time = "2025-11-30T20:22:51.87Z" }, + { url = "https://files.pythonhosted.org/packages/58/95/d9275b05ab96556fefff73a385813eb66032e4c99f411d0795372d9abcea/rpds_py-0.30.0-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:a4796a717bf12b9da9d3ad002519a86063dcac8988b030e405704ef7d74d2d9d", size = 422799, upload-time = "2025-11-30T20:22:53.341Z" }, + { url = "https://files.pythonhosted.org/packages/06/c1/3088fc04b6624eb12a57eb814f0d4997a44b0d208d6cace713033ff1a6ba/rpds_py-0.30.0-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:5d4c2aa7c50ad4728a094ebd5eb46c452e9cb7edbfdb18f9e1221f597a73e1e7", size = 572731, upload-time = "2025-11-30T20:22:54.778Z" }, + { url = "https://files.pythonhosted.org/packages/d8/42/c612a833183b39774e8ac8fecae81263a68b9583ee343db33ab571a7ce55/rpds_py-0.30.0-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:ba81a9203d07805435eb06f536d95a266c21e5b2dfbf6517748ca40c98d19e31", size = 599027, upload-time = "2025-11-30T20:22:56.212Z" }, + { url = "https://files.pythonhosted.org/packages/5f/60/525a50f45b01d70005403ae0e25f43c0384369ad24ffe46e8d9068b50086/rpds_py-0.30.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:945dccface01af02675628334f7cf49c2af4c1c904748efc5cf7bbdf0b579f95", size = 563020, upload-time = "2025-11-30T20:22:58.2Z" }, + { url = "https://files.pythonhosted.org/packages/0b/5d/47c4655e9bcd5ca907148535c10e7d489044243cc9941c16ed7cd53be91d/rpds_py-0.30.0-cp313-cp313-win32.whl", hash = "sha256:b40fb160a2db369a194cb27943582b38f79fc4887291417685f3ad693c5a1d5d", size = 223139, upload-time = "2025-11-30T20:23:00.209Z" }, + { url = "https://files.pythonhosted.org/packages/f2/e1/485132437d20aa4d3e1d8b3fb5a5e65aa8139f1e097080c2a8443201742c/rpds_py-0.30.0-cp313-cp313-win_amd64.whl", hash = "sha256:806f36b1b605e2d6a72716f321f20036b9489d29c51c91f4dd29a3e3afb73b15", size = 240224, upload-time = "2025-11-30T20:23:02.008Z" }, + { url = "https://files.pythonhosted.org/packages/24/95/ffd128ed1146a153d928617b0ef673960130be0009c77d8fbf0abe306713/rpds_py-0.30.0-cp313-cp313-win_arm64.whl", hash = "sha256:d96c2086587c7c30d44f31f42eae4eac89b60dabbac18c7669be3700f13c3ce1", size = 230645, upload-time = "2025-11-30T20:23:03.43Z" }, + { url = "https://files.pythonhosted.org/packages/ff/1b/b10de890a0def2a319a2626334a7f0ae388215eb60914dbac8a3bae54435/rpds_py-0.30.0-cp313-cp313t-macosx_10_12_x86_64.whl", hash = "sha256:eb0b93f2e5c2189ee831ee43f156ed34e2a89a78a66b98cadad955972548be5a", size = 364443, upload-time = "2025-11-30T20:23:04.878Z" }, + { url = "https://files.pythonhosted.org/packages/0d/bf/27e39f5971dc4f305a4fb9c672ca06f290f7c4e261c568f3dea16a410d47/rpds_py-0.30.0-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:922e10f31f303c7c920da8981051ff6d8c1a56207dbdf330d9047f6d30b70e5e", size = 353375, upload-time = "2025-11-30T20:23:06.342Z" }, + { url = "https://files.pythonhosted.org/packages/40/58/442ada3bba6e8e6615fc00483135c14a7538d2ffac30e2d933ccf6852232/rpds_py-0.30.0-cp313-cp313t-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:cdc62c8286ba9bf7f47befdcea13ea0e26bf294bda99758fd90535cbaf408000", size = 383850, upload-time = "2025-11-30T20:23:07.825Z" }, + { url = "https://files.pythonhosted.org/packages/14/14/f59b0127409a33c6ef6f5c1ebd5ad8e32d7861c9c7adfa9a624fc3889f6c/rpds_py-0.30.0-cp313-cp313t-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:47f9a91efc418b54fb8190a6b4aa7813a23fb79c51f4bb84e418f5476c38b8db", size = 392812, upload-time = "2025-11-30T20:23:09.228Z" }, + { url = "https://files.pythonhosted.org/packages/b3/66/e0be3e162ac299b3a22527e8913767d869e6cc75c46bd844aa43fb81ab62/rpds_py-0.30.0-cp313-cp313t-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:1f3587eb9b17f3789ad50824084fa6f81921bbf9a795826570bda82cb3ed91f2", size = 517841, upload-time = "2025-11-30T20:23:11.186Z" }, + { url = "https://files.pythonhosted.org/packages/3d/55/fa3b9cf31d0c963ecf1ba777f7cf4b2a2c976795ac430d24a1f43d25a6ba/rpds_py-0.30.0-cp313-cp313t-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:39c02563fc592411c2c61d26b6c5fe1e51eaa44a75aa2c8735ca88b0d9599daa", size = 408149, upload-time = "2025-11-30T20:23:12.864Z" }, + { url = "https://files.pythonhosted.org/packages/60/ca/780cf3b1a32b18c0f05c441958d3758f02544f1d613abf9488cd78876378/rpds_py-0.30.0-cp313-cp313t-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:51a1234d8febafdfd33a42d97da7a43f5dcb120c1060e352a3fbc0c6d36e2083", size = 383843, upload-time = "2025-11-30T20:23:14.638Z" }, + { url = "https://files.pythonhosted.org/packages/82/86/d5f2e04f2aa6247c613da0c1dd87fcd08fa17107e858193566048a1e2f0a/rpds_py-0.30.0-cp313-cp313t-manylinux_2_31_riscv64.whl", hash = "sha256:eb2c4071ab598733724c08221091e8d80e89064cd472819285a9ab0f24bcedb9", size = 396507, upload-time = "2025-11-30T20:23:16.105Z" }, + { url = "https://files.pythonhosted.org/packages/4b/9a/453255d2f769fe44e07ea9785c8347edaf867f7026872e76c1ad9f7bed92/rpds_py-0.30.0-cp313-cp313t-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:6bdfdb946967d816e6adf9a3d8201bfad269c67efe6cefd7093ef959683c8de0", size = 414949, upload-time = "2025-11-30T20:23:17.539Z" }, + { url = "https://files.pythonhosted.org/packages/a3/31/622a86cdc0c45d6df0e9ccb6becdba5074735e7033c20e401a6d9d0e2ca0/rpds_py-0.30.0-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:c77afbd5f5250bf27bf516c7c4a016813eb2d3e116139aed0096940c5982da94", size = 565790, upload-time = "2025-11-30T20:23:19.029Z" }, + { url = "https://files.pythonhosted.org/packages/1c/5d/15bbf0fb4a3f58a3b1c67855ec1efcc4ceaef4e86644665fff03e1b66d8d/rpds_py-0.30.0-cp313-cp313t-musllinux_1_2_i686.whl", hash = "sha256:61046904275472a76c8c90c9ccee9013d70a6d0f73eecefd38c1ae7c39045a08", size = 590217, upload-time = "2025-11-30T20:23:20.885Z" }, + { url = "https://files.pythonhosted.org/packages/6d/61/21b8c41f68e60c8cc3b2e25644f0e3681926020f11d06ab0b78e3c6bbff1/rpds_py-0.30.0-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:4c5f36a861bc4b7da6516dbdf302c55313afa09b81931e8280361a4f6c9a2d27", size = 555806, upload-time = "2025-11-30T20:23:22.488Z" }, + { url = "https://files.pythonhosted.org/packages/f9/39/7e067bb06c31de48de3eb200f9fc7c58982a4d3db44b07e73963e10d3be9/rpds_py-0.30.0-cp313-cp313t-win32.whl", hash = "sha256:3d4a69de7a3e50ffc214ae16d79d8fbb0922972da0356dcf4d0fdca2878559c6", size = 211341, upload-time = "2025-11-30T20:23:24.449Z" }, + { url = "https://files.pythonhosted.org/packages/0a/4d/222ef0b46443cf4cf46764d9c630f3fe4abaa7245be9417e56e9f52b8f65/rpds_py-0.30.0-cp313-cp313t-win_amd64.whl", hash = "sha256:f14fc5df50a716f7ece6a80b6c78bb35ea2ca47c499e422aa4463455dd96d56d", size = 225768, upload-time = "2025-11-30T20:23:25.908Z" }, + { url = "https://files.pythonhosted.org/packages/86/81/dad16382ebbd3d0e0328776d8fd7ca94220e4fa0798d1dc5e7da48cb3201/rpds_py-0.30.0-cp314-cp314-macosx_10_12_x86_64.whl", hash = "sha256:68f19c879420aa08f61203801423f6cd5ac5f0ac4ac82a2368a9fcd6a9a075e0", size = 362099, upload-time = "2025-11-30T20:23:27.316Z" }, + { url = "https://files.pythonhosted.org/packages/2b/60/19f7884db5d5603edf3c6bce35408f45ad3e97e10007df0e17dd57af18f8/rpds_py-0.30.0-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:ec7c4490c672c1a0389d319b3a9cfcd098dcdc4783991553c332a15acf7249be", size = 353192, upload-time = "2025-11-30T20:23:29.151Z" }, + { url = "https://files.pythonhosted.org/packages/bf/c4/76eb0e1e72d1a9c4703c69607cec123c29028bff28ce41588792417098ac/rpds_py-0.30.0-cp314-cp314-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f251c812357a3fed308d684a5079ddfb9d933860fc6de89f2b7ab00da481e65f", size = 384080, upload-time = "2025-11-30T20:23:30.785Z" }, + { url = "https://files.pythonhosted.org/packages/72/87/87ea665e92f3298d1b26d78814721dc39ed8d2c74b86e83348d6b48a6f31/rpds_py-0.30.0-cp314-cp314-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:ac98b175585ecf4c0348fd7b29c3864bda53b805c773cbf7bfdaffc8070c976f", size = 394841, upload-time = "2025-11-30T20:23:32.209Z" }, + { url = "https://files.pythonhosted.org/packages/77/ad/7783a89ca0587c15dcbf139b4a8364a872a25f861bdb88ed99f9b0dec985/rpds_py-0.30.0-cp314-cp314-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:3e62880792319dbeb7eb866547f2e35973289e7d5696c6e295476448f5b63c87", size = 516670, upload-time = "2025-11-30T20:23:33.742Z" }, + { url = "https://files.pythonhosted.org/packages/5b/3c/2882bdac942bd2172f3da574eab16f309ae10a3925644e969536553cb4ee/rpds_py-0.30.0-cp314-cp314-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:4e7fc54e0900ab35d041b0601431b0a0eb495f0851a0639b6ef90f7741b39a18", size = 408005, upload-time = "2025-11-30T20:23:35.253Z" }, + { url = "https://files.pythonhosted.org/packages/ce/81/9a91c0111ce1758c92516a3e44776920b579d9a7c09b2b06b642d4de3f0f/rpds_py-0.30.0-cp314-cp314-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:47e77dc9822d3ad616c3d5759ea5631a75e5809d5a28707744ef79d7a1bcfcad", size = 382112, upload-time = "2025-11-30T20:23:36.842Z" }, + { url = "https://files.pythonhosted.org/packages/cf/8e/1da49d4a107027e5fbc64daeab96a0706361a2918da10cb41769244b805d/rpds_py-0.30.0-cp314-cp314-manylinux_2_31_riscv64.whl", hash = "sha256:b4dc1a6ff022ff85ecafef7979a2c6eb423430e05f1165d6688234e62ba99a07", size = 399049, upload-time = "2025-11-30T20:23:38.343Z" }, + { url = "https://files.pythonhosted.org/packages/df/5a/7ee239b1aa48a127570ec03becbb29c9d5a9eb092febbd1699d567cae859/rpds_py-0.30.0-cp314-cp314-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:4559c972db3a360808309e06a74628b95eaccbf961c335c8fe0d590cf587456f", size = 415661, upload-time = "2025-11-30T20:23:40.263Z" }, + { url = "https://files.pythonhosted.org/packages/70/ea/caa143cf6b772f823bc7929a45da1fa83569ee49b11d18d0ada7f5ee6fd6/rpds_py-0.30.0-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:0ed177ed9bded28f8deb6ab40c183cd1192aa0de40c12f38be4d59cd33cb5c65", size = 565606, upload-time = "2025-11-30T20:23:42.186Z" }, + { url = "https://files.pythonhosted.org/packages/64/91/ac20ba2d69303f961ad8cf55bf7dbdb4763f627291ba3d0d7d67333cced9/rpds_py-0.30.0-cp314-cp314-musllinux_1_2_i686.whl", hash = "sha256:ad1fa8db769b76ea911cb4e10f049d80bf518c104f15b3edb2371cc65375c46f", size = 591126, upload-time = "2025-11-30T20:23:44.086Z" }, + { url = "https://files.pythonhosted.org/packages/21/20/7ff5f3c8b00c8a95f75985128c26ba44503fb35b8e0259d812766ea966c7/rpds_py-0.30.0-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:46e83c697b1f1c72b50e5ee5adb4353eef7406fb3f2043d64c33f20ad1c2fc53", size = 553371, upload-time = "2025-11-30T20:23:46.004Z" }, + { url = "https://files.pythonhosted.org/packages/72/c7/81dadd7b27c8ee391c132a6b192111ca58d866577ce2d9b0ca157552cce0/rpds_py-0.30.0-cp314-cp314-win32.whl", hash = "sha256:ee454b2a007d57363c2dfd5b6ca4a5d7e2c518938f8ed3b706e37e5d470801ed", size = 215298, upload-time = "2025-11-30T20:23:47.696Z" }, + { url = "https://files.pythonhosted.org/packages/3e/d2/1aaac33287e8cfb07aab2e6b8ac1deca62f6f65411344f1433c55e6f3eb8/rpds_py-0.30.0-cp314-cp314-win_amd64.whl", hash = "sha256:95f0802447ac2d10bcc69f6dc28fe95fdf17940367b21d34e34c737870758950", size = 228604, upload-time = "2025-11-30T20:23:49.501Z" }, + { url = "https://files.pythonhosted.org/packages/e8/95/ab005315818cc519ad074cb7784dae60d939163108bd2b394e60dc7b5461/rpds_py-0.30.0-cp314-cp314-win_arm64.whl", hash = "sha256:613aa4771c99f03346e54c3f038e4cc574ac09a3ddfb0e8878487335e96dead6", size = 222391, upload-time = "2025-11-30T20:23:50.96Z" }, + { url = "https://files.pythonhosted.org/packages/9e/68/154fe0194d83b973cdedcdcc88947a2752411165930182ae41d983dcefa6/rpds_py-0.30.0-cp314-cp314t-macosx_10_12_x86_64.whl", hash = "sha256:7e6ecfcb62edfd632e56983964e6884851786443739dbfe3582947e87274f7cb", size = 364868, upload-time = "2025-11-30T20:23:52.494Z" }, + { url = "https://files.pythonhosted.org/packages/83/69/8bbc8b07ec854d92a8b75668c24d2abcb1719ebf890f5604c61c9369a16f/rpds_py-0.30.0-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:a1d0bc22a7cdc173fedebb73ef81e07faef93692b8c1ad3733b67e31e1b6e1b8", size = 353747, upload-time = "2025-11-30T20:23:54.036Z" }, + { url = "https://files.pythonhosted.org/packages/ab/00/ba2e50183dbd9abcce9497fa5149c62b4ff3e22d338a30d690f9af970561/rpds_py-0.30.0-cp314-cp314t-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0d08f00679177226c4cb8c5265012eea897c8ca3b93f429e546600c971bcbae7", size = 383795, upload-time = "2025-11-30T20:23:55.556Z" }, + { url = "https://files.pythonhosted.org/packages/05/6f/86f0272b84926bcb0e4c972262f54223e8ecc556b3224d281e6598fc9268/rpds_py-0.30.0-cp314-cp314t-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:5965af57d5848192c13534f90f9dd16464f3c37aaf166cc1da1cae1fd5a34898", size = 393330, upload-time = "2025-11-30T20:23:57.033Z" }, + { url = "https://files.pythonhosted.org/packages/cb/e9/0e02bb2e6dc63d212641da45df2b0bf29699d01715913e0d0f017ee29438/rpds_py-0.30.0-cp314-cp314t-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:9a4e86e34e9ab6b667c27f3211ca48f73dba7cd3d90f8d5b11be56e5dbc3fb4e", size = 518194, upload-time = "2025-11-30T20:23:58.637Z" }, + { url = "https://files.pythonhosted.org/packages/ee/ca/be7bca14cf21513bdf9c0606aba17d1f389ea2b6987035eb4f62bd923f25/rpds_py-0.30.0-cp314-cp314t-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:e5d3e6b26f2c785d65cc25ef1e5267ccbe1b069c5c21b8cc724efee290554419", size = 408340, upload-time = "2025-11-30T20:24:00.2Z" }, + { url = "https://files.pythonhosted.org/packages/c2/c7/736e00ebf39ed81d75544c0da6ef7b0998f8201b369acf842f9a90dc8fce/rpds_py-0.30.0-cp314-cp314t-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:626a7433c34566535b6e56a1b39a7b17ba961e97ce3b80ec62e6f1312c025551", size = 383765, upload-time = "2025-11-30T20:24:01.759Z" }, + { url = "https://files.pythonhosted.org/packages/4a/3f/da50dfde9956aaf365c4adc9533b100008ed31aea635f2b8d7b627e25b49/rpds_py-0.30.0-cp314-cp314t-manylinux_2_31_riscv64.whl", hash = "sha256:acd7eb3f4471577b9b5a41baf02a978e8bdeb08b4b355273994f8b87032000a8", size = 396834, upload-time = "2025-11-30T20:24:03.687Z" }, + { url = "https://files.pythonhosted.org/packages/4e/00/34bcc2565b6020eab2623349efbdec810676ad571995911f1abdae62a3a0/rpds_py-0.30.0-cp314-cp314t-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:fe5fa731a1fa8a0a56b0977413f8cacac1768dad38d16b3a296712709476fbd5", size = 415470, upload-time = "2025-11-30T20:24:05.232Z" }, + { url = "https://files.pythonhosted.org/packages/8c/28/882e72b5b3e6f718d5453bd4d0d9cf8df36fddeb4ddbbab17869d5868616/rpds_py-0.30.0-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:74a3243a411126362712ee1524dfc90c650a503502f135d54d1b352bd01f2404", size = 565630, upload-time = "2025-11-30T20:24:06.878Z" }, + { url = "https://files.pythonhosted.org/packages/3b/97/04a65539c17692de5b85c6e293520fd01317fd878ea1995f0367d4532fb1/rpds_py-0.30.0-cp314-cp314t-musllinux_1_2_i686.whl", hash = "sha256:3e8eeb0544f2eb0d2581774be4c3410356eba189529a6b3e36bbbf9696175856", size = 591148, upload-time = "2025-11-30T20:24:08.445Z" }, + { url = "https://files.pythonhosted.org/packages/85/70/92482ccffb96f5441aab93e26c4d66489eb599efdcf96fad90c14bbfb976/rpds_py-0.30.0-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:dbd936cde57abfee19ab3213cf9c26be06d60750e60a8e4dd85d1ab12c8b1f40", size = 556030, upload-time = "2025-11-30T20:24:10.956Z" }, + { url = "https://files.pythonhosted.org/packages/20/53/7c7e784abfa500a2b6b583b147ee4bb5a2b3747a9166bab52fec4b5b5e7d/rpds_py-0.30.0-cp314-cp314t-win32.whl", hash = "sha256:dc824125c72246d924f7f796b4f63c1e9dc810c7d9e2355864b3c3a73d59ade0", size = 211570, upload-time = "2025-11-30T20:24:12.735Z" }, + { url = "https://files.pythonhosted.org/packages/d0/02/fa464cdfbe6b26e0600b62c528b72d8608f5cc49f96b8d6e38c95d60c676/rpds_py-0.30.0-cp314-cp314t-win_amd64.whl", hash = "sha256:27f4b0e92de5bfbc6f86e43959e6edd1425c33b5e69aab0984a72047f2bcf1e3", size = 226532, upload-time = "2025-11-30T20:24:14.634Z" }, + { url = "https://files.pythonhosted.org/packages/69/71/3f34339ee70521864411f8b6992e7ab13ac30d8e4e3309e07c7361767d91/rpds_py-0.30.0-pp311-pypy311_pp73-macosx_10_12_x86_64.whl", hash = "sha256:c2262bdba0ad4fc6fb5545660673925c2d2a5d9e2e0fb603aad545427be0fc58", size = 372292, upload-time = "2025-11-30T20:24:16.537Z" }, + { url = "https://files.pythonhosted.org/packages/57/09/f183df9b8f2d66720d2ef71075c59f7e1b336bec7ee4c48f0a2b06857653/rpds_py-0.30.0-pp311-pypy311_pp73-macosx_11_0_arm64.whl", hash = "sha256:ee6af14263f25eedc3bb918a3c04245106a42dfd4f5c2285ea6f997b1fc3f89a", size = 362128, upload-time = "2025-11-30T20:24:18.086Z" }, + { url = "https://files.pythonhosted.org/packages/7a/68/5c2594e937253457342e078f0cc1ded3dd7b2ad59afdbf2d354869110a02/rpds_py-0.30.0-pp311-pypy311_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:3adbb8179ce342d235c31ab8ec511e66c73faa27a47e076ccc92421add53e2bb", size = 391542, upload-time = "2025-11-30T20:24:20.092Z" }, + { url = "https://files.pythonhosted.org/packages/49/5c/31ef1afd70b4b4fbdb2800249f34c57c64beb687495b10aec0365f53dfc4/rpds_py-0.30.0-pp311-pypy311_pp73-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:250fa00e9543ac9b97ac258bd37367ff5256666122c2d0f2bc97577c60a1818c", size = 404004, upload-time = "2025-11-30T20:24:22.231Z" }, + { url = "https://files.pythonhosted.org/packages/e3/63/0cfbea38d05756f3440ce6534d51a491d26176ac045e2707adc99bb6e60a/rpds_py-0.30.0-pp311-pypy311_pp73-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:9854cf4f488b3d57b9aaeb105f06d78e5529d3145b1e4a41750167e8c213c6d3", size = 527063, upload-time = "2025-11-30T20:24:24.302Z" }, + { url = "https://files.pythonhosted.org/packages/42/e6/01e1f72a2456678b0f618fc9a1a13f882061690893c192fcad9f2926553a/rpds_py-0.30.0-pp311-pypy311_pp73-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:993914b8e560023bc0a8bf742c5f303551992dcb85e247b1e5c7f4a7d145bda5", size = 413099, upload-time = "2025-11-30T20:24:25.916Z" }, + { url = "https://files.pythonhosted.org/packages/b8/25/8df56677f209003dcbb180765520c544525e3ef21ea72279c98b9aa7c7fb/rpds_py-0.30.0-pp311-pypy311_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:58edca431fb9b29950807e301826586e5bbf24163677732429770a697ffe6738", size = 392177, upload-time = "2025-11-30T20:24:27.834Z" }, + { url = "https://files.pythonhosted.org/packages/4a/b4/0a771378c5f16f8115f796d1f437950158679bcd2a7c68cf251cfb00ed5b/rpds_py-0.30.0-pp311-pypy311_pp73-manylinux_2_31_riscv64.whl", hash = "sha256:dea5b552272a944763b34394d04577cf0f9bd013207bc32323b5a89a53cf9c2f", size = 406015, upload-time = "2025-11-30T20:24:29.457Z" }, + { url = "https://files.pythonhosted.org/packages/36/d8/456dbba0af75049dc6f63ff295a2f92766b9d521fa00de67a2bd6427d57a/rpds_py-0.30.0-pp311-pypy311_pp73-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:ba3af48635eb83d03f6c9735dfb21785303e73d22ad03d489e88adae6eab8877", size = 423736, upload-time = "2025-11-30T20:24:31.22Z" }, + { url = "https://files.pythonhosted.org/packages/13/64/b4d76f227d5c45a7e0b796c674fd81b0a6c4fbd48dc29271857d8219571c/rpds_py-0.30.0-pp311-pypy311_pp73-musllinux_1_2_aarch64.whl", hash = "sha256:dff13836529b921e22f15cb099751209a60009731a68519630a24d61f0b1b30a", size = 573981, upload-time = "2025-11-30T20:24:32.934Z" }, + { url = "https://files.pythonhosted.org/packages/20/91/092bacadeda3edf92bf743cc96a7be133e13a39cdbfd7b5082e7ab638406/rpds_py-0.30.0-pp311-pypy311_pp73-musllinux_1_2_i686.whl", hash = "sha256:1b151685b23929ab7beec71080a8889d4d6d9fa9a983d213f07121205d48e2c4", size = 599782, upload-time = "2025-11-30T20:24:35.169Z" }, + { url = "https://files.pythonhosted.org/packages/d1/b7/b95708304cd49b7b6f82fdd039f1748b66ec2b21d6a45180910802f1abf1/rpds_py-0.30.0-pp311-pypy311_pp73-musllinux_1_2_x86_64.whl", hash = "sha256:ac37f9f516c51e5753f27dfdef11a88330f04de2d564be3991384b2f3535d02e", size = 562191, upload-time = "2025-11-30T20:24:36.853Z" }, +] + +[[package]] +name = "tomli" +version = "2.4.1" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/22/de/48c59722572767841493b26183a0d1cc411d54fd759c5607c4590b6563a6/tomli-2.4.1.tar.gz", hash = "sha256:7c7e1a961a0b2f2472c1ac5b69affa0ae1132c39adcb67aba98568702b9cc23f", size = 17543, upload-time = "2026-03-25T20:22:03.828Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/f4/11/db3d5885d8528263d8adc260bb2d28ebf1270b96e98f0e0268d32b8d9900/tomli-2.4.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:f8f0fc26ec2cc2b965b7a3b87cd19c5c6b8c5e5f436b984e85f486d652285c30", size = 154704, upload-time = "2026-03-25T20:21:10.473Z" }, + { url = "https://files.pythonhosted.org/packages/6d/f7/675db52c7e46064a9aa928885a9b20f4124ecb9bc2e1ce74c9106648d202/tomli-2.4.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:4ab97e64ccda8756376892c53a72bd1f964e519c77236368527f758fbc36a53a", size = 149454, upload-time = "2026-03-25T20:21:12.036Z" }, + { url = "https://files.pythonhosted.org/packages/61/71/81c50943cf953efa35bce7646caab3cf457a7d8c030b27cfb40d7235f9ee/tomli-2.4.1-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:96481a5786729fd470164b47cdb3e0e58062a496f455ee41b4403be77cb5a076", size = 237561, upload-time = "2026-03-25T20:21:13.098Z" }, + { url = "https://files.pythonhosted.org/packages/48/c1/f41d9cb618acccca7df82aaf682f9b49013c9397212cb9f53219e3abac37/tomli-2.4.1-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:5a881ab208c0baf688221f8cecc5401bd291d67e38a1ac884d6736cbcd8247e9", size = 243824, upload-time = "2026-03-25T20:21:14.569Z" }, + { url = "https://files.pythonhosted.org/packages/22/e4/5a816ecdd1f8ca51fb756ef684b90f2780afc52fc67f987e3c61d800a46d/tomli-2.4.1-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:47149d5bd38761ac8be13a84864bf0b7b70bc051806bc3669ab1cbc56216b23c", size = 242227, upload-time = "2026-03-25T20:21:15.712Z" }, + { url = "https://files.pythonhosted.org/packages/6b/49/2b2a0ef529aa6eec245d25f0c703e020a73955ad7edf73e7f54ddc608aa5/tomli-2.4.1-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:ec9bfaf3ad2df51ace80688143a6a4ebc09a248f6ff781a9945e51937008fcbc", size = 247859, upload-time = "2026-03-25T20:21:17.001Z" }, + { url = "https://files.pythonhosted.org/packages/83/bd/6c1a630eaca337e1e78c5903104f831bda934c426f9231429396ce3c3467/tomli-2.4.1-cp311-cp311-win32.whl", hash = "sha256:ff2983983d34813c1aeb0fa89091e76c3a22889ee83ab27c5eeb45100560c049", size = 97204, upload-time = "2026-03-25T20:21:18.079Z" }, + { url = "https://files.pythonhosted.org/packages/42/59/71461df1a885647e10b6bb7802d0b8e66480c61f3f43079e0dcd315b3954/tomli-2.4.1-cp311-cp311-win_amd64.whl", hash = "sha256:5ee18d9ebdb417e384b58fe414e8d6af9f4e7a0ae761519fb50f721de398dd4e", size = 108084, upload-time = "2026-03-25T20:21:18.978Z" }, + { url = "https://files.pythonhosted.org/packages/b8/83/dceca96142499c069475b790e7913b1044c1a4337e700751f48ed723f883/tomli-2.4.1-cp311-cp311-win_arm64.whl", hash = "sha256:c2541745709bad0264b7d4705ad453b76ccd191e64aa6f0fc66b69a293a45ece", size = 95285, upload-time = "2026-03-25T20:21:20.309Z" }, + { url = "https://files.pythonhosted.org/packages/c1/ba/42f134a3fe2b370f555f44b1d72feebb94debcab01676bf918d0cb70e9aa/tomli-2.4.1-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:c742f741d58a28940ce01d58f0ab2ea3ced8b12402f162f4d534dfe18ba1cd6a", size = 155924, upload-time = "2026-03-25T20:21:21.626Z" }, + { url = "https://files.pythonhosted.org/packages/dc/c7/62d7a17c26487ade21c5422b646110f2162f1fcc95980ef7f63e73c68f14/tomli-2.4.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:7f86fd587c4ed9dd76f318225e7d9b29cfc5a9d43de44e5754db8d1128487085", size = 150018, upload-time = "2026-03-25T20:21:23.002Z" }, + { url = "https://files.pythonhosted.org/packages/5c/05/79d13d7c15f13bdef410bdd49a6485b1c37d28968314eabee452c22a7fda/tomli-2.4.1-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:ff18e6a727ee0ab0388507b89d1bc6a22b138d1e2fa56d1ad494586d61d2eae9", size = 244948, upload-time = "2026-03-25T20:21:24.04Z" }, + { url = "https://files.pythonhosted.org/packages/10/90/d62ce007a1c80d0b2c93e02cab211224756240884751b94ca72df8a875ca/tomli-2.4.1-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:136443dbd7e1dee43c68ac2694fde36b2849865fa258d39bf822c10e8068eac5", size = 253341, upload-time = "2026-03-25T20:21:25.177Z" }, + { url = "https://files.pythonhosted.org/packages/1a/7e/caf6496d60152ad4ed09282c1885cca4eea150bfd007da84aea07bcc0a3e/tomli-2.4.1-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:5e262d41726bc187e69af7825504c933b6794dc3fbd5945e41a79bb14c31f585", size = 248159, upload-time = "2026-03-25T20:21:26.364Z" }, + { url = "https://files.pythonhosted.org/packages/99/e7/c6f69c3120de34bbd882c6fba7975f3d7a746e9218e56ab46a1bc4b42552/tomli-2.4.1-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:5cb41aa38891e073ee49d55fbc7839cfdb2bc0e600add13874d048c94aadddd1", size = 253290, upload-time = "2026-03-25T20:21:27.46Z" }, + { url = "https://files.pythonhosted.org/packages/d6/2f/4a3c322f22c5c66c4b836ec58211641a4067364f5dcdd7b974b4c5da300c/tomli-2.4.1-cp312-cp312-win32.whl", hash = "sha256:da25dc3563bff5965356133435b757a795a17b17d01dbc0f42fb32447ddfd917", size = 98141, upload-time = "2026-03-25T20:21:28.492Z" }, + { url = "https://files.pythonhosted.org/packages/24/22/4daacd05391b92c55759d55eaee21e1dfaea86ce5c571f10083360adf534/tomli-2.4.1-cp312-cp312-win_amd64.whl", hash = "sha256:52c8ef851d9a240f11a88c003eacb03c31fc1c9c4ec64a99a0f922b93874fda9", size = 108847, upload-time = "2026-03-25T20:21:29.386Z" }, + { url = "https://files.pythonhosted.org/packages/68/fd/70e768887666ddd9e9f5d85129e84910f2db2796f9096aa02b721a53098d/tomli-2.4.1-cp312-cp312-win_arm64.whl", hash = "sha256:f758f1b9299d059cc3f6546ae2af89670cb1c4d48ea29c3cacc4fe7de3058257", size = 95088, upload-time = "2026-03-25T20:21:30.677Z" }, + { url = "https://files.pythonhosted.org/packages/07/06/b823a7e818c756d9a7123ba2cda7d07bc2dd32835648d1a7b7b7a05d848d/tomli-2.4.1-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:36d2bd2ad5fb9eaddba5226aa02c8ec3fa4f192631e347b3ed28186d43be6b54", size = 155866, upload-time = "2026-03-25T20:21:31.65Z" }, + { url = "https://files.pythonhosted.org/packages/14/6f/12645cf7f08e1a20c7eb8c297c6f11d31c1b50f316a7e7e1e1de6e2e7b7e/tomli-2.4.1-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:eb0dc4e38e6a1fd579e5d50369aa2e10acfc9cace504579b2faabb478e76941a", size = 149887, upload-time = "2026-03-25T20:21:33.028Z" }, + { url = "https://files.pythonhosted.org/packages/5c/e0/90637574e5e7212c09099c67ad349b04ec4d6020324539297b634a0192b0/tomli-2.4.1-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:c7f2c7f2b9ca6bdeef8f0fa897f8e05085923eb091721675170254cbc5b02897", size = 243704, upload-time = "2026-03-25T20:21:34.51Z" }, + { url = "https://files.pythonhosted.org/packages/10/8f/d3ddb16c5a4befdf31a23307f72828686ab2096f068eaf56631e136c1fdd/tomli-2.4.1-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:f3c6818a1a86dd6dca7ddcaaf76947d5ba31aecc28cb1b67009a5877c9a64f3f", size = 251628, upload-time = "2026-03-25T20:21:36.012Z" }, + { url = "https://files.pythonhosted.org/packages/e3/f1/dbeeb9116715abee2485bf0a12d07a8f31af94d71608c171c45f64c0469d/tomli-2.4.1-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:d312ef37c91508b0ab2cee7da26ec0b3ed2f03ce12bd87a588d771ae15dcf82d", size = 247180, upload-time = "2026-03-25T20:21:37.136Z" }, + { url = "https://files.pythonhosted.org/packages/d3/74/16336ffd19ed4da28a70959f92f506233bd7cfc2332b20bdb01591e8b1d1/tomli-2.4.1-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:51529d40e3ca50046d7606fa99ce3956a617f9b36380da3b7f0dd3dd28e68cb5", size = 251674, upload-time = "2026-03-25T20:21:38.298Z" }, + { url = "https://files.pythonhosted.org/packages/16/f9/229fa3434c590ddf6c0aa9af64d3af4b752540686cace29e6281e3458469/tomli-2.4.1-cp313-cp313-win32.whl", hash = "sha256:2190f2e9dd7508d2a90ded5ed369255980a1bcdd58e52f7fe24b8162bf9fedbd", size = 97976, upload-time = "2026-03-25T20:21:39.316Z" }, + { url = "https://files.pythonhosted.org/packages/6a/1e/71dfd96bcc1c775420cb8befe7a9d35f2e5b1309798f009dca17b7708c1e/tomli-2.4.1-cp313-cp313-win_amd64.whl", hash = "sha256:8d65a2fbf9d2f8352685bc1364177ee3923d6baf5e7f43ea4959d7d8bc326a36", size = 108755, upload-time = "2026-03-25T20:21:40.248Z" }, + { url = "https://files.pythonhosted.org/packages/83/7a/d34f422a021d62420b78f5c538e5b102f62bea616d1d75a13f0a88acb04a/tomli-2.4.1-cp313-cp313-win_arm64.whl", hash = "sha256:4b605484e43cdc43f0954ddae319fb75f04cc10dd80d830540060ee7cd0243cd", size = 95265, upload-time = "2026-03-25T20:21:41.219Z" }, + { url = "https://files.pythonhosted.org/packages/3c/fb/9a5c8d27dbab540869f7c1f8eb0abb3244189ce780ba9cd73f3770662072/tomli-2.4.1-cp314-cp314-macosx_10_15_x86_64.whl", hash = "sha256:fd0409a3653af6c147209d267a0e4243f0ae46b011aa978b1080359fddc9b6cf", size = 155726, upload-time = "2026-03-25T20:21:42.23Z" }, + { url = "https://files.pythonhosted.org/packages/62/05/d2f816630cc771ad836af54f5001f47a6f611d2d39535364f148b6a92d6b/tomli-2.4.1-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:a120733b01c45e9a0c34aeef92bf0cf1d56cfe81ed9d47d562f9ed591a9828ac", size = 149859, upload-time = "2026-03-25T20:21:43.386Z" }, + { url = "https://files.pythonhosted.org/packages/ce/48/66341bdb858ad9bd0ceab5a86f90eddab127cf8b046418009f2125630ecb/tomli-2.4.1-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:559db847dc486944896521f68d8190be1c9e719fced785720d2216fe7022b662", size = 244713, upload-time = "2026-03-25T20:21:44.474Z" }, + { url = "https://files.pythonhosted.org/packages/df/6d/c5fad00d82b3c7a3ab6189bd4b10e60466f22cfe8a08a9394185c8a8111c/tomli-2.4.1-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:01f520d4f53ef97964a240a035ec2a869fe1a37dde002b57ebc4417a27ccd853", size = 252084, upload-time = "2026-03-25T20:21:45.62Z" }, + { url = "https://files.pythonhosted.org/packages/00/71/3a69e86f3eafe8c7a59d008d245888051005bd657760e96d5fbfb0b740c2/tomli-2.4.1-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:7f94b27a62cfad8496c8d2513e1a222dd446f095fca8987fceef261225538a15", size = 247973, upload-time = "2026-03-25T20:21:46.937Z" }, + { url = "https://files.pythonhosted.org/packages/67/50/361e986652847fec4bd5e4a0208752fbe64689c603c7ae5ea7cb16b1c0ca/tomli-2.4.1-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:ede3e6487c5ef5d28634ba3f31f989030ad6af71edfb0055cbbd14189ff240ba", size = 256223, upload-time = "2026-03-25T20:21:48.467Z" }, + { url = "https://files.pythonhosted.org/packages/8c/9a/b4173689a9203472e5467217e0154b00e260621caa227b6fa01feab16998/tomli-2.4.1-cp314-cp314-win32.whl", hash = "sha256:3d48a93ee1c9b79c04bb38772ee1b64dcf18ff43085896ea460ca8dec96f35f6", size = 98973, upload-time = "2026-03-25T20:21:49.526Z" }, + { url = "https://files.pythonhosted.org/packages/14/58/640ac93bf230cd27d002462c9af0d837779f8773bc03dee06b5835208214/tomli-2.4.1-cp314-cp314-win_amd64.whl", hash = "sha256:88dceee75c2c63af144e456745e10101eb67361050196b0b6af5d717254dddf7", size = 109082, upload-time = "2026-03-25T20:21:50.506Z" }, + { url = "https://files.pythonhosted.org/packages/d5/2f/702d5e05b227401c1068f0d386d79a589bb12bf64c3d2c72ce0631e3bc49/tomli-2.4.1-cp314-cp314-win_arm64.whl", hash = "sha256:b8c198f8c1805dc42708689ed6864951fd2494f924149d3e4bce7710f8eb5232", size = 96490, upload-time = "2026-03-25T20:21:51.474Z" }, + { url = "https://files.pythonhosted.org/packages/45/4b/b877b05c8ba62927d9865dd980e34a755de541eb65fffba52b4cc495d4d2/tomli-2.4.1-cp314-cp314t-macosx_10_15_x86_64.whl", hash = "sha256:d4d8fe59808a54658fcc0160ecfb1b30f9089906c50b23bcb4c69eddc19ec2b4", size = 164263, upload-time = "2026-03-25T20:21:52.543Z" }, + { url = "https://files.pythonhosted.org/packages/24/79/6ab420d37a270b89f7195dec5448f79400d9e9c1826df982f3f8e97b24fd/tomli-2.4.1-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:7008df2e7655c495dd12d2a4ad038ff878d4ca4b81fccaf82b714e07eae4402c", size = 160736, upload-time = "2026-03-25T20:21:53.674Z" }, + { url = "https://files.pythonhosted.org/packages/02/e0/3630057d8eb170310785723ed5adcdfb7d50cb7e6455f85ba8a3deed642b/tomli-2.4.1-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:1d8591993e228b0c930c4bb0db464bdad97b3289fb981255d6c9a41aedc84b2d", size = 270717, upload-time = "2026-03-25T20:21:55.129Z" }, + { url = "https://files.pythonhosted.org/packages/7a/b4/1613716072e544d1a7891f548d8f9ec6ce2faf42ca65acae01d76ea06bb0/tomli-2.4.1-cp314-cp314t-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:734e20b57ba95624ecf1841e72b53f6e186355e216e5412de414e3c51e5e3c41", size = 278461, upload-time = "2026-03-25T20:21:56.228Z" }, + { url = "https://files.pythonhosted.org/packages/05/38/30f541baf6a3f6df77b3df16b01ba319221389e2da59427e221ef417ac0c/tomli-2.4.1-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:8a650c2dbafa08d42e51ba0b62740dae4ecb9338eefa093aa5c78ceb546fcd5c", size = 274855, upload-time = "2026-03-25T20:21:57.653Z" }, + { url = "https://files.pythonhosted.org/packages/77/a3/ec9dd4fd2c38e98de34223b995a3b34813e6bdadf86c75314c928350ed14/tomli-2.4.1-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:504aa796fe0569bb43171066009ead363de03675276d2d121ac1a4572397870f", size = 283144, upload-time = "2026-03-25T20:21:59.089Z" }, + { url = "https://files.pythonhosted.org/packages/ef/be/605a6261cac79fba2ec0c9827e986e00323a1945700969b8ee0b30d85453/tomli-2.4.1-cp314-cp314t-win32.whl", hash = "sha256:b1d22e6e9387bf4739fbe23bfa80e93f6b0373a7f1b96c6227c32bef95a4d7a8", size = 108683, upload-time = "2026-03-25T20:22:00.214Z" }, + { url = "https://files.pythonhosted.org/packages/12/64/da524626d3b9cc40c168a13da8335fe1c51be12c0a63685cc6db7308daae/tomli-2.4.1-cp314-cp314t-win_amd64.whl", hash = "sha256:2c1c351919aca02858f740c6d33adea0c5deea37f9ecca1cc1ef9e884a619d26", size = 121196, upload-time = "2026-03-25T20:22:01.169Z" }, + { url = "https://files.pythonhosted.org/packages/5a/cd/e80b62269fc78fc36c9af5a6b89c835baa8af28ff5ad28c7028d60860320/tomli-2.4.1-cp314-cp314t-win_arm64.whl", hash = "sha256:eab21f45c7f66c13f2a9e0e1535309cee140182a9cdae1e041d02e47291e8396", size = 100393, upload-time = "2026-03-25T20:22:02.137Z" }, + { url = "https://files.pythonhosted.org/packages/7b/61/cceae43728b7de99d9b847560c262873a1f6c98202171fd5ed62640b494b/tomli-2.4.1-py3-none-any.whl", hash = "sha256:0d85819802132122da43cb86656f8d1f8c6587d54ae7dcaf30e90533028b49fe", size = 14583, upload-time = "2026-03-25T20:22:03.012Z" }, +] + +[[package]] +name = "typing-extensions" +version = "4.15.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/72/94/1a15dd82efb362ac84269196e94cf00f187f7ed21c242792a923cdb1c61f/typing_extensions-4.15.0.tar.gz", hash = "sha256:0cea48d173cc12fa28ecabc3b837ea3cf6f38c6d1136f85cbaaf598984861466", size = 109391, upload-time = "2025-08-25T13:49:26.313Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/18/67/36e9267722cc04a6b9f15c7f3441c2363321a3ea07da7ae0c0707beb2a9c/typing_extensions-4.15.0-py3-none-any.whl", hash = "sha256:f0fa19c6845758ab08074a0cfa8b7aecb71c999ca73d62883bc25cc018c4e548", size = 44614, upload-time = "2025-08-25T13:49:24.86Z" }, +] + +[[package]] +name = "typing-inspection" +version = "0.4.2" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "typing-extensions" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/55/e3/70399cb7dd41c10ac53367ae42139cf4b1ca5f36bb3dc6c9d33acdb43655/typing_inspection-0.4.2.tar.gz", hash = "sha256:ba561c48a67c5958007083d386c3295464928b01faa735ab8547c5692e87f464", size = 75949, upload-time = "2025-10-01T02:14:41.687Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/dc/9b/47798a6c91d8bdb567fe2698fe81e0c6b7cb7ef4d13da4114b41d239f65d/typing_inspection-0.4.2-py3-none-any.whl", hash = "sha256:4ed1cacbdc298c220f1bd249ed5287caa16f34d44ef4e9c3d0cbad5b521545e7", size = 14611, upload-time = "2025-10-01T02:14:40.154Z" }, +] + +[[package]] +name = "virtualenv" +version = "21.2.4" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "distlib" }, + { name = "filelock" }, + { name = "platformdirs" }, + { name = "python-discovery" }, + { name = "typing-extensions", marker = "python_full_version < '3.11'" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/0c/98/3a7e644e19cb26133488caff231be390579860bbbb3da35913c49a1d0a46/virtualenv-21.2.4.tar.gz", hash = "sha256:b294ef68192638004d72524ce7ef303e9d0cf5a44c95ce2e54a7500a6381cada", size = 5850742, upload-time = "2026-04-14T22:15:31.438Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/27/8d/edd0bd910ff803c308ee9a6b7778621af0d10252219ad9f19ef4d4982a61/virtualenv-21.2.4-py3-none-any.whl", hash = "sha256:29d21e941795206138d0f22f4e45ff7050e5da6c6472299fb7103318763861ac", size = 5831232, upload-time = "2026-04-14T22:15:29.342Z" }, +] diff --git a/packages/typescript/README.md b/packages/typescript/README.md new file mode 100644 index 0000000..5f8c7ac --- /dev/null +++ b/packages/typescript/README.md @@ -0,0 +1,110 @@ +# @interwebalchemy/model-metadata + +Typed registry of LLM model metadata — context windows, pricing, provider routing — for TypeScript/Node.js projects. + +## Install + +```sh +npm install @interwebalchemy/model-metadata +``` + +## Usage + +### Full registry + +```ts +import { getAllModels, getAllProviders } from "@interwebalchemy/model-metadata"; + +// Populate a model selector dropdown +const models = getAllModels(); +const modelOptions = models.map(m => ({ + value: m.model_id, + label: m.model_name, + contextWindow: m.context_window, + pricePerMillion: m.cost_per_token, +})); +``` + +### Look up a single model + +```ts +import { getModel } from "@interwebalchemy/model-metadata"; + +const model = getModel("gpt-4o"); +if (model) { + console.log(model.context_window); // 128000 + console.log(model.cost_per_token); // { input: 0.000005, output: 0.000015 } +} +``` + +### Filter by provider + +```ts +import { getModelsByProvider } from "@interwebalchemy/model-metadata"; + +const anthropicModels = getModelsByProvider("anthropic"); +const openrouterModels = getModelsByProvider("openrouter"); +``` + +### Provider routing + +```ts +import { getProviderModelId, getProvider } from "@interwebalchemy/model-metadata"; + +// Get the model ID for a specific provider +const openaiId = getProviderModelId("gpt-4o", "openai"); // "gpt-4o" +const openrouterId = getProviderModelId("gpt-4o", "openrouter"); // "openai/gpt-4o" + +// Get provider config (base URL, auth type, etc.) +const provider = getProvider("openai"); +console.log(provider.base_url); // "https://api.openai.com/v1" +console.log(provider.auth_type); // "api_key" +``` + +### Tree-shakeable named exports + +Import only the models you need — bundlers will exclude the rest. + +```ts +import { gpt4o, claudeOpus47 } from "@interwebalchemy/model-metadata"; + +// gpt4o and claudeOpus47 are fully typed ModelMetadata objects +// The full registry + helpers are excluded from the bundle +``` + +### TypeScript types + +All types are exported for your own data structures: + +```ts +import type { ModelMetadata, ProviderMetadata, CostPerToken } from "@interwebalchemy/model-metadata"; + +function logCost(model: ModelMetadata) { + if (model.cost_per_token) { + const cost = model.cost_per_token as CostPerToken; + console.log(`$${cost.input * 1_000_000} per 1M input tokens`); + } +} +``` + +## API + +| Function | Returns | Description | +|---|---|---| +| `getModel(id)` | `ModelMetadata \| undefined` | Lookup by model_id | +| `getAllModels()` | `readonly ModelMetadata[]` | All models | +| `getModelsByProvider(providerId)` | `readonly ModelMetadata[]` | Filter by provider | +| `getModelOnProvider(providerId, providerModelId?)` | `ModelMetadata \| undefined` | Find model on a specific provider | +| `getProvider(id)` | `ProviderMetadata \| undefined` | Provider config | +| `getAllProviders()` | `readonly ProviderMetadata[]` | All providers | +| `getProviderModelId(modelId, providerId)` | `string \| undefined` | Provider-specific model ID | + +## Data + +- Registry compiled from `/models/*.yaml` and `/providers/*.yaml` at build time +- 33 models across 14 providers +- Prices are in USD per token + +## Schema + +Matches [`model-metadata.schema.json`](../../model-metadata.schema.json) and [`provider.schema.json`](../../provider.schema.json). \ No newline at end of file diff --git a/packages/typescript/package-lock.json b/packages/typescript/package-lock.json new file mode 100644 index 0000000..7c73102 --- /dev/null +++ b/packages/typescript/package-lock.json @@ -0,0 +1,65 @@ +{ + "name": "@interwebalchemy/model-metadata", + "version": "0.1.0", + "lockfileVersion": 3, + "requires": true, + "packages": { + "": { + "name": "@interwebalchemy/model-metadata", + "version": "0.1.0", + "license": "MIT", + "devDependencies": { + "@types/node": "^20.0.0", + "typescript": "^5.0.0", + "yaml": "3.0.0-0" + } + }, + "node_modules/@types/node": { + "version": "20.19.39", + "resolved": "https://registry.npmjs.org/@types/node/-/node-20.19.39.tgz", + "integrity": "sha512-orrrD74MBUyK8jOAD/r0+lfa1I2MO6I+vAkmAWzMYbCcgrN4lCrmK52gRFQq/JRxfYPfonkr4b0jcY7Olqdqbw==", + "dev": true, + "license": "MIT", + "dependencies": { + "undici-types": "~6.21.0" + } + }, + "node_modules/typescript": { + "version": "5.9.3", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.9.3.tgz", + "integrity": "sha512-jl1vZzPDinLr9eUt3J/t7V6FgNEw9QjvBPdysz9KfQDD41fQrC2Y4vKQdiaUpFT4bXlb1RHhLpp8wtm6M5TgSw==", + "dev": true, + "license": "Apache-2.0", + "bin": { + "tsc": "bin/tsc", + "tsserver": "bin/tsserver" + }, + "engines": { + "node": ">=14.17" + } + }, + "node_modules/undici-types": { + "version": "6.21.0", + "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-6.21.0.tgz", + "integrity": "sha512-iwDZqg0QAGrg9Rav5H4n0M64c3mkR59cJ6wQp+7C4nI0gsmExaedaYLNO44eT4AtBBwjbTiGPMlt2Md0T9H9JQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/yaml": { + "version": "3.0.0-0", + "resolved": "https://registry.npmjs.org/yaml/-/yaml-3.0.0-0.tgz", + "integrity": "sha512-PHPfns7F4FYUxfWzghNC/VYvFANsZkNSEZ7s7TbL9Aabf781lJ0wq88Hqx7+2gLBnBWUIy/YYaE+AIXJ0cs6Dg==", + "dev": true, + "license": "ISC", + "bin": { + "yaml": "bin.js" + }, + "engines": { + "node": "^20.19 || ^22.12 || >=24" + }, + "funding": { + "url": "https://github.com/sponsors/eemeli" + } + } + } +} diff --git a/packages/typescript/package.json b/packages/typescript/package.json new file mode 100644 index 0000000..e7657f7 --- /dev/null +++ b/packages/typescript/package.json @@ -0,0 +1,48 @@ +{ + "name": "model-metadata-central", + "version": "0.1.0", + "description": "Typed TypeScript registry of LLM model metadata (context windows, pricing, providers)", + "license": "MIT", + "type": "module", + "main": "./dist/index.js", + "types": "./dist/index.d.ts", + "exports": { + ".": { + "import": "./dist/index.js", + "types": "./dist/index.d.ts" + }, + "./providers": { + "import": "./dist/providers.json", + "types": "./dist/providers.d.ts" + }, + "./registry": { + "import": "./dist/registry.json", + "types": "./dist/registry.d.ts" + } + }, + "files": ["dist"], + "scripts": { + "build": "tsc && node src/build-registry.mjs", + "build:registry": "node src/build-registry.mjs", + "generate": "node ../../scripts/codegen.mjs", + "prepare": "npm run generate && npm run build", + "lint": "tsc --noEmit", + "test": "vitest" + }, + "devDependencies": { + "@types/node": "^20.0.0", + "typescript": "^5.0.0", + "yaml": "3.0.0-0" + }, + "keywords": [ + "model-metadata", + "llm", + "openai", + "anthropic", + "google", + "gemini", + "deepseek", + "context-window", + "token-pricing" + ] +} \ No newline at end of file diff --git a/packages/typescript/src/build-registry.mjs b/packages/typescript/src/build-registry.mjs new file mode 100644 index 0000000..08b88db --- /dev/null +++ b/packages/typescript/src/build-registry.mjs @@ -0,0 +1,36 @@ +/** + * Build script: compiles models/*.yaml and providers/*.yaml to JSON registries. + * Run via `pnpm build:registry` or `pnpm prepare`. + */ +import fs from "node:fs"; +import path from "node:path"; +import { fileURLToPath } from "node:url"; +import { parse as parseYAML } from "yaml"; + +const __dirname = path.dirname(fileURLToPath(import.meta.url)); +// 3 levels up from src/ → repo root +const repoRoot = path.resolve(__dirname, "../../../"); + +const MODELS_DIR = path.join(repoRoot, "models"); +const PROVIDERS_DIR = path.join(repoRoot, "providers"); +const SRC_DIR = __dirname; +const OUT_MODELS = path.join(SRC_DIR, "registry.json"); +const OUT_PROVIDERS = path.join(SRC_DIR, "providers.json"); + +function readDir(dir) { + if (!fs.existsSync(dir)) return []; + return fs + .readdirSync(dir) + .filter((f) => f.endsWith(".yaml")) + .map((f) => + parseYAML(fs.readFileSync(path.join(dir, f), "utf8")), + ); +} + +const models = readDir(MODELS_DIR); +const providers = readDir(PROVIDERS_DIR); + +fs.writeFileSync(OUT_MODELS, JSON.stringify(models, null, 2)); +fs.writeFileSync(OUT_PROVIDERS, JSON.stringify(providers, null, 2)); + +console.log(`Wrote ${models.length} models, ${providers.length} providers`); \ No newline at end of file diff --git a/packages/typescript/src/generated/types.ts b/packages/typescript/src/generated/types.ts new file mode 100644 index 0000000..efda1b6 --- /dev/null +++ b/packages/typescript/src/generated/types.ts @@ -0,0 +1,51 @@ +/** Generated from JSON Schema — do not edit manually */ + +// --- Enums --- +export type Model_type = 'chat' | 'completion' | 'embedding'; +export type Api_type = 'openai_compatible' | 'anthropic' | 'openai' | 'other'; +export type Auth_type = 'api_key' | 'bearer' | 'oauth' | 'managed' | 'none'; +export type Routing_priority = 'direct' | 'aggregator' | 'both'; +export type Status = 'active' | 'deprecated' | 'inactive'; +export type Family = 'tiktoken' | 'tekken' | 'sentencepiece' | 'huggingface' | 'other' | 'unknown'; + +// --- $defs --- +export interface Provider_reference { + provider_id: string; + model_id_on_provider?: string; +} + +export interface Tokenizer_config { + family: Family; + name?: string; +} + +// --- Schema types --- +export interface ModelMetadata { + model_id: string; + model_name?: string; + model_provider?: string; + model_description?: string; + model_info?: string; + model_version?: string; + model_type: Model_type; + context_window: number; + max_tokens?: number; + cost_per_token?: unknown; + knowledge_cutoff?: string; + tokenizer?: Tokenizer_config; + tuning?: unknown[]; + deprecated?: boolean; + providers?: unknown[]; +} + +export interface ProviderMetadata { + provider_id: string; + name: string; + website_url?: string; + api_type: Api_type; + base_url?: string; + auth_type?: Auth_type; + routing_priority: Routing_priority; + status?: Status; + notes?: string; +} diff --git a/packages/typescript/src/index.ts b/packages/typescript/src/index.ts new file mode 100644 index 0000000..bd3a95f --- /dev/null +++ b/packages/typescript/src/index.ts @@ -0,0 +1,176 @@ +import type { ModelMetadata, ProviderMetadata, ProviderReference } from "./types.js"; +import registryJson from "./registry.json" with { type: "json" }; +import providersJson from "./providers.json" with { type: "json" }; + +/** All models as a typed array — registry is lazy-indexed so helpers don't inflate bundles */ +const registry = registryJson as unknown as ModelMetadata[]; +const providers = providersJson as unknown as ProviderMetadata[]; + +// Index built only when needed — avoids forcing any helper code into a +// bundle that only imports specific model objects directly. +let index: Map | null = null; +let providerIndex: Map | null = null; + +function getIndex(): Map { + if (!index) { + index = new Map(registry.map((m) => [m.model_id, m])); + } + return index; +} + +function getProviderIndex(): Map { + if (!providerIndex) { + providerIndex = new Map(providers.map((p) => [p.provider_id, p])); + } + return providerIndex; +} + +// --- Public API --- + +/** Look up a model by its model_id. Returns undefined if not found. */ +export function getModel(modelId: string): ModelMetadata | undefined { + return getIndex().get(modelId); +} + +/** Return all models. */ +export function getAllModels(): readonly ModelMetadata[] { + return registry; +} + +/** Filter models by provider. provider_id matches providers/ directory filenames. */ +export function getModelsByProvider(providerId: string): readonly ModelMetadata[] { + return registry.filter((m) => + m.providers?.some((p) => p.provider_id === providerId), + ); +} + +/** Return all models available on a specific model_id as served by a provider. */ +export function getModelOnProvider( + providerId: string, + providerModelId?: string, +): ModelMetadata | undefined { + return registry.find((m) => + m.providers?.some( + (p) => + p.provider_id === providerId && + (providerModelId + ? p.model_id_on_provider === providerModelId + : true), + ), + ); +} + +/** Get a provider definition by provider_id. */ +export function getProvider( + providerId: string, +): ProviderMetadata | undefined { + return getProviderIndex().get(providerId); +} + +/** Return all providers. */ +export function getAllProviders(): readonly ProviderMetadata[] { + return providers; +} + +/** Map provider_id -> model_id_on_provider for a given model on a given provider. */ +export function getProviderModelId( + modelId: string, + providerId: string, +): string | undefined { + return getModel(modelId) + ?.providers?.find((p) => p.provider_id === providerId) + ?.model_id_on_provider; +} + +// --- Named re-exports for tree-shaking --- +// Individual model objects — bundlers can dead-code-eliminate unused ones. +// Kept in sync with models/*.yaml. Usage: import { gpt4o } from 'model-metadata-central'; +export const claudeHaiku4 = getModel("claude-haiku-4"); +export const claudeHaiku45 = getModel("claude-haiku-4-5"); +export const claudeOpus46 = getModel("claude-opus-4-6"); +export const claudeOpus46Fast = getModel("claude-opus-4-6-fast"); +export const claudeOpus47 = getModel("claude-opus-4-7"); +export const claudeOpusLatest = getModel("claude-opus-latest"); +export const claudeSonnet42 = getModel("claude-sonnet-4-2"); +export const claudeSonnet46 = getModel("claude-sonnet-4-6"); +export const codestralLatest = getModel("codestral-latest"); +export const deepseekCoderV4 = getModel("deepseek-coder-v4"); +export const deepseekR1DistillLlama70b = getModel("deepseek-r1-distill-llama-70b"); +export const deepseekV4Flash = getModel("deepseek-v4-flash"); +export const deepseekV4Pro = getModel("deepseek-v4-pro"); +export const gemini20Flash = getModel("gemini-2.0-flash"); +export const gemini25Flash = getModel("gemini-2.5-flash"); +export const gemini25Pro = getModel("gemini-2.5-pro"); +export const gemma426bA4bIt = getModel("gemma-4-26b-a4b-it"); +export const gemma431bIt = getModel("gemma-4-31b-it"); +export const glm47 = getModel("glm-4.7"); +export const glm47Flash = getModel("glm-4.7-flash"); +export const glm5 = getModel("glm-5"); +export const glm5Turbo = getModel("glm-5-turbo"); +export const glm51 = getModel("glm-5.1"); +export const glm5vTurbo = getModel("glm-5v-turbo"); +export const gpt35Turbo = getModel("gpt-3.5-turbo"); +export const gpt35Turbo16k = getModel("gpt-3.5-turbo-16k"); +export const gpt35TurboInstruct = getModel("gpt-3.5-turbo-instruct"); +export const gpt4 = getModel("gpt-4"); +export const gpt432k = getModel("gpt-4-32k"); +export const gpt4Turbo = getModel("gpt-4-turbo"); +export const gpt41 = getModel("gpt-4.1"); +export const gpt41Mini = getModel("gpt-4.1-mini"); +export const gpt41Nano = getModel("gpt-4.1-nano"); +export const gpt45 = getModel("gpt-4.5"); +export const gpt4o = getModel("gpt-4o"); +export const gpt4oMini = getModel("gpt-4o-mini"); +export const gpt5 = getModel("gpt-5"); +export const gpt5Mini = getModel("gpt-5-mini"); +export const gpt5Nano = getModel("gpt-5-nano"); +export const gpt53Codex = getModel("gpt-5.3-codex"); +export const gpt54 = getModel("gpt-5.4"); +export const gpt54Image2 = getModel("gpt-5.4-image-2"); +export const gpt54Mini = getModel("gpt-5.4-mini"); +export const gpt54Nano = getModel("gpt-5.4-nano"); +export const gpt54Pro = getModel("gpt-5.4-pro"); +export const gpt55 = getModel("gpt-5.5"); +export const gpt55Pro = getModel("gpt-5.5-pro"); +export const grok42 = getModel("grok-4.2"); +export const grok42MultiAgent = getModel("grok-4.2-multi-agent"); +export const kimiK26 = getModel("kimi-k2.6"); +export const kimiV3 = getModel("kimi-v3"); +export const llama318bInstant = getModel("llama-3.1-8b-instant"); +export const llama3370bVersatile = getModel("llama-3.3-70b-versatile"); +export const minimaxM2 = getModel("minimax-m2"); +export const minimaxM21 = getModel("minimax-m2.1"); +export const minimaxM21Highspeed = getModel("minimax-m2.1-highspeed"); +export const minimaxM25 = getModel("minimax-m2.5"); +export const minimaxM25Highspeed = getModel("minimax-m2.5-highspeed"); +export const minimaxM27 = getModel("minimax-m2.7"); +export const minimaxM27Highspeed = getModel("minimax-m2.7-highspeed"); +export const mistral7b = getModel("mistral-7b"); +export const mistral7bInstruct = getModel("mistral-7b-instruct"); +export const mistralLarge2411 = getModel("mistral-large-2411"); +export const mistralLarge2512 = getModel("mistral-large-2512"); +export const mistralLargeLatest = getModel("mistral-large-latest"); +export const mistralMediumLatest = getModel("mistral-medium-latest"); +export const mistralNemo = getModel("mistral-nemo"); +export const mistralSmallLatest = getModel("mistral-small-latest"); +export const nemotron3Super120bA12b = getModel("nemotron-3-super-120b-a12b"); +export const o3 = getModel("o3"); +export const o4Mini = getModel("o4-mini"); +export const qwen332b = getModel("qwen3-32b"); +export const qwen36Flash = getModel("qwen3.6-flash"); +export const qwen36Plus = getModel("qwen3.6-plus"); + +// Re-export types +export type { + ModelMetadata, + ProviderMetadata, + ProviderReference, + ModelType, + Tuning, + TokenEncoding, + ApiType, + AuthType, + RoutingPriority, + ProviderStatus, + CostPerToken, +} from "./types.js"; \ No newline at end of file diff --git a/packages/typescript/src/providers.json b/packages/typescript/src/providers.json new file mode 100644 index 0000000..76346a1 --- /dev/null +++ b/packages/typescript/src/providers.json @@ -0,0 +1,189 @@ +[ + { + "provider_id": "anthropic", + "name": "Anthropic", + "website_url": "https://anthropic.com", + "api_type": "anthropic", + "base_url": "https://api.anthropic.com/v1", + "auth_type": "api_key", + "routing_priority": "direct", + "status": "active", + "notes": "Primary provider for Claude models. Uses Anthropic's own API protocol." + }, + { + "provider_id": "cloudflare", + "name": "Cloudflare Workers AI", + "website_url": "https://developers.cloudflare.com/workers-ai", + "api_type": "openai_compatible", + "base_url": "https://api.cloudflare.com/client/v4", + "auth_type": "api_key", + "routing_priority": "direct", + "status": "active", + "notes": "Edge inference via Cloudflare Workers AI. Account-scoped model routes use /accounts/{account_id}/ai/run/{model}; OpenAI-compatible routes use /accounts/{account_id}/ai/v1." + }, + { + "provider_id": "deepseek", + "name": "DeepSeek", + "website_url": "https://deepseek.com", + "api_type": "openai_compatible", + "base_url": "https://api.deepseek.com/v1", + "auth_type": "api_key", + "routing_priority": "direct", + "status": "active", + "notes": "Primary provider for DeepSeek V4 and Coder models." + }, + { + "provider_id": "google", + "name": "Google AI", + "website_url": "https://ai.google", + "api_type": "openai_compatible", + "base_url": "https://generativelanguage.googleapis.com/v1beta", + "auth_type": "api_key", + "routing_priority": "direct", + "status": "active", + "notes": "Primary provider for Gemini, Gemma, and Lyria models via Vertex AI or AI Studio." + }, + { + "provider_id": "groq", + "name": "Groq", + "website_url": "https://console.groq.com", + "api_type": "openai_compatible", + "base_url": "https://api.groq.com/openai/v1", + "auth_type": "api_key", + "routing_priority": "direct", + "status": "active", + "notes": "High-speed inference provider. Good for latency-sensitive applications. Popular for Llama and Mixtral models." + }, + { + "provider_id": "lmstudio", + "name": "LM Studio", + "website_url": "https://lmstudio.ai", + "api_type": "openai_compatible", + "base_url": "http://localhost:1234/v1", + "auth_type": "none", + "routing_priority": "direct", + "status": "active", + "notes": "Local inference GUI and API server for GGUF/GGML models. Similar API to Ollama. Authentication disabled by default." + }, + { + "provider_id": "localai", + "name": "LocalAI", + "website_url": "https://localai.io", + "api_type": "openai_compatible", + "base_url": "http://localhost:8080/v1", + "auth_type": "api_key", + "routing_priority": "direct", + "status": "active", + "notes": "Self-hosted inference engine. Supports many open models via ggml/gguf. Often used in Kubernetes/ Docker stacks. Authentication may be bearer token or disabled depending on config." + }, + { + "provider_id": "minimax", + "name": "MiniMax", + "website_url": "https://platform.minimax.io", + "api_type": "anthropic", + "base_url": "https://api.minimax.io/anthropic", + "auth_type": "api_key", + "routing_priority": "direct", + "status": "active", + "notes": "Primary provider for MiniMax text models. Anthropic-compatible API is recommended and supports streaming plus interleaved thinking; MiniMax also exposes OpenAI-compatible text APIs." + }, + { + "provider_id": "mistralai", + "name": "Mistral AI", + "website_url": "https://mistral.ai", + "api_type": "openai_compatible", + "base_url": "https://api.mistral.ai/v1", + "auth_type": "api_key", + "routing_priority": "direct", + "status": "active", + "notes": "Primary provider for Mistral's own models including Mistral Small, Medium, Large, and Codestral." + }, + { + "provider_id": "moonshotai", + "name": "Moonshot AI", + "website_url": "https://moonshot.ai", + "api_type": "openai_compatible", + "base_url": "https://api.moonshotai.com/v1", + "auth_type": "api_key", + "routing_priority": "direct", + "status": "active", + "notes": "Primary provider for Kimi models." + }, + { + "provider_id": "nvidia", + "name": "NVIDIA NIM", + "website_url": "https://build.nvidia.com", + "api_type": "openai_compatible", + "base_url": "https://integrate.api.nvidia.com/v1", + "auth_type": "api_key", + "routing_priority": "direct", + "status": "active", + "notes": "NVIDIA NIM API catalog for hosted and deployable NVIDIA/open model inference, including Nemotron." + }, + { + "provider_id": "ollama", + "name": "Ollama", + "website_url": "https://ollama.com", + "api_type": "openai_compatible", + "base_url": "http://localhost:11434/v1", + "auth_type": "none", + "routing_priority": "direct", + "status": "active", + "notes": "Local inference runtime for macOS, Linux, and Windows. Serves quantized GGUF models. Authentication disabled by default; configure .env/ollama for credentials in production." + }, + { + "provider_id": "openai", + "name": "OpenAI", + "website_url": "https://openai.com", + "api_type": "openai_compatible", + "base_url": "https://api.openai.com/v1", + "auth_type": "api_key", + "routing_priority": "direct", + "status": "active", + "notes": "The primary provider for OpenAI models including GPT-4, GPT-5, and o-series." + }, + { + "provider_id": "openrouter", + "name": "OpenRouter", + "website_url": "https://openrouter.ai", + "api_type": "openai_compatible", + "base_url": "https://openrouter.ai/api/v1", + "auth_type": "api_key", + "routing_priority": "aggregator", + "status": "active", + "notes": "Aggregator that routes to multiple providers. Useful for model comparison and failover. Access models from OpenAI, Anthropic, Google, DeepSeek and more via a unified API." + }, + { + "provider_id": "qwen", + "name": "Qwen", + "website_url": "https://qwen.ai", + "api_type": "openai_compatible", + "base_url": "https://dashscope-intl.aliyuncs.com/compatible-mode/v1", + "auth_type": "api_key", + "routing_priority": "direct", + "status": "active", + "notes": "Primary provider for Qwen models via Alibaba Cloud DashScope." + }, + { + "provider_id": "x-ai", + "name": "xAI", + "website_url": "https://x.ai", + "api_type": "openai_compatible", + "base_url": "https://api.x.ai/v1", + "auth_type": "api_key", + "routing_priority": "direct", + "status": "active", + "notes": "Primary provider for Grok models." + }, + { + "provider_id": "zai", + "name": "Z.AI", + "website_url": "https://z.ai", + "api_type": "openai_compatible", + "base_url": "https://api.z.ai/api/paas/v4", + "auth_type": "api_key", + "routing_priority": "direct", + "status": "active", + "notes": "Primary provider for GLM models. OpenAI-compatible API endpoint for Z.AI/Zhipu model access." + } +] \ No newline at end of file diff --git a/packages/typescript/src/registry.json b/packages/typescript/src/registry.json new file mode 100644 index 0000000..82ee94b --- /dev/null +++ b/packages/typescript/src/registry.json @@ -0,0 +1,2111 @@ +[ + { + "model_id": "claude-haiku-4-5", + "model_name": "Claude Haiku 4.5 (latest)", + "model_provider": "anthropic", + "model_description": "Anthropic's fast, low-cost Claude 4.5 model with near-frontier intelligence for high-volume work.", + "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 + }, + "knowledge_cutoff": "2025-02-28", + "tuning": [ + "multimodal", + "function" + ], + "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_id": "claude-haiku-4", + "model_name": "Claude Haiku 4", + "model_provider": "anthropic", + "model_description": "Fast, affordable Claude. Optimized for high-volume, latency-sensitive tasks where quality-per-token matters more than raw capability.", + "model_info": "https://docs.anthropic.com/en/docs/models/claude-haiku-4", + "model_type": "chat", + "context_window": 200000, + "cost_per_token": { + "input": 8e-7, + "output": 0.000004 + }, + "providers": [ + { + "provider_id": "anthropic", + "model_id_on_provider": "haiku-4" + }, + { + "provider_id": "openrouter", + "model_id_on_provider": "anthropic/claude-haiku-4" + } + ] + }, + { + "model_id": "claude-opus-4-6-fast", + "model_name": "Claude Opus 4.6 (Fast)", + "model_provider": "anthropic", + "model_description": "High-speed variant of Opus 4.6. Optimized for rapid responses while retaining strong reasoning and capabilities.", + "model_info": "https://docs.anthropic.com/en/docs/models/claude-opus-4-6", + "model_type": "chat", + "context_window": 1000000, + "cost_per_token": { + "input": 0.00003, + "output": 0.00015 + }, + "tuning": [ + "function" + ], + "providers": [ + { + "provider_id": "anthropic", + "model_id_on_provider": "claude-opus-4-6-fast" + }, + { + "provider_id": "openrouter", + "model_id_on_provider": "anthropic/claude-opus-4-6-fast" + } + ] + }, + { + "model_id": "claude-opus-4-6", + "model_name": "Claude Opus 4.6", + "model_provider": "anthropic", + "model_description": "Anthropic's previous-generation Opus model with 1M context, retained for downstream compatibility.", + "model_info": "https://docs.anthropic.com/en/docs/about-claude/models/overview", + "model_type": "chat", + "context_window": 1000000, + "max_tokens": 128000, + "cost_per_token": { + "input": 0.000005, + "output": 0.000025 + }, + "knowledge_cutoff": "2025-05-31", + "tuning": [ + "multimodal", + "function" + ], + "providers": [ + { + "provider_id": "anthropic", + "model_id_on_provider": "claude-opus-4-6" + }, + { + "provider_id": "openrouter", + "model_id_on_provider": "anthropic/claude-opus-4.6" + } + ] + }, + { + "model_id": "claude-opus-4-7", + "model_name": "Claude Opus 4.7", + "model_provider": "anthropic", + "model_description": "Anthropic's most capable model. Exceptional at complex reasoning, coding, creative collaboration, and scientific analysis.", + "model_info": "https://docs.anthropic.com/en/docs/models/claude-opus-4-7", + "model_type": "chat", + "context_window": 1000000, + "cost_per_token": { + "input": 0.000005, + "output": 0.000025 + }, + "tuning": [ + "function" + ], + "providers": [ + { + "provider_id": "anthropic", + "model_id_on_provider": "claude-opus-4-7" + }, + { + "provider_id": "openrouter", + "model_id_on_provider": "anthropic/claude-opus-4-7" + } + ] + }, + { + "model_id": "claude-opus-latest", + "model_name": "Claude Opus Latest", + "model_provider": "anthropic", + "model_description": "Points to the latest stable Opus release. Use when you want the newest Claude without pinning a version.", + "model_info": "https://docs.anthropic.com/en/docs/models", + "model_type": "chat", + "context_window": 1000000, + "cost_per_token": { + "input": 0.000005, + "output": 0.000025 + }, + "tuning": [ + "function" + ], + "providers": [ + { + "provider_id": "anthropic", + "model_id_on_provider": "opus" + }, + { + "provider_id": "openrouter", + "model_id_on_provider": "anthropic/claude-opus-latest" + } + ] + }, + { + "model_id": "claude-sonnet-4-2", + "model_name": "Claude Sonnet 4.2", + "model_provider": "anthropic", + "model_description": "Balanced Anthropic model. Strong for coding, analysis, and everyday tasks at a mid-range price point.", + "model_info": "https://docs.anthropic.com/en/docs/models/claude-sonnet-4-2", + "model_type": "chat", + "context_window": 200000, + "cost_per_token": { + "input": 0.000003, + "output": 0.000015 + }, + "tuning": [ + "function" + ], + "providers": [ + { + "provider_id": "anthropic", + "model_id_on_provider": "claude-sonnet-4-2" + }, + { + "provider_id": "openrouter", + "model_id_on_provider": "anthropic/claude-sonnet-4-2" + } + ] + }, + { + "model_id": "claude-sonnet-4-6", + "model_name": "Claude Sonnet 4.6", + "model_provider": "anthropic", + "model_description": "Anthropic's balanced Claude model with strong speed/intelligence tradeoffs, extended thinking, and 1M context.", + "model_info": "https://docs.anthropic.com/en/docs/about-claude/models/overview", + "model_type": "chat", + "context_window": 1000000, + "max_tokens": 64000, + "cost_per_token": { + "input": 0.000003, + "output": 0.000015 + }, + "knowledge_cutoff": "2025-08-31", + "tuning": [ + "multimodal", + "function" + ], + "providers": [ + { + "provider_id": "anthropic", + "model_id_on_provider": "claude-sonnet-4-6" + }, + { + "provider_id": "openrouter", + "model_id_on_provider": "anthropic/claude-sonnet-4.6" + } + ] + }, + { + "model_id": "codestral-latest", + "model_name": "Codestral (latest)", + "model_provider": "mistralai", + "model_description": "Mistral's code-specialized model for software engineering and code completion workflows.", + "model_info": "https://docs.mistral.ai/getting-started/models/models_overview/", + "model_type": "chat", + "context_window": 256000, + "max_tokens": 4096, + "cost_per_token": { + "input": 3e-7, + "output": 9e-7 + }, + "knowledge_cutoff": "2024-10-01", + "tokenizer": { + "family": "tekken" + }, + "tuning": [ + "function", + "instruction" + ], + "providers": [ + { + "provider_id": "mistralai", + "model_id_on_provider": "codestral-latest" + }, + { + "provider_id": "openrouter", + "model_id_on_provider": "mistralai/codestral-latest" + } + ] + }, + { + "model_id": "deepseek-coder-v4", + "model_name": "DeepSeek Coder V4", + "model_provider": "deepseek", + "model_description": "DeepSeek's dedicated code model. Specialized for code generation, completion, and debugging across many languages.", + "model_info": "https://api.deepseek.com", + "model_type": "chat", + "context_window": 1048576, + "cost_per_token": { + "input": 4.3e-7, + "output": 8.7e-7 + }, + "tuning": [ + "code" + ], + "providers": [ + { + "provider_id": "deepseek", + "model_id_on_provider": "deepseek-coder" + }, + { + "provider_id": "openrouter", + "model_id_on_provider": "deepseek/deepseek-coder-v4" + } + ] + }, + { + "model_id": "deepseek-r1-distill-llama-70b", + "model_name": "DeepSeek R1 Distill Llama 70B", + "model_provider": "groq", + "model_description": "Groq-hosted DeepSeek R1 distilled Llama 70B reasoning model.", + "model_info": "https://console.groq.com/docs/models", + "model_type": "chat", + "context_window": 131072, + "max_tokens": 8192, + "cost_per_token": { + "input": 7.5e-7, + "output": 9.9e-7 + }, + "knowledge_cutoff": "2024-07-01", + "tuning": [ + "function", + "instruction" + ], + "providers": [ + { + "provider_id": "groq", + "model_id_on_provider": "deepseek-r1-distill-llama-70b" + } + ] + }, + { + "model_id": "deepseek-v4-flash", + "model_name": "DeepSeek V4 Flash", + "model_provider": "deepseek", + "model_description": "Fast, efficient DeepSeek variant. Optimized for high-volume applications where latency and cost are critical.", + "model_info": "https://api.deepseek.com", + "model_type": "chat", + "context_window": 1048576, + "cost_per_token": { + "input": 1.4e-7, + "output": 2.8e-7 + }, + "providers": [ + { + "provider_id": "deepseek", + "model_id_on_provider": "deepseek-chat" + }, + { + "provider_id": "openrouter", + "model_id_on_provider": "deepseek/deepseek-v4-flash" + } + ] + }, + { + "model_id": "deepseek-v4-pro", + "model_name": "DeepSeek V4 Pro", + "model_provider": "deepseek", + "model_description": "DeepSeek's flagship model. Excellent reasoning and code capabilities at a fraction of OpenAI's cost.", + "model_info": "https://api.deepseek.com", + "model_type": "chat", + "context_window": 1048576, + "cost_per_token": { + "input": 4.3e-7, + "output": 8.7e-7 + }, + "tuning": [ + "function" + ], + "providers": [ + { + "provider_id": "deepseek", + "model_id_on_provider": "deepseek-chat" + }, + { + "provider_id": "openrouter", + "model_id_on_provider": "deepseek/deepseek-v4-pro" + } + ] + }, + { + "model_id": "gemini-2.0-flash", + "model_name": "Gemini 2.0 Flash", + "model_provider": "google", + "model_description": "Previous-generation Gemini. Good balance of speed, cost, and capability for standard tasks.", + "model_info": "https://ai.google.dev/gemini-api/models/gemini-2.0-flash", + "model_type": "chat", + "context_window": 128000, + "cost_per_token": { + "input": 1e-7, + "output": 4e-7 + }, + "deprecated": true, + "providers": [ + { + "provider_id": "google", + "model_id_on_provider": "gemini-2.0-flash" + }, + { + "provider_id": "openrouter", + "model_id_on_provider": "google/gemini-2.0-flash" + } + ] + }, + { + "model_id": "gemini-2.5-flash", + "model_name": "Gemini 2.5 Flash", + "model_provider": "google", + "model_description": "Fast, efficient Gemini model. Optimized for high-volume applications with strong reasoning and code performance.", + "model_info": "https://ai.google.dev/gemini-api/models/gemini-2.5-flash", + "model_type": "chat", + "context_window": 1000000, + "cost_per_token": { + "input": 7.5e-8, + "output": 3e-7 + }, + "tuning": [ + "multimodal" + ], + "providers": [ + { + "provider_id": "google", + "model_id_on_provider": "gemini-2.5-flash" + }, + { + "provider_id": "openrouter", + "model_id_on_provider": "google/gemini-2.5-flash" + } + ] + }, + { + "model_id": "gemini-2.5-pro", + "model_name": "Gemini 2.5 Pro", + "model_provider": "google", + "model_description": "Google's flagship model. Exceptional at long-context tasks, multimodal reasoning, and code generation.", + "model_info": "https://ai.google.dev/gemini-api/docs/models/gemini-2.5-pro", + "model_type": "chat", + "context_window": 1000000, + "cost_per_token": { + "input": 0.00000125, + "output": 0.000005 + }, + "tuning": [ + "multimodal" + ], + "providers": [ + { + "provider_id": "google", + "model_id_on_provider": "gemini-2.5-pro" + }, + { + "provider_id": "openrouter", + "model_id_on_provider": "google/gemini-2.5-pro" + } + ] + }, + { + "model_id": "gemma-4-26b-a4b-it", + "model_name": "Gemma 4 26B", + "model_provider": "google", + "model_description": "Google's smaller open-weight instruction-tuned model. Efficient for constrained deployment environments.", + "model_info": "https://ai.google.dev/gemma", + "model_type": "chat", + "context_window": 262144, + "cost_per_token": { + "input": 6e-8, + "output": 3.3e-7 + }, + "providers": [ + { + "provider_id": "google", + "model_id_on_provider": "gemma-4-26b-a4b-it" + }, + { + "provider_id": "cloudflare", + "model_id_on_provider": "@cf/google/gemma-4-26b-a4b-it" + }, + { + "provider_id": "openrouter", + "model_id_on_provider": "google/gemma-4-26b-a4b-it" + } + ] + }, + { + "model_id": "gemma-4-31b-it", + "model_name": "Gemma 4 31B", + "model_provider": "google", + "model_description": "Google's open-weight instruction-tuned model. Strong reasoning in a smaller footprint. Good for fine-tuning and self-hosting.", + "model_info": "https://ai.google.dev/gemma", + "model_type": "chat", + "context_window": 262144, + "cost_per_token": { + "input": 1.3e-7, + "output": 3.8e-7 + }, + "providers": [ + { + "provider_id": "google", + "model_id_on_provider": "gemma-4-31b-it" + }, + { + "provider_id": "openrouter", + "model_id_on_provider": "google/gemma-4-31b-it" + } + ] + }, + { + "model_id": "glm-4.7-flash", + "model_name": "GLM-4.7-Flash", + "model_provider": "zai", + "model_description": "Fast open-weight GLM model optimized for multilingual dialogue, tool calling, and reasoning.", + "model_info": "https://docs.z.ai/guides/overview/pricing", + "model_type": "chat", + "context_window": 200000, + "max_tokens": 131072, + "cost_per_token": { + "input": 0, + "output": 0 + }, + "knowledge_cutoff": "2025-04-01", + "tuning": [ + "function", + "instruction" + ], + "providers": [ + { + "provider_id": "zai", + "model_id_on_provider": "glm-4.7-flash" + }, + { + "provider_id": "cloudflare", + "model_id_on_provider": "@cf/zai-org/glm-4.7-flash" + }, + { + "provider_id": "openrouter", + "model_id_on_provider": "z-ai/glm-4.7-flash" + } + ] + }, + { + "model_id": "glm-4.7", + "model_name": "GLM-4.7", + "model_provider": "zai", + "model_description": "Open-weight Z.AI GLM model with strong multilingual, reasoning, and instruction-following capabilities.", + "model_info": "https://docs.z.ai/guides/overview/pricing", + "model_type": "chat", + "context_window": 204800, + "max_tokens": 131072, + "cost_per_token": { + "input": 6e-7, + "output": 0.0000022 + }, + "knowledge_cutoff": "2025-04-01", + "tuning": [ + "function", + "instruction" + ], + "providers": [ + { + "provider_id": "zai", + "model_id_on_provider": "glm-4.7" + }, + { + "provider_id": "openrouter", + "model_id_on_provider": "z-ai/glm-4.7" + } + ] + }, + { + "model_id": "glm-5-turbo", + "model_name": "GLM-5-Turbo", + "model_provider": "zai", + "model_description": "Higher-throughput GLM-5 Turbo model for production Z.AI workloads.", + "model_info": "https://docs.z.ai/guides/overview/pricing", + "model_type": "chat", + "context_window": 200000, + "max_tokens": 131072, + "cost_per_token": { + "input": 0.0000012, + "output": 0.000004 + }, + "tuning": [ + "function" + ], + "providers": [ + { + "provider_id": "zai", + "model_id_on_provider": "glm-5-turbo" + }, + { + "provider_id": "openrouter", + "model_id_on_provider": "z-ai/glm-5-turbo" + } + ] + }, + { + "model_id": "glm-5.1", + "model_name": "GLM-5.1", + "model_provider": "zai", + "model_description": "Updated GLM-5.1 model with current Z.AI pricing and long-context support.", + "model_info": "https://docs.z.ai/guides/overview/pricing", + "model_type": "chat", + "context_window": 200000, + "max_tokens": 131072, + "cost_per_token": { + "input": 0.0000014, + "output": 0.0000044 + }, + "tuning": [ + "function" + ], + "providers": [ + { + "provider_id": "zai", + "model_id_on_provider": "glm-5.1" + }, + { + "provider_id": "openrouter", + "model_id_on_provider": "z-ai/glm-5.1" + } + ] + }, + { + "model_id": "glm-5", + "model_name": "GLM-5", + "model_provider": "zai", + "model_description": "Z.AI GLM-5 model for current-generation reasoning and agentic workloads.", + "model_info": "https://docs.z.ai/guides/overview/pricing", + "model_type": "chat", + "context_window": 204800, + "max_tokens": 131072, + "cost_per_token": { + "input": 0.000001, + "output": 0.0000032 + }, + "tuning": [ + "function", + "instruction" + ], + "providers": [ + { + "provider_id": "zai", + "model_id_on_provider": "glm-5" + }, + { + "provider_id": "openrouter", + "model_id_on_provider": "z-ai/glm-5" + } + ] + }, + { + "model_id": "glm-5v-turbo", + "model_name": "glm-5v-turbo", + "model_provider": "zai", + "model_description": "Vision-capable GLM-5 Turbo variant for multimodal document, image, and video inputs.", + "model_info": "https://docs.z.ai/guides/overview/pricing", + "model_type": "chat", + "context_window": 200000, + "max_tokens": 131072, + "cost_per_token": { + "input": 0.0000012, + "output": 0.000004 + }, + "tuning": [ + "multimodal", + "function" + ], + "providers": [ + { + "provider_id": "zai", + "model_id_on_provider": "glm-5v-turbo" + }, + { + "provider_id": "openrouter", + "model_id_on_provider": "z-ai/glm-5v-turbo" + } + ] + }, + { + "model_id": "gpt-3.5-turbo-16k", + "model_name": "GPT-3.5 Turbo 16K", + "model_provider": "openai", + "model_description": "Deprecated 16K GPT-3.5 Turbo snapshot retained for legacy downstream configurations.", + "model_info": "https://platform.openai.com/docs/models/gpt-3.5-turbo-16k-0613", + "model_version": "0613", + "model_type": "chat", + "context_window": 16385, + "max_tokens": 4096, + "cost_per_token": { + "input": 0.000003, + "output": 0.000004 + }, + "knowledge_cutoff": "2021-09-01", + "tokenizer": { + "family": "tiktoken", + "name": "cl100k_base" + }, + "tuning": [ + "instruction" + ], + "deprecated": true, + "providers": [ + { + "provider_id": "openai", + "model_id_on_provider": "gpt-3.5-turbo-16k-0613" + } + ] + }, + { + "model_id": "gpt-3.5-turbo-instruct", + "model_name": "GPT-3.5 Turbo Instruct", + "model_provider": "openai", + "model_description": "Similar capabilities as text-davinci-003 but compatible with legacy Completions endpoint and not Chat Completions.", + "model_info": "https://platform.openai.com/docs/models/gpt-3-5", + "model_version": "latest", + "model_type": "completion", + "context_window": 4097, + "max_tokens": 4095, + "cost_per_token": { + "input": 0.0000015, + "output": 0.000002 + }, + "knowledge_cutoff": "2021-09-01", + "tokenizer": { + "family": "tiktoken", + "name": "cl100k_base" + }, + "tuning": [ + "instruction", + "function" + ], + "deprecated": true + }, + { + "model_id": "gpt-3.5-turbo", + "model_name": "GPT-3.5 Turbo", + "model_provider": "openai", + "model_description": "Most capable GPT-3.5 model and optimized for chat at 1/10th the cost of text-davinci-003.", + "model_info": "https://platform.openai.com/docs/models/gpt-3-5", + "model_version": "latest", + "model_type": "chat", + "context_window": 4097, + "max_tokens": 4095, + "cost_per_token": { + "input": 0.0000015, + "output": 0.000002 + }, + "knowledge_cutoff": "2021-09-01", + "tokenizer": { + "family": "tiktoken", + "name": "cl100k_base" + }, + "tuning": [ + "function" + ], + "deprecated": true, + "providers": [ + { + "provider_id": "openai", + "model_id_on_provider": "gpt-3.5-turbo" + } + ] + }, + { + "model_id": "gpt-4-32k", + "model_name": "GPT-4 32K", + "model_provider": "openai", + "model_description": "Same capabilities as the standard gpt-4 mode but with 4x the context length.", + "model_info": "https://platform.openai.com/docs/models/gpt-4", + "model_version": "latest", + "model_type": "chat", + "context_window": 32768, + "cost_per_token": { + "input": 0.00006, + "output": 0.00012 + }, + "knowledge_cutoff": "2021-09-01", + "tokenizer": { + "family": "tiktoken", + "name": "cl100k_base" + }, + "tuning": [ + "function" + ], + "deprecated": true + }, + { + "model_id": "gpt-4-turbo", + "model_name": "GPT-4 Turbo", + "model_provider": "openai", + "model_description": "Legacy GPT-4 Turbo model with a 128K context window. Kept for integrations that still route older GPT-4 workloads.", + "model_info": "https://platform.openai.com/docs/models/gpt-4-turbo", + "model_type": "chat", + "context_window": 128000, + "max_tokens": 4096, + "cost_per_token": { + "input": 0.00001, + "output": 0.00003 + }, + "knowledge_cutoff": "2023-12-01", + "tokenizer": { + "family": "tiktoken", + "name": "o200k_base" + }, + "tuning": [ + "multimodal", + "function" + ], + "providers": [ + { + "provider_id": "openai", + "model_id_on_provider": "gpt-4-turbo" + }, + { + "provider_id": "openrouter", + "model_id_on_provider": "openai/gpt-4-turbo" + } + ] + }, + { + "model_id": "gpt-4.1-mini", + "model_name": "GPT-4.1 mini", + "model_provider": "openai", + "model_description": "Smaller GPT-4.1 variant balancing latency, price, and strong general-purpose capability.", + "model_info": "https://platform.openai.com/docs/models/gpt-4.1-mini", + "model_type": "chat", + "context_window": 1047576, + "max_tokens": 32768, + "cost_per_token": { + "input": 4e-7, + "output": 0.0000016 + }, + "knowledge_cutoff": "2024-04-01", + "tokenizer": { + "family": "tiktoken", + "name": "o200k_base" + }, + "tuning": [ + "multimodal", + "function" + ], + "providers": [ + { + "provider_id": "openai", + "model_id_on_provider": "gpt-4.1-mini" + }, + { + "provider_id": "openrouter", + "model_id_on_provider": "openai/gpt-4.1-mini" + } + ] + }, + { + "model_id": "gpt-4.1-nano", + "model_name": "GPT-4.1 nano", + "model_provider": "openai", + "model_description": "Lowest-cost GPT-4.1 variant for classification, extraction, and latency-sensitive tasks.", + "model_info": "https://platform.openai.com/docs/models/gpt-4.1-nano", + "model_type": "chat", + "context_window": 1047576, + "max_tokens": 32768, + "cost_per_token": { + "input": 1e-7, + "output": 4e-7 + }, + "knowledge_cutoff": "2024-04-01", + "tokenizer": { + "family": "tiktoken", + "name": "o200k_base" + }, + "tuning": [ + "multimodal", + "function" + ], + "providers": [ + { + "provider_id": "openai", + "model_id_on_provider": "gpt-4.1-nano" + }, + { + "provider_id": "openrouter", + "model_id_on_provider": "openai/gpt-4.1-nano" + } + ] + }, + { + "model_id": "gpt-4.1", + "model_name": "GPT-4.1", + "model_provider": "openai", + "model_description": "Large-context GPT-4.1 model for coding, instruction following, and multimodal document workflows.", + "model_info": "https://platform.openai.com/docs/models/gpt-4.1", + "model_type": "chat", + "context_window": 1047576, + "max_tokens": 32768, + "cost_per_token": { + "input": 0.000002, + "output": 0.000008 + }, + "knowledge_cutoff": "2024-04-01", + "tokenizer": { + "family": "tiktoken", + "name": "o200k_base" + }, + "tuning": [ + "multimodal", + "function" + ], + "providers": [ + { + "provider_id": "openai", + "model_id_on_provider": "gpt-4.1" + }, + { + "provider_id": "openrouter", + "model_id_on_provider": "openai/gpt-4.1" + } + ] + }, + { + "model_id": "gpt-4.5", + "model_name": "GPT-4.5", + "model_provider": "openai", + "model_description": "GPT-4 successor with improved reasoning and instruction following. Strong all-around model between GPT-4o and GPT-5 series.", + "model_info": "https://platform.openai.com/docs/models/gpt-4.5", + "model_type": "chat", + "context_window": 128000, + "cost_per_token": { + "input": 0.00001, + "output": 0.00003 + }, + "tuning": [ + "function" + ], + "tokenizer": { + "family": "tiktoken", + "name": "o200k_base" + }, + "providers": [ + { + "provider_id": "openai", + "model_id_on_provider": "gpt-4.5" + }, + { + "provider_id": "openrouter", + "model_id_on_provider": "openai/gpt-4.5" + } + ] + }, + { + "model_id": "gpt-4", + "model_name": "GPT-4", + "model_provider": "openai", + "model_description": "More capable than any GPT-3.5 model able to do more complex tasks and optimized for chat.", + "model_info": "https://platform.openai.com/docs/models/gpt-4", + "model_version": "latest", + "model_type": "chat", + "context_window": 8192, + "max_tokens": 8191, + "cost_per_token": { + "input": 0.00003, + "output": 0.00006 + }, + "knowledge_cutoff": "2021-09-01", + "tokenizer": { + "family": "tiktoken", + "name": "cl100k_base" + }, + "tuning": [ + "function" + ], + "deprecated": true, + "providers": [ + { + "provider_id": "openai", + "model_id_on_provider": "gpt-4" + } + ] + }, + { + "model_id": "gpt-4o-mini", + "model_name": "GPT-4o Mini", + "model_provider": "openai", + "model_description": "Smaller, faster, cheaper GPT-4o. Optimized for high-volume, cost-sensitive applications.", + "model_info": "https://platform.openai.com/docs/models/gpt-4o-mini", + "model_type": "chat", + "context_window": 128000, + "max_tokens": 16384, + "cost_per_token": { + "input": 1.5e-7, + "output": 6e-7 + }, + "tuning": [ + "multimodal" + ], + "tokenizer": { + "family": "tiktoken", + "name": "o200k_base" + }, + "providers": [ + { + "provider_id": "openai", + "model_id_on_provider": "gpt-4o-mini" + }, + { + "provider_id": "openrouter", + "model_id_on_provider": "openai/gpt-4o-mini" + } + ] + }, + { + "model_id": "gpt-4o", + "model_name": "GPT-4o", + "model_provider": "openai", + "model_description": "GPT-4 Omni — multimodal model with vision, audio, and text. Fast and cost-efficient relative to GPT-4 Turbo.", + "model_info": "https://platform.openai.com/docs/models/gpt-4o", + "model_type": "chat", + "context_window": 128000, + "max_tokens": 32768, + "cost_per_token": { + "input": 0.000005, + "output": 0.000015 + }, + "tuning": [ + "multimodal" + ], + "tokenizer": { + "family": "tiktoken", + "name": "o200k_base" + }, + "providers": [ + { + "provider_id": "openai", + "model_id_on_provider": "gpt-4o" + }, + { + "provider_id": "openrouter", + "model_id_on_provider": "openai/gpt-4o" + } + ] + }, + { + "model_id": "gpt-5-mini", + "model_name": "GPT-5 Mini", + "model_provider": "openai", + "model_description": "Lower-cost GPT-5 variant for high-volume tasks that still benefit from reasoning support.", + "model_info": "https://platform.openai.com/docs/models/gpt-5-mini", + "model_type": "chat", + "context_window": 400000, + "max_tokens": 128000, + "cost_per_token": { + "input": 2.5e-7, + "output": 0.000002 + }, + "knowledge_cutoff": "2024-05-30", + "tokenizer": { + "family": "tiktoken", + "name": "o200k_base" + }, + "tuning": [ + "multimodal", + "function" + ], + "providers": [ + { + "provider_id": "openai", + "model_id_on_provider": "gpt-5-mini" + }, + { + "provider_id": "openrouter", + "model_id_on_provider": "openai/gpt-5-mini" + } + ] + }, + { + "model_id": "gpt-5-nano", + "model_name": "GPT-5 Nano", + "model_provider": "openai", + "model_description": "Smallest GPT-5 variant for inexpensive, latency-sensitive automation.", + "model_info": "https://platform.openai.com/docs/models/gpt-5-nano", + "model_type": "chat", + "context_window": 400000, + "max_tokens": 128000, + "cost_per_token": { + "input": 5e-8, + "output": 4e-7 + }, + "knowledge_cutoff": "2024-05-30", + "tokenizer": { + "family": "tiktoken", + "name": "o200k_base" + }, + "tuning": [ + "multimodal", + "function" + ], + "providers": [ + { + "provider_id": "openai", + "model_id_on_provider": "gpt-5-nano" + }, + { + "provider_id": "openrouter", + "model_id_on_provider": "openai/gpt-5-nano" + } + ] + }, + { + "model_id": "gpt-5.3-codex", + "model_name": "GPT-5.3 Codex", + "model_provider": "openai", + "model_description": "Codex-optimized GPT-5.3 model for coding agents and long-running software engineering tasks.", + "model_info": "https://platform.openai.com/docs/models/gpt-5.3-codex", + "model_type": "chat", + "context_window": 400000, + "max_tokens": 128000, + "cost_per_token": { + "input": 0.00000175, + "output": 0.000014 + }, + "knowledge_cutoff": "2025-08-31", + "tokenizer": { + "family": "tiktoken", + "name": "o200k_base" + }, + "tuning": [ + "multimodal", + "function" + ], + "providers": [ + { + "provider_id": "openai", + "model_id_on_provider": "gpt-5.3-codex" + }, + { + "provider_id": "openrouter", + "model_id_on_provider": "openai/gpt-5.3-codex" + } + ] + }, + { + "model_id": "gpt-5.4-image-2", + "model_name": "GPT-5.4 Image 2", + "model_provider": "openai", + "model_description": "GPT-5.4 optimized for image understanding and generation. Multimodal model supporting vision tasks.", + "model_info": "https://platform.openai.com/docs/models/gpt-5.4-image-2", + "model_type": "chat", + "context_window": 272000, + "cost_per_token": { + "input": 0.000008, + "output": 0.000015 + }, + "tuning": [ + "multimodal" + ], + "providers": [ + { + "provider_id": "openai", + "model_id_on_provider": "gpt-5.4-image-2" + }, + { + "provider_id": "openrouter", + "model_id_on_provider": "openai/gpt-5.4-image-2" + } + ] + }, + { + "model_id": "gpt-5.4-mini", + "model_name": "GPT-5.4 mini", + "model_provider": "openai", + "model_description": "Fast, cost-efficient GPT-5.4 variant for coding, computer use, and subagent workloads.", + "model_info": "https://platform.openai.com/docs/models/gpt-5.4-mini", + "model_type": "chat", + "context_window": 400000, + "max_tokens": 128000, + "cost_per_token": { + "input": 7.5e-7, + "output": 0.0000045 + }, + "knowledge_cutoff": "2025-08-31", + "tokenizer": { + "family": "tiktoken", + "name": "o200k_base" + }, + "tuning": [ + "multimodal", + "function" + ], + "providers": [ + { + "provider_id": "openai", + "model_id_on_provider": "gpt-5.4-mini" + }, + { + "provider_id": "openrouter", + "model_id_on_provider": "openai/gpt-5.4-mini" + } + ] + }, + { + "model_id": "gpt-5.4-nano", + "model_name": "GPT-5.4 nano", + "model_provider": "openai", + "model_description": "Lowest-latency GPT-5.4 variant for inexpensive high-volume tasks.", + "model_info": "https://platform.openai.com/docs/models/gpt-5.4-nano", + "model_type": "chat", + "context_window": 400000, + "max_tokens": 128000, + "cost_per_token": { + "input": 2e-7, + "output": 0.00000125 + }, + "knowledge_cutoff": "2025-08-31", + "tokenizer": { + "family": "tiktoken", + "name": "o200k_base" + }, + "tuning": [ + "multimodal", + "function" + ], + "providers": [ + { + "provider_id": "openai", + "model_id_on_provider": "gpt-5.4-nano" + }, + { + "provider_id": "openrouter", + "model_id_on_provider": "openai/gpt-5.4-nano" + } + ] + }, + { + "model_id": "gpt-5.4-pro", + "model_name": "GPT-5.4 Pro", + "model_provider": "openai", + "model_description": "High-capability GPT-5.4 Pro model for the hardest reasoning and professional workloads.", + "model_info": "https://platform.openai.com/docs/models/gpt-5.4-pro", + "model_type": "chat", + "context_window": 1050000, + "max_tokens": 128000, + "cost_per_token": { + "input": 0.00003, + "output": 0.00018 + }, + "knowledge_cutoff": "2025-08-31", + "tokenizer": { + "family": "tiktoken", + "name": "o200k_base" + }, + "tuning": [ + "multimodal", + "function" + ], + "providers": [ + { + "provider_id": "openai", + "model_id_on_provider": "gpt-5.4-pro" + }, + { + "provider_id": "openrouter", + "model_id_on_provider": "openai/gpt-5.4-pro" + } + ] + }, + { + "model_id": "gpt-5.4", + "model_name": "GPT-5.4", + "model_provider": "openai", + "model_description": "Current OpenAI model for coding and professional work with a 1M token context window.", + "model_info": "https://platform.openai.com/docs/models/gpt-5.4", + "model_type": "chat", + "context_window": 1050000, + "max_tokens": 128000, + "cost_per_token": { + "input": 0.0000025, + "output": 0.000015 + }, + "knowledge_cutoff": "2025-08-31", + "tokenizer": { + "family": "tiktoken", + "name": "o200k_base" + }, + "tuning": [ + "multimodal", + "function" + ], + "providers": [ + { + "provider_id": "openai", + "model_id_on_provider": "gpt-5.4" + }, + { + "provider_id": "openrouter", + "model_id_on_provider": "openai/gpt-5.4" + } + ] + }, + { + "model_id": "gpt-5.5-pro", + "model_name": "GPT-5.5 Pro", + "model_provider": "openai", + "model_description": "Most capable OpenAI model with largest context window. Optimized for complex reasoning, advanced coding, and scientific analysis.", + "model_info": "https://platform.openai.com/docs/models/gpt-5.5-pro", + "model_type": "chat", + "context_window": 1050000, + "max_tokens": 1049999, + "cost_per_token": { + "input": 0.00003, + "output": 0.00018 + }, + "tuning": [ + "function" + ], + "providers": [ + { + "provider_id": "openai", + "model_id_on_provider": "gpt-5.5-pro" + }, + { + "provider_id": "openrouter", + "model_id_on_provider": "openai/gpt-5.5-pro" + } + ] + }, + { + "model_id": "gpt-5.5", + "model_name": "GPT-5.5", + "model_provider": "openai", + "model_description": "Capable OpenAI model with large context window. Strong for complex tasks at lower cost than Pro.", + "model_info": "https://platform.openai.com/docs/models/gpt-5.5", + "model_type": "chat", + "context_window": 1050000, + "max_tokens": 1049999, + "cost_per_token": { + "input": 0.000005, + "output": 0.00003 + }, + "tuning": [ + "function" + ], + "providers": [ + { + "provider_id": "openai", + "model_id_on_provider": "gpt-5.5" + }, + { + "provider_id": "openrouter", + "model_id_on_provider": "openai/gpt-5.5" + } + ] + }, + { + "model_id": "gpt-5", + "model_name": "GPT-5", + "model_provider": "openai", + "model_description": "General GPT-5 model for reasoning, coding, and multimodal text/image workflows.", + "model_info": "https://platform.openai.com/docs/models/gpt-5", + "model_type": "chat", + "context_window": 400000, + "max_tokens": 128000, + "cost_per_token": { + "input": 0.00000125, + "output": 0.00001 + }, + "knowledge_cutoff": "2024-09-30", + "tokenizer": { + "family": "tiktoken", + "name": "o200k_base" + }, + "tuning": [ + "multimodal", + "function" + ], + "providers": [ + { + "provider_id": "openai", + "model_id_on_provider": "gpt-5" + }, + { + "provider_id": "openrouter", + "model_id_on_provider": "openai/gpt-5" + } + ] + }, + { + "model_id": "grok-4.2-multi-agent", + "model_name": "Grok 4.2 Multi-Agent", + "model_provider": "x-ai", + "model_description": "Grok 4.2 optimized for multi-agent workflows. Enhanced tool use and coordination for parallel task execution.", + "model_info": "https://x.ai/api", + "model_type": "chat", + "context_window": 2000000, + "cost_per_token": { + "input": 0.000002, + "output": 0.000006 + }, + "providers": [ + { + "provider_id": "x-ai", + "model_id_on_provider": "grok-4.2" + }, + { + "provider_id": "openrouter", + "model_id_on_provider": "x-ai/grok-4.2-multi-agent" + } + ] + }, + { + "model_id": "grok-4.2", + "model_name": "Grok 4.2", + "model_provider": "x-ai", + "model_description": "xAI's flagship model. Strong reasoning with real-time web access. Known for personality and directness.", + "model_info": "https://x.ai/api", + "model_type": "chat", + "context_window": 2000000, + "cost_per_token": { + "input": 0.000002, + "output": 0.000006 + }, + "tuning": [ + "function" + ], + "providers": [ + { + "provider_id": "x-ai", + "model_id_on_provider": "grok-4.2" + }, + { + "provider_id": "openrouter", + "model_id_on_provider": "x-ai/grok-4.2" + } + ] + }, + { + "model_id": "kimi-k2.6", + "model_name": "Kimi K2.6", + "model_provider": "moonshotai", + "model_description": "Moonshot AI's flagship model. Strong long-context understanding and reasoning at competitive pricing.", + "model_info": "https://platform.moonshot.ai/docs", + "model_type": "chat", + "context_window": 256000, + "cost_per_token": { + "input": 7.4e-7, + "output": 0.00000466 + }, + "tuning": [ + "function" + ], + "providers": [ + { + "provider_id": "moonshotai", + "model_id_on_provider": "kimi-k2.6" + }, + { + "provider_id": "cloudflare", + "model_id_on_provider": "@cf/moonshotai/kimi-k2.6" + }, + { + "provider_id": "openrouter", + "model_id_on_provider": "moonshotai/kimi-k2.6" + } + ] + }, + { + "model_id": "kimi-v3", + "model_name": "Kimi V3", + "model_provider": "moonshotai", + "model_description": "Mid-range Moonshot model. Good balance of capability and cost for standard tasks.", + "model_info": "https://platform.moonshot.ai/docs", + "model_type": "chat", + "context_window": 256000, + "cost_per_token": { + "input": 2e-7, + "output": 0.000001 + }, + "providers": [ + { + "provider_id": "moonshotai", + "model_id_on_provider": "kimi-v3" + }, + { + "provider_id": "openrouter", + "model_id_on_provider": "moonshotai/kimi-v3" + } + ] + }, + { + "model_id": "llama-3.1-8b-instant", + "model_name": "Llama 3.1 8B Instant", + "model_provider": "groq", + "model_description": "Groq-hosted Llama 3.1 8B model for very low-latency, low-cost chat and automation.", + "model_info": "https://console.groq.com/docs/models", + "model_type": "chat", + "context_window": 131072, + "max_tokens": 131072, + "cost_per_token": { + "input": 5e-8, + "output": 8e-8 + }, + "knowledge_cutoff": "2023-12-01", + "tuning": [ + "function", + "instruction" + ], + "providers": [ + { + "provider_id": "groq", + "model_id_on_provider": "llama-3.1-8b-instant" + } + ] + }, + { + "model_id": "llama-3.3-70b-versatile", + "model_name": "Llama 3.3 70B Versatile", + "model_provider": "groq", + "model_description": "Groq-hosted Llama 3.3 70B model optimized for fast general-purpose chat and tool workloads.", + "model_info": "https://console.groq.com/docs/models", + "model_type": "chat", + "context_window": 131072, + "max_tokens": 32768, + "cost_per_token": { + "input": 5.9e-7, + "output": 7.9e-7 + }, + "knowledge_cutoff": "2023-12-01", + "tuning": [ + "function", + "instruction" + ], + "providers": [ + { + "provider_id": "groq", + "model_id_on_provider": "llama-3.3-70b-versatile" + } + ] + }, + { + "model_id": "minimax-m2.1-highspeed", + "model_name": "MiniMax M2.1-highspeed", + "model_provider": "minimax", + "model_description": "High-speed MiniMax M2.1 variant for faster multilingual programming and agent workflows.", + "model_info": "https://platform.minimax.io/docs/guides/text-generation", + "model_type": "chat", + "context_window": 204800, + "max_tokens": 131072, + "cost_per_token": { + "input": 6e-7, + "output": 0.0000024 + }, + "tuning": [ + "function", + "instruction", + "code", + "multilingual" + ], + "providers": [ + { + "provider_id": "minimax", + "model_id_on_provider": "MiniMax-M2.1-highspeed" + } + ] + }, + { + "model_id": "minimax-m2.1", + "model_name": "MiniMax M2.1", + "model_provider": "minimax", + "model_description": "MiniMax M2.1 model with strong multilingual programming and enhanced coding experience.", + "model_info": "https://platform.minimax.io/docs/guides/text-generation", + "model_type": "chat", + "context_window": 204800, + "max_tokens": 131072, + "cost_per_token": { + "input": 3e-7, + "output": 0.0000012 + }, + "tuning": [ + "function", + "instruction", + "code", + "multilingual" + ], + "providers": [ + { + "provider_id": "minimax", + "model_id_on_provider": "MiniMax-M2.1" + }, + { + "provider_id": "openrouter", + "model_id_on_provider": "minimax/minimax-m2.1" + } + ] + }, + { + "model_id": "minimax-m2.5-highspeed", + "model_name": "MiniMax M2.5-highspeed", + "model_provider": "minimax", + "model_description": "High-speed MiniMax M2.5 variant for lower-latency coding and agent workloads.", + "model_info": "https://platform.minimax.io/docs/guides/text-generation", + "model_type": "chat", + "context_window": 204800, + "max_tokens": 131072, + "cost_per_token": { + "input": 6e-7, + "output": 0.0000024 + }, + "tuning": [ + "function", + "instruction", + "code", + "multilingual" + ], + "providers": [ + { + "provider_id": "minimax", + "model_id_on_provider": "MiniMax-M2.5-highspeed" + } + ] + }, + { + "model_id": "minimax-m2.5", + "model_name": "MiniMax M2.5", + "model_provider": "minimax", + "model_description": "MiniMax M2.5 model for complex programming, agent, and productivity tasks.", + "model_info": "https://platform.minimax.io/docs/guides/text-generation", + "model_type": "chat", + "context_window": 204800, + "max_tokens": 131072, + "cost_per_token": { + "input": 3e-7, + "output": 0.0000012 + }, + "tuning": [ + "function", + "instruction", + "code", + "multilingual" + ], + "providers": [ + { + "provider_id": "minimax", + "model_id_on_provider": "MiniMax-M2.5" + }, + { + "provider_id": "openrouter", + "model_id_on_provider": "minimax/minimax-m2.5" + } + ] + }, + { + "model_id": "minimax-m2.7-highspeed", + "model_name": "MiniMax M2.7-highspeed", + "model_provider": "minimax", + "model_description": "High-speed MiniMax M2.7 variant with the same capability profile and faster output for latency-sensitive workloads.", + "model_info": "https://platform.minimax.io/docs/guides/text-generation", + "model_type": "chat", + "context_window": 204800, + "max_tokens": 131072, + "cost_per_token": { + "input": 6e-7, + "output": 0.0000024 + }, + "tuning": [ + "function", + "instruction", + "code", + "multilingual" + ], + "providers": [ + { + "provider_id": "minimax", + "model_id_on_provider": "MiniMax-M2.7-highspeed" + } + ] + }, + { + "model_id": "minimax-m2.7", + "model_name": "MiniMax M2.7", + "model_provider": "minimax", + "model_description": "Beginning the journey of recursive self-improvement. Strong for programming, tool calling, search, office productivity, and complex agent workflows.", + "model_info": "https://platform.minimax.io/docs/guides/text-generation", + "model_type": "chat", + "context_window": 204800, + "max_tokens": 131072, + "cost_per_token": { + "input": 3e-7, + "output": 0.0000012 + }, + "tuning": [ + "function", + "instruction", + "code", + "multilingual" + ], + "providers": [ + { + "provider_id": "minimax", + "model_id_on_provider": "MiniMax-M2.7" + }, + { + "provider_id": "openrouter", + "model_id_on_provider": "minimax/minimax-m2.7" + } + ] + }, + { + "model_id": "minimax-m2", + "model_name": "MiniMax M2", + "model_provider": "minimax", + "model_description": "MiniMax M2 model for agentic workflows, advanced reasoning, function calling, and real-time streaming.", + "model_info": "https://platform.minimax.io/docs/guides/text-generation", + "model_type": "chat", + "context_window": 204800, + "max_tokens": 128000, + "cost_per_token": { + "input": 3e-7, + "output": 0.0000012 + }, + "tuning": [ + "function", + "instruction", + "code", + "multilingual" + ], + "providers": [ + { + "provider_id": "minimax", + "model_id_on_provider": "MiniMax-M2" + }, + { + "provider_id": "openrouter", + "model_id_on_provider": "minimax/minimax-m2" + } + ] + }, + { + "model_id": "mistral-7b-instruct", + "model_name": "Mistral 7B Instruct", + "model_provider": "mistralai", + "model_description": "Mistral-7B fine-tuned on instruction datasets publicly available on HuggingFace.", + "model_info": "https://huggingface.co/mistralai/Mistral-7B-Instruct-v0.1", + "model_type": "chat", + "context_window": 8192, + "tuning": [ + "instruction" + ], + "deprecated": true, + "providers": [ + { + "provider_id": "mistralai", + "model_id_on_provider": "mistral-7b-instruct-0.3" + }, + { + "provider_id": "openrouter", + "model_id_on_provider": "mistralai/mistral-7b-instruct" + } + ] + }, + { + "model_id": "mistral-7b", + "model_name": "Mistral 7B", + "model_provider": "mistralai", + "model_description": "Mistral-7B-v0.1 is a small yet powerful model adaptable to many use-cases.", + "model_info": "https://mistral.ai/news/announcing-mistral-7b/", + "model_type": "chat", + "context_window": 8192, + "cost_per_token": 0, + "deprecated": true, + "providers": [ + { + "provider_id": "mistralai", + "model_id_on_provider": "open-mistral-7b" + }, + { + "provider_id": "openrouter", + "model_id_on_provider": "mistralai/mistral-7b" + } + ] + }, + { + "model_id": "mistral-large-2411", + "model_name": "Mistral Large 2.1", + "model_provider": "mistralai", + "model_description": "Versioned Mistral Large 2.1 model retained for integrations pinned to the 24.11 release.", + "model_info": "https://docs.mistral.ai/getting-started/models/models_overview/", + "model_type": "chat", + "context_window": 131072, + "max_tokens": 16384, + "cost_per_token": { + "input": 0.000002, + "output": 0.000006 + }, + "knowledge_cutoff": "2024-11-01", + "tokenizer": { + "family": "tekken" + }, + "tuning": [ + "function", + "instruction" + ], + "providers": [ + { + "provider_id": "mistralai", + "model_id_on_provider": "mistral-large-2411" + }, + { + "provider_id": "openrouter", + "model_id_on_provider": "mistralai/mistral-large-2411" + } + ] + }, + { + "model_id": "mistral-large-2512", + "model_name": "Mistral Large 3", + "model_provider": "mistralai", + "model_description": "Mistral Large 3 versioned model with long context and strong multimodal/coding capabilities.", + "model_info": "https://docs.mistral.ai/getting-started/models/models_overview/", + "model_type": "chat", + "context_window": 262144, + "max_tokens": 262144, + "cost_per_token": { + "input": 5e-7, + "output": 0.0000015 + }, + "knowledge_cutoff": "2024-11-01", + "tokenizer": { + "family": "tekken" + }, + "tuning": [ + "multimodal", + "function", + "instruction" + ], + "providers": [ + { + "provider_id": "mistralai", + "model_id_on_provider": "mistral-large-2512" + }, + { + "provider_id": "openrouter", + "model_id_on_provider": "mistralai/mistral-large-2512" + } + ] + }, + { + "model_id": "mistral-large-latest", + "model_name": "Mistral Large (latest)", + "model_provider": "mistralai", + "model_description": "Mistral's current flagship alias for high-quality reasoning, coding, and multimodal workloads.", + "model_info": "https://docs.mistral.ai/getting-started/models/models_overview/", + "model_type": "chat", + "context_window": 262144, + "max_tokens": 262144, + "cost_per_token": { + "input": 5e-7, + "output": 0.0000015 + }, + "knowledge_cutoff": "2024-11-01", + "tokenizer": { + "family": "tekken" + }, + "tuning": [ + "multimodal", + "function", + "instruction" + ], + "providers": [ + { + "provider_id": "mistralai", + "model_id_on_provider": "mistral-large-latest" + }, + { + "provider_id": "openrouter", + "model_id_on_provider": "mistralai/mistral-large-latest" + } + ] + }, + { + "model_id": "mistral-medium-latest", + "model_name": "Mistral Medium (latest)", + "model_provider": "mistralai", + "model_description": "Mistral's balanced mid-tier model for reasoning, coding, and multimodal workflows.", + "model_info": "https://docs.mistral.ai/getting-started/models/models_overview/", + "model_type": "chat", + "context_window": 128000, + "max_tokens": 16384, + "cost_per_token": { + "input": 4e-7, + "output": 0.000002 + }, + "knowledge_cutoff": "2025-05-01", + "tokenizer": { + "family": "tekken" + }, + "tuning": [ + "multimodal", + "function", + "instruction" + ], + "providers": [ + { + "provider_id": "mistralai", + "model_id_on_provider": "mistral-medium-latest" + }, + { + "provider_id": "openrouter", + "model_id_on_provider": "mistralai/mistral-medium-latest" + } + ] + }, + { + "model_id": "mistral-nemo", + "model_name": "Mistral Nemo", + "model_provider": "mistralai", + "model_description": "Open-weight Mistral Nemo model, useful for local or low-cost multilingual deployments.", + "model_info": "https://docs.mistral.ai/getting-started/models/models_overview/", + "model_type": "chat", + "context_window": 128000, + "max_tokens": 128000, + "cost_per_token": { + "input": 1.5e-7, + "output": 1.5e-7 + }, + "knowledge_cutoff": "2024-07-01", + "tokenizer": { + "family": "tekken" + }, + "tuning": [ + "function", + "instruction" + ], + "providers": [ + { + "provider_id": "mistralai", + "model_id_on_provider": "mistral-nemo" + }, + { + "provider_id": "openrouter", + "model_id_on_provider": "mistralai/mistral-nemo" + } + ] + }, + { + "model_id": "mistral-small-latest", + "model_name": "Mistral Small (latest)", + "model_provider": "mistralai", + "model_description": "Mistral's efficient small model alias for low-cost general-purpose and agentic workloads.", + "model_info": "https://docs.mistral.ai/getting-started/models/models_overview/", + "model_type": "chat", + "context_window": 256000, + "max_tokens": 256000, + "cost_per_token": { + "input": 1.5e-7, + "output": 6e-7 + }, + "knowledge_cutoff": "2025-06-01", + "tokenizer": { + "family": "tekken" + }, + "tuning": [ + "multimodal", + "function", + "instruction" + ], + "providers": [ + { + "provider_id": "mistralai", + "model_id_on_provider": "mistral-small-latest" + }, + { + "provider_id": "openrouter", + "model_id_on_provider": "mistralai/mistral-small-latest" + } + ] + }, + { + "model_id": "nemotron-3-super-120b-a12b", + "model_name": "Nemotron 3 Super", + "model_provider": "nvidia", + "model_description": "NVIDIA Nemotron 3 Super, an open-weight hybrid MoE model for agentic reasoning, tool use, and long-context workloads.", + "model_info": "https://docs.api.nvidia.com/nim/reference/nvidia-nemotron-3-super-120b-a12b", + "model_type": "chat", + "context_window": 262144, + "max_tokens": 262144, + "cost_per_token": { + "input": 2e-7, + "output": 8e-7 + }, + "knowledge_cutoff": "2024-04-01", + "tuning": [ + "function", + "instruction" + ], + "providers": [ + { + "provider_id": "nvidia", + "model_id_on_provider": "nvidia/nemotron-3-super-120b-a12b" + }, + { + "provider_id": "openrouter", + "model_id_on_provider": "nvidia/nemotron-3-super-120b-a12b" + }, + { + "provider_id": "cloudflare", + "model_id_on_provider": "@cf/nvidia/nemotron-3-120b-a12b" + } + ] + }, + { + "model_id": "o3", + "model_name": "o3", + "model_provider": "openai", + "model_description": "OpenAI reasoning model. Extended thinking model optimized for complex reasoning, science, and coding. Charges for reasoning tokens.", + "model_info": "https://platform.openai.com/docs/models/o3", + "model_type": "chat", + "context_window": 200000, + "cost_per_token": { + "input": 0.000004, + "output": 0.000016 + }, + "tokenizer": { + "family": "tiktoken", + "name": "o200k_base" + }, + "providers": [ + { + "provider_id": "openai", + "model_id_on_provider": "o3" + }, + { + "provider_id": "openrouter", + "model_id_on_provider": "openai/o3" + } + ] + }, + { + "model_id": "o4-mini", + "model_name": "o4 Mini", + "model_provider": "openai", + "model_description": "Lightweight OpenAI reasoning model. Fast and cost-efficient reasoning for simpler tasks.", + "model_info": "https://platform.openai.com/docs/models/o4-mini", + "model_type": "chat", + "context_window": 100000, + "cost_per_token": { + "input": 0.000001, + "output": 0.000004 + }, + "tokenizer": { + "family": "tiktoken", + "name": "o200k_base" + }, + "providers": [ + { + "provider_id": "openai", + "model_id_on_provider": "o4-mini" + }, + { + "provider_id": "openrouter", + "model_id_on_provider": "openai/o4-mini" + } + ] + }, + { + "model_id": "qwen3-32b", + "model_name": "Qwen3 32B", + "model_provider": "qwen", + "model_description": "Groq-hosted Qwen3 32B open-weight model for reasoning, code, and multilingual work.", + "model_info": "https://console.groq.com/docs/models", + "model_type": "chat", + "context_window": 131072, + "max_tokens": 40960, + "cost_per_token": { + "input": 2.9e-7, + "output": 5.9e-7 + }, + "knowledge_cutoff": "2024-11-08", + "tuning": [ + "function", + "instruction" + ], + "providers": [ + { + "provider_id": "groq", + "model_id_on_provider": "qwen/qwen3-32b" + }, + { + "provider_id": "qwen", + "model_id_on_provider": "qwen3-32b" + }, + { + "provider_id": "openrouter", + "model_id_on_provider": "qwen/qwen3-32b" + } + ] + }, + { + "model_id": "qwen3.6-flash", + "model_name": "Qwen 3.6 Flash", + "model_provider": "qwen", + "model_description": "Fast, efficient Qwen variant. Optimized for high-volume applications.", + "model_info": "https://qwen.io/docs", + "model_type": "chat", + "context_window": 1000000, + "cost_per_token": { + "input": 1e-7, + "output": 4e-7 + }, + "providers": [ + { + "provider_id": "qwen", + "model_id_on_provider": "qwen3.6-flash" + }, + { + "provider_id": "openrouter", + "model_id_on_provider": "qwen/qwen3.6-flash" + } + ] + }, + { + "model_id": "qwen3.6-plus", + "model_name": "Qwen 3.6 Plus", + "model_provider": "qwen", + "model_description": "Alibaba's flagship model. Strong multilingual and reasoning capabilities with large context support.", + "model_info": "https://qwen.io/docs", + "model_type": "chat", + "context_window": 1000000, + "cost_per_token": { + "input": 3.3e-7, + "output": 0.00000195 + }, + "tuning": [ + "function" + ], + "providers": [ + { + "provider_id": "qwen", + "model_id_on_provider": "qwen3.6-plus" + }, + { + "provider_id": "openrouter", + "model_id_on_provider": "qwen/qwen3.6-plus" + } + ] + } +] \ No newline at end of file diff --git a/packages/typescript/src/types.ts b/packages/typescript/src/types.ts new file mode 100644 index 0000000..9fc3919 --- /dev/null +++ b/packages/typescript/src/types.ts @@ -0,0 +1,70 @@ +/** + * TypeScript types matching model-metadata.schema.json and provider.schema.json + */ + +export type ModelType = "chat" | "completion" | "embedding"; + +export type Tuning = "function" | "instruction" | "code" | "multilingual" | "multimodal"; + +export type TokenEncoding = + | "cl100k_base" + | "p50k_base" + | "p50k_edit" + | "r50k_base" + | "llama" + | "unknown"; + +export type ApiType = "openai_compatible" | "anthropic" | "openai" | "other"; + +export type AuthType = "api_key" | "bearer" | "oauth" | "managed"; + +export type RoutingPriority = "direct" | "aggregator" | "both"; + +export type ProviderStatus = "active" | "deprecated" | "inactive"; + +export interface ProviderReference { + provider_id: string; + model_id_on_provider?: string; +} + +export interface CostPerToken { + input: number; + output: number; +} + +export interface ModelMetadata { + model_id: string; + model_name?: string; + model_provider?: string; + model_description?: string; + model_info?: string; + model_version?: string; + model_type: ModelType; + context_window: number; + max_tokens?: number; + cost_per_token?: CostPerToken | number; + knowledge_cutoff?: string; + token_encoding?: TokenEncoding; + tuning?: Tuning[]; + deprecated?: boolean; + providers?: ProviderReference[]; +} + +export interface ProviderMetadata { + provider_id: string; + name: string; + website_url?: string; + api_type: ApiType; + base_url?: string; + auth_type?: AuthType; + routing_priority: RoutingPriority; + status?: ProviderStatus; + notes?: string; +} + +export class ModelNotFoundError extends Error { + constructor(readonly modelId: string) { + super(`No metadata found for model: ${modelId}`); + this.name = "ModelNotFoundError"; + } +} \ No newline at end of file diff --git a/packages/typescript/tsconfig.json b/packages/typescript/tsconfig.json new file mode 100644 index 0000000..9a7e6b1 --- /dev/null +++ b/packages/typescript/tsconfig.json @@ -0,0 +1,16 @@ +{ + "compilerOptions": { + "target": "ES2022", + "module": "NodeNext", + "moduleResolution": "NodeNext", + "declaration": true, + "declarationMap": true, + "outDir": "dist", + "rootDir": "src", + "strict": true, + "esModuleInterop": true, + "skipLibCheck": true + }, + "include": ["src"], + "exclude": ["src/build-registry.mjs", "src/**/*.json"] +} \ No newline at end of file diff --git a/provider.schema.json b/provider.schema.json new file mode 100644 index 0000000..905bab7 --- /dev/null +++ b/provider.schema.json @@ -0,0 +1,54 @@ +{ + "$schema": "https://json-schema.org/draft/2020-12/schema", + "$id": "https://raw.githubusercontent.com/InterwebAlchemy/model-metadata-central/provider.schema.json", + "title": "Provider Metadata", + "description": "A provider definition for model routing and API configuration", + "type": "object", + "properties": { + "provider_id": { + "description": "Unique identifier for the provider (used in model provider_reference)", + "type": "string", + "pattern": "^[a-z0-9_-]+$" + }, + "name": { + "description": "Human-readable provider name (example: OpenAI)", + "type": "string" + }, + "website_url": { + "description": "Link to the provider's website", + "type": "string", + "format": "uri" + }, + "api_type": { + "description": "The type of API the provider exposes", + "type": "string", + "enum": ["openai_compatible", "anthropic", "openai", "other"] + }, + "base_url": { + "description": "The base URL for API requests", + "type": "string", + "format": "uri" + }, + "auth_type": { + "description": "How authentication is handled", + "type": "string", + "enum": ["api_key", "bearer", "oauth", "managed", "none"] + }, + "routing_priority": { + "description": "Whether this provider routes to other providers (aggregator) or serves models directly", + "type": "string", + "enum": ["direct", "aggregator", "both"] + }, + "status": { + "description": "Whether this provider definition is active", + "type": "string", + "enum": ["active", "deprecated", "inactive"], + "default": "active" + }, + "notes": { + "description": "Additional notes about the provider", + "type": "string" + } + }, + "required": ["provider_id", "name", "api_type", "routing_priority"] +} \ No newline at end of file diff --git a/providers/anthropic.yaml b/providers/anthropic.yaml new file mode 100644 index 0000000..df1b9a2 --- /dev/null +++ b/providers/anthropic.yaml @@ -0,0 +1,9 @@ +provider_id: anthropic +name: Anthropic +website_url: https://anthropic.com +api_type: anthropic +base_url: https://api.anthropic.com/v1 +auth_type: api_key +routing_priority: direct +status: active +notes: Primary provider for Claude models. Uses Anthropic's own API protocol. \ No newline at end of file diff --git a/providers/cloudflare.yaml b/providers/cloudflare.yaml new file mode 100644 index 0000000..177dc23 --- /dev/null +++ b/providers/cloudflare.yaml @@ -0,0 +1,9 @@ +provider_id: cloudflare +name: Cloudflare Workers AI +website_url: https://developers.cloudflare.com/workers-ai +api_type: openai_compatible +base_url: https://api.cloudflare.com/client/v4 +auth_type: api_key +routing_priority: direct +status: active +notes: Edge inference via Cloudflare Workers AI. Account-scoped model routes use /accounts/{account_id}/ai/run/{model}; OpenAI-compatible routes use /accounts/{account_id}/ai/v1. diff --git a/providers/deepseek.yaml b/providers/deepseek.yaml new file mode 100644 index 0000000..c80cbbe --- /dev/null +++ b/providers/deepseek.yaml @@ -0,0 +1,9 @@ +provider_id: deepseek +name: DeepSeek +website_url: https://deepseek.com +api_type: openai_compatible +base_url: https://api.deepseek.com/v1 +auth_type: api_key +routing_priority: direct +status: active +notes: Primary provider for DeepSeek V4 and Coder models. \ No newline at end of file diff --git a/providers/google.yaml b/providers/google.yaml new file mode 100644 index 0000000..1f1a6ce --- /dev/null +++ b/providers/google.yaml @@ -0,0 +1,9 @@ +provider_id: google +name: Google AI +website_url: https://ai.google +api_type: openai_compatible +base_url: https://generativelanguage.googleapis.com/v1beta +auth_type: api_key +routing_priority: direct +status: active +notes: Primary provider for Gemini, Gemma, and Lyria models via Vertex AI or AI Studio. \ No newline at end of file diff --git a/providers/groq.yaml b/providers/groq.yaml new file mode 100644 index 0000000..359efb9 --- /dev/null +++ b/providers/groq.yaml @@ -0,0 +1,9 @@ +provider_id: groq +name: Groq +website_url: https://console.groq.com +api_type: openai_compatible +base_url: https://api.groq.com/openai/v1 +auth_type: api_key +routing_priority: direct +status: active +notes: High-speed inference provider. Good for latency-sensitive applications. Popular for Llama and Mixtral models. \ No newline at end of file diff --git a/providers/lmstudio.yaml b/providers/lmstudio.yaml new file mode 100644 index 0000000..cf7104d --- /dev/null +++ b/providers/lmstudio.yaml @@ -0,0 +1,9 @@ +provider_id: lmstudio +name: LM Studio +website_url: https://lmstudio.ai +api_type: openai_compatible +base_url: http://localhost:1234/v1 +auth_type: none +routing_priority: direct +status: active +notes: Local inference GUI and API server for GGUF/GGML models. Similar API to Ollama. Authentication disabled by default. \ No newline at end of file diff --git a/providers/localai.yaml b/providers/localai.yaml new file mode 100644 index 0000000..12bc5d6 --- /dev/null +++ b/providers/localai.yaml @@ -0,0 +1,9 @@ +provider_id: localai +name: LocalAI +website_url: https://localai.io +api_type: openai_compatible +base_url: http://localhost:8080/v1 +auth_type: api_key +routing_priority: direct +status: active +notes: Self-hosted inference engine. Supports many open models via ggml/gguf. Often used in Kubernetes/ Docker stacks. Authentication may be bearer token or disabled depending on config. \ No newline at end of file diff --git a/providers/minimax.yaml b/providers/minimax.yaml new file mode 100644 index 0000000..b9bb079 --- /dev/null +++ b/providers/minimax.yaml @@ -0,0 +1,9 @@ +provider_id: minimax +name: MiniMax +website_url: https://platform.minimax.io +api_type: anthropic +base_url: https://api.minimax.io/anthropic +auth_type: api_key +routing_priority: direct +status: active +notes: Primary provider for MiniMax text models. Anthropic-compatible API is recommended and supports streaming plus interleaved thinking; MiniMax also exposes OpenAI-compatible text APIs. diff --git a/providers/mistralai.yaml b/providers/mistralai.yaml new file mode 100644 index 0000000..a61fa19 --- /dev/null +++ b/providers/mistralai.yaml @@ -0,0 +1,9 @@ +provider_id: mistralai +name: Mistral AI +website_url: https://mistral.ai +api_type: openai_compatible +base_url: https://api.mistral.ai/v1 +auth_type: api_key +routing_priority: direct +status: active +notes: Primary provider for Mistral's own models including Mistral Small, Medium, Large, and Codestral. \ No newline at end of file diff --git a/providers/moonshotai.yaml b/providers/moonshotai.yaml new file mode 100644 index 0000000..692d2c3 --- /dev/null +++ b/providers/moonshotai.yaml @@ -0,0 +1,9 @@ +provider_id: moonshotai +name: Moonshot AI +website_url: https://moonshot.ai +api_type: openai_compatible +base_url: https://api.moonshotai.com/v1 +auth_type: api_key +routing_priority: direct +status: active +notes: Primary provider for Kimi models. \ No newline at end of file diff --git a/providers/nvidia.yaml b/providers/nvidia.yaml new file mode 100644 index 0000000..ddbd3ac --- /dev/null +++ b/providers/nvidia.yaml @@ -0,0 +1,9 @@ +provider_id: nvidia +name: NVIDIA NIM +website_url: https://build.nvidia.com +api_type: openai_compatible +base_url: https://integrate.api.nvidia.com/v1 +auth_type: api_key +routing_priority: direct +status: active +notes: NVIDIA NIM API catalog for hosted and deployable NVIDIA/open model inference, including Nemotron. diff --git a/providers/ollama.yaml b/providers/ollama.yaml new file mode 100644 index 0000000..670e5af --- /dev/null +++ b/providers/ollama.yaml @@ -0,0 +1,9 @@ +provider_id: ollama +name: Ollama +website_url: https://ollama.com +api_type: openai_compatible +base_url: http://localhost:11434/v1 +auth_type: none +routing_priority: direct +status: active +notes: Local inference runtime for macOS, Linux, and Windows. Serves quantized GGUF models. Authentication disabled by default; configure .env/ollama for credentials in production. \ No newline at end of file diff --git a/providers/openai.yaml b/providers/openai.yaml new file mode 100644 index 0000000..2099278 --- /dev/null +++ b/providers/openai.yaml @@ -0,0 +1,9 @@ +provider_id: openai +name: OpenAI +website_url: https://openai.com +api_type: openai_compatible +base_url: https://api.openai.com/v1 +auth_type: api_key +routing_priority: direct +status: active +notes: The primary provider for OpenAI models including GPT-4, GPT-5, and o-series. \ No newline at end of file diff --git a/providers/openrouter.yaml b/providers/openrouter.yaml new file mode 100644 index 0000000..6ea20b2 --- /dev/null +++ b/providers/openrouter.yaml @@ -0,0 +1,9 @@ +provider_id: openrouter +name: OpenRouter +website_url: https://openrouter.ai +api_type: openai_compatible +base_url: https://openrouter.ai/api/v1 +auth_type: api_key +routing_priority: aggregator +status: active +notes: Aggregator that routes to multiple providers. Useful for model comparison and failover. Access models from OpenAI, Anthropic, Google, DeepSeek and more via a unified API. \ No newline at end of file diff --git a/providers/qwen.yaml b/providers/qwen.yaml new file mode 100644 index 0000000..6349d09 --- /dev/null +++ b/providers/qwen.yaml @@ -0,0 +1,9 @@ +provider_id: qwen +name: Qwen +website_url: https://qwen.ai +api_type: openai_compatible +base_url: https://dashscope-intl.aliyuncs.com/compatible-mode/v1 +auth_type: api_key +routing_priority: direct +status: active +notes: Primary provider for Qwen models via Alibaba Cloud DashScope. diff --git a/providers/x-ai.yaml b/providers/x-ai.yaml new file mode 100644 index 0000000..cc659c6 --- /dev/null +++ b/providers/x-ai.yaml @@ -0,0 +1,9 @@ +provider_id: x-ai +name: xAI +website_url: https://x.ai +api_type: openai_compatible +base_url: https://api.x.ai/v1 +auth_type: api_key +routing_priority: direct +status: active +notes: Primary provider for Grok models. \ No newline at end of file diff --git a/providers/zai.yaml b/providers/zai.yaml new file mode 100644 index 0000000..7bcd7ff --- /dev/null +++ b/providers/zai.yaml @@ -0,0 +1,9 @@ +provider_id: zai +name: Z.AI +website_url: https://z.ai +api_type: openai_compatible +base_url: https://api.z.ai/api/paas/v4 +auth_type: api_key +routing_priority: direct +status: active +notes: Primary provider for GLM models. OpenAI-compatible API endpoint for Z.AI/Zhipu model access. diff --git a/scripts/codegen.mjs b/scripts/codegen.mjs new file mode 100644 index 0000000..fed4720 --- /dev/null +++ b/scripts/codegen.mjs @@ -0,0 +1,208 @@ +/** + * Codegen: generates TypeScript types and Python Pydantic models from JSON Schema. + * Single source of truth — edit the schemas, run `node scripts/codegen.mjs`. + */ +import fs from "node:fs"; +import path from "node:path"; +import { fileURLToPath } from "node:url"; + +const __dirname = path.dirname(fileURLToPath(import.meta.url)); +const ROOT = path.resolve(__dirname, ".."); + +// ─── Schema loading ──────────────────────────────────────────────────────────── + +const modelSchema = JSON.parse( + fs.readFileSync(path.join(ROOT, "model-metadata.schema.json"), "utf8"), +); +const providerSchema = JSON.parse( + fs.readFileSync(path.join(ROOT, "provider.schema.json"), "utf8"), +); + +// ─── Helpers ─────────────────────────────────────────────────────────────────── + +function upperFirst(s) { + return s.charAt(0).toUpperCase() + s.slice(1); +} + +function toPascalCase(s) { + return s + .split("_") + .map((part) => upperFirst(part)) + .join(""); +} + +function isRequired(schema, key) { + return schema.required?.includes(key); +} + +// ─── TypeScript codegen ─────────────────────────────────────────────────────── + +function tsEnumType(key, prop, enums) { + if (prop.enum) { + enums.set(upperFirst(key), prop.enum); + } +} + +function tsFieldType(key, prop, defs) { + if (prop.$ref) { + const ref = prop.$ref.replace("#/$defs/", ""); + return upperFirst(ref); + } + if (prop.type === "string") { + return prop.enum ? upperFirst(key) : "string"; + } + if (prop.type === "number" || prop.type === "integer") return "number"; + if (prop.type === "boolean") return "boolean"; + if (prop.type === "array") return "unknown[]"; + if (prop.type === "object") return "Record"; + return "unknown"; +} + +function buildTsInterface(name, schema, enums, defs) { + const lines = [`export interface ${name} {`]; + for (const [key, prop] of Object.entries(schema.properties ?? {})) { + const opt = isRequired(schema, key) ? "" : "?"; + lines.push(` ${key}${opt}: ${tsFieldType(key, prop, defs)};`); + } + lines.push("}"); + return lines.join("\n"); +} + +const tsEnums = new Map(); +const tsDefs = new Map(); +const tsInterfaces = new Map(); + +// Collect enums +for (const [key, prop] of Object.entries(modelSchema.properties ?? {})) { + tsEnumType(key, prop, tsEnums); +} +for (const [key, prop] of Object.entries(providerSchema.properties ?? {})) { + tsEnumType(key, prop, tsEnums); +} +for (const def of Object.values(modelSchema.$defs ?? {})) { + for (const [key, prop] of Object.entries(def.properties ?? {})) { + tsEnumType(key, prop, tsEnums); + } +} + +// Build $defs interfaces +for (const [name, def] of Object.entries(modelSchema.$defs ?? {})) { + const tsName = upperFirst(name); + const lines = [`export interface ${tsName} {`]; + for (const [key, prop] of Object.entries(def.properties ?? {})) { + const opt = def.required?.includes(key) ? "" : "?"; + lines.push(` ${key}${opt}: ${tsFieldType(key, prop, tsDefs)};`); + } + lines.push("}"); + tsDefs.set(tsName, lines.join("\n")); +} + +tsInterfaces.set("ModelMetadata", buildTsInterface("ModelMetadata", modelSchema, tsEnums, tsDefs)); +tsInterfaces.set("ProviderMetadata", buildTsInterface("ProviderMetadata", providerSchema, tsEnums, tsDefs)); + +const tsLines = [ + "/** Generated from JSON Schema — do not edit manually */", + "", + "// --- Enums ---", +]; +for (const [name, values] of tsEnums) { + tsLines.push(`export type ${name} = ${values.map((v) => `'${v}'`).join(" | ")};`); +} + +tsLines.push(""); +tsLines.push("// --- $defs ---"); +for (const [, src] of tsDefs) { + tsLines.push(src); + tsLines.push(""); +} + +tsLines.push("// --- Schema types ---"); +tsLines.push(tsInterfaces.get("ModelMetadata")); +tsLines.push(""); +tsLines.push(tsInterfaces.get("ProviderMetadata")); + +const tsOutput = tsLines.join("\n") + "\n"; + +// ─── Python codegen ─────────────────────────────────────────────────────────── + +function pyField(key, prop, required) { + const req = required.includes(key); + let ann; + + if (prop.$ref) { + ann = upperFirst(prop.$ref.replace("#/$defs/", "")); + } else if (prop.type === "string") { + ann = prop.enum + ? "Literal[" + prop.enum.map((v) => `'${v}'`).join(", ") + "]" + : "str"; + } else if (prop.type === "number" || prop.type === "integer") { + ann = "float"; + } else if (prop.type === "boolean") { + ann = "bool"; + } else if (prop.type === "array") { + ann = "list"; + } else if (prop.type === "object") { + ann = "dict"; + } else { + ann = "Any"; + } + + if (!req) { + if (prop.type === "array") return ` ${key}: list | None = None`; + if (prop.type === "object") return ` ${key}: dict | None = None`; + return ` ${key}: ${ann} | None = None`; + } else { + if (prop.type === "array") return ` ${key}: list = Field()`; + if (prop.type === "object") return ` ${key}: dict = Field()`; + return ` ${key}: ${ann}`; + } +} + +const pyLines = [ + "# Generated from JSON Schema — do not edit manually", + "", + "from __future__ import annotations", + "", + "from typing import Any, Literal", + "from pydantic import BaseModel, Field", + "", +]; + +// $defs first (e.g. ProviderReference) +for (const [name, def] of Object.entries(modelSchema.$defs ?? {})) { + const className = upperFirst(name); + pyLines.push(`class ${className}(BaseModel):`); + const req = def.required ?? []; + for (const [k, v] of Object.entries(def.properties ?? {})) { + pyLines.push(pyField(k, v, req)); + } + pyLines.push(""); +} + +const modelReq = modelSchema.required ?? []; +pyLines.push("class ModelMetadata(BaseModel):"); +pyLines.push(' """Generated from model-metadata.schema.json"""'); +for (const [key, prop] of Object.entries(modelSchema.properties ?? {})) { + pyLines.push(pyField(key, prop, modelReq)); +} + +const providerReq = providerSchema.required ?? []; +pyLines.push(""); +pyLines.push("class ProviderMetadata(BaseModel):"); +pyLines.push(' """Generated from provider.schema.json"""'); +for (const [key, prop] of Object.entries(providerSchema.properties ?? {})) { + pyLines.push(pyField(key, prop, providerReq)); +} + +const pyOutput = pyLines.join("\n") + "\n"; + +// ─── Write outputs ─────────────────────────────────────────────────────────── + +const tsOut = path.join(ROOT, "packages/typescript/src/generated/types.ts"); +const pyOut = path.join(ROOT, "packages/python/model_metadata_central/generated/models.py"); + +fs.writeFileSync(tsOut, tsOutput); +fs.writeFileSync(pyOut, pyOutput); + +console.log(`Wrote ${tsOut}`); +console.log(`Wrote ${pyOut}`);