Custom OpenAI-Compatible Provider

A custom provider is an OpenAI Chat Completions-compatible service configured by name, Base URL, and API key. The provider type determines the wire protocol; model names do not.

Verified gap

A host-only Base URL currently produces /models and /chat/completions. Some services expose their compatible API below /v1. An HTML website response with status 200 is also currently accepted as a valid credential response.

Address contract

Configured valueResolved API Base
https://hosthttps://host/v1
https://host/https://host/v1
https://host/v1https://host/v1
https://host/compatible-mode/v1unchanged

The stored value remains the user's input. Model listing, credential validation, enabled-model registration, and inference use the resolved value.

Data flow and failures

GET {base}/models validates credentials and lists models. A successful validation response must be JSON. Model rows are stored with api=openai-completions and the resolved Base URL. Runtime inference uses POST {base}/chat/completions.

Authentication rejection, balance errors, rate limits, transport failures, non-JSON success pages, malformed model envelopes, and empty model lists remain distinct observable outcomes. Error text must not include API keys or response bodies.

Compatibility

Existing custom providers and enabled model rows are interpreted at read time with the same resolver, so no configuration migration or re-creation is required. Built-in provider protocols retain their current resolution rules.

Acceptance criteria

Implementation evidence

Implemented through the shared provider Base URL resolver, credential validator, generic OpenAI-compatible model fetcher, listing normalizer, and enabled-model registry. Focused provider tests cover host-only resolution, explicit-path preservation, legacy enabled rows, and non-JSON success responses. The packaged App resolved Yuanheng to https://nan.meta-api.vip/v1 and fetched 10 remote models in the default profile.