Skip to content

fix: support custom models not in DEFAULT_MODELS (issue #4221)#6858

Draft
ljluestc wants to merge 1 commit into
ChatGPTNextWeb:mainfrom
ljluestc:private/issue-4221-custom-model-fix
Draft

fix: support custom models not in DEFAULT_MODELS (issue #4221)#6858
ljluestc wants to merge 1 commit into
ChatGPTNextWeb:mainfrom
ljluestc:private/issue-4221-custom-model-fix

Conversation

@ljluestc

Copy link
Copy Markdown

fix: Support custom models not in DEFAULT_MODELS (issue #4221)

Problem

When a user adds a custom model name (e.g. chatglm3-6b) through the Custom
Model setting and then sends a message, NextChat would fail because:

  1. TypeScript type mismatchModelType was narrowly typed as a union of
    literal strings from DEFAULT_MODELS. Any custom model name was not part of
    that union, leading to unsafe as ModelType casts throughout the code.

  2. Incorrect {{ServiceProvider}} in templatesfillTemplateWith looked
    up the model only in DEFAULT_MODELS. For custom models the lookup returns
    undefined, causing the service provider to always fall back to "OpenAI"
    even when a different provider was actually configured.

  3. Server-side model gate could incorrectly block custom models
    isModelNotavailableInServer checked a fixed list of provider names. If the
    request arrived with only standard provider names (["OpenAI", "Azure"]) but
    the model was added as a provider-less custom model (stored under the key
    <name>@<name>), the model could still be denied even though the server's
    CUSTOM_MODEL env var explicitly listed it.

Root cause (historical)

An older version of the code contained an explicit throw:

const modelInfo = DEFAULT_MODELS.find((m) => m.name === modelConfig.model);
if (!modelInfo) {
  throw new Error(`Model ${modelConfig.model} not found in DEFAULT_MODELS array`);
}

That check was removed, but related fragilities remained.

Changes

app/store/config.ts

  • Widened ModelType from a strict union of built-in model name literals to:
    type ModelType = (typeof DEFAULT_MODELS)[number]["name"] | (string & {});
    The string & {} trick preserves IDE autocomplete for known model names while
    accepting any custom string at the type level — no more unsafe as ModelType.

app/store/chat.ts

  • fillTemplateWith: when the model is not found in DEFAULT_MODELS, the
    function now falls back to modelConfig.providerName for the
    {{ServiceProvider}} template variable, so templates correctly reflect the
    configured provider for user-defined models.

app/utils/model.ts

  • isModelNotavailableInServer: added a final fallback check — if any
    entry in the built model table has name === modelName, available === true,
    and providerType === "custom", the model is allowed. This ensures that a
    custom model listed in the server's CUSTOM_MODEL env var is never blocked
    simply because the incoming request's provider list doesn't match the
    auto-generated <name>@<name> key.

test/custom-model.test.ts (new)

  • 9 new tests covering:
    • collectModelTable with provider-less custom models, explicit-provider
      custom models, disabled custom models, and display-name aliases
    • isModelNotavailableInServer for the standard pattern (provider = model
      name), the new fallback (only ["OpenAI", "Azure"] passed), blocked
      unknown models, and built-in model pass-through

Testing

npx jest test/custom-model.test.ts test/model-available.test.ts test/model-provider.test.ts --no-coverage
# → 21 tests passed, 0 failed

How to reproduce / verify the fix

  1. In NextChat Settings → Custom Model, enter chatglm3-6b (no @provider).
  2. Configure a custom OpenAI-compatible endpoint pointing at your local model
    server (e.g. Ollama, vLLM).
  3. Select chatglm3-6b in the model picker and send a message.
  4. The message routes through the OpenAI-compatible client to your endpoint —
    no "not found in DEFAULT_MODELS" error.

Notes

  • Custom models still route through the OpenAI-compatible client by default
    (getClientApi falls through to the GPT client for unrecognised providers).
    Users who run a custom model behind an OpenAI-compatible API need to configure
    a custom base URL in Settings → Provider.
  • The vision-model-checker.test.ts pre-existing ESM/nanoid parse failure is
    unrelated to this PR and was present on main before these changes.

Branch: private/issue-4221-custom-model-fix
Fixes: #4221

…b#4221)

- Widen ModelType to (typeof DEFAULT_MODELS)[number]["name"] | (string & {})
  so custom model names are accepted by the type system without unsafe casts
- Fix fillTemplateWith to fall back to modelConfig.providerName when the model
  is not found in DEFAULT_MODELS, so {{ServiceProvider}} in templates reflects
  the actual provider for user-defined models
- Add fallback in isModelNotavailableInServer: if any available entry in the
  custom model table has providerType=="custom" and matches the model name, the
  model is allowed even when providerNames doesn't include the model name itself
- Add test/custom-model.test.ts covering collectModelTable and
  isModelNotavailableInServer behaviour for custom models
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Bug] 添加自定义模型信息后报错 Uncaught (in promise) Error: Model chatglm3-6b not found in DEFAULT_MODELS array.

1 participant