fix(capabilities): stop caching the catalog source per module copy (#4351)

This commit is contained in:
Mohammad Hijjawi
2026-09-26 16:18:18 +07:00
parent dd293d3c62
commit fdcba3e1b2
2 changed files with 20 additions and 4 deletions

View File

@@ -484,7 +484,8 @@ const MODALITY_KEYS = ["vision", "pdf", "audioInput", "videoInput"];
// The server bundles this module into every route chunk that needs it, and each
// copy carries its own module state, so an install landing in the copy the
// startup hook imported stays invisible to the copy resolving requests. The slot
// lives on globalThis instead; the local binding is the fast path.
// lives on globalThis instead, and every read goes through it: caching it locally
// would keep a reader alive in other copies after setCatalogSource(null).
let catalogSource = null;
/**
@@ -498,9 +499,8 @@ export function setCatalogSource(source) {
}
function getCatalogSource() {
if (catalogSource) return catalogSource;
if (typeof globalThis === "undefined") return null;
return (catalogSource = globalThis.__9rCatalogSource || null);
if (typeof globalThis === "undefined") return catalogSource;
return globalThis.__9rCatalogSource || null;
}
// Apply the synced catalog + name heuristic on top of a table-resolved result.

View File

@@ -122,6 +122,22 @@ describe("model catalog", () => {
}
expect(globalThis.__9rCatalogSource).toBeNull();
});
it("detaches the source from a copy that already resolved through it", async () => {
capabilities.setCatalogSource({
getModalities: (provider) => (provider === "gateway-a" ? { vision: true } : null),
getLimits: () => null,
});
const other = await import("../../open-sse/providers/capabilities.js?copy=3");
try {
expect(other.getCapabilitiesForModel("gateway-a", "laguna-9-preview").vision).toBe(true);
} finally {
capabilities.setCatalogSource(null);
}
// the sync resets the source before rebuilding; a copy that has read the
// slot once must not keep serving the uninstalled reader
expect(other.getCapabilitiesForModel("gateway-a", "laguna-9-preview").vision).toBe(false);
});
});
describe("catalog schema", () => {