Research, compare, and update AI model configurations. Covers text model tiers, image and video generation models, image tool models, pricing data sourcing, and provider-cost metering against prepaid org credit. Use when bumping model versions, adding new models, updating pricing, or auditing model specs against provider documentation.
73
90%
Does it follow best practices?
Run evals on this skill
Adds up to 20 points to the overall score
View guide
Passed
No findings from the security scan
| File | Role |
|---|---|
packages/grida-ai-models/src/models.ts | Central catalogue. Sole export is the models namespace: models.text (ModelSpec, catalog, byTier, modelSpecById), models.image, models.audio, models.video, models.image_tools |
packages/grida-ai-models/src/tiers.ts | ModelTier set + TIER_MODEL_IDS (type-uses models.text.CatalogId from models.ts) |
editor/lib/ai/models.ts | AI Gateway + BYOK provider seam (catalogue is re-exported from @grida/ai-models) |
editor/lib/ai/ai.ts | toMills() + Replicate call shapes; re-aggregates the shared catalogue under ai.* |
editor/lib/ai/server.ts | AI seam: prepaid-credit gate, provider call, and post-flight usage ingest |
editor/lib/billing/metronome.ts | Organization credit entitlement, cached balance gate, and Metronome usage ledger |
editor/app/(www)/(ai)/ai/models/page.tsx | Public models catalog page |
docs/models/index.md | User-facing models & pricing documentation |
Script: .agents/skills/ai-models/scripts/model_info.py (symlink to .tools/model_info.py)
# Text / language models
python .agents/skills/ai-models/scripts/model_info.py <model_id>
# Image models
python .agents/skills/ai-models/scripts/model_info.py --image <model_id>
python .agents/skills/ai-models/scripts/model_info.py --image --allSource: models.dev/api.json. Accepts exact IDs (anthropic/claude-sonnet-4.6) or substring search (gpt-5.4).
Note: models.dev has per-token costs but not per-image tier breakdowns. For per-image pricing (OpenAI quality tiers, BFL flat rates), consult provider docs directly.
| Provider | URL |
|---|---|
| OpenAI | https://developers.openai.com/api/docs/models/<model_id> |
| Anthropic | https://docs.anthropic.com/en/docs/about-claude/models |
https://ai.google.dev/pricing | |
| BFL (Flux) | https://docs.bfl.ml/pricing |
| fal.ai | https://fal.ai/models/<endpoint-id> · pricing API: https://fal.ai/docs/documentation/model-apis/pricing |
| OpenRouter | https://openrouter.ai/<vendor>/<model> |
The same model has different ids — and different availability and pricing — across providers; an id is never portable. Two cataloguing patterns:
id is in that
provider's format, and the provider field (or the namespace) fixes the route.vendor/model,
e.g. google/veo-3.1) and carries a providers record (keyed by provider) of bindings,
each with its own call id + meter. Default-provider choice is deferred (see Video Models).
Pick a route with video.binding(card, provider).| Provider | Used in catalogue for | ID format / example |
|---|---|---|
| Vercel AI Gateway | text, image, video binding | google/veo-3.1-generate-001, bytedance/seedance-2.0 |
| Replicate | audio, image_tools | google/lyria-3, nightmareai/real-esrgan |
| fal.ai | video binding (+ image) | fal-ai/veo3.1, fal-ai/kling-video/v3/pro/image-to-video, fal-ai/flux/dev |
| OpenRouter | video binding | google/veo-3.1, google/veo-3.1-fast, google/veo-3.1-lite |
$0.40/s on both Vercel and fal, but fal also meters silent ($0.20/s) and 4K, while OpenRouter exposes only $0/MTok token pricing for video — no usable per-second meter (don't invent one).provider label like audio's "replicate").The catalogue states what is true and useful now. Its shape must never be a record of how recently someone got round to updating it — a stale entry is a wrong answer, not a conservative one.
deprecated: true is for a model someone might still reasonably pick — same
price as its successor, or better at something. Delete the entry when the
successor is strictly dominant (never worse on any axis, better on at least
one): a card nobody should choose is noise in every picker, and keeping it is
not caution.Removal is the kill switch — the id stops passing the run gate, and on a
published catalogue that reaches installed clients within a refresh interval
(docs/wg/platform/hosted-ai.md). That decisiveness is the point; it also means
removal is the wrong tool for tidying.
Live in packages/grida-ai-models/src/models.ts under models.text.catalog: Record<CatalogId, ModelSpec>. The tier set and tier→model id table sit in packages/grida-ai-models/src/tiers.ts and type-use models.text.CatalogId from models.ts — so every tier id must resolve to a real catalogued spec.
Fields to update per tier:
id — gateway format: provider/model-namelabel — human-readable namecontextWindow, outputLimit — from model_info.pycost — { input, output, cacheRead?, cacheWrite? } per 1M tokensLive in packages/grida-ai-models/src/models.ts under models.image.models. Editor consumers reach the same data via import { ai } from "@/lib/ai/ai" (a thin re-aggregator that adds ai.toMills and ai.server.methods.*).
Three pricing schemes, modeled as discriminated union ImageModelPricing:
per_image_tiered — quality x size tiers (e.g. OpenAI)
{ type: "per_image_tiered", tiers: { "medium/1024x1024": 0.034, ... } }
per_image_flat — single price per image (e.g. BFL Flux)
{ type: "per_image_flat", usd: 0.06 }
per_token — charged by token (e.g. Google Gemini)
{ type: "per_token", input: 0.5, output: 3.0 }pricing — real provider data, one of the three types aboveavg_cost_usd — fallback billable-cost estimate, not displayed to users. Mid-tier for tiered, flat rate for flat, conservative estimate for per-token.min_width, max_width, min_height, max_height, sizes — dimension constraintsImageModelId type unionImage generation currently routes through the Vercel AI Gateway (gateway.image(id)); fal.ai is the main alternative for models the gateway lacks (see Providers & model IDs). For a new provider:
provider label for fal.ai / OpenRouter)Vendor type if neededLogos map on the models pageLive in models.video.models in packages/grida-ai-models/src/models.ts. The video provider ecosystem is fragmented, so unlike image/audio (one card = one provider) a video card is canonical: id is provider-agnostic (vendor/model, e.g. google/veo-3.1) and holds the intrinsic specs; per-provider routes live in providers, a record keyed by provider.
id (canonical), label, vendor, aspect_ratios, min_duration/max_duration, audio, default (resolution/aspect/duration/audio), url (original vendor's model card).providers: Partial<Record<VideoProvider, VideoProviderBinding>> — one binding per serving provider: provider, id, pricing, avg_cost_usd, optional url/deprecated. No preference order — the default-provider choice is deliberately deferred to the runtime. Look a route up with video.binding(card, provider).Cards catalogue the image-to-video route only (canvas-relevant; Grok's sole mode), so each binding has a single id — on fal the capability is keyed into the id (fal-ai/veo3.1/image-to-video). Don't add a per-capability endpoints map until a second capability is actually served: identical ids across capabilities are YAGNI, and divergent ones (other fal endpoints) are a new binding/id when needed.
provider is a bare routing tag — auth (incl. BYOK) is a runtime concern, not catalogue data, so there is no provider registry or byok flag. The catalogue's only job is to hold each provider's real id + rate.
avg_cost_usd (per binding) = its rate at the model's default (resolution, audio) × default duration, plus any required input-image surcharge. Video dwarfs image costs (Veo 3.1 ≈ $3.20 for an 8s 1080p clip). The current prepaid-credit gate checks a global balance floor, not an estimated per-request ceiling, so audit metering and bounded-overspend exposure before serving a new video route.
per_second, nested resolution → audio-mode → USD/s, with an optional
provider-native usd_per_input_image surcharge. The rate varies by both
resolution and whether audio is generated, so the keys are the exact
(resolution, mode) combos that provider serves & meters:
{ type: "per_second", usd_per_second: {
"720p": { audio: 0.4, silent: 0.2 }, // fal: meters both modes
"1080p": { audio: 0.4, silent: 0.2 },
"4k": { audio: 0.6, silent: 0.4 },
} }
// Vercel Veo omits "4k" + "silent" (gateway sells neither); Seedance lists only "audio" (bundled free).listed: false, and compatibility-only records stay out
entirely.VideoModelId and a card with ≥1 binding. Every binding must price the model's default (resolution, audio) — enforced by catalogue-invariant tests (plus: provider field matches key).VideoProviderBinding under its provider key, only with a verified rate (e.g. OpenRouter surfaces $0/MTok for video — not usable; leave it out).id shape only then.Live in models.image_tools.models in packages/grida-ai-models/src/models.ts. Flat cost_usd pricing via Replicate.
Grida Gateway (GG) usage is metered against the organization's prepaid AI credit. Unit: mills (1 mill = $0.001 USD).
ai.toMills(cost_usd) converts a provider cost to the integer usage unit.avg_cost_usd only where the provider does not
expose a more exact billable dimension.pnpm tsc --noEmit passesdocs/models/index.md matches the code/ai/models page renders correctly8ef5e53
If you maintain this skill, you can claim it as your own. Once claimed, you can manage eval scenarios, bundle related skills, attach documentation or rules, and ensure cross-agent compatibility.