Skip to content

feat: add new model configurations for various AI models#1

Open
teith wants to merge 2 commits into
devfrom
runware
Open

feat: add new model configurations for various AI models#1
teith wants to merge 2 commits into
devfrom
runware

Conversation

@teith

@teith teith commented Jun 23, 2026

Copy link
Copy Markdown
Collaborator
#!/usr/bin/env python3.12
"""Build reviewed models.dev TOMLs for Runware from the model list.

No requests are sent to the models. Capabilities (reasoning, tool_call,
structured_output) default on; edit the exceptions. Missing required numbers
are left as TODO. Each new model is shown for approve/edit/skip.
"""
import argparse
import datetime as dt
import json
import os
import subprocess
import sys
import tempfile
from pathlib import Path

import httpx

PROVIDER = "runware"
PROVIDER_NAME = "Runware"
API_KEY_ENV = "RUNWARE_API_KEY"
DOC = "https://runware.ai/docs"
PROPRIETARY = {"openai", "anthropic", "google", "xai"}
MODALITY = {"text": "text", "image": "image", "audio": "audio", "video": "video", "pdf": "pdf", "file": "pdf"}
SCALARS = ("name", "attachment", "reasoning", "tool_call", "structured_output", "release_date", "last_updated", "open_weights")
DEFAULT_CAPS = {"reasoning": True, "tool_call": True, "structured_output": True}


def fetch_models(base: str) -> list[dict]:
    try:
        token = os.environ[API_KEY_ENV]
    except KeyError:
        sys.exit(f"{API_KEY_ENV} is not set")
    with httpx.Client(base_url=base, headers={"Authorization": f"Bearer {token}"}, timeout=30) as client:
        data = client.get("models").json()
    return data["data"] if isinstance(data, dict) and "data" in data else data


def per_million(value: str | None) -> float | None:
    try:
        rate = float(value)
    except (TypeError, ValueError):
        return None
    return round(rate * 1_000_000, 6) if rate else None


def listing_date(created: int | None) -> str | None:
    return dt.datetime.fromtimestamp(created, dt.UTC).strftime("%Y-%m-%d") if created else None


def build_spec(model: dict) -> dict:
    price = model.get("pricing") or {}
    mods = [MODALITY[m] for m in model.get("input_modalities", ["text"]) if m in MODALITY] or ["text"]
    cache = {k: per_million(price.get(src)) for k, src in (("cache_read", "input_cache_read"), ("cache_write", "input_cache_write"))}
    date = listing_date(model.get("created"))
    return {
        "name": model.get("name") or model["id"],
        "attachment": any(m in mods for m in ("image", "audio", "video", "pdf")),
        **DEFAULT_CAPS,
        "release_date": date,
        "last_updated": date,
        "open_weights": (model.get("owned_by") or "").lower() not in PROPRIETARY,
        "cost": {"input": per_million(price.get("prompt")), "output": per_million(price.get("completion")),
                 **{k: v for k, v in cache.items() if v is not None}},
        "limit": {"context": model.get("context_length"), "input": model.get("context_length"), "output": model.get("max_output_tokens")},
        "modalities": {"input": mods, "output": ["text"]},
    }


def field(key: str, value) -> str:
    if value is None:
        return f"{key} = 0  # TODO: /v1/models returned null"
    return f"{key} = {json.dumps(value, ensure_ascii=False)}"


def render(spec: dict) -> str:
    lines = [field(k, spec[k]) for k in SCALARS]
    for table in ("cost", "limit", "modalities"):
        lines.append(f"\n[{table}]")
        lines += [field(k, v) for k, v in spec[table].items()]
    return "\n".join(lines) + "\n"


def edit(text: str) -> str:
    with tempfile.NamedTemporaryFile("w+", suffix=".toml", delete=False) as fh:
        fh.write(text)
        path = Path(fh.name)
    subprocess.run([os.environ.get("EDITOR", "nano"), str(path)], check=False)
    edited = path.read_text()
    path.unlink()
    return edited


def review(model_id: str, toml: str) -> str | None:
    print(f"\n# providers/{PROVIDER}/models/{model_id}.toml\n{toml}")
    while True:
        match input("[a]pprove / [e]dit / [s]kip > ").strip().lower():
            case "a" | "y" | "":
                return toml
            case "s":
                return None
            case "e":
                toml = edit(toml)
                print(f"\n{toml}")


def main() -> None:
    parser = argparse.ArgumentParser(description=__doc__)
    parser.add_argument("--repo", type=Path, default=Path("."), help="cloned models.dev repo root")
    parser.add_argument("--all", action="store_true", help="re-review models that already exist")
    args = parser.parse_args()

    base = os.environ.get("RUNWARE_BASE_URL", "https://api.runware.ai/v1").rstrip("/") + "/"
    models = fetch_models(base)

    models_dir = args.repo / "providers" / PROVIDER / "models"
    models_dir.mkdir(parents=True, exist_ok=True)
    provider_toml = models_dir.parent / "provider.toml"
    if not provider_toml.exists():
        provider_toml.write_text(
            f'name = "{PROVIDER_NAME}"\nnpm = "@ai-sdk/openai-compatible"\n'
            f'api = "{base.rstrip("/")}"\nenv = ["{API_KEY_ENV}"]\ndoc = "{DOC}"\n')

    todo = [m for m in models if args.all or not (models_dir / f"{m['id']}.toml").exists()]
    if not todo:
        sys.exit("nothing new to add")

    for model in todo:
        if (result := review(model["id"], render(build_spec(model)))) is not None:
            (models_dir / f"{model['id']}.toml").write_text(result)
            print(f"  wrote {model['id']}.toml", file=sys.stderr)


if __name__ == "__main__":
    main()

@teith teith requested a review from neramirez June 23, 2026 22:43
@coderabbitai

coderabbitai Bot commented Jun 23, 2026

Copy link
Copy Markdown

Important

Review skipped

Auto reviews are disabled on this repository. To trigger a review, include coderabbit-review in the PR description. Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro Plus

Run ID: 77e209fe-0842-4a30-8460-8e7a206810a7

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review
✨ Finishing Touches
✨ Simplify code
  • Create PR with simplified code
  • Commit simplified code in branch runware

Comment @coderabbitai help to get the list of available commands.

reasoning = true
tool_call = true
structured_output = true
release_date = "2026-06-12"

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

release_date = "2026-06-09"

reasoning = true
tool_call = true
structured_output = true
release_date = "2026-05-05"

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

release_date = "2025-10-15"

reasoning = true
tool_call = true
structured_output = true
release_date = "2026-05-05"

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

release_date = "2026-04-16"

reasoning = true
tool_call = true
structured_output = true
release_date = "2026-05-15"

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

release_date = "2026-04-24"

reasoning = true
tool_call = true
structured_output = true
release_date = "2026-06-12"

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

release_date = "2026-04-24"

reasoning = true
tool_call = true
structured_output = true
release_date = "2026-05-22"

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

release_date = "2026-04-30"

reasoning = true
tool_call = true
structured_output = true
release_date = "2026-03-12"

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

release_date = "2025-12-22"

reasoning = true
tool_call = true
structured_output = true
release_date = "2026-04-17"

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

release_date = "2026-04-07"

[limit]
context = 1000000
input = 1000000
output = 64000

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

output = 128000

reasoning = true
tool_call = true
structured_output = true
release_date = "2026-06-03"

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

release_date = "2026-06-01"

@jose-ares-runware jose-ares-runware left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Checked

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants