#11198: fix(models): strip @profile suffix from model selection
agents
size: S
trusted-contributor
experienced-contributor
Fixes #10882
#### Summary
When using `/model provider/model@profile:name` syntax, the `@profile` suffix was included in the model name during allowlist lookup, causing a "model not allowed" error even when the model is properly configured.
#### Repro Steps
1. Configure an allowlist with `nvidia/moonshotai/kimi-k2.5`
2. Send `/model nvidia/moonshotai/kimi-k2.5@nvidia:default`
3. Result: "model not allowed" error because the key becomes `nvidia/moonshotai/kimi-k2.5@nvidia:default` instead of `nvidia/moonshotai/kimi-k2.5`
#### Root Cause
`resolveModelRefFromString()` in `src/agents/model-selection.ts` passed the full input (including `@profile` suffix) to `parseModelRef()`. The inline directive path (`extractModelDirective()` in `src/auto-reply/model.ts`) already strips `@profile` before calling resolution, but the session reset path (`applyResetModelOverride()` → `buildSelectionFromExplicit()`) does not — it calls `resolveModelRefFromString()` with the raw token.
Fixing at the `resolveModelRefFromString()` level ensures all code paths that resolve model refs correctly strip the `@profile` suffix, regardless of whether the caller pre-strips it.
#### Behavior Changes
- `resolveModelRefFromString()` now strips `@profile` suffix before alias lookup and `parseModelRef()` call
- No change to `parseModelRef()` itself (profile stripping is an application-level concern, not a model-ref concern)
- Existing callers that already strip `@profile` (inline directive path) are unaffected — double-stripping is safe
#### Codebase and GitHub Search
- Searched for all callers of `resolveModelRefFromString` — confirmed session reset path and directive handling path both benefit
- Searched for `@` handling in model resolution — `extractModelDirective()` already strips but `resolveModelRefFromString` did not
- No existing PRs or claims on #10882
#### Tests
4 new tests in `src/agents/model-selection.test.ts` — all 4 fail before fix, pass after:
- [x] Strip `@profile` suffix from `provider/model` input (`nvidia/moonshotai/kimi-k2.5@nvidia:default`)
- [x] Strip `@profile` suffix from single-segment model input (`gpt-5@myprofile`)
- [x] Strip `@profile` suffix with colon in profile name (`google/gemini-flash-latest@google:bevfresh`)
- [x] Resolve alias with `@profile` suffix (`kimi@nvidia:default`)
Full test suite: 220 tests pass across 36 files. Build and lint clean.
lobster-biscuit
**Sign-Off**
- Models used: Claude Opus 4.6
- Submitter effort: autonomous (TDD)
- Agent notes: Fix applied at deepest shared layer (`resolveModelRefFromString`) to benefit all code paths. The inline directive path already handled this correctly; the session reset path did not.
<!-- greptile_comment -->
<h2>Greptile Overview</h2>
<h3>Greptile Summary</h3>
This PR updates `resolveModelRefFromString()` to strip a trailing `@profile` suffix from model tokens before alias lookup and `parseModelRef()` parsing, fixing allowlist key mismatches when users specify `/model provider/model@profile:name`. It also adds unit tests covering provider/model inputs, single-segment inputs, aliases, and profile names containing colons to ensure all resolution paths behave consistently.
<h3>Confidence Score: 5/5</h3>
- This PR is safe to merge with minimal risk.
- Change is narrowly scoped to stripping `@profile` suffixes before alias lookup/parsing, with added unit tests covering the affected cases. No other resolution logic is altered, and the new behavior is consistent across callers.
- No files require special attention
<!-- greptile_other_comments_section -->
<!-- /greptile_comment -->
Most Similar PRs
#9905: fix: require provider prefix for models set without alias (#5790)
by petter-b · 2026-02-05
82.2%
#7570: fix: allow models from providers with auth profiles configured
by DonSqualo · 2026-02-03
81.9%
#6673: fix: preserve allowAny flag in createModelSelectionState for custom...
by tenor0 · 2026-02-01
80.6%
#9583: fix(models): allow models in agents.defaults.models even if not in ...
by hotzen100 · 2026-02-05
80.1%
#15632: fix: use provider-qualified key in MODEL_CACHE for context window l...
by linwebs · 2026-02-13
79.8%
#9822: fix: allow local/custom model providers for sub-agent inference
by stammtobias91 · 2026-02-05
79.7%
#11349: fix(agents): do not filter fallback models by models allowlist
by liuxiaopai-ai · 2026-02-07
79.6%
#15756: [Security]: strip provider apiKey from models.json before prompt se...
by SecBear · 2026-02-13
79.6%
#20185: fix(model): recognize default/reset/clear keywords to clear session...
by yxshee · 2026-02-18
79.4%
#4459: fix: enable image input for Kimi K2.5 and refresh stale config mode...
by manikv12 · 2026-01-30
79.2%