pi-mono/packages/ai/catalog
robopipi[bot] d53980fe11
fix(ai): add glm-5.3 to qwen-token-plan-individual models (#11785)
`qwen-token-plan-individual` filters the models.dev `alibaba-token-plan`
catalog through a fixed list of model IDs. That list still stopped at
`glm-5.2`. models.dev now has `glm-5.3`, and `qwen-token-plan` and
`qwen-token-plan-cn` already list it. Individual did not, because
`glm-5.3` was not on its list.

This change adds `glm-5.3` to the Individual list and updates the
"verified" date in the comment above it.

Tests in `packages/ai/test/qwen-token-plan-models.test.ts`:
- `glm-5.3` is added to the expected list for the exact-list test.
- A new test checks that Individual's `glm-5.3` uses the international
Token Plan base URL. It also checks the thinking levels models.dev gives
for it: low, high and max.

How I tested it:
- `npm run generate-models`, then `test/qwen-token-plan-models.test.ts`:
all 90 tests pass. Without the change to the list, 3 tests fail.
- `npm run check` passes.
- Before: `pi --list-models qwen-token-plan-individual` listed `glm-5.2`
but not `glm-5.3`. After: it lists both.

Fixes #11658

Requested by @badlogic

Co-authored-by: triagent <triagent@localhost>
2026-11-04 09:54:48 +01:00
..
families feat(ai): refactor provider definitions (#11368) 2026-10-28 11:06:10 +01:00
providers fix(ai): add glm-5.3 to qwen-token-plan-individual models (#11785) 2026-11-04 09:54:48 +01:00
sources feat(ai): refactor provider definitions (#11368) 2026-10-28 11:06:10 +01:00
build.ts feat(ai): refactor provider definitions (#11368) 2026-10-28 11:06:10 +01:00
define.ts feat(ai): refactor provider definitions (#11368) 2026-10-28 11:06:10 +01:00
generate.ts feat(ai): refactor provider definitions (#11368) 2026-10-28 11:06:10 +01:00
README.md feat(ai): refactor provider definitions (#11368) 2026-10-28 11:06:10 +01:00
reasoning.ts feat(ai): refactor provider definitions (#11368) 2026-10-28 11:06:10 +01:00

Model catalog

node catalog/generate.ts (npm run generate-models) fetches upstream catalogs and writes the built-in model catalog:

  • src/providers/data/<provider>.json: model values, grouped by API (gitignored)
  • src/providers/<provider>.models.ts and src/models.generated.ts: typed wrappers (committed)
  • with --json-output <dir>: the public catalog JSON served by pi.dev

Layout

Path Contents
sources/ Upstream fetchers. models-dev.ts normalizes the models.dev v2 catalog; OpenRouter, Vercel AI Gateway, NVIDIA NIM, and Radius have their own modules. All sources are fetched before anything is built.
providers/<id>.ts One file per built-in provider: where its models come from, its API and base URL, compat defaults, corrections, and models upstream does not list. Register new files in providers/index.ts.
families/ Facts about a model family that hold on every host, such as Claude effort levels or GPT-6 thinking levels. They apply to every provider's models.
define.ts defineProvider() and the helpers provider files use.
build.ts Runs the provider definitions in a fixed order.

Build order

For each provider:

  1. models(ctx) returns its chat models: upstream entries mapped to pi models, data corrections (limits, prices), and authored models. ctx.providerModels(id) returns another provider's models from this step, e.g. Azure derives from OpenAI.
  2. compat defaults for each API are merged under each model's own compat. Then the shared rules run: models.dev effort levels for APIs that send them natively, and the rules in families/.
  3. finalize(model, ctx) applies provider-specific behavior. It runs after the shared rules, so its values win.
  4. Image input limits get the default resize profile, then finalizeAll(models, ctx) runs cross-model logic such as Anthropic's allowed fallback models.

Adding a provider

Most providers are a models.dev provider served on one API:

import { defineProvider, modelsDevModels } from "../define.ts";

export default defineProvider({
	id: "example",
	models: (ctx) =>
		modelsDevModels(ctx, "example", { api: "openai-completions", baseUrl: "https://api.example.com/v1" }),
	compat: { "openai-completions": { supportsStore: false, supportsDeveloperRole: false } },
});

modelsDevModels() keeps tool-capable chat models and maps names, input modalities, costs (including context tiers), and limits. Use its include and map options for provider-specific filtering and fields. Prefer fixing wrong upstream data in models.dev; keep local corrections small and say why they exist.

Checking changes

npm run diff:model-catalog -- [provider ...] from the repository root generates the catalog at HEAD and in the worktree and prints the JSON differences.