Osy#the first language built for agents
Agents firstAgentic appsWorkflowsDurable Execution — built inSecurityTestingThe editorThe UI modelOne program

Reference / Agent

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

app.Models = [ new LlmConfig("Fast") { Provider = LlmProvider.Anthropic, Model = "…", ApiKey = Secret.X } ];

`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.

preview2 examples compiled by CIagentllmconfigprovider

Summary#

default LLM model (app.DefaultModel) 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#

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

app.DefaultModel = Llm.<name>;

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:

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#

Two models, one of them the default:

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:

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#

Related

default LLM model (app.DefaultModel)

Declares the app's default LLM — the provider, model, API-key secret, and optional endpoint — as a single app-level…

declaring secrets (app.Secrets)

`app.Secrets` declares the named secrets your app uses — API keys, tokens, client secrets. Each is `new…

LlmClient.Stream — a model's answer as it is written

`LlmClient.Stream(prompt)` gives you a model's answer in the pieces it was produced in, so a reader sees it being…