com um clique
discourse-ai-llm-presets
// Use when refreshing the default LLM presets shipped with Discourse AI — model versions, pricing, context windows, vision flags, and the matching `model_description` i18n keys.
// Use when refreshing the default LLM presets shipped with Discourse AI — model versions, pricing, context windows, vision flags, and the matching `model_description` i18n keys.
Write and structure RSpec tests for Discourse core, plugins, themes, or theme components. Use when creating or modifying model specs, controller specs, service specs, job specs, system tests, or integration tests. Covers fabricators, page objects, test structure, and theme test setup.
Use when adding a new upcoming change feature flag to Discourse - handles site settings, translations, images, and code access patterns
MUST load before writing or reviewing any database migration (db/migrate, db/post_migrate, plugin migrations)
Use when modifying, debugging, or extending the upcoming changes framework code and system itself.
Capture screenshots of the local Discourse site across the two core themes (Foundation, Horizon) and color modes (light, dark). Use when the user asks for "screenshots of themes", "light/dark mode shots", or similar.
Generate a Discourse-style commit message and PR description from current changes
| name | discourse-ai-llm-presets |
| description | Use when refreshing the default LLM presets shipped with Discourse AI — model versions, pricing, context windows, vision flags, and the matching `model_description` i18n keys. |
Discourse AI ships a curated set of LLM model presets in plugins/discourse-ai/lib/completions/llm_presets.rb so admins can create new LLM configurations with one click. This skill keeps them current — refreshing model IDs, pricing, context windows, and vision flags as providers evolve.
| Path | What lives there |
|---|---|
plugins/discourse-ai/lib/completions/llm_presets.rb | The four provider preset blocks: anthropic_preset, google_preset, open_ai_preset, open_router_preset. |
plugins/discourse-ai/config/locales/client.en.yml | One-line model_description strings keyed by <provider_id>-<model_name> with .///: replaced by -. Every preset model needs a matching key. |
Out of scope for this skill:
plugins/discourse-ai/config/eval-llms.yml — internal evaluation suite. May reference older models intentionally; do not auto-update.client.de.yml, client.es.yml, …) — translations are managed via Crowdin. Only update client.en.yml; stale keys in other locales clean up automatically.LlmModel DB rows. Preset changes only affect new one-click creations; previously-configured models keep working under their original names.Two primary sources, cross-reference both:
https://www.llm-prices.com/current-v1.json — curated pricing for first-party APIs (Anthropic, OpenAI, Google, xAI, etc.). Has input, output, and input_cached per 1M tokens.https://catwalk.charm.land/v2/providers — broader catalog with context windows, max output tokens, vision flags, cached pricing, and provider defaults (default_large_model_id, default_small_model_id). Use for context windows and vision support that llm-prices omits.For the OpenRouter provider list specifically, also use:
curl -s "https://openrouter.ai/api/frontend/models/find?order=top-weekly&limit=30"
The user's reference URL is https://openrouter.ai/models?fmt=cards&order=top-weekly&output_modalities=text but WebFetch cannot read it — go straight to the API.Each preset block is a hash with id, models (array), tokenizer, endpoint, and provider. Each model entry uses the model(...) helper:
model(
name: "claude-sonnet-4-6", # API model name — also the lookup key
tokens: 1_000_000, # context window in tokens
display_name: "Claude Sonnet 4.6",
max_output_tokens: 64_000,
input_cost: 3.0, # USD per 1M input tokens
cached_input_cost: 0.30, # USD per 1M cached input tokens
cache_write_cost: 3.75, # Anthropic-specific
output_cost: 15.0,
vision_enabled: true,
endpoint: "...", # only when the model needs a different endpoint than the provider default
)
Notes:
cache_write_cost is currently only set on Anthropic models (Anthropic has a separate write price).vision_enabled defaults to false and is only added when true. Trust catwalk's supports_attachments flag — it has been wrong in the file before (e.g. minimax-m2.7 and glm-5.1 were marked vision-capable but are text-only).endpoint per model because the API path encodes the model name.endpoint: is chat/completions but every model overrides it with /responses — leave the provider-level value alone.gpt-5.4 and gpt-5.4-mini is redundant when gpt-5.4-nano already covers the cheap end).default_large_model_id and default_small_model_id as a hint for what the provider currently considers canonical.:free variants — they rotate out of OpenRouter within weeks and break presets.~latest aliases (slug starts with ~, e.g. ~anthropic/claude-sonnet-latest) — those redirect and the underlying model can change.Every preset model needs a one-line description in config/locales/client.en.yml under discourse_ai.llms.model_description. The key format is:
<provider_id>-<model_name>
…with ., /, and : all replaced by - (handled in JS by llm.id.replace(/[.:\/]/g, "-") in ai-llms-list-editor.gjs).
Examples:
| Provider | Model name | i18n key |
|---|---|---|
anthropic | claude-opus-4-7 | anthropic-claude-opus-4-7 |
open_ai | gpt-5.4 | open_ai-gpt-5-4 |
open_router | deepseek/deepseek-v4-flash | open_router-deepseek-deepseek-v4-flash |
open_router | moonshotai/kimi-k2.6 | open_router-moonshotai-kimi-k2-6 |
Whenever a model is added, renamed, or removed in llm_presets.rb, the matching key must be added/renamed/removed in client.en.yml. Missing keys silently fall through to an empty description (I18n.lookup(..., { ignoreMissing: true })).
Fetch source data in parallel:
curl -s https://www.llm-prices.com/current-v1.json -o /tmp/llm_prices.json
curl -s https://catwalk.charm.land/v2/providers -o /tmp/catwalk.json
curl -s "https://openrouter.ai/api/frontend/models/find?order=top-weekly&limit=30" -o /tmp/or_top.json
Read the current presets file at plugins/discourse-ai/lib/completions/llm_presets.rb.
For each first-party provider block (Anthropic / Google / OpenAI): cross-reference each model's tokens, max_output_tokens, all *_cost fields, and vision_enabled against catwalk + llm-prices. Catwalk wins on context windows and vision flags; llm-prices wins on first-party API pricing.
For the OpenRouter block: parse /tmp/or_top.json, filter out :free, slugs starting with ~, and first-party Anthropic/Google/OpenAI models. Take the top 5–6 remaining as the new list. Pricing comes from each entry's endpoint.pricing (multiply by 1_000_000 for per-1M tokens).
Apply edits to llm_presets.rb — prefer targeted Edit calls per model rather than rewriting whole blocks.
Update client.en.yml — add/rename/remove model_description keys to exactly match the new model set. Diff the model name list before/after to make sure no key is left orphaned.
Validate:
bundle exec rubocop --force-exclusion plugins/discourse-ai/lib/completions/llm_presets.rb
ruby -ryaml -e "YAML.load_file('plugins/discourse-ai/config/locales/client.en.yml'); puts 'YAML OK'"
Also grep for orphaned references to any removed model names elsewhere in the plugin:
grep -rn "<old-model-name>" plugins/discourse-ai --include="*.rb" --include="*.js" --include="*.gjs" --include="*.yml" \
| grep -v lib/completions/llm_presets.rb
Summarise the diff to the user grouped by provider, calling out any pricing corrections (these are usually the most consequential — e.g. a model whose price had drifted vs. the provider's current price).
client.en.yml in the same commit.llm-prices or catwalk's first-party listing.vision_enabled has been incorrect in the past — verify against catwalk every refresh.spec/system/llms/ai_llm_spec.rb and lib/completions/endpoints/aws_bedrock.rb reference Anthropic model names by string. Grep before renaming.:free and ~latest alias slugs both churn faster than the release cycle of this file. Always skip them.