# Teach crystl your models once

> Fill in what small, standard, and large launch for your own agents so heroes, quests, and scheduled runs land on the model you meant.

**Goal:** fill in what `small`, `standard`, and `large` launch for the agent you run, once, so you stop typing model ids.

## What you need

- An agent installed and running in a shard. Profiles follow the exact launch command, with native sharing for bare seeded commands as described below.
- Reading and writing the profile are **free on every tier**. It's local machine config.

crystl ships no size-to-model table on purpose. Model ids churn, there are more agent CLIs every month, and a compiled-in list would be stale the moment a provider renames something. So the map is learned from you.

## Steps

1. **See what's already known:**

   ```bash
   crystl agent profile
   crystl agent profile show --agent codex
   ```

2. **Fill it in.** Pick the agent's cheapest and fastest setup for `--small`, its everyday default for `--standard`, and its most capable for `--large`:

   ```bash
   crystl agent profile set --agent codex \
     --small gpt-5.6-luna --standard gpt-5.6-sol --large gpt-5.6-terra
   ```

   A size holds the complete command you would type in a terminal, which is the form to reach for whenever the setup also needs effort, a path, environment, or other arguments:

   ```bash
   crystl agent profile set --agent claude \
     --small 'claude --model haiku --effort low' \
     --standard 'claude --model sonnet --effort high' \
     --large 'claude --model opus --effort max'
   ```

   crystl preserves structured commands exactly. Put pipelines, redirects, substitutions, or command lists in a wrapper script. A bare model id like the codex example above still works: crystl composes it into a command through that agent's known convention, and rewrites it as the full command the next time you edit the profile. Only the sizes you pass change, so you can do one now and the rest later. Passing an empty string clears one.

   Any of these can name an [open-model connection](/docs/open-models/) with `model@endpoint`, including inside a command's own flag: `--standard 'claude --model glm-4.6@glm'`.

   For a custom command using bare model ids, also tell crystl how to deliver the chosen model. **MODEL VIA** accepts a template with exactly one `{model}`: `'-m {model}'`, `'--model {model}'`, or `'MODEL={model}'`. A complete command in the size field needs no template.

   ```bash
   crystl agent profile set --agent 'npx my-agent --fast' \
     --small model-mini --standard model-pro --large model-max \
     --model-via '--model {model}'
   ```

   crystl appends argument templates to the full command and prefixes the environment form. It never guesses an unknown CLI's convention.

3. **Or let crystl read the list for you** when the models come from an [open-model connection](/docs/open-models/) you configured:

   ```bash
   crystl agent profile suggest --agent codex --slot closet-box
   ```

   It reads the models the endpoint serves, proposes a mapping, and waits for a yes. It never writes a profile unprompted.

4. **Or click it in.** **Settings → agents → agents** has one row per native profile or configured exact command, and small, standard, and large are properties of that agent. Each size field accepts a complete start command or a bare model id; custom and exact full-command rows also have **MODEL VIA** for bare model ids.

5. **Set the fallbacks too.** **Settings → agents → defaults** holds exactly three raw launch commands, one per size. Those are what run when nothing names an agent, which is the case for an unassigned hero, quest member, or fan-out worker.

## What you'll see when it works

`crystl agent profile` prints the map, stored at `~/.config/crystl/agent-profiles.json`. A bare seeded command resolves to its native profile, so recognized aliases such as `agy` and `antigravity` share one row. A user-owned path, arguments, leading environment assignments, wrapper, or full custom command gets a distinct exact profile. Exact profiles can inherit untouched native settings when crystl recognizes the executable, while their own overrides remain separate.

Summon a [hero](/docs/hero-shards/) or launch a party at a size and it starts with that size's command instead of the agent's default.

Nothing breaks if you skip the size map. A size is a hint that's allowed to evaporate: with no profile, or no mapping for the requested size, crystl passes no model selection and the agent launches on whatever it's configured to run. A custom command with a selected model still needs MODEL VIA; crystl warns or refuses instead of guessing its syntax.

Which model actually launches, most deliberate first: an explicit model (a hero's pin, or `--model` on the summon), then the size, through the named agent's own three or the three defaults, then nothing.

## Go deeper

- [model sizes](/docs/model-sizes/) for why sizes exist and how they resolve.
- [Starting a quest](/docs/starting-a-quest/#2-choose-a-model-size) for running a whole party at one size.
- [CLI reference](/docs/cli/#agent-profile) for every flag.

---
Source: https://crystl.dev/docs/scenario-teach-crystl-your-models/
