Custom (user-added) providers were hard-coded supportModelDiscovery=false in
createCustomProvider, so self-hosted OpenAI-compatible endpoints (vLLM /
Xinference / LocalAI / gateways) never surfaced the 'discover models' button —
users had to add every model id by hand.
- ModelProtocol: add per-protocol supportsSelfConfiguredDiscovery() + resolve()
helper (single source of truth for chat-model class and capability flags).
baseUrl+apiKey protocols (openai-compatible, dashscope-native, gemini-native,
anthropic-messages) => true; OAuth protocols => false. The flag is deliberately
narrower than 'can ever discover' (built-in ChatGPT-OAuth still discovers via
its OAuth session); javadoc warns against reusing it to gate the button.
- createCustomProvider: default supportModelDiscovery from the resolved protocol
instead of always false. Existing rows are unaffected (no migration).
- OpenAiModelsPath: new single source of truth for the models-listing path,
honoring an optional 'modelsPath' generateKwargs override (mirrors the existing
'completionsPath' override) for endpoints behind a reverse proxy / non-standard
prefix (e.g. /openai/v1/models) that would otherwise 404 on /v1/models.
Shared by BOTH discovery (ModelDiscoveryService) and the failover liveness
probe (OpenAiCompatibleListModelsProbe) so an override can't make a provider
discoverable yet still marked unhealthy by a probe hitting the wrong path.
- Tests: ModelProtocolTest (capability table + resolve fallback), OpenAiModelsPathTest
(path branch table + vendor cases + modelsPath override), and custom-provider
discovery-default assertions. Path-resolution coverage consolidated into
OpenAiModelsPathTest (was split across the discovery + probe test files).
- Docs: zh/en models.md note custom-provider discovery + modelsPath override.
Refs matevip/mateclaw#519