From abfb8aff229163a7494f5d998fbab1252aed00a2 Mon Sep 17 00:00:00 2001 From: Jun Siang Cheah Date: Sat, 25 Oct 2025 21:52:15 +0100 Subject: [PATCH] Pull Cohere models via API --- .github/workflows/update-readme.yml | 1 + README.md | 20 +++++--- src/pull_available_models.py | 76 +++++++++++++++++++++++++---- 3 files changed, 79 insertions(+), 18 deletions(-) diff --git a/.github/workflows/update-readme.yml b/.github/workflows/update-readme.yml index 07a3801..32c6d6c 100644 --- a/.github/workflows/update-readme.yml +++ b/.github/workflows/update-readme.yml @@ -38,6 +38,7 @@ jobs: LAMBDA_API_KEY: ${{ secrets.LAMBDA_API_KEY }} MISTRAL_API_KEY: ${{ secrets.MISTRAL_API_KEY }} SCALEWAY_API_KEY: ${{ secrets.SCALEWAY_API_KEY }} + COHERE_API_KEY: ${{ secrets.COHERE_API_KEY }} run: | python -u src/pull_available_models.py - name: Remove credentials diff --git a/README.md b/README.md index d5d1923..3d6ba7a 100644 --- a/README.md +++ b/README.md @@ -207,14 +207,18 @@ Routes to various supported providers. Models share a common quota. -- Command-A -- Command-R7B -- Command-R+ -- Command-R -- Aya Expanse 8B -- Aya Expanse 32B -- Aya Vision 8B -- Aya Vision 32B +- c4ai-aya-expanse-32b +- c4ai-aya-expanse-8b +- c4ai-aya-vision-32b +- c4ai-aya-vision-8b +- command-a-03-2025 +- command-a-reasoning-08-2025 +- command-a-translate-08-2025 +- command-a-vision-07-2025 +- command-r-08-2024 +- command-r-plus-08-2024 +- command-r7b-12-2024 +- command-r7b-arabic-02-2025 ### [GitHub Models](https://github.com/marketplace/models) diff --git a/src/pull_available_models.py b/src/pull_available_models.py index 135346c..c331677 100644 --- a/src/pull_available_models.py +++ b/src/pull_available_models.py @@ -532,6 +532,66 @@ def fetch_scaleway_models(logger): return ret_models +def fetch_cohere_models(logger): + logger.info("Fetching Cohere models...") + headers = { + "accept": "application/json", + "Authorization": f"Bearer {os.environ['COHERE_API_KEY']}", + } + params = {} + all_models = [] + page = 1 + + try: + while True: + response = requests.get( + "https://api.cohere.com/v1/models", + headers=headers, + params=params or None, + timeout=10, + ) + response.raise_for_status() + payload = response.json() + models = payload.get("models", []) + logger.info(f"Fetched {len(models)} models from Cohere (page {page})") + all_models.extend(models) + next_token = payload.get("next_page_token") + if not next_token: + break + params["page_token"] = next_token + page += 1 + except requests.exceptions.RequestException as exc: + logger.error(f"Error fetching Cohere models: {exc}") + return [] + except json.JSONDecodeError as exc: + logger.error(f"Error decoding Cohere API response: {exc}") + return [] + + ret_models = [] + for model in all_models: + model_id = model.get("name") + if not model_id: + continue + if model.get("is_deprecated"): + logger.debug(f"Skipping deprecated Cohere model {model_id}") + continue + endpoints = set(model.get("endpoints") or []) | set( + model.get("default_endpoints") or [] + ) + if "chat" not in endpoints: + logger.debug(f"Skipping non-chat Cohere model {model_id}") + continue + ret_models.append( + { + "id": model_id, + "name": get_model_name(model_id), + } + ) + + logger.info(f"Found {len(ret_models)} Cohere chat models") + return sorted(ret_models, key=lambda x: x["name"]) + + def fetch_chutes_models(logger): logger.info("Fetching Chutes models...") r = requests.get( @@ -598,6 +658,7 @@ def main(): hyperbolic_logger = create_logger("Hyperbolic") samba_logger = create_logger("SambaNova") scaleway_logger = create_logger("Scaleway") + cohere_logger = create_logger("Cohere") fetch_concurrently = os.getenv("FETCH_CONCURRENTLY", "false").lower() == "true" @@ -611,6 +672,7 @@ def main(): executor.submit(fetch_github_models, github_logger), executor.submit(fetch_samba_models, samba_logger), executor.submit(fetch_scaleway_models, scaleway_logger), + executor.submit(fetch_cohere_models, cohere_logger), ] ( gemini_models, @@ -620,6 +682,7 @@ def main(): github_models, samba_models, scaleway_models, + cohere_models, ) = [f.result() for f in futures] # Fetch groq models after others complete @@ -632,6 +695,7 @@ def main(): github_models = fetch_github_models(github_logger) samba_models = fetch_samba_models(samba_logger) scaleway_models = fetch_scaleway_models(scaleway_logger) + cohere_models = fetch_cohere_models(cohere_logger) groq_models = fetch_groq_models(groq_logger) # Initialize markdown string for free providers @@ -830,16 +894,6 @@ def main(): model_list_markdown += "\n" # --- Cohere --- - cohere_models = [ - {"id": "command-a-03-2025", "name": "Command-A"}, - {"id": "command-r7b-12-2024", "name": "Command-R7B"}, - {"id": "command-r-plus", "name": "Command-R+"}, - {"id": "command-r", "name": "Command-R"}, - {"id": "c4ai-aya-expanse-8b", "name": "Aya Expanse 8B"}, - {"id": "c4ai-aya-expanse-32b", "name": "Aya Expanse 32B"}, - {"id": "c4ai-aya-vision-8b", "name": "Aya Vision 8B"}, - {"id": "c4ai-aya-vision-32b", "name": "Aya Vision 32B"}, - ] model_list_markdown += "### [Cohere](https://cohere.com)\n\n" model_list_markdown += "**Limits:**\n\n" model_list_markdown += "[20 requests/minute
1,000 requests/month](https://docs.cohere.com/docs/rate-limits)\n\n" @@ -847,6 +901,8 @@ def main(): if cohere_models: for model in cohere_models: model_list_markdown += f"- {model['name']}\n" + else: + model_list_markdown += "- No chat models available right now.\n" model_list_markdown += "\n" # --- GitHub Models ---