# app.Models — the models an app admits, each with a name

> `app.Models` declares more than one model your app may use, each under a name you choose. The name is what your code and your users refer to — `Llm.Fast` — so a call site never quotes a provider's model string, and pointing a name at a different model is a one-line change.

<!-- id: agent-models · area: agent · stability: preview · html: https://osysharp.com/reference/agent/models/ -->

## Summary        {#summary}
[default LLM model (app.DefaultModel)](https://osysharp.com/reference/agent/default-model/) declares one model. `app.Models` declares several, each under a name — so your app can offer
a choice, or use a cheap model for one job and a strong one for another.

## Signature      {#signature}
```osy syntax
app.Models = [
  new LlmConfig("<name>") { Provider = LlmProvider.X, Model = "…", ApiKey = Secret.X, BaseUrl = "…" },
  …
];

app.DefaultModel = Llm.<name>;
```

## Description    {#description}
Each entry is the same `LlmConfig` you would write for a single default, plus a **name of your choosing**.

**The name is a real name, not a string.** You refer to it as `Llm.Fast`, and a name nothing declares is a compile
error that lists what you did declare. So a typo fails the build rather than quietly matching no model, and renaming
an entry breaks every place that used it — which is what you want, because those are the places that need updating.

**Name the models for what they are to your app, not for what the vendor calls them.** `Llm.Fast` and `Llm.Smart`
stay true when you point them at newer models next month; `Llm.Haiku` becomes a lie. The name is also what your users
see if you build a picker.

**`app.DefaultModel` says which one serves a call that does not ask for a particular model:**

```osy syntax
app.DefaultModel = Llm.Fast;
```

Pointing the default at a name rather than repeating the settings means there is one description of each model, so
the default can never disagree with the entry it names. You can still write `app.DefaultModel = new LlmConfig { … }`
directly — that is the right form for an app with only one model, and it keeps working unchanged.

**Your app can only use models it declares.** Naming one at a call site can narrow the choice to any declared model,
but never reach one you did not declare — that is refused, with a reason, rather than quietly served by something
else. `app.Models` is how a model becomes available to be chosen.

**Removing an entry removes the model.** The list is reconciled against your source on every compile, so deleting a
line withdraws that model from the app rather than leaving it behind.

`DefaultModel` is a reserved name — it is how the default itself is stored — so an entry cannot be called that.

## Examples       {#examples}

Two models, one of them the default:

```osy title="two models from one provider, one of them the default" test app=models-two
app.Secrets = [ new Secret("Anthropic") ];

app.Models = [
  new LlmConfig("Fast")  { Provider = LlmProvider.Anthropic, Model = "claude-haiku-4-5", ApiKey = Secret.Anthropic },
  new LlmConfig("Smart") { Provider = LlmProvider.Anthropic, Model = "claude-opus-5",    ApiKey = Secret.Anthropic },
];

app.DefaultModel = Llm.Fast;

entity Note { [MaxLength(140)] string Title; }
```

Models from two different providers, which is the case a single default cannot express at all:

```osy title="two different providers — what a single default cannot express" test app=models-two-providers
app.Secrets = [ new Secret("Anthropic"), new Secret("OpenAI") ];

app.Models = [
  new LlmConfig("Writer")  { Provider = LlmProvider.Anthropic, Model = "claude-opus-5", ApiKey = Secret.Anthropic },
  new LlmConfig("Checker") { Provider = LlmProvider.OpenAI,    Model = "gpt-5",         ApiKey = Secret.OpenAI },
];

app.DefaultModel = Llm.Writer;

entity Draft { [MaxLength(140)] string Title; }
```

## See also       {#see-also}
- [default LLM model (app.DefaultModel)](https://osysharp.com/reference/agent/default-model/) — declaring a single model, for an app that needs only one
- [declaring secrets (app.Secrets)](https://osysharp.com/reference/config/secrets/) — where the `Secret.X` an entry names comes from
- [LlmClient.Stream — a model's answer as it is written](https://osysharp.com/reference/function/llm-stream/) — calling a model
