#!/usr/bin/env python3 """Rebuild catalog.json from the public arka-ai.ru OpenAI-compatible models list. Keep FORCED_MODELS / NON_CHAT in lockstep with opencode/plugins/arka-ai.ts. """ from __future__ import annotations import json import re import sys import urllib.request from datetime import datetime, timezone from pathlib import Path API_URL = "https://api.arka-ai.ru/v1/models" ROOT = Path(__file__).resolve().parents[1] OUT = ROOT / "catalog.json" FORCED_MODELS = [ "DeepSeek-V4-Pro", "deepseek-v4-flash-0731", "qwen3.8-max", "kimi-k3", "MiniMax-M3", "GLM-5.3", ] NON_CHAT = re.compile( "|".join( [ "tts", "asr", "audio", "speech", "voice", "whisper", "sensevoice", "image", r"(^|[.-])img", "wan", "vidu", "video", "sora", "flux", "diffus", "kolors", "cogview", "ocr", "embedding", r"(^|[.-])embed", "rerank", "clip", "moderation", r"(^|[.-])filter", "detect", "classif", r"(^|[.-])location", r"(^|[.-])search", "comfyui", "meme", "hello", r"(^|[.-])sam", "florence", "esrgan", "rmbg", "background", "poster", r"(^|[.-])face", r"(^|[.-])lip", "translate", r"(^|[.-])mt([2-]|$)", r"(^|[.-])bge", r"(^|[.-])e5", r"(^|[.-])jina", r"(^|[.-])mpnet", "spark-tts", "cosyvoice", "chattts", "indextts", "step-audio", "fish-speech", "cosy", "mate-gguf", "tokenizer", ] ), re.I, ) def fetch_models() -> list[dict]: req = urllib.request.Request(API_URL, headers={"User-Agent": "arka-public-catalog-sync"}) with urllib.request.urlopen(req, timeout=30) as resp: payload = json.load(resp) data = payload.get("data") or [] if not isinstance(data, list) or not data: raise SystemExit("empty models list from api.arka-ai.ru") return data def keep(item: dict) -> bool: mid = item.get("id") or "" return mid in FORCED_MODELS or not NON_CHAT.search(mid) def main() -> int: raw = fetch_models() chat = [item for item in raw if keep(item)] chat.sort(key=lambda item: item.get("id") or "") missing = [mid for mid in FORCED_MODELS if not any(item.get("id") == mid for item in chat)] if missing: print("warning: forced models missing from catalog:", ", ".join(missing), file=sys.stderr) out = { "updated_at": datetime.now(timezone.utc).strftime("%Y-%m-%dT%H:%M:%SZ"), "source": API_URL, "raw_count": len(raw), "chat_count": len(chat), "object": "list", "data": [{"id": item.get("id"), "object": "model"} for item in chat], } text = json.dumps(out, ensure_ascii=False, indent=2) + "\n" OUT.write_text(text, encoding="utf-8") print(f"wrote {OUT} raw={out['raw_count']} chat={out['chat_count']}") return 0 if __name__ == "__main__": raise SystemExit(main())