fix(config): bumped openai-models-list discovery cache namespace

Warm context-v2 rows cached before server input-modality parsing pinned vision-capable ids at input: ["text"] until a forced refresh. Bump the namespace to context-v3 so the modality fix takes effect on the next online-if-uncached refresh, and add a regression proving v2 rows are orphaned.
This commit is contained in:
roboomp
2026-08-04 03:32:06 +00:00
parent 0c27e521c4
commit 67441e2eec
2 changed files with 52 additions and 2 deletions
@@ -1715,7 +1715,10 @@ export class ModelRegistry {
return resolveOllamaModelCacheProviderId(providerConfig.provider, providerConfig.baseUrl);
}
if (providerConfig.discovery.type === "openai-models-list") {
return `${providerConfig.provider}:openai-models-list-context-v2`;
// context-v3 invalidates rows cached before server-advertised input
// modalities were parsed from `/v1/models`; warm v2 rows pinned
// vision-capable ids at `input: ["text"]` until a forced refresh.
return `${providerConfig.provider}:openai-models-list-context-v3`;
}
if (providerConfig.discovery.type === "litellm") {
// rich-v2 invalidates rows cached before reseller usage-suffix stripping
@@ -1876,6 +1876,7 @@ describe("ModelRegistry", () => {
let vertexStale: ModelRegistry;
let litellmStaleNamespaceCache: ModelRegistry;
let litellmCurrentNamespaceCache: ModelRegistry;
let openaiModelsListStaleNamespaceCache: ModelRegistry;
const vertexProjectModel = () =>
buildModel({
id: "zai-org/glm-4.7-maas",
@@ -2101,7 +2102,7 @@ describe("ModelRegistry", () => {
{
seedCache: dbPath =>
writeModelCache(
"cached-compact-proxy:openai-models-list-context-v2",
"cached-compact-proxy:openai-models-list-context-v3",
Date.now(),
[
buildModel({
@@ -2171,6 +2172,45 @@ describe("ModelRegistry", () => {
dbPath,
),
});
openaiModelsListStaleNamespaceCache = readonlyRegistry(
{
providers: {
"stale-openai-proxy": {
baseUrl: "https://stale-proxy.example.com/v1",
apiKey: "TEST_KEY",
api: "openai-completions",
discovery: { type: "openai-models-list" },
models: [],
},
},
},
{
// Row under the retired pre-modality namespace; the context-v3
// bump must orphan it instead of serving the stale text-only row.
seedCache: dbPath =>
writeModelCache(
"stale-openai-proxy:openai-models-list-context-v2",
Date.now(),
[
buildModel({
id: "stale-vlm",
name: "Stale VLM",
api: "openai-completions",
provider: "stale-openai-proxy",
baseUrl: "https://stale-proxy.example.com/v1",
reasoning: false,
input: ["text"],
cost: { input: 0, output: 0, cacheRead: 0, cacheWrite: 0 },
contextWindow: 128_000,
maxTokens: 16_384,
}),
],
true,
"",
dbPath,
),
},
);
});
test("legacy cached discovery sentinels are ignored after nullable limit cutover", () => {
@@ -2223,6 +2263,13 @@ describe("ModelRegistry", () => {
expect(model?.provider).toBe("litellm-proxy");
});
test("ignores openai-models-list rows cached under the retired context-v2 namespace", () => {
// PR #7584 added server-advertised input-modality parsing; warm v2 rows
// pinned vision-capable ids at text-only and must not load.
expect(openaiModelsListStaleNamespaceCache.find("stale-openai-proxy", "stale-vlm")).toBeUndefined();
expect(getModelsForProvider(openaiModelsListStaleNamespaceCache, "stale-openai-proxy")).toHaveLength(0);
});
test("replaces bundled google-vertex models with authoritative Vertex project discovery", () => {
const vertexModels = getModelsForProvider(vertexAuthoritative, "google-vertex");
expect(vertexModels.map(model => model.id)).toEqual(["zai-org/glm-4.7-maas"]);