From 044f0f8951255f907a4fd614acea2119bec49454 Mon Sep 17 00:00:00 2001 From: Alexander Whitestone Date: Wed, 8 Apr 2026 08:15:27 -0400 Subject: [PATCH 1/2] ci: add check_no_duplicate_models.py - catches duplicate model IDs (#224) --- scripts/check_no_duplicate_models.py | 74 ++++++++++++++++++++++++++++ 1 file changed, 74 insertions(+) create mode 100755 scripts/check_no_duplicate_models.py diff --git a/scripts/check_no_duplicate_models.py b/scripts/check_no_duplicate_models.py new file mode 100755 index 000000000..17d2ceb29 --- /dev/null +++ b/scripts/check_no_duplicate_models.py @@ -0,0 +1,74 @@ +#!/usr/bin/env python3 +"""CI check: ensure no duplicate model IDs exist in provider configs. + +Catches the class of bugs where a rename introduces a duplicate entry +(e.g. PR #225 kimi-for-coding -> kimi-k2.5 when kimi-k2.5 already existed). + +Runtime target: < 2 seconds. +""" + +from __future__ import annotations + +import sys +from pathlib import Path + +# Allow running from repo root +REPO_ROOT = Path(__file__).parent.parent +sys.path.insert(0, str(REPO_ROOT)) + + +def check_openrouter_models() -> list[str]: + """Check OPENROUTER_MODELS for duplicate model IDs.""" + try: + from hermes_cli.models import OPENROUTER_MODELS + except ImportError: + return [] + + errors = [] + seen: dict[str, int] = {} + for i, (model_id, _desc) in enumerate(OPENROUTER_MODELS): + if model_id in seen: + errors.append( + f" OPENROUTER_MODELS: duplicate '{model_id}' " + f"(index {seen[model_id]} and {i})" + ) + else: + seen[model_id] = i + return errors + + +def check_provider_models() -> list[str]: + """Check _PROVIDER_MODELS for duplicate model IDs within each provider list.""" + from hermes_cli.models import _PROVIDER_MODELS + + errors = [] + for provider, models in _PROVIDER_MODELS.items(): + seen: dict[str, int] = {} + for i, model_id in enumerate(models): + if model_id in seen: + errors.append( + f" _PROVIDER_MODELS['{provider}']: duplicate '{model_id}' " + f"(index {seen[model_id]} and {i})" + ) + else: + seen[model_id] = i + return errors + + +def main() -> int: + errors = [] + errors.extend(check_openrouter_models()) + errors.extend(check_provider_models()) + + if errors: + print(f"FAIL: {len(errors)} duplicate model(s) found:") + for e in errors: + print(e) + return 1 + + print("OK: no duplicate model entries") + return 0 + + +if __name__ == "__main__": + raise SystemExit(main()) -- 2.43.0 From 5a942d71a1f7efd472460f339b611651af4d2cf7 Mon Sep 17 00:00:00 2001 From: Alexander Whitestone Date: Wed, 8 Apr 2026 08:16:00 -0400 Subject: [PATCH 2/2] ci: add duplicate model check step to CI workflow --- .gitea/workflows/ci.yml | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/.gitea/workflows/ci.yml b/.gitea/workflows/ci.yml index 07ee501c0..f50565a2f 100644 --- a/.gitea/workflows/ci.yml +++ b/.gitea/workflows/ci.yml @@ -47,6 +47,11 @@ jobs: source .venv/bin/activate python scripts/syntax_guard.py + - name: No duplicate models + run: | + source .venv/bin/activate + python scripts/check_no_duplicate_models.py + - name: Green-path E2E run: | source .venv/bin/activate -- 2.43.0