( modelInput: ModelName | ModelAlias, )
| 556 | * @param modelInput The model alias or name provided by the user. |
| 557 | */ |
| 558 | export function parseUserSpecifiedModel( |
| 559 | modelInput: ModelName | ModelAlias, |
| 560 | ): ModelName { |
| 561 | const modelInputTrimmed = modelInput.trim() |
| 562 | const normalizedModel = modelInputTrimmed.toLowerCase() |
| 563 | |
| 564 | const has1mTag = has1mContext(normalizedModel) |
| 565 | const modelString = has1mTag |
| 566 | ? normalizedModel.replace(/\[1m]$/i, '').trim() |
| 567 | : normalizedModel |
| 568 | |
| 569 | // BYOK OpenAI-compat: the model id names a model on the user's own server and |
| 570 | // must pass through verbatim. Never resolve it against the built-in NCODE |
| 571 | // managed-model aliases — an id that collides with a reserved alias (e.g. |
| 572 | // `glm-5.2`, `k2.7`) would otherwise be rewritten to an internal deployment |
| 573 | // path the user's server does not recognize, causing a 404. |
| 574 | if (!isOpenAICompatByokActive()) { |
| 575 | const exactNcodeModel = resolveNCodeManagedModel(normalizedModel) |
| 576 | if (exactNcodeModel) { |
| 577 | return exactNcodeModel.model |
| 578 | } |
| 579 | } |
| 580 | |
| 581 | if (isModelAlias(modelString)) { |
| 582 | switch (modelString) { |
| 583 | case 'opusplan': |
| 584 | return getDefaultOpusModel() + (has1mTag ? '[1m]' : '') // Opus-tier reasoning in plan mode |
| 585 | case 'sonnet': |
| 586 | return getDefaultFlashModel() + (has1mTag ? '[1m]' : '') |
| 587 | case 'haiku': |
| 588 | return getDefaultHaikuModel() + (has1mTag ? '[1m]' : '') |
| 589 | case 'opus': |
| 590 | return getDefaultOpusModel() + (has1mTag ? '[1m]' : '') |
| 591 | case 'best': |
| 592 | return getBestModel() |
| 593 | default: |
| 594 | } |
| 595 | } |
| 596 | |
| 597 | // See the BYOK note above: managed-alias resolution is skipped entirely for |
| 598 | // BYOK OpenAI-compat sessions so the user's model id is forwarded verbatim. |
| 599 | if (!isOpenAICompatByokActive()) { |
| 600 | const ncodeModel = resolveNCodeManagedModel(modelString) |
| 601 | if (ncodeModel) { |
| 602 | return ncodeModel.model |
| 603 | } |
| 604 | } |
| 605 | |
| 606 | // Opus 4/4.1 are no longer available on the first-party API (same as |
| 607 | // the Anthropic first-party API) — silently remap to the current Opus default. The 'opus' |
| 608 | // alias already resolves to 4.6, so the only users on these explicit |
| 609 | // strings pinned them in settings/env/--model/SDK before 4.5 launched. |
| 610 | // 3P providers may not yet have 4.6 capacity, so pass through unchanged. |
| 611 | if ( |
| 612 | getAPIProvider() === 'firstParty' && |
| 613 | isLegacyOpusFirstParty(modelString) && |
| 614 | isLegacyModelRemapEnabled() |
| 615 | ) { |
no test coverage detected