Skip to content
skyl

Model IDs are pass-through

Never block a user from a model they are entitled to use.

Request.Model is an opaque string passed straight to the provider. skyl ships no model constants and validates nothing against a list. This is the most consequential decision in the project.

The rule#

A library that maintains a hardcoded list of valid model IDs will, inevitably, reject a model that its user is entitled to use — because the model shipped last Tuesday and the library has not cut a release.

A model released after your skyl build works immediately.

The evidence#

Consider a four-week window in mid-2026:

ModelReleased
GPT-5.6 Sol9 Jul 2026
Gemini 3.6 Flash21 Jul 2026
Claude Opus 524 Jul 2026
Qwen3.7 Flash27 Jul 2026

Any hardcoded table is wrong within weeks. And the failure mode is the worst possible one: skyl rejecting a model you are already paying for.

What it costs you#

What follows from it#

  • Client.Models(ctx) asks the provider live rather than returning a compiled-in list, so the answer is never stale.
  • The sandbox serves a deliberately small model catalogue and 404s anything else — a sandbox that accepted every string would never exercise the not-found path, which is the only thing between a typo and an unactionable failure.
  • Model metadata, when it lands, will be a generated registry refreshed from live endpoints by CI — never a hand-typed table that silently rots.

In practice#

Keep model IDs in configuration

goCompiles
type Config struct {
	FastModel  string `env:"FAST_MODEL,required"`
	SmartModel string `env:"SMART_MODEL,required"`
}
type Config struct {
	FastModel  string `env:"FAST_MODEL,required"`
	SmartModel string `env:"SMART_MODEL,required"`
}

Changing model becomes a deploy rather than a release — which is the benefit pass-through was protecting.

Validate at startup, not per request

// A cheap sanity check. Per request it doubles your calls, and the list is a
// snapshot that can go stale between the check and the call.
if err := checkModels(ctx, client, cfg.FastModel, cfg.SmartModel); err != nil {
	return err
}
// A cheap sanity check. Per request it doubles your calls, and the list is a
// snapshot that can go stale between the check and the call.
if err := checkModels(ctx, client, cfg.FastModel, cfg.SmartModel); err != nil {
	return err
}

Recorded as ADR-0004.

Edit this page on GitHub