fix(config): preserved LM Studio native modalities

Keep the richer LM Studio /api/v0/models input metadata ahead of the thin OpenAI-compatible row while retaining row-first behavior for generic openai-models-list discovery. Add a regression covering a text-only /v1/models row paired with a native VLM record.
This commit is contained in:
roboomp
2026-08-04 03:24:53 +00:00
parent a29acbfa40
commit 0c27e521c4
2 changed files with 34 additions and 2 deletions
@@ -826,8 +826,8 @@ export async function discoverOpenAIModelsList(
baseUrl,
reasoning: reference?.reasoning ?? false,
thinking: inheritReferenceThinking(undefined, reference, providerConfig.provider),
input: extractOpenAIModelsListInputCapabilities(item) ??
nativeMetadataForModel?.input ??
input: nativeMetadataForModel?.input ??
extractOpenAIModelsListInputCapabilities(item) ??
reference?.input ?? ["text"],
...(providerConfig.discovery.type === "lm-studio" ? { imageInputDecoder: "stb" as const } : {}),
// Proxy/gateway pricing is provider-specific and rarely matches
@@ -2212,6 +2212,38 @@ providers:
expect(registry.find("openai-test", "medium")?.input).toEqual(["text"]);
});
test("lm-studio discovery keeps native VLM modalities over a thin OpenAI row", async () => {
writeRawModelsJson({
"lm-studio-test": {
baseUrl: "http://127.0.0.1:9995",
api: "openai-completions",
auth: "none",
discovery: { type: "lm-studio" },
},
});
const fetchMock: FetchImpl = async input => {
const url = String(input);
if (url === "http://127.0.0.1:9995/v1/models") {
return new Response(JSON.stringify({ data: [{ id: "local-vlm", object: "model", input: ["text"] }] }), {
status: 200,
headers: { "Content-Type": "application/json" },
});
}
if (url === "http://127.0.0.1:9995/api/v0/models") {
return new Response(
JSON.stringify({
data: [{ id: "local-vlm", type: "vlm", capabilities: ["vision"], state: "loaded" }],
}),
{ status: 200, headers: { "Content-Type": "application/json" } },
);
}
throw new Error(`Unexpected URL: ${url}`);
};
const registry = new ModelRegistry(authStorage, modelsJsonPath, { fetch: fetchMock });
await registry.refresh();
expect(registry.find("lm-studio-test", "local-vlm")?.input).toEqual(["text", "image"]);
});
test("proxy discovery honors API-reported context_length and endpoint routing", async () => {
writeRawModelsJson({
"proxy-test": {